Skip to content

Commit 4173c8c

Browse files
authored
Enable strict mode for executors. (#4303)
Any violations would kill the app in debug builds of firebase-common, and log a warning in release builds. This is done to fail tests that incorrectly use executors while not affecting 3p apps in release builds. Additionally correctly set thread priorities in an Android specific way.
1 parent 6b7178a commit 4173c8c

File tree

2 files changed

+50
-6
lines changed

2 files changed

+50
-6
lines changed

firebase-common/src/main/java/com/google/firebase/concurrent/CustomThreadFactory.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,38 @@
1414

1515
package com.google.firebase.concurrent;
1616

17+
import android.os.Process;
18+
import android.os.StrictMode;
1719
import java.util.Locale;
1820
import java.util.concurrent.Executors;
1921
import java.util.concurrent.ThreadFactory;
2022
import java.util.concurrent.atomic.AtomicLong;
23+
import javax.annotation.Nullable;
2124

2225
class CustomThreadFactory implements ThreadFactory {
2326
private static final ThreadFactory DEFAULT = Executors.defaultThreadFactory();
2427
private final AtomicLong threadCount = new AtomicLong();
2528
private final String namePrefix;
2629
private final int priority;
30+
private final StrictMode.ThreadPolicy policy;
2731

28-
CustomThreadFactory(String namePrefix, int priority) {
32+
CustomThreadFactory(String namePrefix, int priority, @Nullable StrictMode.ThreadPolicy policy) {
2933
this.namePrefix = namePrefix;
3034
this.priority = priority;
35+
this.policy = policy;
3136
}
3237

3338
@Override
3439
public Thread newThread(Runnable r) {
35-
Thread thread = DEFAULT.newThread(r);
36-
thread.setPriority(priority);
40+
Thread thread =
41+
DEFAULT.newThread(
42+
() -> {
43+
Process.setThreadPriority(priority);
44+
if (policy != null) {
45+
StrictMode.setThreadPolicy(policy);
46+
}
47+
r.run();
48+
});
3749
thread.setName(
3850
String.format(Locale.ROOT, "%s Thread #%d", namePrefix, threadCount.getAndIncrement()));
3951
return thread;

firebase-common/src/main/java/com/google/firebase/concurrent/ExecutorsRegistrar.java

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515
package com.google.firebase.concurrent;
1616

1717
import android.annotation.SuppressLint;
18+
import android.os.Build;
1819
import android.os.Process;
20+
import android.os.StrictMode;
21+
import com.google.firebase.BuildConfig;
1922
import com.google.firebase.annotations.concurrent.Background;
2023
import com.google.firebase.annotations.concurrent.Blocking;
2124
import com.google.firebase.annotations.concurrent.Lightweight;
@@ -39,15 +42,17 @@ public class ExecutorsRegistrar implements ComponentRegistrar {
3942
() ->
4043
scheduled(
4144
Executors.newFixedThreadPool(
42-
4, factory("Firebase Background", Process.THREAD_PRIORITY_BACKGROUND))));
45+
4,
46+
factory(
47+
"Firebase Background", Process.THREAD_PRIORITY_BACKGROUND, bgPolicy()))));
4348

4449
private static final Lazy<ScheduledExecutorService> LITE_EXECUTOR =
4550
new Lazy<>(
4651
() ->
4752
scheduled(
4853
Executors.newFixedThreadPool(
4954
Math.max(2, Runtime.getRuntime().availableProcessors()),
50-
factory("Firebase Lite", Process.THREAD_PRIORITY_DEFAULT))));
55+
factory("Firebase Lite", Process.THREAD_PRIORITY_DEFAULT, litePolicy()))));
5156

5257
private static final Lazy<ScheduledExecutorService> BLOCKING_EXECUTOR =
5358
new Lazy<>(
@@ -96,6 +101,33 @@ private static ScheduledExecutorService scheduled(ExecutorService delegate) {
96101
}
97102

98103
private static ThreadFactory factory(String threadPrefix, int priority) {
99-
return new CustomThreadFactory(threadPrefix, priority);
104+
return new CustomThreadFactory(threadPrefix, priority, null);
105+
}
106+
107+
private static ThreadFactory factory(
108+
String threadPrefix, int priority, StrictMode.ThreadPolicy policy) {
109+
return new CustomThreadFactory(threadPrefix, priority, policy);
110+
}
111+
112+
private static StrictMode.ThreadPolicy bgPolicy() {
113+
StrictMode.ThreadPolicy.Builder builder = new StrictMode.ThreadPolicy.Builder().detectNetwork();
114+
if (Build.VERSION.SDK_INT >= 23) {
115+
builder.detectResourceMismatches();
116+
if (Build.VERSION.SDK_INT >= 26) {
117+
builder.detectUnbufferedIo();
118+
}
119+
}
120+
if (BuildConfig.DEBUG) {
121+
builder.penaltyDeath();
122+
}
123+
return builder.penaltyLog().build();
124+
}
125+
126+
private static StrictMode.ThreadPolicy litePolicy() {
127+
StrictMode.ThreadPolicy.Builder builder = new StrictMode.ThreadPolicy.Builder().detectAll();
128+
if (BuildConfig.DEBUG) {
129+
builder.penaltyDeath();
130+
}
131+
return builder.penaltyLog().build();
100132
}
101133
}

0 commit comments

Comments
 (0)