17
17
import static com .google .android .gms .common .internal .Preconditions .checkNotEmpty ;
18
18
import static com .google .android .gms .common .internal .Preconditions .checkNotNull ;
19
19
20
- import android .annotation .SuppressLint ;
21
20
import android .content .Context ;
22
21
import androidx .annotation .NonNull ;
23
22
import androidx .annotation .VisibleForTesting ;
32
31
import com .google .firebase .FirebaseApp ;
33
32
import com .google .firebase .annotations .concurrent .Background ;
34
33
import com .google .firebase .annotations .concurrent .Blocking ;
34
+ import com .google .firebase .annotations .concurrent .Lightweight ;
35
35
import com .google .firebase .appcheck .AppCheckProvider ;
36
36
import com .google .firebase .appcheck .AppCheckToken ;
37
- import com .google .firebase .appcheck .internal .AppCheckTokenResponse ;
38
37
import com .google .firebase .appcheck .internal .DefaultAppCheckToken ;
39
38
import com .google .firebase .appcheck .internal .NetworkClient ;
40
39
import com .google .firebase .appcheck .internal .RetryManager ;
@@ -51,19 +50,22 @@ public class SafetyNetAppCheckProvider implements AppCheckProvider {
51
50
52
51
private final Task <SafetyNetClient > safetyNetClientTask ;
53
52
private final NetworkClient networkClient ;
53
+ private final Executor liteExecutor ;
54
54
private final Executor blockingExecutor ;
55
55
private final RetryManager retryManager ;
56
56
private final String apiKey ;
57
57
58
58
/** @param firebaseApp the FirebaseApp to which this Factory is tied. */
59
59
public SafetyNetAppCheckProvider (
60
60
@ NonNull FirebaseApp firebaseApp ,
61
+ @ Lightweight Executor liteExecutor ,
61
62
@ Background Executor backgroundExecutor ,
62
63
@ Blocking Executor blockingExecutor ) {
63
64
this (
64
65
firebaseApp ,
65
66
new NetworkClient (firebaseApp ),
66
67
GoogleApiAvailability .getInstance (),
68
+ liteExecutor ,
67
69
backgroundExecutor ,
68
70
blockingExecutor );
69
71
}
@@ -73,13 +75,15 @@ public SafetyNetAppCheckProvider(
73
75
@ NonNull FirebaseApp firebaseApp ,
74
76
@ NonNull NetworkClient networkClient ,
75
77
@ NonNull GoogleApiAvailability googleApiAvailability ,
78
+ @ NonNull Executor liteExecutor ,
76
79
@ NonNull Executor backgroundExecutor ,
77
80
@ NonNull Executor blockingExecutor ) {
78
81
checkNotNull (firebaseApp );
79
82
checkNotNull (networkClient );
80
83
checkNotNull (googleApiAvailability );
81
84
checkNotNull (backgroundExecutor );
82
85
this .apiKey = firebaseApp .getOptions ().getApiKey ();
86
+ this .liteExecutor = liteExecutor ;
83
87
this .blockingExecutor = blockingExecutor ;
84
88
this .safetyNetClientTask =
85
89
initSafetyNetClient (
@@ -93,11 +97,13 @@ public SafetyNetAppCheckProvider(
93
97
@ NonNull FirebaseApp firebaseApp ,
94
98
@ NonNull SafetyNetClient safetyNetClient ,
95
99
@ NonNull NetworkClient networkClient ,
100
+ @ NonNull Executor liteExecutor ,
96
101
@ NonNull Executor blockingExecutor ,
97
102
@ NonNull RetryManager retryManager ) {
98
103
this .apiKey = firebaseApp .getOptions ().getApiKey ();
99
104
this .safetyNetClientTask = Tasks .forResult (safetyNetClient );
100
105
this .networkClient = networkClient ;
106
+ this .liteExecutor = liteExecutor ;
101
107
this .blockingExecutor = blockingExecutor ;
102
108
this .retryManager = retryManager ;
103
109
}
@@ -142,35 +148,15 @@ Task<SafetyNetClient> getSafetyNetClientTask() {
142
148
return safetyNetClientTask ;
143
149
}
144
150
145
- // TODO(b/261013814): Use an explicit executor in continuations.
146
- @ SuppressLint ("TaskMainThread" )
147
151
@ NonNull
148
152
@ Override
149
153
public Task <AppCheckToken > getToken () {
150
154
return safetyNetClientTask
151
- .continueWithTask (
152
- task -> {
153
- if (task .isSuccessful ()) {
154
- return task .getResult ().attest (NONCE .getBytes (), apiKey );
155
- }
156
- return Tasks .forException (task .getException ());
157
- })
158
- .continueWithTask (
159
- task -> {
160
- if (!task .isSuccessful ()) {
161
- // Proxies errors to the client directly; need to wrap to get the
162
- // types right.
163
- // TODO: more specific error mapping to help clients debug more
164
- // easily.
165
- return Tasks .forException (task .getException ());
166
- } else {
167
- return exchangeSafetyNetAttestationResponseForToken (task .getResult ());
168
- }
169
- });
155
+ .onSuccessTask (
156
+ liteExecutor , safetyNetClient -> safetyNetClient .attest (NONCE .getBytes (), apiKey ))
157
+ .onSuccessTask (liteExecutor , this ::exchangeSafetyNetAttestationResponseForToken );
170
158
}
171
159
172
- // TODO(b/261013814): Use an explicit executor in continuations.
173
- @ SuppressLint ("TaskMainThread" )
174
160
@ NonNull
175
161
Task <AppCheckToken > exchangeSafetyNetAttestationResponseForToken (
176
162
@ NonNull SafetyNetApi .AttestationResponse attestationResponse ) {
@@ -180,22 +166,14 @@ Task<AppCheckToken> exchangeSafetyNetAttestationResponseForToken(
180
166
181
167
ExchangeSafetyNetTokenRequest request = new ExchangeSafetyNetTokenRequest (safetyNetJwsResult );
182
168
183
- Task <AppCheckTokenResponse > networkTask =
184
- Tasks .call (
169
+ return Tasks .call (
185
170
blockingExecutor ,
186
171
() ->
187
172
networkClient .exchangeAttestationForAppCheckToken (
188
- request .toJsonString ().getBytes (UTF_8 ),
189
- NetworkClient .SAFETY_NET ,
190
- retryManager ));
191
- return networkTask .continueWithTask (
192
- task -> {
193
- if (task .isSuccessful ()) {
194
- return Tasks .forResult (
195
- DefaultAppCheckToken .constructFromAppCheckTokenResponse (task .getResult ()));
196
- }
197
- // TODO: Surface more error details.
198
- return Tasks .forException (task .getException ());
199
- });
173
+ request .toJsonString ().getBytes (UTF_8 ), NetworkClient .SAFETY_NET , retryManager ))
174
+ .onSuccessTask (
175
+ liteExecutor ,
176
+ response ->
177
+ Tasks .forResult (DefaultAppCheckToken .constructFromAppCheckTokenResponse (response )));
200
178
}
201
179
}
0 commit comments