16
16
17
17
import static com .google .firebase .appdistribution .FirebaseAppDistributionException .Status .DOWNLOAD_FAILURE ;
18
18
import static com .google .firebase .appdistribution .FirebaseAppDistributionException .Status .NETWORK_FAILURE ;
19
- import static com .google .firebase .appdistribution .impl .TaskUtils .safeSetTaskException ;
20
- import static com .google .firebase .appdistribution .impl .TaskUtils .safeSetTaskResult ;
21
19
22
20
import android .content .Context ;
23
21
import android .os .Build .VERSION ;
24
22
import android .os .Build .VERSION_CODES ;
25
- import androidx .annotation .GuardedBy ;
26
23
import androidx .annotation .NonNull ;
27
24
import androidx .annotation .VisibleForTesting ;
28
25
import com .google .android .gms .tasks .Task ;
29
26
import com .google .firebase .FirebaseApp ;
27
+ import com .google .firebase .annotations .concurrent .Blocking ;
28
+ import com .google .firebase .annotations .concurrent .Lightweight ;
30
29
import com .google .firebase .appdistribution .FirebaseAppDistribution ;
31
30
import com .google .firebase .appdistribution .FirebaseAppDistributionException ;
32
31
import com .google .firebase .appdistribution .FirebaseAppDistributionException .Status ;
33
32
import com .google .firebase .appdistribution .UpdateStatus ;
33
+ import com .google .firebase .appdistribution .UpdateTask ;
34
34
import java .io .BufferedOutputStream ;
35
35
import java .io .File ;
36
36
import java .io .IOException ;
@@ -46,24 +46,23 @@ class ApkUpdater {
46
46
private static final String REQUEST_METHOD_GET = "GET" ;
47
47
private static final String DEFAULT_APK_FILE_NAME = "downloaded_release.apk" ;
48
48
49
- private final Executor blockingExecutor ; // Executor to run task listeners on a background thread
49
+ private final @ Blocking Executor blockingExecutor ;
50
+ private final @ Lightweight Executor lightweightExecutor ;
50
51
private final Context context ;
51
52
private final ApkInstaller apkInstaller ;
52
53
private final FirebaseAppDistributionNotificationsManager appDistributionNotificationsManager ;
53
54
private final HttpsUrlConnectionFactory httpsUrlConnectionFactory ;
54
55
private final FirebaseAppDistributionLifecycleNotifier lifeCycleNotifier ;
55
-
56
- @ GuardedBy ("updateTaskLock" )
57
- private UpdateTaskImpl cachedUpdateTask ;
58
-
59
- private final Object updateTaskLock = new Object ();
56
+ private UpdateTaskCache cachedUpdateTask ;
60
57
61
58
public ApkUpdater (
62
59
@ NonNull FirebaseApp firebaseApp ,
63
60
@ NonNull ApkInstaller apkInstaller ,
64
- @ NonNull Executor blockingExecutor ) {
61
+ @ NonNull @ Blocking Executor blockingExecutor ,
62
+ @ NonNull @ Lightweight Executor lightweightExecutor ) {
65
63
this (
66
64
blockingExecutor ,
65
+ lightweightExecutor ,
67
66
firebaseApp .getApplicationContext (),
68
67
apkInstaller ,
69
68
new FirebaseAppDistributionNotificationsManager (firebaseApp .getApplicationContext ()),
@@ -73,57 +72,45 @@ public ApkUpdater(
73
72
74
73
@ VisibleForTesting
75
74
public ApkUpdater (
76
- @ NonNull Executor blockingExecutor ,
75
+ @ NonNull @ Blocking Executor blockingExecutor ,
76
+ @ NonNull @ Lightweight Executor lightweightExecutor ,
77
77
@ NonNull Context context ,
78
78
@ NonNull ApkInstaller apkInstaller ,
79
79
@ NonNull FirebaseAppDistributionNotificationsManager appDistributionNotificationsManager ,
80
80
@ NonNull HttpsUrlConnectionFactory httpsUrlConnectionFactory ,
81
81
@ NonNull FirebaseAppDistributionLifecycleNotifier lifeCycleNotifier ) {
82
82
this .blockingExecutor = blockingExecutor ;
83
+ this .lightweightExecutor = lightweightExecutor ;
83
84
this .context = context ;
84
85
this .apkInstaller = apkInstaller ;
85
86
this .appDistributionNotificationsManager = appDistributionNotificationsManager ;
86
87
this .httpsUrlConnectionFactory = httpsUrlConnectionFactory ;
87
88
this .lifeCycleNotifier = lifeCycleNotifier ;
89
+ this .cachedUpdateTask = new UpdateTaskCache (lightweightExecutor );
88
90
}
89
91
90
- UpdateTaskImpl updateApk (
92
+ UpdateTask updateApk (
91
93
@ NonNull AppDistributionReleaseInternal newRelease , boolean showNotification ) {
92
- synchronized (updateTaskLock ) {
93
- if (cachedUpdateTask != null && !cachedUpdateTask .isComplete ()) {
94
- return cachedUpdateTask ;
95
- }
96
-
97
- cachedUpdateTask = new UpdateTaskImpl ();
98
- }
99
-
100
- downloadApk (newRelease , showNotification )
101
- .addOnSuccessListener (blockingExecutor , file -> installApk (file , showNotification ))
102
- .addOnFailureListener (
103
- blockingExecutor ,
104
- e -> {
105
- setUpdateTaskCompletionErrorWithDefault (
106
- e , "Failed to download APK" , Status .DOWNLOAD_FAILURE );
107
- });
108
-
109
- synchronized (updateTaskLock ) {
110
- return cachedUpdateTask ;
111
- }
94
+ return cachedUpdateTask .getOrCreateUpdateTask (
95
+ () -> {
96
+ downloadApk (newRelease , showNotification )
97
+ .addOnSuccessListener (lightweightExecutor , file -> installApk (file , showNotification ))
98
+ .addOnFailureListener (
99
+ lightweightExecutor ,
100
+ e ->
101
+ setUpdateTaskCompletionErrorWithDefault (
102
+ e , "Failed to download APK" , Status .DOWNLOAD_FAILURE ));
103
+ return new UpdateTaskImpl ();
104
+ });
112
105
}
113
106
114
107
private void installApk (File file , boolean showDownloadNotificationManager ) {
115
108
lifeCycleNotifier
116
109
.applyToForegroundActivityTask (
117
110
activity -> apkInstaller .installApk (file .getPath (), activity ))
118
- .addOnSuccessListener (
119
- blockingExecutor ,
120
- unused -> {
121
- synchronized (updateTaskLock ) {
122
- safeSetTaskResult (cachedUpdateTask );
123
- }
124
- })
111
+ .addOnSuccessListener (lightweightExecutor , unused -> cachedUpdateTask .setResult ())
125
112
.addOnFailureListener (
126
- blockingExecutor ,
113
+ lightweightExecutor ,
127
114
e -> {
128
115
postUpdateProgress (
129
116
file .length (),
@@ -261,17 +248,11 @@ private String getApkFileName() {
261
248
}
262
249
}
263
250
264
- private void setUpdateTaskCompletionError (FirebaseAppDistributionException e ) {
265
- synchronized (updateTaskLock ) {
266
- safeSetTaskException (cachedUpdateTask , e );
267
- }
268
- }
269
-
270
251
private void setUpdateTaskCompletionErrorWithDefault (Exception e , String message , Status status ) {
271
252
if (e instanceof FirebaseAppDistributionException ) {
272
- setUpdateTaskCompletionError ((FirebaseAppDistributionException ) e );
253
+ cachedUpdateTask . setException ((FirebaseAppDistributionException ) e );
273
254
} else {
274
- setUpdateTaskCompletionError (new FirebaseAppDistributionException (message , status , e ));
255
+ cachedUpdateTask . setException (new FirebaseAppDistributionException (message , status , e ));
275
256
}
276
257
}
277
258
@@ -281,14 +262,12 @@ private void postUpdateProgress(
281
262
UpdateStatus status ,
282
263
boolean showNotification ,
283
264
int stringResourceId ) {
284
- synchronized (updateTaskLock ) {
285
- cachedUpdateTask .updateProgress (
286
- UpdateProgressImpl .builder ()
287
- .setApkFileTotalBytes (totalBytes )
288
- .setApkBytesDownloaded (downloadedBytes )
289
- .setUpdateStatus (status )
290
- .build ());
291
- }
265
+ cachedUpdateTask .setProgress (
266
+ UpdateProgressImpl .builder ()
267
+ .setApkFileTotalBytes (totalBytes )
268
+ .setApkBytesDownloaded (downloadedBytes )
269
+ .setUpdateStatus (status )
270
+ .build ());
292
271
if (showNotification ) {
293
272
appDistributionNotificationsManager .showAppUpdateNotification (
294
273
totalBytes , downloadedBytes , stringResourceId );
0 commit comments