Skip to content

Commit fea8375

Browse files
author
rachaprince
authored
Fad only show UI for basic config (#3260)
* Move SignInDialog to FirebaseAppDistribution * Move updatedialog to DialogUtils * Refactor dialogs and basic config * Use onSuccessTask * Update dialog handling and null activities * Add todos to update other references to currrent activity * update api.txt * Respond to review comments * Add comment to explain signInTester call * Fix formatting
1 parent 6178b13 commit fea8375

File tree

8 files changed

+197
-204
lines changed

8 files changed

+197
-204
lines changed

firebase-app-distribution/api.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ package com.google.firebase.app.distribution {
3434
enum_constant public static final com.google.firebase.app.distribution.FirebaseAppDistributionException.Status AUTHENTICATION_CANCELED;
3535
enum_constant public static final com.google.firebase.app.distribution.FirebaseAppDistributionException.Status AUTHENTICATION_FAILURE;
3636
enum_constant public static final com.google.firebase.app.distribution.FirebaseAppDistributionException.Status DOWNLOAD_FAILURE;
37+
enum_constant public static final com.google.firebase.app.distribution.FirebaseAppDistributionException.Status FOREGROUND_ACTIVITY_NOT_AVAILABLE;
3738
enum_constant public static final com.google.firebase.app.distribution.FirebaseAppDistributionException.Status INSTALLATION_CANCELED;
3839
enum_constant public static final com.google.firebase.app.distribution.FirebaseAppDistributionException.Status INSTALLATION_FAILURE;
3940
enum_constant public static final com.google.firebase.app.distribution.FirebaseAppDistributionException.Status INSTALLATION_FAILURE_SIGNATURE_MISMATCH;

firebase-app-distribution/src/main/java/com/google/firebase/app/distribution/AabUpdater.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ private static boolean isRedirectResponse(int responseCode) {
135135

136136
private void redirectToPlayForAabUpdate(String downloadUrl) {
137137
synchronized (updateAabLock) {
138+
// TODO(rachelprince): change this to getCurrentNonNullActivity
138139
if (lifecycleNotifier.getCurrentActivity() == null) {
139140
safeSetTaskException(
140141
cachedUpdateTask,

firebase-app-distribution/src/main/java/com/google/firebase/app/distribution/FirebaseAppDistribution.java

Lines changed: 108 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
package com.google.firebase.app.distribution;
1616

17+
import static com.google.firebase.app.distribution.FirebaseAppDistributionException.Status.AUTHENTICATION_CANCELED;
1718
import static com.google.firebase.app.distribution.FirebaseAppDistributionException.Status.AUTHENTICATION_FAILURE;
1819
import static com.google.firebase.app.distribution.FirebaseAppDistributionException.Status.UPDATE_NOT_AVAILABLE;
1920
import static com.google.firebase.app.distribution.TaskUtils.safeSetTaskException;
@@ -27,6 +28,7 @@
2728
import androidx.annotation.Nullable;
2829
import androidx.annotation.VisibleForTesting;
2930
import com.google.android.gms.tasks.Task;
31+
import com.google.android.gms.tasks.TaskCompletionSource;
3032
import com.google.android.gms.tasks.Tasks;
3133
import com.google.firebase.FirebaseApp;
3234
import com.google.firebase.app.distribution.Constants.ErrorMessages;
@@ -38,6 +40,7 @@
3840
import com.google.firebase.installations.FirebaseInstallationsApi;
3941

4042
public class FirebaseAppDistribution {
43+
4144
private static final int UNKNOWN_RELEASE_FILE_SIZE = -1;
4245

4346
private final FirebaseApp firebaseApp;
@@ -60,7 +63,7 @@ public class FirebaseAppDistribution {
6063

6164
private Task<AppDistributionRelease> cachedCheckForNewReleaseTask;
6265
private AlertDialog updateDialog;
63-
private boolean updateDialogShown;
66+
private AlertDialog signInDialog;
6467

6568
/** Constructor for FirebaseAppDistribution */
6669
@VisibleForTesting
@@ -132,12 +135,30 @@ public UpdateTask updateIfNewReleaseAvailable() {
132135
if (cachedUpdateIfNewReleaseTask != null && !cachedUpdateIfNewReleaseTask.isComplete()) {
133136
return cachedUpdateIfNewReleaseTask;
134137
}
135-
136138
cachedUpdateIfNewReleaseTask = new UpdateTaskImpl();
137139
}
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+
141162
if (release == null) {
142163
postProgressToCachedUpdateIfNewReleaseTask(
143164
UpdateProgress.builder()
@@ -150,26 +171,59 @@ public UpdateTask updateIfNewReleaseAvailable() {
150171
}
151172
return showUpdateAlertDialog(release);
152173
})
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);
167179

168180
synchronized (updateIfNewReleaseTaskLock) {
169181
return cachedUpdateIfNewReleaseTask;
170182
}
171183
}
172184

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+
173227
/** Signs in the App Distribution tester. Presents the tester with a Google sign in UI */
174228
@NonNull
175229
public Task<Void> signInTester() {
@@ -276,7 +330,7 @@ void onActivityDestroyed(@NonNull Activity activity) {
276330
// SignInResult is internal to the SDK and is destroyed after creation
277331
return;
278332
}
279-
if (updateDialogShown) {
333+
if (updateDialog != null && updateDialog.isShowing()) {
280334
setCachedUpdateIfNewReleaseCompletionError(
281335
new FirebaseAppDistributionException(
282336
ErrorMessages.UPDATE_CANCELED, Status.INSTALLATION_CANCELED));
@@ -297,18 +351,18 @@ AppDistributionReleaseInternal getCachedNewRelease() {
297351
}
298352
}
299353

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);
311362
}
363+
364+
Context context = firebaseApp.getApplicationContext();
365+
312366
updateDialog = new AlertDialog.Builder(currentActivity).create();
313367
updateDialog.setTitle(context.getString(R.string.update_dialog_title));
314368

@@ -321,89 +375,64 @@ private UpdateTaskImpl showUpdateAlertDialog(AppDistributionRelease newRelease)
321375
if (newRelease.getReleaseNotes() != null && !newRelease.getReleaseNotes().isEmpty()) {
322376
message.append(String.format("\n\nRelease notes: %s", newRelease.getReleaseNotes()));
323377
}
324-
325378
updateDialog.setMessage(message);
379+
326380
updateDialog.setButton(
327381
AlertDialog.BUTTON_POSITIVE,
328382
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));
338384

339385
updateDialog.setButton(
340386
AlertDialog.BUTTON_NEGATIVE,
341387
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)));
343392

344393
updateDialog.setOnCancelListener(
345-
dialogInterface -> {
346-
dismissUpdateDialogCallback();
347-
});
394+
dialogInterface ->
395+
showUpdateDialogTask.setException(
396+
new FirebaseAppDistributionException(
397+
ErrorMessages.UPDATE_CANCELED, Status.INSTALLATION_CANCELED)));
348398

349399
updateDialog.show();
350-
updateDialogShown = true;
351-
synchronized (updateIfNewReleaseTaskLock) {
352-
return cachedUpdateIfNewReleaseTask;
353-
}
354-
}
355400

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();
368402
}
369403

370-
private void setCachedUpdateIfNewReleaseCompletionError(FirebaseAppDistributionException e) {
404+
private void setCachedUpdateIfNewReleaseCompletionError(Exception e) {
371405
synchronized (updateIfNewReleaseTaskLock) {
372406
safeSetTaskException(cachedUpdateIfNewReleaseTask, e);
373407
}
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();
384409
}
385410

386411
private void postProgressToCachedUpdateIfNewReleaseTask(UpdateProgress progress) {
387412
synchronized (updateIfNewReleaseTaskLock) {
388-
cachedUpdateIfNewReleaseTask.updateProgress(progress);
413+
if (cachedUpdateIfNewReleaseTask != null && !cachedUpdateIfNewReleaseTask.isComplete()) {
414+
cachedUpdateIfNewReleaseTask.updateProgress(progress);
415+
}
389416
}
390417
}
391418

392419
private void setCachedUpdateIfNewReleaseResult() {
393420
synchronized (updateIfNewReleaseTaskLock) {
394421
safeSetTaskResult(cachedUpdateIfNewReleaseTask);
395422
}
396-
dismissUpdateDialog();
423+
dismissDialogs();
397424
}
398425

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()) {
401431
updateDialog.dismiss();
402-
updateDialogShown = false;
403432
}
404433
}
405434

406-
private UpdateTask getErrorUpdateTask(Exception e) {
435+
private UpdateTaskImpl getErrorUpdateTask(Exception e) {
407436
UpdateTaskImpl updateTask = new UpdateTaskImpl();
408437
updateTask.setException(e);
409438
return updateTask;

firebase-app-distribution/src/main/java/com/google/firebase/app/distribution/FirebaseAppDistributionException.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ 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+
4549
/** Update not available for the current tester and app */
4650
UPDATE_NOT_AVAILABLE,
4751

firebase-app-distribution/src/main/java/com/google/firebase/app/distribution/FirebaseAppDistributionLifecycleNotifier.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import androidx.annotation.GuardedBy;
2121
import androidx.annotation.NonNull;
2222
import androidx.annotation.Nullable;
23+
import com.google.firebase.app.distribution.Constants.ErrorMessages;
24+
import com.google.firebase.app.distribution.FirebaseAppDistributionException.Status;
2325
import java.util.ArrayDeque;
2426
import java.util.Queue;
2527

@@ -78,6 +80,16 @@ Activity getCurrentActivity() {
7880
}
7981
}
8082

83+
Activity getNonNullCurrentActivity() throws FirebaseAppDistributionException {
84+
synchronized (lock) {
85+
if (currentActivity == null) {
86+
throw new FirebaseAppDistributionException(
87+
ErrorMessages.APP_BACKGROUNDED, Status.FOREGROUND_ACTIVITY_NOT_AVAILABLE);
88+
}
89+
return currentActivity;
90+
}
91+
}
92+
8193
void addOnActivityCreatedListener(@NonNull OnActivityCreatedListener listener) {
8294
synchronized (lock) {
8395
this.onActivityCreatedListeners.add(listener);

0 commit comments

Comments
 (0)