Skip to content

Commit a841ab4

Browse files
authored
Migrate firebase-appcheck to use standard executors provided by Firebase Common. (#4431)
* Migrate to use standard executors provided by Firebase Common. * Update changelog and fix unit test. * Address review comments. * Fix unit test. * Address review comments.
1 parent e05db82 commit a841ab4

File tree

8 files changed

+60
-34
lines changed

8 files changed

+60
-34
lines changed

appcheck/firebase-appcheck/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# Unreleased
2+
* [changed] Migrated the `firebase-appcheck` library to use standard Firebase executors. (#4431)
23

34
# 16.1.0
45
* [unchanged] Updated to accommodate the release of the updated

appcheck/firebase-appcheck/firebase-appcheck.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ android {
4141
}
4242

4343
dependencies {
44+
implementation project(':firebase-annotations')
4445
implementation project(':firebase-common')
4546
implementation project(':firebase-components')
4647
implementation project(":appcheck:firebase-appcheck-interop")
@@ -49,6 +50,7 @@ dependencies {
4950

5051
javadocClasspath 'com.google.auto.value:auto-value-annotations:1.6.6'
5152

53+
testImplementation project(':integ-testing')
5254
testImplementation 'junit:junit:4.13-beta-2'
5355
testImplementation 'org.mockito:mockito-core:2.25.0'
5456
testImplementation 'org.mockito:mockito-inline:2.25.0'

appcheck/firebase-appcheck/src/main/java/com/google/firebase/appcheck/FirebaseAppCheckRegistrar.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,21 @@
1616

1717
import com.google.android.gms.common.annotation.KeepForSdk;
1818
import com.google.firebase.FirebaseApp;
19+
import com.google.firebase.annotations.concurrent.Background;
20+
import com.google.firebase.annotations.concurrent.Blocking;
1921
import com.google.firebase.appcheck.internal.DefaultFirebaseAppCheck;
2022
import com.google.firebase.appcheck.interop.InternalAppCheckTokenProvider;
2123
import com.google.firebase.components.Component;
2224
import com.google.firebase.components.ComponentRegistrar;
2325
import com.google.firebase.components.Dependency;
26+
import com.google.firebase.components.Qualified;
2427
import com.google.firebase.heartbeatinfo.HeartBeatConsumerComponent;
2528
import com.google.firebase.heartbeatinfo.HeartBeatController;
2629
import com.google.firebase.platforminfo.LibraryVersionComponent;
2730
import java.util.Arrays;
2831
import java.util.List;
32+
import java.util.concurrent.Executor;
33+
import java.util.concurrent.ScheduledExecutorService;
2934

3035
/**
3136
* {@link ComponentRegistrar} for setting up FirebaseAppCheck's dependency injections in Firebase
@@ -39,16 +44,24 @@ public class FirebaseAppCheckRegistrar implements ComponentRegistrar {
3944

4045
@Override
4146
public List<Component<?>> getComponents() {
47+
Qualified<Executor> backgroundExecutor = Qualified.qualified(Background.class, Executor.class);
48+
Qualified<ScheduledExecutorService> blockingScheduledExecutorService =
49+
Qualified.qualified(Blocking.class, ScheduledExecutorService.class);
50+
4251
return Arrays.asList(
4352
Component.builder(FirebaseAppCheck.class, (InternalAppCheckTokenProvider.class))
4453
.name(LIBRARY_NAME)
4554
.add(Dependency.required(FirebaseApp.class))
55+
.add(Dependency.required(backgroundExecutor))
56+
.add(Dependency.required(blockingScheduledExecutorService))
4657
.add(Dependency.optionalProvider(HeartBeatController.class))
4758
.factory(
4859
(container) ->
4960
new DefaultFirebaseAppCheck(
5061
container.get(FirebaseApp.class),
51-
container.getProvider(HeartBeatController.class)))
62+
container.getProvider(HeartBeatController.class),
63+
container.get(backgroundExecutor),
64+
container.get(blockingScheduledExecutorService)))
5265
.alwaysEager()
5366
.build(),
5467
HeartBeatConsumerComponent.create(),

appcheck/firebase-appcheck/src/main/java/com/google/firebase/appcheck/internal/DefaultFirebaseAppCheck.java

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import com.google.android.gms.tasks.Tasks;
2626
import com.google.firebase.FirebaseApp;
2727
import com.google.firebase.FirebaseException;
28+
import com.google.firebase.annotations.concurrent.Background;
29+
import com.google.firebase.annotations.concurrent.Blocking;
2830
import com.google.firebase.appcheck.AppCheckProvider;
2931
import com.google.firebase.appcheck.AppCheckProviderFactory;
3032
import com.google.firebase.appcheck.AppCheckToken;
@@ -36,8 +38,8 @@
3638
import com.google.firebase.inject.Provider;
3739
import java.util.ArrayList;
3840
import java.util.List;
39-
import java.util.concurrent.ExecutorService;
40-
import java.util.concurrent.Executors;
41+
import java.util.concurrent.Executor;
42+
import java.util.concurrent.ScheduledExecutorService;
4143

4244
public class DefaultFirebaseAppCheck extends FirebaseAppCheck {
4345

@@ -49,30 +51,19 @@ public class DefaultFirebaseAppCheck extends FirebaseAppCheck {
4951
private final List<AppCheckListener> appCheckListenerList;
5052
private final StorageHelper storageHelper;
5153
private final TokenRefreshManager tokenRefreshManager;
52-
private final ExecutorService backgroundExecutor;
54+
private final Executor backgroundExecutor;
5355
private final Task<Void> retrieveStoredTokenTask;
5456
private final Clock clock;
5557

5658
private AppCheckProviderFactory appCheckProviderFactory;
5759
private AppCheckProvider appCheckProvider;
5860
private AppCheckToken cachedToken;
5961

60-
// TODO(b/258273630): Migrate to go/firebase-android-executors
61-
@SuppressLint("ThreadPoolCreation")
6262
public DefaultFirebaseAppCheck(
63-
@NonNull FirebaseApp firebaseApp,
64-
@NonNull Provider<HeartBeatController> heartBeatController) {
65-
this(
66-
checkNotNull(firebaseApp),
67-
checkNotNull(heartBeatController),
68-
Executors.newCachedThreadPool());
69-
}
70-
71-
@VisibleForTesting
72-
DefaultFirebaseAppCheck(
7363
@NonNull FirebaseApp firebaseApp,
7464
@NonNull Provider<HeartBeatController> heartBeatController,
75-
@NonNull ExecutorService backgroundExecutor) {
65+
@Background Executor backgroundExecutor,
66+
@Blocking ScheduledExecutorService scheduledExecutorService) {
7667
checkNotNull(firebaseApp);
7768
checkNotNull(heartBeatController);
7869
this.firebaseApp = firebaseApp;
@@ -82,13 +73,16 @@ public DefaultFirebaseAppCheck(
8273
this.storageHelper =
8374
new StorageHelper(firebaseApp.getApplicationContext(), firebaseApp.getPersistenceKey());
8475
this.tokenRefreshManager =
85-
new TokenRefreshManager(firebaseApp.getApplicationContext(), /* firebaseAppCheck= */ this);
76+
new TokenRefreshManager(
77+
firebaseApp.getApplicationContext(),
78+
/* firebaseAppCheck= */ this,
79+
scheduledExecutorService);
8680
this.backgroundExecutor = backgroundExecutor;
8781
this.retrieveStoredTokenTask = retrieveStoredAppCheckTokenInBackground(backgroundExecutor);
8882
this.clock = new Clock.DefaultClock();
8983
}
9084

91-
private Task<Void> retrieveStoredAppCheckTokenInBackground(@NonNull ExecutorService executor) {
85+
private Task<Void> retrieveStoredAppCheckTokenInBackground(@NonNull Executor executor) {
9286
TaskCompletionSource<Void> taskCompletionSource = new TaskCompletionSource<>();
9387
executor.execute(
9488
() -> {

appcheck/firebase-appcheck/src/main/java/com/google/firebase/appcheck/internal/DefaultTokenRefresher.java

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import android.annotation.SuppressLint;
2222
import androidx.annotation.NonNull;
2323
import androidx.annotation.VisibleForTesting;
24-
import java.util.concurrent.Executors;
24+
import com.google.firebase.annotations.concurrent.Blocking;
2525
import java.util.concurrent.ScheduledExecutorService;
2626
import java.util.concurrent.ScheduledFuture;
2727

@@ -41,16 +41,10 @@ public class DefaultTokenRefresher {
4141
private volatile ScheduledFuture<?> refreshFuture;
4242
private volatile long delayAfterFailureSeconds;
4343

44-
// TODO(b/258273630): Migrate to go/firebase-android-executors
45-
@SuppressLint("ThreadPoolCreation")
46-
DefaultTokenRefresher(@NonNull DefaultFirebaseAppCheck firebaseAppCheck) {
47-
this(checkNotNull(firebaseAppCheck), Executors.newScheduledThreadPool(/* corePoolSize= */ 1));
48-
}
49-
50-
@VisibleForTesting
5144
DefaultTokenRefresher(
52-
DefaultFirebaseAppCheck firebaseAppCheck, ScheduledExecutorService scheduledExecutorService) {
53-
this.firebaseAppCheck = firebaseAppCheck;
45+
@NonNull DefaultFirebaseAppCheck firebaseAppCheck,
46+
@Blocking ScheduledExecutorService scheduledExecutorService) {
47+
this.firebaseAppCheck = checkNotNull(firebaseAppCheck);
5448
this.scheduledExecutorService = scheduledExecutorService;
5549
this.delayAfterFailureSeconds = UNSET_DELAY;
5650
}

appcheck/firebase-appcheck/src/main/java/com/google/firebase/appcheck/internal/TokenRefreshManager.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@
2222
import androidx.annotation.VisibleForTesting;
2323
import com.google.android.gms.common.api.internal.BackgroundDetector;
2424
import com.google.android.gms.common.api.internal.BackgroundDetector.BackgroundStateChangeListener;
25+
import com.google.firebase.annotations.concurrent.Blocking;
2526
import com.google.firebase.appcheck.AppCheckToken;
2627
import com.google.firebase.appcheck.internal.util.Clock;
28+
import java.util.concurrent.ScheduledExecutorService;
2729

2830
/** Class to manage whether or not to schedule an {@link AppCheckToken} refresh attempt. */
2931
public final class TokenRefreshManager {
@@ -41,10 +43,13 @@ public final class TokenRefreshManager {
4143
private volatile long nextRefreshTimeMillis;
4244
private volatile boolean isAutoRefreshEnabled;
4345

44-
TokenRefreshManager(@NonNull Context context, @NonNull DefaultFirebaseAppCheck firebaseAppCheck) {
46+
TokenRefreshManager(
47+
@NonNull Context context,
48+
@NonNull DefaultFirebaseAppCheck firebaseAppCheck,
49+
@Blocking ScheduledExecutorService scheduledExecutorService) {
4550
this(
4651
checkNotNull(context),
47-
new DefaultTokenRefresher(checkNotNull(firebaseAppCheck)),
52+
new DefaultTokenRefresher(checkNotNull(firebaseAppCheck), scheduledExecutorService),
4853
new Clock.DefaultClock());
4954
}
5055

appcheck/firebase-appcheck/src/test/java/com/google/firebase/appcheck/FirebaseAppCheckRegistrarTest.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,15 @@
1717
import static com.google.common.truth.Truth.assertThat;
1818

1919
import com.google.firebase.FirebaseApp;
20+
import com.google.firebase.annotations.concurrent.Background;
21+
import com.google.firebase.annotations.concurrent.Blocking;
2022
import com.google.firebase.components.Component;
2123
import com.google.firebase.components.Dependency;
24+
import com.google.firebase.components.Qualified;
2225
import com.google.firebase.heartbeatinfo.HeartBeatController;
2326
import java.util.List;
27+
import java.util.concurrent.Executor;
28+
import java.util.concurrent.ScheduledExecutorService;
2429
import org.junit.Test;
2530
import org.junit.runner.RunWith;
2631
import org.robolectric.RobolectricTestRunner;
@@ -39,6 +44,9 @@ public void testGetComponents() {
3944
assertThat(firebaseAppCheckComponent.getDependencies())
4045
.containsExactly(
4146
Dependency.required(FirebaseApp.class),
47+
Dependency.required(Qualified.qualified(Background.class, Executor.class)),
48+
Dependency.required(
49+
Qualified.qualified(Blocking.class, ScheduledExecutorService.class)),
4250
Dependency.optionalProvider(HeartBeatController.class));
4351
assertThat(firebaseAppCheckComponent.isAlwaysEager()).isTrue();
4452
}

appcheck/firebase-appcheck/src/test/java/com/google/firebase/appcheck/internal/DefaultFirebaseAppCheckTest.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import com.google.firebase.appcheck.AppCheckTokenResult;
3333
import com.google.firebase.appcheck.FirebaseAppCheck.AppCheckListener;
3434
import com.google.firebase.appcheck.interop.AppCheckTokenListener;
35+
import com.google.firebase.concurrent.TestOnlyExecutors;
3536
import com.google.firebase.heartbeatinfo.HeartBeatController;
3637
import org.junit.Before;
3738
import org.junit.Test;
@@ -76,19 +77,26 @@ public void setup() {
7677
when(mockAppCheckProviderFactory.create(any())).thenReturn(mockAppCheckProvider);
7778
when(mockAppCheckProvider.getToken()).thenReturn(Tasks.forResult(validDefaultAppCheckToken));
7879

80+
// TODO(b/258273630): Use TestOnlyExecutors.background() instead of
81+
// MoreExecutors.directExecutor().
7982
defaultFirebaseAppCheck =
8083
new DefaultFirebaseAppCheck(
8184
mockFirebaseApp,
8285
() -> mockHeartBeatController,
83-
MoreExecutors.newDirectExecutorService());
86+
MoreExecutors.directExecutor(),
87+
TestOnlyExecutors.blocking());
8488
}
8589

8690
@Test
8791
public void testConstructor_nullFirebaseApp_expectThrows() {
8892
assertThrows(
8993
NullPointerException.class,
9094
() -> {
91-
new DefaultFirebaseAppCheck(null, () -> mockHeartBeatController);
95+
new DefaultFirebaseAppCheck(
96+
null,
97+
() -> mockHeartBeatController,
98+
TestOnlyExecutors.background(),
99+
TestOnlyExecutors.blocking());
92100
});
93101
}
94102

@@ -97,7 +105,8 @@ public void testConstructor_nullHeartBeatControllerProvider_expectThrows() {
97105
assertThrows(
98106
NullPointerException.class,
99107
() -> {
100-
new DefaultFirebaseAppCheck(mockFirebaseApp, null);
108+
new DefaultFirebaseAppCheck(
109+
mockFirebaseApp, null, TestOnlyExecutors.background(), TestOnlyExecutors.blocking());
101110
});
102111
}
103112

0 commit comments

Comments
 (0)