Skip to content

Commit 0c1240e

Browse files
authored
Reduce default timeout on main thread by 1 second to avoid ANRs. (#4685)
* Reduce default timeout on main thread by 1 second to avoid ANRs. * Use an explicit executor in callTask continuation This will prevent it from running on the main thread.
1 parent 0a36c34 commit 0c1240e

File tree

2 files changed

+33
-36
lines changed

2 files changed

+33
-36
lines changed

firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/internal/common/CrashlyticsCore.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public class CrashlyticsCore {
5959
static final String CRASHLYTICS_REQUIRE_BUILD_ID = "com.crashlytics.RequireBuildId";
6060
static final boolean CRASHLYTICS_REQUIRE_BUILD_ID_DEFAULT = true;
6161

62-
static final int DEFAULT_MAIN_HANDLER_TIMEOUT_SEC = 4;
62+
static final int DEFAULT_MAIN_HANDLER_TIMEOUT_SEC = 3;
6363

6464
private static final String ON_DEMAND_RECORDED_KEY =
6565
"com.crashlytics.on-demand.recorded-exceptions";

firebase-crashlytics/src/main/java/com/google/firebase/crashlytics/internal/common/Utils.java

Lines changed: 32 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,8 @@
1414

1515
package com.google.firebase.crashlytics.internal.common;
1616

17-
import static java.util.Objects.requireNonNull;
18-
1917
import android.annotation.SuppressLint;
20-
import androidx.annotation.NonNull;
18+
import android.os.Looper;
2119
import com.google.android.gms.tasks.Continuation;
2220
import com.google.android.gms.tasks.Task;
2321
import com.google.android.gms.tasks.TaskCompletionSource;
@@ -30,9 +28,9 @@
3028
import java.util.concurrent.TimeoutException;
3129

3230
/** Utils */
31+
@SuppressWarnings({"ResultOfMethodCallIgnored", "UnusedReturnValue"})
3332
public final class Utils {
34-
35-
private Utils() {}
33+
private static final int TIMEOUT_SEC = 4;
3634

3735
/** @return A tasks that is resolved when either of the given tasks is resolved. */
3836
// TODO(b/261014167): Use an explicit executor in continuations.
@@ -43,8 +41,8 @@ public static <T> Task<T> race(Task<T> t1, Task<T> t2) {
4341
task -> {
4442
if (task.isSuccessful()) {
4543
result.trySetResult(task.getResult());
46-
} else {
47-
result.trySetException(requireNonNull(task.getException()));
44+
} else if (task.getException() != null) {
45+
result.trySetException(task.getException());
4846
}
4947
return null;
5048
};
@@ -60,8 +58,8 @@ public static <T> Task<T> race(Executor executor, Task<T> t1, Task<T> t2) {
6058
task -> {
6159
if (task.isSuccessful()) {
6260
result.trySetResult(task.getResult());
63-
} else {
64-
result.trySetException(requireNonNull(task.getException()));
61+
} else if (task.getException() != null) {
62+
result.trySetException(task.getException());
6563
}
6664
return null;
6765
};
@@ -72,34 +70,27 @@ public static <T> Task<T> race(Executor executor, Task<T> t1, Task<T> t2) {
7270

7371
/** Similar to Tasks.call, but takes a Callable that returns a Task. */
7472
public static <T> Task<T> callTask(Executor executor, Callable<Task<T>> callable) {
75-
final TaskCompletionSource<T> tcs = new TaskCompletionSource<T>();
73+
final TaskCompletionSource<T> result = new TaskCompletionSource<>();
7674
executor.execute(
77-
new Runnable() {
78-
// TODO(b/261014167): Use an explicit executor in continuations.
79-
@SuppressLint("TaskMainThread")
80-
@Override
81-
public void run() {
82-
try {
83-
callable
84-
.call()
85-
.continueWith(
86-
new Continuation<T, Void>() {
87-
@Override
88-
public Void then(@NonNull Task<T> task) throws Exception {
89-
if (task.isSuccessful()) {
90-
tcs.setResult(task.getResult());
91-
} else {
92-
tcs.setException(task.getException());
93-
}
94-
return null;
95-
}
96-
});
97-
} catch (Exception e) {
98-
tcs.setException(e);
99-
}
75+
() -> {
76+
try {
77+
callable
78+
.call()
79+
.continueWith(
80+
executor,
81+
task -> {
82+
if (task.isSuccessful()) {
83+
result.setResult(task.getResult());
84+
} else if (task.getException() != null) {
85+
result.setException(task.getException());
86+
}
87+
return null;
88+
});
89+
} catch (Exception e) {
90+
result.setException(e);
10091
}
10192
});
102-
return tcs.getTask();
93+
return result.getTask();
10394
}
10495

10596
/**
@@ -126,7 +117,11 @@ public static <T> T awaitEvenIfOnMainThread(Task<T> task)
126117
return null;
127118
});
128119

129-
latch.await(CrashlyticsCore.DEFAULT_MAIN_HANDLER_TIMEOUT_SEC, TimeUnit.SECONDS);
120+
if (Looper.getMainLooper() == Looper.myLooper()) {
121+
latch.await(CrashlyticsCore.DEFAULT_MAIN_HANDLER_TIMEOUT_SEC, TimeUnit.SECONDS);
122+
} else {
123+
latch.await(TIMEOUT_SEC, TimeUnit.SECONDS);
124+
}
130125

131126
if (task.isSuccessful()) {
132127
return task.getResult();
@@ -170,4 +165,6 @@ public static boolean awaitUninterruptibly(CountDownLatch latch, long timeout, T
170165
private static final ExecutorService TASK_CONTINUATION_EXECUTOR_SERVICE =
171166
ExecutorUtils.buildSingleThreadExecutorService(
172167
"awaitEvenIfOnMainThread task continuation executor");
168+
169+
private Utils() {}
173170
}

0 commit comments

Comments
 (0)