diff --git a/firebase-common/src/main/java/com/google/firebase/concurrent/CustomThreadFactory.java b/firebase-common/src/main/java/com/google/firebase/concurrent/CustomThreadFactory.java index b3079db1d20..417435c2abf 100644 --- a/firebase-common/src/main/java/com/google/firebase/concurrent/CustomThreadFactory.java +++ b/firebase-common/src/main/java/com/google/firebase/concurrent/CustomThreadFactory.java @@ -14,26 +14,38 @@ package com.google.firebase.concurrent; +import android.os.Process; +import android.os.StrictMode; import java.util.Locale; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicLong; +import javax.annotation.Nullable; class CustomThreadFactory implements ThreadFactory { private static final ThreadFactory DEFAULT = Executors.defaultThreadFactory(); private final AtomicLong threadCount = new AtomicLong(); private final String namePrefix; private final int priority; + private final StrictMode.ThreadPolicy policy; - CustomThreadFactory(String namePrefix, int priority) { + CustomThreadFactory(String namePrefix, int priority, @Nullable StrictMode.ThreadPolicy policy) { this.namePrefix = namePrefix; this.priority = priority; + this.policy = policy; } @Override public Thread newThread(Runnable r) { - Thread thread = DEFAULT.newThread(r); - thread.setPriority(priority); + Thread thread = + DEFAULT.newThread( + () -> { + Process.setThreadPriority(priority); + if (policy != null) { + StrictMode.setThreadPolicy(policy); + } + r.run(); + }); thread.setName( String.format(Locale.ROOT, "%s Thread #%d", namePrefix, threadCount.getAndIncrement())); return thread; diff --git a/firebase-common/src/main/java/com/google/firebase/concurrent/ExecutorsRegistrar.java b/firebase-common/src/main/java/com/google/firebase/concurrent/ExecutorsRegistrar.java index 1b28eb8aec9..1ea0c4ffd68 100644 --- a/firebase-common/src/main/java/com/google/firebase/concurrent/ExecutorsRegistrar.java +++ b/firebase-common/src/main/java/com/google/firebase/concurrent/ExecutorsRegistrar.java @@ -15,7 +15,10 @@ package com.google.firebase.concurrent; import android.annotation.SuppressLint; +import android.os.Build; import android.os.Process; +import android.os.StrictMode; +import com.google.firebase.BuildConfig; import com.google.firebase.annotations.concurrent.Background; import com.google.firebase.annotations.concurrent.Blocking; import com.google.firebase.annotations.concurrent.Lightweight; @@ -40,7 +43,9 @@ public class ExecutorsRegistrar implements ComponentRegistrar { () -> scheduled( Executors.newFixedThreadPool( - 4, factory("Firebase Background", Process.THREAD_PRIORITY_BACKGROUND)))); + 4, + factory( + "Firebase Background", Process.THREAD_PRIORITY_BACKGROUND, bgPolicy())))); private static final Lazy LITE_EXECUTOR = new Lazy<>( @@ -48,7 +53,7 @@ public class ExecutorsRegistrar implements ComponentRegistrar { scheduled( Executors.newFixedThreadPool( Math.max(2, Runtime.getRuntime().availableProcessors()), - factory("Firebase Lite", Process.THREAD_PRIORITY_DEFAULT)))); + factory("Firebase Lite", Process.THREAD_PRIORITY_DEFAULT, litePolicy())))); private static final Lazy BLOCKING_EXECUTOR = new Lazy<>( @@ -97,6 +102,33 @@ private static ScheduledExecutorService scheduled(ExecutorService delegate) { } private static ThreadFactory factory(String threadPrefix, int priority) { - return new CustomThreadFactory(threadPrefix, priority); + return new CustomThreadFactory(threadPrefix, priority, null); + } + + private static ThreadFactory factory( + String threadPrefix, int priority, StrictMode.ThreadPolicy policy) { + return new CustomThreadFactory(threadPrefix, priority, policy); + } + + private static StrictMode.ThreadPolicy bgPolicy() { + StrictMode.ThreadPolicy.Builder builder = new StrictMode.ThreadPolicy.Builder().detectNetwork(); + if (Build.VERSION.SDK_INT >= 23) { + builder.detectResourceMismatches(); + if (Build.VERSION.SDK_INT >= 26) { + builder.detectUnbufferedIo(); + } + } + if (BuildConfig.DEBUG) { + builder.penaltyDeath(); + } + return builder.penaltyLog().build(); + } + + private static StrictMode.ThreadPolicy litePolicy() { + StrictMode.ThreadPolicy.Builder builder = new StrictMode.ThreadPolicy.Builder().detectAll(); + if (BuildConfig.DEBUG) { + builder.penaltyDeath(); + } + return builder.penaltyLog().build(); } }