Skip to content

Commit 96e4dcd

Browse files
authored
Save token on a separate thread. (#3693)
#3681 * Changed blockingGetToken() to save the token on an Executor thread to avoid doing file IO on the main thread.
1 parent cc6d48f commit 96e4dcd

File tree

2 files changed

+23
-11
lines changed

2 files changed

+23
-11
lines changed

firebase-messaging/src/main/java/com/google/firebase/messaging/FirebaseMessaging.java

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// limitations under the License.
1414
package com.google.firebase.messaging;
1515

16+
import static com.google.firebase.messaging.FcmExecutors.newFileIOExecutor;
1617
import static com.google.firebase.messaging.FcmExecutors.newInitExecutor;
1718
import static com.google.firebase.messaging.FcmExecutors.newTaskExecutor;
1819
import static com.google.firebase.messaging.FcmExecutors.newTopicsSyncExecutor;
@@ -110,8 +111,9 @@ public class FirebaseMessaging {
110111
private final GmsRpc gmsRpc;
111112
private final RequestDeduplicator requestDeduplicator;
112113
private final AutoInit autoInit;
113-
private final Executor fileIoExecutor;
114+
private final Executor initExecutor;
114115
private final Executor taskExecutor;
116+
private final Executor fileExecutor;
115117
private final Task<TopicsSubscriber> topicsSubscriberTask;
116118
private final Metadata metadata;
117119

@@ -195,7 +197,8 @@ static synchronized FirebaseMessaging getInstance(@NonNull FirebaseApp firebaseA
195197
new GmsRpc(
196198
firebaseApp, metadata, userAgentPublisher, heartBeatInfo, firebaseInstallationsApi),
197199
/* taskExecutor= */ newTaskExecutor(),
198-
/* fileIoExecutor= */ newInitExecutor());
200+
/* initExecutor= */ newInitExecutor(),
201+
/* fileExecutor= */ newFileIOExecutor());
199202
}
200203

201204
FirebaseMessaging(
@@ -207,7 +210,8 @@ static synchronized FirebaseMessaging getInstance(@NonNull FirebaseApp firebaseA
207210
Metadata metadata,
208211
GmsRpc gmsRpc,
209212
Executor taskExecutor,
210-
Executor fileIoExecutor) {
213+
Executor initExecutor,
214+
Executor fileExecutor) {
211215

212216
FirebaseMessaging.transportFactory = transportFactory;
213217

@@ -221,7 +225,8 @@ static synchronized FirebaseMessaging getInstance(@NonNull FirebaseApp firebaseA
221225
this.taskExecutor = taskExecutor;
222226
this.gmsRpc = gmsRpc;
223227
this.requestDeduplicator = new RequestDeduplicator(taskExecutor);
224-
this.fileIoExecutor = fileIoExecutor;
228+
this.initExecutor = initExecutor;
229+
this.fileExecutor = fileExecutor;
225230

226231
Context appContext = firebaseApp.getApplicationContext();
227232
if (appContext instanceof Application) {
@@ -243,7 +248,7 @@ static synchronized FirebaseMessaging getInstance(@NonNull FirebaseApp firebaseA
243248
});
244249
}
245250

246-
fileIoExecutor.execute(
251+
initExecutor.execute(
247252
() -> {
248253
if (isAutoInitEnabled()) {
249254
startSyncIfNecessary();
@@ -257,7 +262,7 @@ static synchronized FirebaseMessaging getInstance(@NonNull FirebaseApp firebaseA
257262
// During FCM instantiation, as part of the initial setup, we spin up a couple of background
258263
// threads to handle topic syncing and proxy notification configuration.
259264
topicsSubscriberTask.addOnSuccessListener(
260-
fileIoExecutor,
265+
initExecutor,
261266
topicsSubscriber -> {
262267
// Topics operations relay on IID for token generation, thus the sync is also
263268
// subject to an auto-init check.
@@ -266,7 +271,7 @@ static synchronized FirebaseMessaging getInstance(@NonNull FirebaseApp firebaseA
266271
}
267272
});
268273

269-
fileIoExecutor.execute(
274+
initExecutor.execute(
270275
() ->
271276
// Initializes proxy notification support for the app.
272277
ProxyNotificationInitializer.initialize(context));
@@ -363,7 +368,7 @@ public boolean isNotificationDelegationEnabled() {
363368
* @return A Task that completes when the notification delegation has been set.
364369
*/
365370
public Task<Void> setNotificationDelegationEnabled(boolean enable) {
366-
return ProxyNotificationInitializer.setEnableProxyNotification(fileIoExecutor, context, enable);
371+
return ProxyNotificationInitializer.setEnableProxyNotification(initExecutor, context, enable);
367372
}
368373

369374
/**
@@ -381,7 +386,7 @@ public Task<String> getToken() {
381386
return iid.getTokenTask();
382387
}
383388
TaskCompletionSource<String> taskCompletionSource = new TaskCompletionSource<>();
384-
fileIoExecutor.execute(
389+
initExecutor.execute(
385390
() -> {
386391
try {
387392
taskCompletionSource.setResult(blockingGetToken());
@@ -405,7 +410,7 @@ public Task<String> getToken() {
405410
public Task<Void> deleteToken() {
406411
if (iid != null) {
407412
TaskCompletionSource<Void> taskCompletionSource = new TaskCompletionSource<>();
408-
fileIoExecutor.execute(
413+
initExecutor.execute(
409414
() -> {
410415
try {
411416
iid.deleteToken(Metadata.getDefaultSenderId(firebaseApp), INSTANCE_ID_SCOPE);
@@ -604,7 +609,7 @@ String blockingGetToken() throws IOException {
604609
gmsRpc
605610
.getToken()
606611
.onSuccessTask(
607-
Runnable::run, // direct executor
612+
fileExecutor,
608613
token -> {
609614
getStore(context)
610615
.saveToken(

firebase-messaging/src/test/java/com/google/firebase/messaging/FirebaseMessagingRoboTest.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ public void testGetToken() throws Exception {
278278
new Metadata(context),
279279
mockGmsRpc,
280280
Runnable::run,
281+
Runnable::run,
281282
Runnable::run);
282283
when(mockGmsRpc.getToken()).thenReturn(Tasks.forResult("fake_token"));
283284

@@ -304,6 +305,7 @@ public void getToken_withFiid() throws Exception {
304305
mock(Metadata.class),
305306
mockGmsRpc,
306307
Runnable::run,
308+
Runnable::run,
307309
Runnable::run);
308310
when(mockFiid.getTokenTask()).thenReturn(Tasks.forResult("fake_token"));
309311

@@ -328,6 +330,7 @@ public void testDeleteToken() throws Exception {
328330
new Metadata(context),
329331
mockGmsRpc,
330332
Runnable::run,
333+
Runnable::run,
331334
Runnable::run);
332335
when(mockGmsRpc.getToken()).thenReturn(Tasks.forResult("fake_token"));
333336
when(mockGmsRpc.deleteToken()).thenReturn(Tasks.forResult(null));
@@ -356,6 +359,7 @@ public void deleteToken_withFiid() throws Exception {
356359
mock(Metadata.class),
357360
mockGmsRpc,
358361
Runnable::run,
362+
Runnable::run,
359363
Runnable::run);
360364

361365
Task<Void> deleteTokenTask = messaging.deleteToken();
@@ -380,6 +384,7 @@ public void isProxyNotificationEnabledDefaultsToTrueForNewerDevices() {
380384
mock(Metadata.class),
381385
mock(GmsRpc.class),
382386
Runnable::run,
387+
Runnable::run,
383388
Runnable::run);
384389

385390
assertThat(messaging.isNotificationDelegationEnabled()).isTrue();
@@ -398,6 +403,7 @@ public void isProxyNotificationEnabledDefaultsToFalseForOlderDevices() {
398403
mock(Metadata.class),
399404
mock(GmsRpc.class),
400405
Runnable::run,
406+
Runnable::run,
401407
Runnable::run);
402408

403409
assertThat(messaging.isNotificationDelegationEnabled()).isFalse();
@@ -508,6 +514,7 @@ public void blockingGetToken_calledTwice_OnNewTokenInvokedOnce() throws Exceptio
508514
new Metadata(context),
509515
mockGmsRpc,
510516
Runnable::run,
517+
Runnable::run,
511518
Runnable::run);
512519

513520
// Call blockingGetToken() twice. Since GmsRpc.getToken() is blocked, neither call should see a

0 commit comments

Comments
 (0)