@@ -57,17 +57,13 @@ class FirebaseAppDistributionImpl implements FirebaseAppDistribution {
57
57
private final AabUpdater aabUpdater ;
58
58
private final SignInStorage signInStorage ;
59
59
60
- private final Object updateIfNewReleaseTaskLock = new Object ();
61
-
62
- @ GuardedBy ("updateIfNewReleaseTaskLock" )
63
- private UpdateTaskImpl cachedUpdateIfNewReleaseTask ;
64
-
65
60
private final Object cachedNewReleaseLock = new Object ();
66
61
67
62
@ GuardedBy ("cachedNewReleaseLock" )
68
63
private AppDistributionReleaseInternal cachedNewRelease ;
69
64
70
- private Task <AppDistributionRelease > cachedCheckForNewReleaseTask ;
65
+ private TaskCache <UpdateTask > updateIfNewReleaseAvailableTaskCache = new TaskCache <>();
66
+ private TaskCache <Task <AppDistributionRelease >> checkForNewReleaseTaskCache = new TaskCache <>();
71
67
private AlertDialog updateConfirmationDialog ;
72
68
private AlertDialog signInConfirmationDialog ;
73
69
@ Nullable private Activity dialogHostActivity = null ;
@@ -102,55 +98,57 @@ class FirebaseAppDistributionImpl implements FirebaseAppDistribution {
102
98
@ Override
103
99
@ NonNull
104
100
public UpdateTask updateIfNewReleaseAvailable () {
105
- synchronized (updateIfNewReleaseTaskLock ) {
106
- if (updateIfNewReleaseAvailableIsTaskInProgress ()) {
107
- return cachedUpdateIfNewReleaseTask ;
108
- }
109
- cachedUpdateIfNewReleaseTask = new UpdateTaskImpl ();
110
- remakeSignInConfirmationDialog = false ;
111
- remakeUpdateConfirmationDialog = false ;
112
- dialogHostActivity = null ;
113
- }
114
-
115
- lifecycleNotifier
116
- .applyToForegroundActivityTask (this ::showSignInConfirmationDialog )
117
- .onSuccessTask (unused -> signInTester ())
118
- .onSuccessTask (unused -> checkForNewRelease ())
119
- .continueWithTask (
120
- task -> {
121
- if (!task .isSuccessful ()) {
122
- postProgressToCachedUpdateIfNewReleaseTask (
123
- UpdateProgressImpl .builder ()
124
- .setApkBytesDownloaded (UNKNOWN_RELEASE_FILE_SIZE )
125
- .setApkFileTotalBytes (UNKNOWN_RELEASE_FILE_SIZE )
126
- .setUpdateStatus (UpdateStatus .NEW_RELEASE_CHECK_FAILED )
127
- .build ());
128
- }
129
- // if the task failed, this get() will cause the error to propagate to the handler
130
- // below
131
- AppDistributionRelease release = task .getResult ();
132
- if (release == null ) {
133
- postProgressToCachedUpdateIfNewReleaseTask (
134
- UpdateProgressImpl .builder ()
135
- .setApkFileTotalBytes (UNKNOWN_RELEASE_FILE_SIZE )
136
- .setApkBytesDownloaded (UNKNOWN_RELEASE_FILE_SIZE )
137
- .setUpdateStatus (UpdateStatus .NEW_RELEASE_NOT_AVAILABLE )
138
- .build ());
139
- setCachedUpdateIfNewReleaseResult ();
140
- return Tasks .forResult (null );
141
- }
142
- return lifecycleNotifier .applyToForegroundActivityTask (
143
- activity -> showUpdateConfirmationDialog (activity , release ));
144
- })
145
- .onSuccessTask (
146
- unused ->
147
- updateApp (true )
148
- .addOnProgressListener (this ::postProgressToCachedUpdateIfNewReleaseTask ))
149
- .addOnFailureListener (this ::setCachedUpdateIfNewReleaseCompletionError );
150
-
151
- synchronized (updateIfNewReleaseTaskLock ) {
152
- return cachedUpdateIfNewReleaseTask ;
153
- }
101
+ return updateIfNewReleaseAvailableTaskCache .getOrCreateTask (
102
+ () -> {
103
+ UpdateTaskImpl updateTask = new UpdateTaskImpl ();
104
+ remakeSignInConfirmationDialog = false ;
105
+ remakeUpdateConfirmationDialog = false ;
106
+ dialogHostActivity = null ;
107
+
108
+ lifecycleNotifier
109
+ .applyToForegroundActivityTask (this ::showSignInConfirmationDialog )
110
+ .onSuccessTask (unused -> signInTester ())
111
+ .onSuccessTask (unused -> checkForNewRelease ())
112
+ .continueWithTask (
113
+ task -> {
114
+ if (!task .isSuccessful ()) {
115
+ postProgressToCachedUpdateIfNewReleaseTask (
116
+ updateTask ,
117
+ UpdateProgressImpl .builder ()
118
+ .setApkBytesDownloaded (UNKNOWN_RELEASE_FILE_SIZE )
119
+ .setApkFileTotalBytes (UNKNOWN_RELEASE_FILE_SIZE )
120
+ .setUpdateStatus (UpdateStatus .NEW_RELEASE_CHECK_FAILED )
121
+ .build ());
122
+ }
123
+ // if the task failed, this get() will cause the error to propagate to the
124
+ // handler below
125
+ AppDistributionRelease release = task .getResult ();
126
+ if (release == null ) {
127
+ postProgressToCachedUpdateIfNewReleaseTask (
128
+ updateTask ,
129
+ UpdateProgressImpl .builder ()
130
+ .setApkFileTotalBytes (UNKNOWN_RELEASE_FILE_SIZE )
131
+ .setApkBytesDownloaded (UNKNOWN_RELEASE_FILE_SIZE )
132
+ .setUpdateStatus (UpdateStatus .NEW_RELEASE_NOT_AVAILABLE )
133
+ .build ());
134
+ setCachedUpdateIfNewReleaseResult (updateTask );
135
+ return Tasks .forResult (null );
136
+ }
137
+ return lifecycleNotifier .applyToForegroundActivityTask (
138
+ activity -> showUpdateConfirmationDialog (activity , release ));
139
+ })
140
+ .onSuccessTask (
141
+ unused ->
142
+ updateApp (true )
143
+ .addOnProgressListener (
144
+ updateProgress ->
145
+ postProgressToCachedUpdateIfNewReleaseTask (
146
+ updateTask , updateProgress )))
147
+ .addOnFailureListener (
148
+ exception -> setCachedUpdateIfNewReleaseCompletionError (updateTask , exception ));
149
+
150
+ return updateTask ;
151
+ });
154
152
}
155
153
156
154
@ NonNull
@@ -220,37 +218,35 @@ public void signOutTester() {
220
218
@ Override
221
219
@ NonNull
222
220
public synchronized Task <AppDistributionRelease > checkForNewRelease () {
223
- if (cachedCheckForNewReleaseTask != null && !cachedCheckForNewReleaseTask .isComplete ()) {
224
- LogWrapper .getInstance ().v ("Response in progress" );
225
- return cachedCheckForNewReleaseTask ;
226
- }
227
- if (!isTesterSignedIn ()) {
228
- return Tasks .forException (
229
- new FirebaseAppDistributionException ("Tester is not signed in" , AUTHENTICATION_FAILURE ));
230
- }
221
+ return checkForNewReleaseTaskCache .getOrCreateTask (
222
+ () -> {
223
+ if (!isTesterSignedIn ()) {
224
+ return Tasks .forException (
225
+ new FirebaseAppDistributionException (
226
+ "Tester is not signed in" , AUTHENTICATION_FAILURE ));
227
+ }
231
228
232
- cachedCheckForNewReleaseTask =
233
- newReleaseFetcher
234
- .checkForNewRelease ()
235
- .onSuccessTask (
236
- appDistributionReleaseInternal -> {
237
- setCachedNewRelease (appDistributionReleaseInternal );
238
- return Tasks .forResult (
239
- ReleaseUtils .convertToAppDistributionRelease (appDistributionReleaseInternal ));
240
- })
241
- .addOnFailureListener (
242
- e -> {
243
- if (e instanceof FirebaseAppDistributionException
244
- && ((FirebaseAppDistributionException ) e ).getErrorCode ()
245
- == AUTHENTICATION_FAILURE ) {
246
- // If CheckForNewRelease returns authentication error, the FID is no longer
247
- // valid or does not have access to the latest release. So sign out the tester
248
- // to force FID re-registration
249
- signOutTester ();
250
- }
251
- });
252
-
253
- return cachedCheckForNewReleaseTask ;
229
+ return newReleaseFetcher
230
+ .checkForNewRelease ()
231
+ .onSuccessTask (
232
+ appDistributionReleaseInternal -> {
233
+ setCachedNewRelease (appDistributionReleaseInternal );
234
+ return Tasks .forResult (
235
+ ReleaseUtils .convertToAppDistributionRelease (
236
+ appDistributionReleaseInternal ));
237
+ })
238
+ .addOnFailureListener (
239
+ e -> {
240
+ if (e instanceof FirebaseAppDistributionException
241
+ && ((FirebaseAppDistributionException ) e ).getErrorCode ()
242
+ == AUTHENTICATION_FAILURE ) {
243
+ // If CheckForNewRelease returns authentication error, the FID is no longer
244
+ // valid or does not have access to the latest release. So sign out the tester
245
+ // to force FID re-registration
246
+ signOutTester ();
247
+ }
248
+ });
249
+ });
254
250
}
255
251
256
252
@ Override
@@ -407,25 +403,20 @@ private Task<Void> showUpdateConfirmationDialog(
407
403
return showUpdateDialogTask .getTask ();
408
404
}
409
405
410
- private void setCachedUpdateIfNewReleaseCompletionError (Exception e ) {
411
- synchronized (updateIfNewReleaseTaskLock ) {
412
- safeSetTaskException (cachedUpdateIfNewReleaseTask , e );
413
- }
406
+ private void setCachedUpdateIfNewReleaseCompletionError (UpdateTaskImpl updateTask , Exception e ) {
407
+ safeSetTaskException (updateTask , e );
414
408
dismissDialogs ();
415
409
}
416
410
417
- private void postProgressToCachedUpdateIfNewReleaseTask (UpdateProgress progress ) {
418
- synchronized (updateIfNewReleaseTaskLock ) {
419
- if (cachedUpdateIfNewReleaseTask != null && !cachedUpdateIfNewReleaseTask .isComplete ()) {
420
- cachedUpdateIfNewReleaseTask .updateProgress (progress );
421
- }
411
+ private void postProgressToCachedUpdateIfNewReleaseTask (
412
+ UpdateTaskImpl updateTask , UpdateProgress progress ) {
413
+ if (updateTask != null && !updateTask .isComplete ()) {
414
+ updateTask .updateProgress (progress );
422
415
}
423
416
}
424
417
425
- private void setCachedUpdateIfNewReleaseResult () {
426
- synchronized (updateIfNewReleaseTaskLock ) {
427
- safeSetTaskResult (cachedUpdateIfNewReleaseTask );
428
- }
418
+ private void setCachedUpdateIfNewReleaseResult (UpdateTaskImpl updateTask ) {
419
+ safeSetTaskResult (updateTask );
429
420
dismissDialogs ();
430
421
}
431
422
@@ -444,12 +435,6 @@ private UpdateTaskImpl getErrorUpdateTask(Exception e) {
444
435
return updateTask ;
445
436
}
446
437
447
- private boolean updateIfNewReleaseAvailableIsTaskInProgress () {
448
- synchronized (updateIfNewReleaseTaskLock ) {
449
- return cachedUpdateIfNewReleaseTask != null && !cachedUpdateIfNewReleaseTask .isComplete ();
450
- }
451
- }
452
-
453
438
private boolean awaitingSignInDialogConfirmation () {
454
439
return (showSignInDialogTask != null
455
440
&& !showSignInDialogTask .getTask ().isComplete ()
0 commit comments