Skip to content

Commit 0252a8e

Browse files
committed
Migrate firebase-appcheck-safetynet to go/firebase-android-executors.
1 parent 66c7398 commit 0252a8e

File tree

5 files changed

+77
-27
lines changed

5 files changed

+77
-27
lines changed

appcheck/firebase-appcheck-safetynet/firebase-appcheck-safetynet.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')
@@ -51,6 +52,7 @@ dependencies {
5152
javadocClasspath 'com.google.auto.value:auto-value-annotations:1.6.6'
5253
javadocClasspath 'org.checkerframework:checker-qual:2.5.2'
5354

55+
testImplementation project(':integ-testing')
5456
testImplementation 'junit:junit:4.13-beta-2'
5557
testImplementation 'org.mockito:mockito-core:2.25.0'
5658
testImplementation "org.robolectric:robolectric:$robolectricVersion"

appcheck/firebase-appcheck-safetynet/src/main/java/com/google/firebase/appcheck/safetynet/FirebaseAppCheckSafetyNetRegistrar.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,17 @@
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.safetynet.internal.SafetyNetAppCheckProvider;
2022
import com.google.firebase.components.Component;
2123
import com.google.firebase.components.ComponentRegistrar;
2224
import com.google.firebase.components.Dependency;
25+
import com.google.firebase.components.Qualified;
2326
import com.google.firebase.platforminfo.LibraryVersionComponent;
2427
import java.util.Arrays;
2528
import java.util.List;
29+
import java.util.concurrent.Executor;
2630

2731
/**
2832
* {@link ComponentRegistrar} for setting up FirebaseAppCheck safety net's dependency injections in
@@ -36,11 +40,21 @@ public class FirebaseAppCheckSafetyNetRegistrar implements ComponentRegistrar {
3640

3741
@Override
3842
public List<Component<?>> getComponents() {
43+
Qualified<Executor> backgroundExecutor = Qualified.qualified(Background.class, Executor.class);
44+
Qualified<Executor> blockingExecutor = Qualified.qualified(Blocking.class, Executor.class);
45+
3946
return Arrays.asList(
4047
Component.builder(SafetyNetAppCheckProvider.class)
4148
.name(LIBRARY_NAME)
4249
.add(Dependency.required(FirebaseApp.class))
43-
.factory((container) -> new SafetyNetAppCheckProvider(container.get(FirebaseApp.class)))
50+
.add(Dependency.required(backgroundExecutor))
51+
.add(Dependency.required(blockingExecutor))
52+
.factory(
53+
(container) ->
54+
new SafetyNetAppCheckProvider(
55+
container.get(FirebaseApp.class),
56+
container.get(backgroundExecutor),
57+
container.get(blockingExecutor)))
4458
.build(),
4559
LibraryVersionComponent.create(LIBRARY_NAME, BuildConfig.VERSION_NAME));
4660
}

appcheck/firebase-appcheck-safetynet/src/main/java/com/google/firebase/appcheck/safetynet/internal/SafetyNetAppCheckProvider.java

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,15 @@
3030
import com.google.android.gms.tasks.TaskCompletionSource;
3131
import com.google.android.gms.tasks.Tasks;
3232
import com.google.firebase.FirebaseApp;
33+
import com.google.firebase.annotations.concurrent.Background;
34+
import com.google.firebase.annotations.concurrent.Blocking;
3335
import com.google.firebase.appcheck.AppCheckProvider;
3436
import com.google.firebase.appcheck.AppCheckToken;
3537
import com.google.firebase.appcheck.internal.AppCheckTokenResponse;
3638
import com.google.firebase.appcheck.internal.DefaultAppCheckToken;
3739
import com.google.firebase.appcheck.internal.NetworkClient;
3840
import com.google.firebase.appcheck.internal.RetryManager;
39-
import java.util.concurrent.ExecutorService;
40-
import java.util.concurrent.Executors;
41+
import java.util.concurrent.Executor;
4142

4243
public class SafetyNetAppCheckProvider implements AppCheckProvider {
4344

@@ -51,35 +52,41 @@ public class SafetyNetAppCheckProvider implements AppCheckProvider {
5152
private final Context context;
5253
private final Task<SafetyNetClient> safetyNetClientTask;
5354
private final NetworkClient networkClient;
54-
private final ExecutorService backgroundExecutor;
55+
private final Executor backgroundExecutor;
56+
private final Executor blockingExecutor;
5557
private final RetryManager retryManager;
5658
private final String apiKey;
5759

5860
/** @param firebaseApp the FirebaseApp to which this Factory is tied. */
59-
// TODO(b/258273630): Migrate to go/firebase-android-executors
60-
@SuppressLint("ThreadPoolCreation")
61-
public SafetyNetAppCheckProvider(@NonNull FirebaseApp firebaseApp) {
61+
public SafetyNetAppCheckProvider(
62+
@NonNull FirebaseApp firebaseApp,
63+
@Background Executor backgroundExecutor,
64+
@Blocking Executor blockingExecutor) {
6265
this(
6366
firebaseApp,
6467
new NetworkClient(firebaseApp),
6568
GoogleApiAvailability.getInstance(),
66-
Executors.newCachedThreadPool());
69+
backgroundExecutor,
70+
blockingExecutor);
6771
}
6872

6973
@VisibleForTesting
7074
SafetyNetAppCheckProvider(
7175
@NonNull FirebaseApp firebaseApp,
7276
@NonNull NetworkClient networkClient,
7377
@NonNull GoogleApiAvailability googleApiAvailability,
74-
@NonNull ExecutorService backgroundExecutor) {
78+
@NonNull Executor backgroundExecutor,
79+
@NonNull Executor blockingExecutor) {
7580
checkNotNull(firebaseApp);
7681
checkNotNull(networkClient);
7782
checkNotNull(googleApiAvailability);
7883
checkNotNull(backgroundExecutor);
7984
this.context = firebaseApp.getApplicationContext();
8085
this.apiKey = firebaseApp.getOptions().getApiKey();
8186
this.backgroundExecutor = backgroundExecutor;
82-
this.safetyNetClientTask = initSafetyNetClient(googleApiAvailability, this.backgroundExecutor);
87+
this.blockingExecutor = blockingExecutor;
88+
this.safetyNetClientTask =
89+
initSafetyNetClient(this.context, googleApiAvailability, this.backgroundExecutor);
8390
this.networkClient = networkClient;
8491
this.retryManager = new RetryManager();
8592
}
@@ -89,18 +96,20 @@ public SafetyNetAppCheckProvider(@NonNull FirebaseApp firebaseApp) {
8996
@NonNull FirebaseApp firebaseApp,
9097
@NonNull SafetyNetClient safetyNetClient,
9198
@NonNull NetworkClient networkClient,
92-
@NonNull ExecutorService backgroundExecutor,
99+
@NonNull Executor backgroundExecutor,
100+
@NonNull Executor blockingExecutor,
93101
@NonNull RetryManager retryManager) {
94102
this.context = firebaseApp.getApplicationContext();
95103
this.apiKey = firebaseApp.getOptions().getApiKey();
96104
this.safetyNetClientTask = Tasks.forResult(safetyNetClient);
97105
this.networkClient = networkClient;
98106
this.backgroundExecutor = backgroundExecutor;
107+
this.blockingExecutor = blockingExecutor;
99108
this.retryManager = retryManager;
100109
}
101110

102-
private Task<SafetyNetClient> initSafetyNetClient(
103-
GoogleApiAvailability googleApiAvailability, ExecutorService executor) {
111+
private static Task<SafetyNetClient> initSafetyNetClient(
112+
Context context, GoogleApiAvailability googleApiAvailability, Executor executor) {
104113
TaskCompletionSource<SafetyNetClient> taskCompletionSource = new TaskCompletionSource<>();
105114
executor.execute(
106115
() -> {
@@ -117,7 +126,7 @@ private Task<SafetyNetClient> initSafetyNetClient(
117126
return taskCompletionSource.getTask();
118127
}
119128

120-
private String getGooglePlayServicesConnectionErrorString(int connectionResult) {
129+
private static String getGooglePlayServicesConnectionErrorString(int connectionResult) {
121130
switch (connectionResult) {
122131
case ConnectionResult.SERVICE_MISSING:
123132
return "Google Play services is missing on this device.";
@@ -179,7 +188,7 @@ Task<AppCheckToken> exchangeSafetyNetAttestationResponseForToken(
179188

180189
Task<AppCheckTokenResponse> networkTask =
181190
Tasks.call(
182-
backgroundExecutor,
191+
blockingExecutor,
183192
() ->
184193
networkClient.exchangeAttestationForAppCheckToken(
185194
request.toJsonString().getBytes(UTF_8),

appcheck/firebase-appcheck-safetynet/src/test/java/com/google/firebase/appcheck/safetynet/FirebaseAppCheckSafetyNetRegistrarTest.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,13 @@
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 java.util.List;
26+
import java.util.concurrent.Executor;
2327
import org.junit.Test;
2428
import org.junit.runner.RunWith;
2529
import org.robolectric.RobolectricTestRunner;
@@ -35,7 +39,10 @@ public void testGetComponents() {
3539
assertThat(components).hasSize(2);
3640
Component<?> appCheckSafetyNetComponent = components.get(0);
3741
assertThat(appCheckSafetyNetComponent.getDependencies())
38-
.containsExactly(Dependency.required(FirebaseApp.class));
42+
.containsExactly(
43+
Dependency.required(FirebaseApp.class),
44+
Dependency.required(Qualified.qualified(Background.class, Executor.class)),
45+
Dependency.required(Qualified.qualified(Blocking.class, Executor.class)));
3946
assertThat(appCheckSafetyNetComponent.isLazy()).isTrue();
4047
}
4148
}

appcheck/firebase-appcheck-safetynet/src/test/java/com/google/firebase/appcheck/safetynet/internal/SafetyNetAppCheckProviderTest.java

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@
3737
import com.google.firebase.appcheck.internal.DefaultAppCheckToken;
3838
import com.google.firebase.appcheck.internal.NetworkClient;
3939
import com.google.firebase.appcheck.internal.RetryManager;
40+
import com.google.firebase.concurrent.TestOnlyExecutors;
4041
import java.io.IOException;
41-
import java.util.concurrent.ExecutorService;
4242
import org.junit.Before;
4343
import org.junit.Test;
4444
import org.junit.runner.RunWith;
@@ -62,7 +62,6 @@ public class SafetyNetAppCheckProviderTest {
6262
private static final String TIME_TO_LIVE = "3600s";
6363

6464
private FirebaseApp firebaseApp;
65-
private ExecutorService backgroundExecutor = MoreExecutors.newDirectExecutorService();
6665
@Mock private GoogleApiAvailability mockGoogleApiAvailability;
6766
@Mock private SafetyNetClient mockSafetyNetClient;
6867
@Mock private NetworkClient mockNetworkClient;
@@ -84,7 +83,8 @@ public void testPublicConstructor_nullFirebaseApp_expectThrows() {
8483
assertThrows(
8584
NullPointerException.class,
8685
() -> {
87-
new SafetyNetAppCheckProvider(null);
86+
new SafetyNetAppCheckProvider(
87+
null, TestOnlyExecutors.background(), TestOnlyExecutors.blocking());
8888
});
8989
}
9090

@@ -95,7 +95,11 @@ public void testPublicConstructor_nullFirebaseApp_expectThrows() {
9595
.thenReturn(ConnectionResult.SERVICE_MISSING);
9696
SafetyNetAppCheckProvider provider =
9797
new SafetyNetAppCheckProvider(
98-
firebaseApp, mockNetworkClient, mockGoogleApiAvailability, backgroundExecutor);
98+
firebaseApp,
99+
mockNetworkClient,
100+
mockGoogleApiAvailability,
101+
TestOnlyExecutors.background(),
102+
TestOnlyExecutors.blocking());
99103
assertThat(provider.getSafetyNetClientTask().isSuccessful()).isFalse();
100104
}
101105

@@ -105,7 +109,11 @@ public void testGetToken_googlePlayServicesIsNotAvailable_expectGetTokenTaskExce
105109
.thenReturn(ConnectionResult.SERVICE_MISSING);
106110
SafetyNetAppCheckProvider provider =
107111
new SafetyNetAppCheckProvider(
108-
firebaseApp, mockNetworkClient, mockGoogleApiAvailability, backgroundExecutor);
112+
firebaseApp,
113+
mockNetworkClient,
114+
mockGoogleApiAvailability,
115+
TestOnlyExecutors.background(),
116+
TestOnlyExecutors.blocking());
109117
assertThat(provider.getSafetyNetClientTask().isSuccessful()).isFalse();
110118

111119
Task<AppCheckToken> tokenTask = provider.getToken();
@@ -120,7 +128,8 @@ public void testGetToken_nonNullSafetyNetClient_expectCallsSafetyNetForAttestati
120128
firebaseApp,
121129
mockSafetyNetClient,
122130
mockNetworkClient,
123-
backgroundExecutor,
131+
TestOnlyExecutors.background(),
132+
TestOnlyExecutors.blocking(),
124133
mockRetryManager);
125134
assertThat(provider.getSafetyNetClientTask().getResult()).isEqualTo(mockSafetyNetClient);
126135

@@ -142,7 +151,8 @@ public void testExchangeSafetyNetJwsForToken_nullAttestationResponse_expectThrow
142151
firebaseApp,
143152
mockSafetyNetClient,
144153
mockNetworkClient,
145-
backgroundExecutor,
154+
TestOnlyExecutors.background(),
155+
TestOnlyExecutors.blocking(),
146156
mockRetryManager);
147157
assertThrows(
148158
NullPointerException.class,
@@ -160,7 +170,8 @@ public void testExchangeSafetyNetJwsForToken_emptySafetyNetJwsResult_expectThrow
160170
firebaseApp,
161171
mockSafetyNetClient,
162172
mockNetworkClient,
163-
backgroundExecutor,
173+
TestOnlyExecutors.background(),
174+
TestOnlyExecutors.blocking(),
164175
mockRetryManager);
165176
assertThrows(
166177
IllegalArgumentException.class,
@@ -177,7 +188,8 @@ public void testExchangeSafetyNetJwsForToken_validFields_expectReturnsTask() {
177188
firebaseApp,
178189
mockSafetyNetClient,
179190
mockNetworkClient,
180-
backgroundExecutor,
191+
TestOnlyExecutors.background(),
192+
TestOnlyExecutors.blocking(),
181193
mockRetryManager);
182194
Task<AppCheckToken> task =
183195
provider.exchangeSafetyNetAttestationResponseForToken(mockSafetyNetAttestationResponse);
@@ -193,12 +205,15 @@ public void exchangeSafetyNetJwsForToken_onSuccess_setsTaskResult() throws Excep
193205
when(mockAppCheckTokenResponse.getToken()).thenReturn(APP_CHECK_TOKEN);
194206
when(mockAppCheckTokenResponse.getTimeToLive()).thenReturn(TIME_TO_LIVE);
195207

208+
// TODO(b/258273630): Use TestOnlyExecutors.background() instead of
209+
// MoreExecutors.directExecutor().
196210
SafetyNetAppCheckProvider provider =
197211
new SafetyNetAppCheckProvider(
198212
firebaseApp,
199213
mockSafetyNetClient,
200214
mockNetworkClient,
201-
backgroundExecutor,
215+
MoreExecutors.directExecutor(),
216+
MoreExecutors.directExecutor(),
202217
mockRetryManager);
203218
Task<AppCheckToken> task =
204219
provider.exchangeSafetyNetAttestationResponseForToken(mockSafetyNetAttestationResponse);
@@ -219,12 +234,15 @@ public void exchangeSafetyNetJwsForToken_onFailure_setsTaskException() throws Ex
219234
any(), eq(NetworkClient.SAFETY_NET), eq(mockRetryManager)))
220235
.thenThrow(new IOException());
221236

237+
// TODO(b/258273630): Use TestOnlyExecutors.background() instead of
238+
// MoreExecutors.directExecutor().
222239
SafetyNetAppCheckProvider provider =
223240
new SafetyNetAppCheckProvider(
224241
firebaseApp,
225242
mockSafetyNetClient,
226243
mockNetworkClient,
227-
backgroundExecutor,
244+
MoreExecutors.directExecutor(),
245+
MoreExecutors.directExecutor(),
228246
mockRetryManager);
229247
Task<AppCheckToken> task =
230248
provider.exchangeSafetyNetAttestationResponseForToken(mockSafetyNetAttestationResponse);

0 commit comments

Comments
 (0)