Skip to content

Commit ff2dff1

Browse files
author
Rachel Prince
committed
Merge remote-tracking branch 'origin/master' into fad-reference-docs
2 parents 35be4e8 + e8659b5 commit ff2dff1

File tree

23 files changed

+254
-174
lines changed

23 files changed

+254
-174
lines changed

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

Lines changed: 75 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -215,36 +215,42 @@ private Task<Void> showSignInConfirmationDialog(Activity hostActivity) {
215215
showSignInDialogTask = new TaskCompletionSource<>();
216216
}
217217

218-
signInConfirmationDialog = new AlertDialog.Builder(hostActivity).create();
219218
dialogHostActivity = hostActivity;
220219

221-
Context context = firebaseApp.getApplicationContext();
222-
signInConfirmationDialog.setTitle(context.getString(R.string.signin_dialog_title));
223-
signInConfirmationDialog.setMessage(context.getString(R.string.singin_dialog_message));
224-
225-
signInConfirmationDialog.setButton(
226-
AlertDialog.BUTTON_POSITIVE,
227-
context.getString(R.string.singin_yes_button),
228-
(dialogInterface, i) -> showSignInDialogTask.setResult(null));
229-
230-
signInConfirmationDialog.setButton(
231-
AlertDialog.BUTTON_NEGATIVE,
232-
context.getString(R.string.singin_no_button),
233-
(dialogInterface, i) ->
234-
showSignInDialogTask.setException(
235-
new FirebaseAppDistributionException(
236-
FirebaseAppDistributionException.ErrorMessages.AUTHENTICATION_CANCELED,
237-
AUTHENTICATION_CANCELED)));
238-
239-
signInConfirmationDialog.setOnCancelListener(
240-
dialogInterface ->
241-
showSignInDialogTask.setException(
242-
new FirebaseAppDistributionException(
243-
FirebaseAppDistributionException.ErrorMessages.AUTHENTICATION_CANCELED,
244-
AUTHENTICATION_CANCELED)));
245-
246-
signInConfirmationDialog.show();
247-
220+
// We may not be on the main (UI) thread in some cases, specifically if the developer calls
221+
// the basic config from the background. If we are already on the main thread, this will
222+
// execute immediately.
223+
hostActivity.runOnUiThread(
224+
() -> {
225+
signInConfirmationDialog = new AlertDialog.Builder(hostActivity).create();
226+
227+
Context context = firebaseApp.getApplicationContext();
228+
signInConfirmationDialog.setTitle(context.getString(R.string.signin_dialog_title));
229+
signInConfirmationDialog.setMessage(context.getString(R.string.singin_dialog_message));
230+
231+
signInConfirmationDialog.setButton(
232+
AlertDialog.BUTTON_POSITIVE,
233+
context.getString(R.string.singin_yes_button),
234+
(dialogInterface, i) -> showSignInDialogTask.setResult(null));
235+
236+
signInConfirmationDialog.setButton(
237+
AlertDialog.BUTTON_NEGATIVE,
238+
context.getString(R.string.singin_no_button),
239+
(dialogInterface, i) ->
240+
showSignInDialogTask.setException(
241+
new FirebaseAppDistributionException(
242+
FirebaseAppDistributionException.ErrorMessages.AUTHENTICATION_CANCELED,
243+
AUTHENTICATION_CANCELED)));
244+
245+
signInConfirmationDialog.setOnCancelListener(
246+
dialogInterface ->
247+
showSignInDialogTask.setException(
248+
new FirebaseAppDistributionException(
249+
FirebaseAppDistributionException.ErrorMessages.AUTHENTICATION_CANCELED,
250+
AUTHENTICATION_CANCELED)));
251+
252+
signInConfirmationDialog.show();
253+
});
248254
return showSignInDialogTask.getTask();
249255
}
250256

@@ -425,44 +431,49 @@ private Task<Void> showUpdateConfirmationDialog(
425431
}
426432

427433
Context context = firebaseApp.getApplicationContext();
428-
429-
updateConfirmationDialog = new AlertDialog.Builder(hostActivity).create();
430434
dialogHostActivity = hostActivity;
431-
updateConfirmationDialog.setTitle(context.getString(R.string.update_dialog_title));
432435

433-
StringBuilder message =
434-
new StringBuilder(
435-
String.format(
436-
"Version %s (%s) is available.",
437-
newRelease.getDisplayVersion(), newRelease.getVersionCode()));
438-
439-
if (newRelease.getReleaseNotes() != null && !newRelease.getReleaseNotes().isEmpty()) {
440-
message.append(String.format("\n\nRelease notes: %s", newRelease.getReleaseNotes()));
441-
}
442-
updateConfirmationDialog.setMessage(message);
443-
444-
updateConfirmationDialog.setButton(
445-
AlertDialog.BUTTON_POSITIVE,
446-
context.getString(R.string.update_yes_button),
447-
(dialogInterface, i) -> showUpdateDialogTask.setResult(null));
448-
449-
updateConfirmationDialog.setButton(
450-
AlertDialog.BUTTON_NEGATIVE,
451-
context.getString(R.string.update_no_button),
452-
(dialogInterface, i) ->
453-
showUpdateDialogTask.setException(
454-
new FirebaseAppDistributionException(
455-
FirebaseAppDistributionException.ErrorMessages.UPDATE_CANCELED,
456-
Status.INSTALLATION_CANCELED)));
457-
458-
updateConfirmationDialog.setOnCancelListener(
459-
dialogInterface ->
460-
showUpdateDialogTask.setException(
461-
new FirebaseAppDistributionException(
462-
FirebaseAppDistributionException.ErrorMessages.UPDATE_CANCELED,
463-
Status.INSTALLATION_CANCELED)));
464-
465-
updateConfirmationDialog.show();
436+
// We should already be on the main (UI) thread here, but be explicit just to be safe. If we are
437+
// already on the main thread, this will execute immediately.
438+
hostActivity.runOnUiThread(
439+
() -> {
440+
updateConfirmationDialog = new AlertDialog.Builder(hostActivity).create();
441+
updateConfirmationDialog.setTitle(context.getString(R.string.update_dialog_title));
442+
443+
StringBuilder message =
444+
new StringBuilder(
445+
String.format(
446+
"Version %s (%s) is available.",
447+
newRelease.getDisplayVersion(), newRelease.getVersionCode()));
448+
449+
if (newRelease.getReleaseNotes() != null && !newRelease.getReleaseNotes().isEmpty()) {
450+
message.append(String.format("\n\nRelease notes: %s", newRelease.getReleaseNotes()));
451+
}
452+
updateConfirmationDialog.setMessage(message);
453+
454+
updateConfirmationDialog.setButton(
455+
AlertDialog.BUTTON_POSITIVE,
456+
context.getString(R.string.update_yes_button),
457+
(dialogInterface, i) -> showUpdateDialogTask.setResult(null));
458+
459+
updateConfirmationDialog.setButton(
460+
AlertDialog.BUTTON_NEGATIVE,
461+
context.getString(R.string.update_no_button),
462+
(dialogInterface, i) ->
463+
showUpdateDialogTask.setException(
464+
new FirebaseAppDistributionException(
465+
FirebaseAppDistributionException.ErrorMessages.UPDATE_CANCELED,
466+
Status.INSTALLATION_CANCELED)));
467+
468+
updateConfirmationDialog.setOnCancelListener(
469+
dialogInterface ->
470+
showUpdateDialogTask.setException(
471+
new FirebaseAppDistributionException(
472+
FirebaseAppDistributionException.ErrorMessages.UPDATE_CANCELED,
473+
Status.INSTALLATION_CANCELED)));
474+
475+
updateConfirmationDialog.show();
476+
});
466477

467478
return showUpdateDialogTask.getTask();
468479
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ interface OnActivityDestroyedListener {
9898
/**
9999
* Apply a function to a foreground activity, when one is available, returning a {@link Task} that
100100
* will complete immediately after the function is applied.
101+
*
102+
* <p>The consumer function will be called immediately once the activity is available. This may be
103+
* on the main thread or the calling thread, depending on whether or not there is already a
104+
* foreground activity available when this method is called.
101105
*/
102106
Task<Void> applyToForegroundActivity(ActivityConsumer consumer) {
103107
return getForegroundActivity()
@@ -117,6 +121,10 @@ Task<Void> applyToForegroundActivity(ActivityConsumer consumer) {
117121
/**
118122
* Apply a function to a foreground activity, when one is available, returning a {@link Task} that
119123
* will complete with the result of the Task returned by that function.
124+
*
125+
* <p>The continuation function will be called immediately once the activity is available. This
126+
* may be on the main thread or the calling thread, depending on whether or not there is already a
127+
* foreground activity available when this method is called.
120128
*/
121129
<T> Task<T> applyToForegroundActivityTask(SuccessContinuation<Activity, T> continuation) {
122130
return getForegroundActivity()

firebase-appdistribution/src/test/java/com/google/firebase/appdistribution/FirebaseAppDistributionTest.java

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@
6060
import com.google.firebase.installations.InstallationTokenResult;
6161
import java.util.ArrayList;
6262
import java.util.List;
63+
import java.util.concurrent.ExecutionException;
64+
import java.util.concurrent.ExecutorService;
65+
import java.util.concurrent.Executors;
66+
import java.util.concurrent.Future;
6367
import org.junit.Before;
6468
import org.junit.Test;
6569
import org.junit.runner.RunWith;
@@ -231,7 +235,7 @@ public void updateApp_whenNotSignedIn_throwsError() {
231235
}
232236

233237
@Test
234-
public void updateToNewRelease_whenNewAabReleaseAvailable_showsUpdateDialog() {
238+
public void updateIfNewReleaseAvailable_whenNewAabReleaseAvailable_showsUpdateDialog() {
235239
when(mockNewReleaseFetcher.checkForNewRelease())
236240
.thenReturn(Tasks.forResult((TEST_RELEASE_NEWER_AAB_INTERNAL.build())));
237241

@@ -248,7 +252,20 @@ public void updateToNewRelease_whenNewAabReleaseAvailable_showsUpdateDialog() {
248252
}
249253

250254
@Test
251-
public void updateToNewRelease_whenReleaseNotesEmpty_doesNotShowReleaseNotes() {
255+
public void updateIfNewReleaseAvailable_fromABackgroundThread_showsUpdateDialog()
256+
throws InterruptedException {
257+
when(mockNewReleaseFetcher.checkForNewRelease())
258+
.thenReturn(Tasks.forResult((TEST_RELEASE_NEWER_AAB_INTERNAL.build())));
259+
260+
ExecutorService executorService = Executors.newSingleThreadExecutor();
261+
executorService.submit(() -> firebaseAppDistribution.updateIfNewReleaseAvailable());
262+
TestUtils.awaitAsyncOperations(executorService);
263+
264+
assertAlertDialogShown();
265+
}
266+
267+
@Test
268+
public void updateIfNewReleaseAvailable_whenReleaseNotesEmpty_doesNotShowReleaseNotes() {
252269
when(mockNewReleaseFetcher.checkForNewRelease())
253270
.thenReturn(Tasks.forResult((TEST_RELEASE_NEWER_AAB_INTERNAL.setReleaseNotes("").build())));
254271

@@ -263,7 +280,7 @@ public void updateToNewRelease_whenReleaseNotesEmpty_doesNotShowReleaseNotes() {
263280
}
264281

265282
@Test
266-
public void updateToNewRelease_whenNoReleaseAvailable_updateDialogNotShown() {
283+
public void updateIfNewReleaseAvailable_whenNoReleaseAvailable_updateDialogNotShown() {
267284
when(mockNewReleaseFetcher.checkForNewRelease()).thenReturn(Tasks.forResult(null));
268285

269286
UpdateTask task = firebaseAppDistribution.updateIfNewReleaseAvailable();
@@ -277,7 +294,7 @@ public void updateToNewRelease_whenNoReleaseAvailable_updateDialogNotShown() {
277294
}
278295

279296
@Test
280-
public void updateToNewRelease_whenActivityBackgrounded_updateDialogNotShown() {
297+
public void updateIfNewReleaseAvailable_whenActivityBackgrounded_updateDialogNotShown() {
281298
when(mockNewReleaseFetcher.checkForNewRelease()).thenReturn(Tasks.forResult(null));
282299

283300
UpdateTask task = firebaseAppDistribution.updateIfNewReleaseAvailable();
@@ -291,7 +308,7 @@ public void updateToNewRelease_whenActivityBackgrounded_updateDialogNotShown() {
291308
}
292309

293310
@Test
294-
public void updateToNewRelease_whenSignInCancelled_checkForUpdateNotCalled() {
311+
public void updateIfNewReleaseAvailable_whenSignInCancelled_checkForUpdateNotCalled() {
295312
when(mockSignInStorage.getSignInStatus()).thenReturn(false);
296313
when(mockTesterSignInManager.signInTester())
297314
.thenReturn(
@@ -314,7 +331,7 @@ public void updateToNewRelease_whenSignInCancelled_checkForUpdateNotCalled() {
314331
}
315332

316333
@Test
317-
public void updateToNewRelease_whenSignInFailed_checkForUpdateNotCalled() {
334+
public void updateIfNewReleaseAvailable_whenSignInFailed_checkForUpdateNotCalled() {
318335
when(mockSignInStorage.getSignInStatus()).thenReturn(false);
319336
when(mockTesterSignInManager.signInTester())
320337
.thenReturn(
@@ -332,7 +349,7 @@ public void updateToNewRelease_whenSignInFailed_checkForUpdateNotCalled() {
332349
}
333350

334351
@Test
335-
public void updateToNewRelease_whenDialogDismissed_taskFails() {
352+
public void updateIfNewReleaseAvailable_whenDialogDismissed_taskFails() {
336353
when(mockNewReleaseFetcher.checkForNewRelease())
337354
.thenReturn(Tasks.forResult(TEST_RELEASE_NEWER_AAB_INTERNAL.build()));
338355

@@ -346,7 +363,7 @@ public void updateToNewRelease_whenDialogDismissed_taskFails() {
346363
}
347364

348365
@Test
349-
public void updateToNewRelease_whenDialogCanceled_taskFails() {
366+
public void updateIfNewReleaseAvailable_whenDialogCanceled_taskFails() {
350367
when(mockNewReleaseFetcher.checkForNewRelease())
351368
.thenReturn(Tasks.forResult(TEST_RELEASE_NEWER_AAB_INTERNAL.build()));
352369

@@ -361,7 +378,7 @@ public void updateToNewRelease_whenDialogCanceled_taskFails() {
361378
}
362379

363380
@Test
364-
public void updateToNewRelease_whenCheckForUpdateFails_updateAppNotCalled() {
381+
public void updateIfNewReleaseAvailable_whenCheckForUpdateFails_updateAppNotCalled() {
365382
when(mockNewReleaseFetcher.checkForNewRelease())
366383
.thenReturn(
367384
Tasks.forException(
@@ -381,7 +398,7 @@ public void updateToNewRelease_whenCheckForUpdateFails_updateAppNotCalled() {
381398
}
382399

383400
@Test
384-
public void updateToNewRelease_whenTesterIsSignedIn_doesNotOpenDialog() {
401+
public void updateIfNewReleaseAvailable_whenTesterIsSignedIn_doesNotOpenDialog() {
385402
when(mockSignInStorage.getSignInStatus()).thenReturn(true);
386403

387404
firebaseAppDistribution.updateIfNewReleaseAvailable();
@@ -406,7 +423,7 @@ public void signInTester_whenDialogDismissed_taskFails() {
406423
}
407424

408425
@Test
409-
public void updateToNewRelease_whenSignInDialogCanceled_taskFails() {
426+
public void updateIfNewReleaseAvailable_whenSignInDialogCanceled_taskFails() {
410427
when(mockSignInStorage.getSignInStatus()).thenReturn(false);
411428
Task signInTask = firebaseAppDistribution.updateIfNewReleaseAvailable();
412429

@@ -436,7 +453,7 @@ public void signOutTester_setsSignInStatusFalse() {
436453
}
437454

438455
@Test
439-
public void updateToNewRelease_receiveProgressUpdateFromUpdateApp() {
456+
public void updateIfNewReleaseAvailable_receiveProgressUpdateFromUpdateApp() {
440457
AppDistributionReleaseInternal newRelease = TEST_RELEASE_NEWER_AAB_INTERNAL.build();
441458
when(mockNewReleaseFetcher.checkForNewRelease()).thenReturn(Tasks.forResult(newRelease));
442459
UpdateTaskImpl mockTask = new UpdateTaskImpl();
@@ -462,6 +479,20 @@ public void updateToNewRelease_receiveProgressUpdateFromUpdateApp() {
462479
assertEquals(UpdateStatus.DOWNLOADING, progressEvents.get(0).getUpdateStatus());
463480
}
464481

482+
@Test
483+
public void updateIfNewReleaseAvailable_fromABackgroundThread_showsSignInDialog()
484+
throws InterruptedException, ExecutionException {
485+
when(mockSignInStorage.getSignInStatus()).thenReturn(false);
486+
487+
ExecutorService executorService = Executors.newSingleThreadExecutor();
488+
Future<UpdateTask> future =
489+
executorService.submit(() -> firebaseAppDistribution.updateIfNewReleaseAvailable());
490+
TestUtils.awaitAsyncOperations(executorService);
491+
492+
assertAlertDialogShown();
493+
assertFalse(((UpdateTask) future.get()).isComplete());
494+
}
495+
465496
@Test
466497
public void updateIfNewReleaseAvailable_whenScreenRotates_signInConfirmationDialogReappears() {
467498
when(mockSignInStorage.getSignInStatus()).thenReturn(false);
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
version=18.2.5
2-
latestReleasedVersion=18.2.4
1+
version=18.2.9
2+
latestReleasedVersion=18.2.8
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
version=18.2.5
2-
latestReleasedVersion=18.2.4
1+
version=18.2.9
2+
latestReleasedVersion=18.2.8

firebase-database/gradle.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
version=20.0.3
16-
latestReleasedVersion=20.0.2
15+
version=20.0.4
16+
latestReleasedVersion=20.0.3
1717
android.enableUnitTestBinaryResources=true
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
version=18.1.1
2-
latestReleasedVersion=18.1.0
1+
version=18.1.2
2+
latestReleasedVersion=18.1.1
33
android.enableUnitTestBinaryResources=true
44

firebase-firestore/gradle.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
version=24.0.1
2-
latestReleasedVersion=24.0.0
1+
version=24.0.2
2+
latestReleasedVersion=24.0.1

firebase-firestore/src/main/java/com/google/firebase/firestore/core/FirestoreClient.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,8 @@ public FirestoreClient(
129129

130130
appCheckProvider.setChangeListener(
131131
(String appCheckToken) -> {
132-
// This will ensure that once a new App Check token is retrieved, streams are
133-
// re-established using the new token.
134-
asyncQueue.enqueueAndForget(
135-
() -> {
136-
Logger.debug(LOG_TAG, "App Check token changed.");
137-
remoteStore.handleCredentialChange();
138-
});
132+
// Register an empty credentials change listener to activate token
133+
// refresh.
139134
});
140135
}
141136

0 commit comments

Comments
 (0)