From 9a0e8aaa14da08d081918fb247f8fca8dc6a3f84 Mon Sep 17 00:00:00 2001 From: Andre Bandarra Date: Mon, 7 Jun 2021 11:09:01 +0100 Subject: [PATCH 1/5] Fixes asynch launchTwa freezing splash screens - Moved code that builds the splash screen strategy to run on `onCreate()`, so they will already be available when `onEnterAnimationComplete()` is invoked. - When `finish()` is called early, on `onCreate()`, to bring an existing Activity to front, `launchTwa()` shouldn't be invoked. - We update the Firebase demo to reflect that and add a guard in `launcTwa()`. --- .../trusted/LauncherActivity.java | 28 ++++++++++++------- .../FirebaseAnalyticsLauncherActivity.java | 12 +++++--- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/androidbrowserhelper/src/main/java/com/google/androidbrowserhelper/trusted/LauncherActivity.java b/androidbrowserhelper/src/main/java/com/google/androidbrowserhelper/trusted/LauncherActivity.java index e50a9b22..3536ba64 100644 --- a/androidbrowserhelper/src/main/java/com/google/androidbrowserhelper/trusted/LauncherActivity.java +++ b/androidbrowserhelper/src/main/java/com/google/androidbrowserhelper/trusted/LauncherActivity.java @@ -155,6 +155,18 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { return; } + mMetadata = LauncherActivityMetadata.parse(this); + + if (splashScreenNeeded()) { + mSplashScreenStrategy = new PwaWrapperSplashScreenStrategy(this, + mMetadata.splashImageDrawableId, + getColorCompat(mMetadata.splashScreenBackgroundColorId), + getSplashImageScaleType(), + getSplashImageTransformationMatrix(), + mMetadata.splashScreenFadeOutDurationMillis, + mMetadata.fileProviderAuthority); + } + if (shouldLaunchImmediately()) { launchTwa(); } @@ -175,16 +187,12 @@ protected boolean shouldLaunchImmediately() { * {@link #shouldLaunchImmediately()} returns {@code false}. */ protected void launchTwa() { - mMetadata = LauncherActivityMetadata.parse(this); - - if (splashScreenNeeded()) { - mSplashScreenStrategy = new PwaWrapperSplashScreenStrategy(this, - mMetadata.splashImageDrawableId, - getColorCompat(mMetadata.splashScreenBackgroundColorId), - getSplashImageScaleType(), - getSplashImageTransformationMatrix(), - mMetadata.splashScreenFadeOutDurationMillis, - mMetadata.fileProviderAuthority); + // When launching asynchronously, developers should check if the Activity is finishing + // before calling launchTwa(). We double check the condition here and prevent the launch + // if that's the case. + if (isFinishing()) { + Log.d(TAG, "Aborting launchTwa() as Activity is finishing"); + return; } CustomTabColorSchemeParams darkModeColorScheme = new CustomTabColorSchemeParams.Builder() diff --git a/demos/twa-firebase-analytics/src/main/java/com/google/androidbrowserhelper/demos/twa_firebase_analytics/FirebaseAnalyticsLauncherActivity.java b/demos/twa-firebase-analytics/src/main/java/com/google/androidbrowserhelper/demos/twa_firebase_analytics/FirebaseAnalyticsLauncherActivity.java index c2aa68d6..24643392 100644 --- a/demos/twa-firebase-analytics/src/main/java/com/google/androidbrowserhelper/demos/twa_firebase_analytics/FirebaseAnalyticsLauncherActivity.java +++ b/demos/twa-firebase-analytics/src/main/java/com/google/androidbrowserhelper/demos/twa_firebase_analytics/FirebaseAnalyticsLauncherActivity.java @@ -36,15 +36,19 @@ public class FirebaseAnalyticsLauncherActivity extends LauncherActivity { protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - FirebaseAnalytics firebaseAnalytics = FirebaseAnalytics.getInstance(this); + // The Activity was finished before the launch because an existing instance of + // the app was brought to front. We don't want to call launchTwa() in this case. + if (!isFinishing()) { + FirebaseAnalytics firebaseAnalytics = FirebaseAnalytics.getInstance(this); - // Start the asynchronous task to get the Firebase application instance id. - firebaseAnalytics.getAppInstanceId().addOnCompleteListener(task -> { + // Start the asynchronous task to get the Firebase application instance id. + firebaseAnalytics.getAppInstanceId().addOnCompleteListener(task -> { // Once the task is complete, save the instance id so it can be used by // getLaunchingUrl(). mAppInstanceId = task.getResult(); launchTwa(); - }); + }); + } } @Override From ea81d75bb006d861f323c44cf6771bbac7db2d60 Mon Sep 17 00:00:00 2001 From: Andre Bandarra Date: Mon, 7 Jun 2021 11:13:58 +0100 Subject: [PATCH 2/5] Code style improvement - Uses an early return in the Firebase demo --- .../FirebaseAnalyticsLauncherActivity.java | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/demos/twa-firebase-analytics/src/main/java/com/google/androidbrowserhelper/demos/twa_firebase_analytics/FirebaseAnalyticsLauncherActivity.java b/demos/twa-firebase-analytics/src/main/java/com/google/androidbrowserhelper/demos/twa_firebase_analytics/FirebaseAnalyticsLauncherActivity.java index 24643392..99489aec 100644 --- a/demos/twa-firebase-analytics/src/main/java/com/google/androidbrowserhelper/demos/twa_firebase_analytics/FirebaseAnalyticsLauncherActivity.java +++ b/demos/twa-firebase-analytics/src/main/java/com/google/androidbrowserhelper/demos/twa_firebase_analytics/FirebaseAnalyticsLauncherActivity.java @@ -38,17 +38,19 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { // The Activity was finished before the launch because an existing instance of // the app was brought to front. We don't want to call launchTwa() in this case. - if (!isFinishing()) { - FirebaseAnalytics firebaseAnalytics = FirebaseAnalytics.getInstance(this); - - // Start the asynchronous task to get the Firebase application instance id. - firebaseAnalytics.getAppInstanceId().addOnCompleteListener(task -> { - // Once the task is complete, save the instance id so it can be used by - // getLaunchingUrl(). - mAppInstanceId = task.getResult(); - launchTwa(); - }); + if (isFinishing()) { + return; } + + FirebaseAnalytics firebaseAnalytics = FirebaseAnalytics.getInstance(this); + + // Start the asynchronous task to get the Firebase application instance id. + firebaseAnalytics.getAppInstanceId().addOnCompleteListener(task -> { + // Once the task is complete, save the instance id so it can be used by + // getLaunchingUrl(). + mAppInstanceId = task.getResult(); + launchTwa(); + }); } @Override From 052c26052022f1464ef9e004660d4f5c9e77f1d6 Mon Sep 17 00:00:00 2001 From: Andre Bandarra Date: Mon, 7 Jun 2021 11:15:19 +0100 Subject: [PATCH 3/5] Restores identation --- .../FirebaseAnalyticsLauncherActivity.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/demos/twa-firebase-analytics/src/main/java/com/google/androidbrowserhelper/demos/twa_firebase_analytics/FirebaseAnalyticsLauncherActivity.java b/demos/twa-firebase-analytics/src/main/java/com/google/androidbrowserhelper/demos/twa_firebase_analytics/FirebaseAnalyticsLauncherActivity.java index 99489aec..016ceb13 100644 --- a/demos/twa-firebase-analytics/src/main/java/com/google/androidbrowserhelper/demos/twa_firebase_analytics/FirebaseAnalyticsLauncherActivity.java +++ b/demos/twa-firebase-analytics/src/main/java/com/google/androidbrowserhelper/demos/twa_firebase_analytics/FirebaseAnalyticsLauncherActivity.java @@ -46,10 +46,10 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { // Start the asynchronous task to get the Firebase application instance id. firebaseAnalytics.getAppInstanceId().addOnCompleteListener(task -> { - // Once the task is complete, save the instance id so it can be used by - // getLaunchingUrl(). - mAppInstanceId = task.getResult(); - launchTwa(); + // Once the task is complete, save the instance id so it can be used by + // getLaunchingUrl(). + mAppInstanceId = task.getResult(); + launchTwa(); }); } From 762b94b98c1b83c622c434f0c06bb77a64a139a7 Mon Sep 17 00:00:00 2001 From: Andre Bandarra Date: Mon, 7 Jun 2021 11:37:21 +0100 Subject: [PATCH 4/5] Adds guard to the offline demo --- .../twa_offline_first/OfflineFirstTWALauncherActivity.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/demos/twa-offline-first/src/main/java/com/google/androidbrowserhelper/demos/twa_offline_first/OfflineFirstTWALauncherActivity.java b/demos/twa-offline-first/src/main/java/com/google/androidbrowserhelper/demos/twa_offline_first/OfflineFirstTWALauncherActivity.java index 91066d78..c3c3caab 100644 --- a/demos/twa-offline-first/src/main/java/com/google/androidbrowserhelper/demos/twa_offline_first/OfflineFirstTWALauncherActivity.java +++ b/demos/twa-offline-first/src/main/java/com/google/androidbrowserhelper/demos/twa_offline_first/OfflineFirstTWALauncherActivity.java @@ -30,6 +30,12 @@ public class OfflineFirstTWALauncherActivity extends LauncherActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + + // The Activity was finished before the launch because an existing instance of + // the app was brought to front. We don't want to call launchTwa() in this case. + if (isFinishing()) { + return; + } tryLaunchTwa(); } From ec21f9590180679da94ef69fd8520d1b61977a50 Mon Sep 17 00:00:00 2001 From: Andre Bandarra Date: Mon, 7 Jun 2021 13:24:35 +0100 Subject: [PATCH 5/5] Address review feedback --- .../FirebaseAnalyticsLauncherActivity.java | 3 +-- .../twa_offline_first/OfflineFirstTWALauncherActivity.java | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/demos/twa-firebase-analytics/src/main/java/com/google/androidbrowserhelper/demos/twa_firebase_analytics/FirebaseAnalyticsLauncherActivity.java b/demos/twa-firebase-analytics/src/main/java/com/google/androidbrowserhelper/demos/twa_firebase_analytics/FirebaseAnalyticsLauncherActivity.java index 016ceb13..6967939a 100644 --- a/demos/twa-firebase-analytics/src/main/java/com/google/androidbrowserhelper/demos/twa_firebase_analytics/FirebaseAnalyticsLauncherActivity.java +++ b/demos/twa-firebase-analytics/src/main/java/com/google/androidbrowserhelper/demos/twa_firebase_analytics/FirebaseAnalyticsLauncherActivity.java @@ -36,8 +36,7 @@ public class FirebaseAnalyticsLauncherActivity extends LauncherActivity { protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - // The Activity was finished before the launch because an existing instance of - // the app was brought to front. We don't want to call launchTwa() in this case. + // `super.onCreate()` may have called `finish()`. In this case, we don't do any work. if (isFinishing()) { return; } diff --git a/demos/twa-offline-first/src/main/java/com/google/androidbrowserhelper/demos/twa_offline_first/OfflineFirstTWALauncherActivity.java b/demos/twa-offline-first/src/main/java/com/google/androidbrowserhelper/demos/twa_offline_first/OfflineFirstTWALauncherActivity.java index c3c3caab..50ffd0e8 100644 --- a/demos/twa-offline-first/src/main/java/com/google/androidbrowserhelper/demos/twa_offline_first/OfflineFirstTWALauncherActivity.java +++ b/demos/twa-offline-first/src/main/java/com/google/androidbrowserhelper/demos/twa_offline_first/OfflineFirstTWALauncherActivity.java @@ -31,8 +31,7 @@ public class OfflineFirstTWALauncherActivity extends LauncherActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - // The Activity was finished before the launch because an existing instance of - // the app was brought to front. We don't want to call launchTwa() in this case. + // `super.onCreate()` may have called `finish()`. In this case, we don't do any work. if (isFinishing()) { return; }