Skip to content

Commit 2095003

Browse files
committed
Merge branch 'executors' into vk.thread_detector
2 parents 48b4ddd + 4173c8c commit 2095003

File tree

5 files changed

+362
-7
lines changed

5 files changed

+362
-7
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 & 4 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;
@@ -32,23 +35,24 @@
3235
import java.util.concurrent.ScheduledExecutorService;
3336
import java.util.concurrent.ThreadFactory;
3437

35-
/** @hide */
3638
@SuppressLint("ThreadPoolCreation")
3739
public class ExecutorsRegistrar implements ComponentRegistrar {
3840
private static final Lazy<ScheduledExecutorService> BG_EXECUTOR =
3941
new Lazy<>(
4042
() ->
4143
scheduled(
4244
Executors.newFixedThreadPool(
43-
4, factory("Firebase Background", Process.THREAD_PRIORITY_BACKGROUND))));
45+
4,
46+
factory(
47+
"Firebase Background", Process.THREAD_PRIORITY_BACKGROUND, bgPolicy()))));
4448

4549
private static final Lazy<ScheduledExecutorService> LITE_EXECUTOR =
4650
new Lazy<>(
4751
() ->
4852
scheduled(
4953
Executors.newFixedThreadPool(
5054
Math.max(2, Runtime.getRuntime().availableProcessors()),
51-
factory("Firebase Lite", Process.THREAD_PRIORITY_DEFAULT))));
55+
factory("Firebase Lite", Process.THREAD_PRIORITY_DEFAULT, litePolicy()))));
5256

5357
private static final Lazy<ScheduledExecutorService> BLOCKING_EXECUTOR =
5458
new Lazy<>(
@@ -97,6 +101,33 @@ private static ScheduledExecutorService scheduled(ExecutorService delegate) {
97101
}
98102

99103
private static ThreadFactory factory(String threadPrefix, int priority) {
100-
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();
101132
}
102133
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright 2022 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.google.firebase.concurrent;
16+
17+
import java.util.concurrent.Executor;
18+
19+
/** Provides commonly useful executors. */
20+
public class FirebaseExecutors {
21+
private FirebaseExecutors() {}
22+
23+
/**
24+
* Creates a sequential executor.
25+
*
26+
* <p>Executes tasks sequentially and provides memory synchronization guarantees for any mutations
27+
* of shared state.
28+
*
29+
* <p>For details see:
30+
* https://guava.dev/releases/31.1-jre/api/docs/com/google/common/util/concurrent/MoreExecutors.html#newSequentialExecutor(java.util.concurrent.Executor)
31+
*/
32+
public static Executor newSequentialExecutor(Executor delegate) {
33+
return new SequentialExecutor(delegate);
34+
}
35+
36+
/** Returns a direct executor. */
37+
public static Executor directExecutor() {
38+
return DirectExecutor.INSTANCE;
39+
}
40+
41+
private enum DirectExecutor implements Executor {
42+
INSTANCE;
43+
44+
@Override
45+
public void execute(Runnable command) {
46+
command.run();
47+
}
48+
}
49+
}

0 commit comments

Comments
 (0)