14
14
15
15
package com .google .firebase .app .distribution ;
16
16
17
+ import static com .google .firebase .app .distribution .FirebaseAppDistributionException .Status .AUTHENTICATION_CANCELED ;
17
18
import static com .google .firebase .app .distribution .FirebaseAppDistributionException .Status .AUTHENTICATION_FAILURE ;
18
19
import static com .google .firebase .app .distribution .FirebaseAppDistributionException .Status .UPDATE_NOT_AVAILABLE ;
19
20
import static com .google .firebase .app .distribution .TaskUtils .safeSetTaskException ;
27
28
import androidx .annotation .Nullable ;
28
29
import androidx .annotation .VisibleForTesting ;
29
30
import com .google .android .gms .tasks .Task ;
31
+ import com .google .android .gms .tasks .TaskCompletionSource ;
30
32
import com .google .android .gms .tasks .Tasks ;
31
33
import com .google .firebase .FirebaseApp ;
32
34
import com .google .firebase .app .distribution .Constants .ErrorMessages ;
38
40
import com .google .firebase .installations .FirebaseInstallationsApi ;
39
41
40
42
public class FirebaseAppDistribution {
43
+
41
44
private static final int UNKNOWN_RELEASE_FILE_SIZE = -1 ;
42
45
43
46
private final FirebaseApp firebaseApp ;
@@ -60,7 +63,7 @@ public class FirebaseAppDistribution {
60
63
61
64
private Task <AppDistributionRelease > cachedCheckForNewReleaseTask ;
62
65
private AlertDialog updateDialog ;
63
- private boolean updateDialogShown ;
66
+ private AlertDialog signInDialog ;
64
67
65
68
/** Constructor for FirebaseAppDistribution */
66
69
@ VisibleForTesting
@@ -132,12 +135,30 @@ public UpdateTask updateIfNewReleaseAvailable() {
132
135
if (cachedUpdateIfNewReleaseTask != null && !cachedUpdateIfNewReleaseTask .isComplete ()) {
133
136
return cachedUpdateIfNewReleaseTask ;
134
137
}
135
-
136
138
cachedUpdateIfNewReleaseTask = new UpdateTaskImpl ();
137
139
}
138
- checkForNewRelease ()
139
- .onSuccessTask (
140
- release -> {
140
+
141
+ showSignInDialog ()
142
+ // TODO(rachelprince): Revisit this comment once changes to checkForNewRelease are reviewed
143
+ // Even though checkForNewRelease() calls signInTester(), we explicitly call signInTester
144
+ // here both for code clarifty, and because we plan to remove the signInTester() call
145
+ // from checkForNewRelease() in the near future
146
+ .onSuccessTask (unused -> signInTester ())
147
+ .onSuccessTask (unused -> checkForNewRelease ())
148
+ .continueWithTask (
149
+ task -> {
150
+ if (!task .isSuccessful ()) {
151
+ postProgressToCachedUpdateIfNewReleaseTask (
152
+ UpdateProgress .builder ()
153
+ .setApkBytesDownloaded (UNKNOWN_RELEASE_FILE_SIZE )
154
+ .setApkFileTotalBytes (UNKNOWN_RELEASE_FILE_SIZE )
155
+ .setUpdateStatus (UpdateStatus .NEW_RELEASE_CHECK_FAILED )
156
+ .build ());
157
+ }
158
+ // if the task failed, this get() will cause the error to propogate to the handler
159
+ // below
160
+ AppDistributionRelease release = task .getResult ();
161
+
141
162
if (release == null ) {
142
163
postProgressToCachedUpdateIfNewReleaseTask (
143
164
UpdateProgress .builder ()
@@ -150,26 +171,59 @@ public UpdateTask updateIfNewReleaseAvailable() {
150
171
}
151
172
return showUpdateAlertDialog (release );
152
173
})
153
- .addOnFailureListener (
154
- e -> {
155
- postProgressToCachedUpdateIfNewReleaseTask (
156
- UpdateProgress .builder ()
157
- .setApkFileTotalBytes (UNKNOWN_RELEASE_FILE_SIZE )
158
- .setApkBytesDownloaded (UNKNOWN_RELEASE_FILE_SIZE )
159
- .setUpdateStatus (UpdateStatus .NEW_RELEASE_CHECK_FAILED )
160
- .build ());
161
- setCachedUpdateIfNewReleaseCompletionError (
162
- e ,
163
- new FirebaseAppDistributionException (
164
- Constants .ErrorMessages .NETWORK_ERROR ,
165
- FirebaseAppDistributionException .Status .NETWORK_FAILURE ));
166
- });
174
+ .onSuccessTask (
175
+ unused ->
176
+ updateApp (true )
177
+ .addOnProgressListener (this ::postProgressToCachedUpdateIfNewReleaseTask ))
178
+ .addOnFailureListener (this ::setCachedUpdateIfNewReleaseCompletionError );
167
179
168
180
synchronized (updateIfNewReleaseTaskLock ) {
169
181
return cachedUpdateIfNewReleaseTask ;
170
182
}
171
183
}
172
184
185
+ private Task <Void > showSignInDialog () {
186
+ if (isTesterSignedIn ()) {
187
+ return Tasks .forResult (null );
188
+ }
189
+
190
+ TaskCompletionSource <Void > showDialogTask = new TaskCompletionSource <>();
191
+
192
+ Activity currentActivity ;
193
+ try {
194
+ currentActivity = lifecycleNotifier .getNonNullCurrentActivity ();
195
+ } catch (FirebaseAppDistributionException e ) {
196
+ return Tasks .forException (e );
197
+ }
198
+
199
+ signInDialog = new AlertDialog .Builder (currentActivity ).create ();
200
+ Context context = firebaseApp .getApplicationContext ();
201
+ signInDialog .setTitle (context .getString (R .string .signin_dialog_title ));
202
+ signInDialog .setMessage (context .getString (R .string .singin_dialog_message ));
203
+
204
+ signInDialog .setButton (
205
+ AlertDialog .BUTTON_POSITIVE ,
206
+ context .getString (R .string .singin_yes_button ),
207
+ (dialogInterface , i ) -> showDialogTask .setResult (null ));
208
+
209
+ signInDialog .setButton (
210
+ AlertDialog .BUTTON_NEGATIVE ,
211
+ context .getString (R .string .singin_no_button ),
212
+ (dialogInterface , i ) ->
213
+ showDialogTask .setException (
214
+ new FirebaseAppDistributionException (
215
+ ErrorMessages .AUTHENTICATION_CANCELED , AUTHENTICATION_CANCELED )));
216
+
217
+ signInDialog .setOnCancelListener (
218
+ dialogInterface ->
219
+ showDialogTask .setException (
220
+ new FirebaseAppDistributionException (
221
+ ErrorMessages .AUTHENTICATION_CANCELED , AUTHENTICATION_CANCELED )));
222
+
223
+ signInDialog .show ();
224
+ return showDialogTask .getTask ();
225
+ }
226
+
173
227
/** Signs in the App Distribution tester. Presents the tester with a Google sign in UI */
174
228
@ NonNull
175
229
public Task <Void > signInTester () {
@@ -276,7 +330,7 @@ void onActivityDestroyed(@NonNull Activity activity) {
276
330
// SignInResult is internal to the SDK and is destroyed after creation
277
331
return ;
278
332
}
279
- if (updateDialogShown ) {
333
+ if (updateDialog != null && updateDialog . isShowing () ) {
280
334
setCachedUpdateIfNewReleaseCompletionError (
281
335
new FirebaseAppDistributionException (
282
336
ErrorMessages .UPDATE_CANCELED , Status .INSTALLATION_CANCELED ));
@@ -297,18 +351,18 @@ AppDistributionReleaseInternal getCachedNewRelease() {
297
351
}
298
352
}
299
353
300
- private UpdateTaskImpl showUpdateAlertDialog (AppDistributionRelease newRelease ) {
301
- Context context = firebaseApp .getApplicationContext ();
302
- Activity currentActivity = lifecycleNotifier .getCurrentActivity ();
303
- if (currentActivity == null ) {
304
- LogWrapper .getInstance ().e ("No foreground activity found." );
305
- UpdateTaskImpl updateTask = new UpdateTaskImpl ();
306
- updateTask .setException (
307
- new FirebaseAppDistributionException (
308
- ErrorMessages .APP_BACKGROUNDED ,
309
- FirebaseAppDistributionException .Status .UPDATE_NOT_AVAILABLE ));
310
- return updateTask ;
354
+ private Task <Void > showUpdateAlertDialog (AppDistributionRelease newRelease ) {
355
+ TaskCompletionSource <Void > showUpdateDialogTask = new TaskCompletionSource <>();
356
+
357
+ Activity currentActivity ;
358
+ try {
359
+ currentActivity = lifecycleNotifier .getNonNullCurrentActivity ();
360
+ } catch (FirebaseAppDistributionException e ) {
361
+ return Tasks .forException (e );
311
362
}
363
+
364
+ Context context = firebaseApp .getApplicationContext ();
365
+
312
366
updateDialog = new AlertDialog .Builder (currentActivity ).create ();
313
367
updateDialog .setTitle (context .getString (R .string .update_dialog_title ));
314
368
@@ -321,89 +375,64 @@ private UpdateTaskImpl showUpdateAlertDialog(AppDistributionRelease newRelease)
321
375
if (newRelease .getReleaseNotes () != null && !newRelease .getReleaseNotes ().isEmpty ()) {
322
376
message .append (String .format ("\n \n Release notes: %s" , newRelease .getReleaseNotes ()));
323
377
}
324
-
325
378
updateDialog .setMessage (message );
379
+
326
380
updateDialog .setButton (
327
381
AlertDialog .BUTTON_POSITIVE ,
328
382
context .getString (R .string .update_yes_button ),
329
- (dialogInterface , i ) -> {
330
- synchronized (updateIfNewReleaseTaskLock ) {
331
- // show download progress in notification manager
332
- updateApp (true )
333
- .addOnProgressListener (this ::postProgressToCachedUpdateIfNewReleaseTask )
334
- .addOnSuccessListener (unused -> setCachedUpdateIfNewReleaseResult ())
335
- .addOnFailureListener (cachedUpdateIfNewReleaseTask ::setException );
336
- }
337
- });
383
+ (dialogInterface , i ) -> showUpdateDialogTask .setResult (null ));
338
384
339
385
updateDialog .setButton (
340
386
AlertDialog .BUTTON_NEGATIVE ,
341
387
context .getString (R .string .update_no_button ),
342
- (dialogInterface , i ) -> dismissUpdateDialogCallback ());
388
+ (dialogInterface , i ) ->
389
+ showUpdateDialogTask .setException (
390
+ new FirebaseAppDistributionException (
391
+ ErrorMessages .UPDATE_CANCELED , Status .INSTALLATION_CANCELED )));
343
392
344
393
updateDialog .setOnCancelListener (
345
- dialogInterface -> {
346
- dismissUpdateDialogCallback ();
347
- });
394
+ dialogInterface ->
395
+ showUpdateDialogTask .setException (
396
+ new FirebaseAppDistributionException (
397
+ ErrorMessages .UPDATE_CANCELED , Status .INSTALLATION_CANCELED )));
348
398
349
399
updateDialog .show ();
350
- updateDialogShown = true ;
351
- synchronized (updateIfNewReleaseTaskLock ) {
352
- return cachedUpdateIfNewReleaseTask ;
353
- }
354
- }
355
400
356
- private void dismissUpdateDialogCallback () {
357
- synchronized (updateIfNewReleaseTaskLock ) {
358
- postProgressToCachedUpdateIfNewReleaseTask (
359
- UpdateProgress .builder ()
360
- .setApkFileTotalBytes (UNKNOWN_RELEASE_FILE_SIZE )
361
- .setApkBytesDownloaded (UNKNOWN_RELEASE_FILE_SIZE )
362
- .setUpdateStatus (UpdateStatus .UPDATE_CANCELED )
363
- .build ());
364
- setCachedUpdateIfNewReleaseCompletionError (
365
- new FirebaseAppDistributionException (
366
- ErrorMessages .UPDATE_CANCELED , Status .INSTALLATION_CANCELED ));
367
- }
401
+ return showUpdateDialogTask .getTask ();
368
402
}
369
403
370
- private void setCachedUpdateIfNewReleaseCompletionError (FirebaseAppDistributionException e ) {
404
+ private void setCachedUpdateIfNewReleaseCompletionError (Exception e ) {
371
405
synchronized (updateIfNewReleaseTaskLock ) {
372
406
safeSetTaskException (cachedUpdateIfNewReleaseTask , e );
373
407
}
374
- dismissUpdateDialog ();
375
- }
376
-
377
- private void setCachedUpdateIfNewReleaseCompletionError (
378
- Exception e , FirebaseAppDistributionException defaultFirebaseException ) {
379
- if (e instanceof FirebaseAppDistributionException ) {
380
- setCachedUpdateIfNewReleaseCompletionError ((FirebaseAppDistributionException ) e );
381
- } else {
382
- setCachedUpdateIfNewReleaseCompletionError (defaultFirebaseException );
383
- }
408
+ dismissDialogs ();
384
409
}
385
410
386
411
private void postProgressToCachedUpdateIfNewReleaseTask (UpdateProgress progress ) {
387
412
synchronized (updateIfNewReleaseTaskLock ) {
388
- cachedUpdateIfNewReleaseTask .updateProgress (progress );
413
+ if (cachedUpdateIfNewReleaseTask != null && !cachedUpdateIfNewReleaseTask .isComplete ()) {
414
+ cachedUpdateIfNewReleaseTask .updateProgress (progress );
415
+ }
389
416
}
390
417
}
391
418
392
419
private void setCachedUpdateIfNewReleaseResult () {
393
420
synchronized (updateIfNewReleaseTaskLock ) {
394
421
safeSetTaskResult (cachedUpdateIfNewReleaseTask );
395
422
}
396
- dismissUpdateDialog ();
423
+ dismissDialogs ();
397
424
}
398
425
399
- private void dismissUpdateDialog () {
400
- if (updateDialog != null ) {
426
+ private void dismissDialogs () {
427
+ if (signInDialog != null && signInDialog .isShowing ()) {
428
+ signInDialog .dismiss ();
429
+ }
430
+ if (updateDialog != null && updateDialog .isShowing ()) {
401
431
updateDialog .dismiss ();
402
- updateDialogShown = false ;
403
432
}
404
433
}
405
434
406
- private UpdateTask getErrorUpdateTask (Exception e ) {
435
+ private UpdateTaskImpl getErrorUpdateTask (Exception e ) {
407
436
UpdateTaskImpl updateTask = new UpdateTaskImpl ();
408
437
updateTask .setException (e );
409
438
return updateTask ;
0 commit comments