Skip to content

Commit adaa1df

Browse files
manny-jimenezManny Jimenez
and
Manny Jimenez
authored
Removing failures when app is backgrounded (#3310)
* Removing failures when app is backgrounded * Fast follow clean up * Fixing tests and responding to some comments * fixing test * Fixing tests and api text file * Preventing window leak error on rotate * Removing log * removing TODO * removing finish and changing getActivity * Responding to comments and fixing tests * Fixing api.txt * Removing tests with null activity * responding to nit * Fixing name Co-authored-by: Manny Jimenez <[email protected]>
1 parent 32c9ad5 commit adaa1df

File tree

16 files changed

+169
-168
lines changed

16 files changed

+169
-168
lines changed

firebase-appdistribution-stub/api.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ package com.google.firebase.appdistribution {
3434
enum_constant public static final com.google.firebase.appdistribution.FirebaseAppDistributionException.Status AUTHENTICATION_CANCELED;
3535
enum_constant public static final com.google.firebase.appdistribution.FirebaseAppDistributionException.Status AUTHENTICATION_FAILURE;
3636
enum_constant public static final com.google.firebase.appdistribution.FirebaseAppDistributionException.Status DOWNLOAD_FAILURE;
37-
enum_constant public static final com.google.firebase.appdistribution.FirebaseAppDistributionException.Status FOREGROUND_ACTIVITY_NOT_AVAILABLE;
3837
enum_constant public static final com.google.firebase.appdistribution.FirebaseAppDistributionException.Status INSTALLATION_CANCELED;
3938
enum_constant public static final com.google.firebase.appdistribution.FirebaseAppDistributionException.Status INSTALLATION_FAILURE;
4039
enum_constant public static final com.google.firebase.appdistribution.FirebaseAppDistributionException.Status INSTALLATION_FAILURE_SIGNATURE_MISMATCH;

firebase-appdistribution-stub/src/main/java/com/google/firebase/appdistribution/FirebaseAppDistributionException.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,6 @@ public enum Status {
4242
/** Installation canceled */
4343
INSTALLATION_CANCELED,
4444

45-
/** No foreground activity available for a given intent */
46-
// TODO(rachelprince): add this to API council review
47-
FOREGROUND_ACTIVITY_NOT_AVAILABLE,
48-
4945
/** Update not available for the current tester and app */
5046
UPDATE_NOT_AVAILABLE,
5147

firebase-appdistribution/api.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ package com.google.firebase.appdistribution {
3434
enum_constant public static final com.google.firebase.appdistribution.FirebaseAppDistributionException.Status AUTHENTICATION_CANCELED;
3535
enum_constant public static final com.google.firebase.appdistribution.FirebaseAppDistributionException.Status AUTHENTICATION_FAILURE;
3636
enum_constant public static final com.google.firebase.appdistribution.FirebaseAppDistributionException.Status DOWNLOAD_FAILURE;
37-
enum_constant public static final com.google.firebase.appdistribution.FirebaseAppDistributionException.Status FOREGROUND_ACTIVITY_NOT_AVAILABLE;
3837
enum_constant public static final com.google.firebase.appdistribution.FirebaseAppDistributionException.Status INSTALLATION_CANCELED;
3938
enum_constant public static final com.google.firebase.appdistribution.FirebaseAppDistributionException.Status INSTALLATION_FAILURE;
4039
enum_constant public static final com.google.firebase.appdistribution.FirebaseAppDistributionException.Status INSTALLATION_FAILURE_SIGNATURE_MISMATCH;

firebase-appdistribution/src/main/java/com/google/firebase/appdistribution/ApkInstaller.java

Lines changed: 2 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,6 @@ class ApkInstaller {
3333
@GuardedBy("installTaskLock")
3434
private TaskCompletionSource<Void> installTaskCompletionSource;
3535

36-
@GuardedBy("installTaskLock")
37-
private boolean promptInstallOnActivityResume = false;
38-
39-
@GuardedBy("installTaskLock")
40-
private String cachedInstallApkPath = "";
41-
4236
private final Object installTaskLock = new Object();
4337

4438
ApkInstaller(FirebaseAppDistributionLifecycleNotifier lifeCycleNotifier) {
@@ -59,8 +53,6 @@ void onActivityStarted(@Nullable Activity activity) {
5953
return;
6054
}
6155
}
62-
63-
handleAppResume(activity);
6456
}
6557

6658
void onActivityDestroyed(@Nullable Activity activity) {
@@ -71,30 +63,9 @@ void onActivityDestroyed(@Nullable Activity activity) {
7163
}
7264
}
7365

74-
void handleAppResume(Activity activity) {
75-
// This ensures that if the app was backgrounded during download, installation would continue
76-
// after app resume
66+
Task<Void> installApk(String path, Activity currentActivity) {
7767
synchronized (installTaskLock) {
78-
if (promptInstallOnActivityResume
79-
&& cachedInstallApkPath != null
80-
&& !cachedInstallApkPath.isEmpty()) {
81-
startInstallActivity(cachedInstallApkPath, activity);
82-
}
83-
}
84-
}
85-
86-
Task<Void> installApk(String path) {
87-
synchronized (installTaskLock) {
88-
Activity currentActivity = lifeCycleNotifier.getCurrentActivity();
89-
// This ensures that we save the state of the install if the app is backgrounded during
90-
// APK download
91-
if (currentActivity == null) {
92-
promptInstallOnActivityResume = true;
93-
cachedInstallApkPath = path;
94-
} else {
95-
// only start the install activity if current Activity is in the foreground
96-
startInstallActivity(path, currentActivity);
97-
}
68+
startInstallActivity(path, currentActivity);
9869

9970
if (this.installTaskCompletionSource == null
10071
|| this.installTaskCompletionSource.getTask().isComplete()) {
@@ -105,10 +76,6 @@ Task<Void> installApk(String path) {
10576
}
10677

10778
private void startInstallActivity(String path, Activity currentActivity) {
108-
synchronized (installTaskLock) {
109-
promptInstallOnActivityResume = false;
110-
cachedInstallApkPath = "";
111-
}
11279
Intent intent = new Intent(currentActivity, InstallActivity.class);
11380
intent.putExtra("INSTALL_PATH", path);
11481
currentActivity.startActivity(intent);

firebase-appdistribution/src/main/java/com/google/firebase/appdistribution/ApkUpdater.java

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,11 @@ class ApkUpdater {
5050

5151
private TaskCompletionSource<File> downloadTaskCompletionSource;
5252
private final Executor taskExecutor; // Executor to run task listeners on a background thread
53-
private final FirebaseApp firebaseApp;
5453
private final Context context;
5554
private final ApkInstaller apkInstaller;
5655
private final FirebaseAppDistributionNotificationsManager appDistributionNotificationsManager;
5756
private final HttpsUrlConnectionFactory httpsUrlConnectionFactory;
57+
private final FirebaseAppDistributionLifecycleNotifier lifeCycleNotifier;
5858

5959
@GuardedBy("updateTaskLock")
6060
private UpdateTaskImpl cachedUpdateTask;
@@ -64,25 +64,27 @@ class ApkUpdater {
6464
public ApkUpdater(@NonNull FirebaseApp firebaseApp, @NonNull ApkInstaller apkInstaller) {
6565
this(
6666
Executors.newSingleThreadExecutor(),
67-
firebaseApp,
67+
firebaseApp.getApplicationContext(),
6868
apkInstaller,
6969
new FirebaseAppDistributionNotificationsManager(firebaseApp.getApplicationContext()),
70-
new HttpsUrlConnectionFactory());
70+
new HttpsUrlConnectionFactory(),
71+
FirebaseAppDistributionLifecycleNotifier.getInstance());
7172
}
7273

7374
@VisibleForTesting
7475
public ApkUpdater(
7576
@NonNull Executor taskExecutor,
76-
@NonNull FirebaseApp firebaseApp,
77+
@NonNull Context context,
7778
@NonNull ApkInstaller apkInstaller,
7879
@NonNull FirebaseAppDistributionNotificationsManager appDistributionNotificationsManager,
79-
@NonNull HttpsUrlConnectionFactory httpsUrlConnectionFactory) {
80+
@NonNull HttpsUrlConnectionFactory httpsUrlConnectionFactory,
81+
@NonNull FirebaseAppDistributionLifecycleNotifier lifeCycleNotifier) {
8082
this.taskExecutor = taskExecutor;
81-
this.firebaseApp = firebaseApp;
83+
this.context = context;
8284
this.apkInstaller = apkInstaller;
8385
this.appDistributionNotificationsManager = appDistributionNotificationsManager;
8486
this.httpsUrlConnectionFactory = httpsUrlConnectionFactory;
85-
this.context = firebaseApp.getApplicationContext();
87+
this.lifeCycleNotifier = lifeCycleNotifier;
8688
}
8789

8890
UpdateTaskImpl updateApk(
@@ -110,8 +112,9 @@ UpdateTaskImpl updateApk(
110112
}
111113

112114
private void installApk(File file, boolean showDownloadNotificationManager) {
113-
apkInstaller
114-
.installApk(file.getPath())
115+
lifeCycleNotifier
116+
.getForegroundActivity()
117+
.onSuccessTask(taskExecutor, activity -> apkInstaller.installApk(file.getPath(), activity))
115118
.addOnSuccessListener(
116119
taskExecutor,
117120
unused -> {

firebase-appdistribution/src/main/java/com/google/firebase/appdistribution/Constants.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ static class ErrorMessages {
3737

3838
public static final String DOWNLOAD_URL_NOT_FOUND = "Download URL not found";
3939

40-
public static final String APP_BACKGROUNDED = "No foreground activity available";
41-
4240
public static final String APK_INSTALLATION_FAILED =
4341
"The APK failed to install or installation was cancelled";
4442
}

firebase-appdistribution/src/main/java/com/google/firebase/appdistribution/FirebaseAppDistribution.java

Lines changed: 21 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import android.app.Activity;
2424
import android.app.AlertDialog;
2525
import android.content.Context;
26-
import android.os.Looper;
2726
import androidx.annotation.GuardedBy;
2827
import androidx.annotation.NonNull;
2928
import androidx.annotation.Nullable;
@@ -64,7 +63,7 @@ public class FirebaseAppDistribution {
6463

6564
private Task<AppDistributionRelease> cachedCheckForNewReleaseTask;
6665
private AlertDialog updateDialog;
67-
private AlertDialog signInDialog;
66+
private AlertDialog signInConfirmationDialog;
6867

6968
/** Constructor for FirebaseAppDistribution */
7069
@VisibleForTesting
@@ -137,19 +136,11 @@ public UpdateTask updateIfNewReleaseAvailable() {
137136
return cachedUpdateIfNewReleaseTask;
138137
}
139138
cachedUpdateIfNewReleaseTask = new UpdateTaskImpl();
140-
141-
if (isOnBackgroundThread()) {
142-
LogWrapper.getInstance()
143-
.e("updateIfNewReleaseAvailable cannot be called from a background thread");
144-
setCachedUpdateIfNewReleaseCompletionError(
145-
new FirebaseAppDistributionException(
146-
"updateIfNewReleaseAvailable cannot be called from a background thread",
147-
Status.UNKNOWN));
148-
return cachedUpdateIfNewReleaseTask;
149-
}
150139
}
151140

152-
showSignInDialog()
141+
lifecycleNotifier
142+
.getForegroundActivity()
143+
.onSuccessTask(this::showSignInConfirmationDialog)
153144
// TODO(rachelprince): Revisit this comment once changes to checkForNewRelease are reviewed
154145
// Even though checkForNewRelease() calls signInTester(), we explicitly call signInTester
155146
// here both for code clarifty, and because we plan to remove the signInTester() call
@@ -179,7 +170,9 @@ public UpdateTask updateIfNewReleaseAvailable() {
179170
setCachedUpdateIfNewReleaseResult();
180171
return Tasks.forResult(null);
181172
}
182-
return showUpdateAlertDialog(release);
173+
return lifecycleNotifier
174+
.getForegroundActivity()
175+
.onSuccessTask((activity) -> showUpdateAlertDialog(activity, release));
183176
})
184177
.onSuccessTask(
185178
unused ->
@@ -192,49 +185,38 @@ public UpdateTask updateIfNewReleaseAvailable() {
192185
}
193186
}
194187

195-
private boolean isOnBackgroundThread() {
196-
return Looper.myLooper() != Looper.getMainLooper();
197-
}
198-
199-
private Task<Void> showSignInDialog() {
188+
private Task<Void> showSignInConfirmationDialog(Activity hostActivity) {
200189
if (isTesterSignedIn()) {
201190
return Tasks.forResult(null);
202191
}
203192

204193
TaskCompletionSource<Void> showDialogTask = new TaskCompletionSource<>();
205194

206-
Activity currentActivity;
207-
try {
208-
currentActivity = lifecycleNotifier.getNonNullCurrentActivity();
209-
} catch (FirebaseAppDistributionException e) {
210-
return Tasks.forException(e);
211-
}
212-
213-
signInDialog = new AlertDialog.Builder(currentActivity).create();
195+
signInConfirmationDialog = new AlertDialog.Builder(hostActivity).create();
214196
Context context = firebaseApp.getApplicationContext();
215-
signInDialog.setTitle(context.getString(R.string.signin_dialog_title));
216-
signInDialog.setMessage(context.getString(R.string.singin_dialog_message));
197+
signInConfirmationDialog.setTitle(context.getString(R.string.signin_dialog_title));
198+
signInConfirmationDialog.setMessage(context.getString(R.string.singin_dialog_message));
217199

218-
signInDialog.setButton(
200+
signInConfirmationDialog.setButton(
219201
AlertDialog.BUTTON_POSITIVE,
220202
context.getString(R.string.singin_yes_button),
221203
(dialogInterface, i) -> showDialogTask.setResult(null));
222204

223-
signInDialog.setButton(
205+
signInConfirmationDialog.setButton(
224206
AlertDialog.BUTTON_NEGATIVE,
225207
context.getString(R.string.singin_no_button),
226208
(dialogInterface, i) ->
227209
showDialogTask.setException(
228210
new FirebaseAppDistributionException(
229211
ErrorMessages.AUTHENTICATION_CANCELED, AUTHENTICATION_CANCELED)));
230212

231-
signInDialog.setOnCancelListener(
213+
signInConfirmationDialog.setOnCancelListener(
232214
dialogInterface ->
233215
showDialogTask.setException(
234216
new FirebaseAppDistributionException(
235217
ErrorMessages.AUTHENTICATION_CANCELED, AUTHENTICATION_CANCELED)));
236218

237-
signInDialog.show();
219+
signInConfirmationDialog.show();
238220
return showDialogTask.getTask();
239221
}
240222

@@ -344,7 +326,7 @@ void onActivityDestroyed(@NonNull Activity activity) {
344326
// SignInResult is internal to the SDK and is destroyed after creation
345327
return;
346328
}
347-
if (signInDialog != null && signInDialog.isShowing()) {
329+
if (signInConfirmationDialog != null && signInConfirmationDialog.isShowing()) {
348330
setCachedUpdateIfNewReleaseCompletionError(
349331
new FirebaseAppDistributionException(
350332
ErrorMessages.AUTHENTICATION_CANCELED, AUTHENTICATION_CANCELED));
@@ -371,19 +353,13 @@ AppDistributionReleaseInternal getCachedNewRelease() {
371353
}
372354
}
373355

374-
private Task<Void> showUpdateAlertDialog(AppDistributionRelease newRelease) {
356+
private Task<Void> showUpdateAlertDialog(
357+
Activity hostActivity, AppDistributionRelease newRelease) {
375358
TaskCompletionSource<Void> showUpdateDialogTask = new TaskCompletionSource<>();
376359

377-
Activity currentActivity;
378-
try {
379-
currentActivity = lifecycleNotifier.getNonNullCurrentActivity();
380-
} catch (FirebaseAppDistributionException e) {
381-
return Tasks.forException(e);
382-
}
383-
384360
Context context = firebaseApp.getApplicationContext();
385361

386-
updateDialog = new AlertDialog.Builder(currentActivity).create();
362+
updateDialog = new AlertDialog.Builder(hostActivity).create();
387363
updateDialog.setTitle(context.getString(R.string.update_dialog_title));
388364

389365
StringBuilder message =
@@ -444,8 +420,8 @@ private void setCachedUpdateIfNewReleaseResult() {
444420
}
445421

446422
private void dismissDialogs() {
447-
if (signInDialog != null && signInDialog.isShowing()) {
448-
signInDialog.dismiss();
423+
if (signInConfirmationDialog != null && signInConfirmationDialog.isShowing()) {
424+
signInConfirmationDialog.dismiss();
449425
}
450426
if (updateDialog != null && updateDialog.isShowing()) {
451427
updateDialog.dismiss();

firebase-appdistribution/src/main/java/com/google/firebase/appdistribution/FirebaseAppDistributionException.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,6 @@ public enum Status {
4242
/** Installation canceled */
4343
INSTALLATION_CANCELED,
4444

45-
/** No foreground activity available for a given intent */
46-
// TODO(rachelprince): add this to API council review
47-
FOREGROUND_ACTIVITY_NOT_AVAILABLE,
48-
4945
/** Update not available for the current tester and app */
5046
UPDATE_NOT_AVAILABLE,
5147

0 commit comments

Comments
 (0)