From 0ba1d266b36bad8b6ab8c36deb0a8e5e3ba782a9 Mon Sep 17 00:00:00 2001 From: Mugurell Date: Fri, 19 Jun 2020 21:33:16 +0300 Subject: [PATCH] For #9144 - Ignore previous Intent if activity is started from Recents We'll now clearly differentiate between cold / hot starts of HomeActivity.kt. This is needed because Android will resend the original Intent which initially started the Activity whenever it is restarted from the Recents Screen if the activity is already destroyed at that time. So in the event that the activity was before started with an Intent to open a webpage for example whenever the activity is restarted from Recents it will receive the same Intent to open a webpage even though that Intent has already been consumed. Activity's onCreate() will only use the intent processors when the activity is cold started so that we'll only initially act upon Intents configured for different behaviors inside the app. If the activity is destroyed while in background and opened from Recents it will not act upon the original Intent which is now resent by Android. Activity's onNewIntent() will be called to act upon a new Intent if the activity is hot started since we are declared as singleTask and it now has the responsibility to delegate various intent processors to consume that Intent. --- .../java/org/mozilla/fenix/HomeActivity.kt | 13 ++++++- .../org/mozilla/fenix/HomeActivityTest.kt | 37 +++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt index 7f9c5282e..36c2ac6da 100644 --- a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt @@ -154,7 +154,9 @@ open class HomeActivity : LocaleAwareAppCompatActivity() { sessionObserver = UriOpenedObserver(this) - externalSourceIntentProcessors.any { it.process(intent, navHost.navController, this.intent) } + if (isActivityColdStarted(intent, savedInstanceState)) { + externalSourceIntentProcessors.any { it.process(intent, navHost.navController, this.intent) } + } Performance.processIntentIfPerformanceTest(intent, this) @@ -476,6 +478,15 @@ open class HomeActivity : LocaleAwareAppCompatActivity() { this.visualCompletenessQueue = visualCompletenessQueue } + @VisibleForTesting + internal fun isActivityColdStarted(startingIntent: Intent, activityIcicle: Bundle?): Boolean = + // First time opening this activity in the task. + // Cold start / start from Recents after back press. + activityIcicle == null && + // Activity was restarted from Recents after it was destroyed by Android while in background + // in cases of memory pressure / "Don't keep activities". + startingIntent.flags and Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY == 0 + companion object { const val OPEN_TO_BROWSER = "open_to_browser" const val OPEN_TO_BROWSER_AND_LOAD = "open_to_browser_and_load" diff --git a/app/src/test/java/org/mozilla/fenix/HomeActivityTest.kt b/app/src/test/java/org/mozilla/fenix/HomeActivityTest.kt index a919da928..1b45dc5df 100644 --- a/app/src/test/java/org/mozilla/fenix/HomeActivityTest.kt +++ b/app/src/test/java/org/mozilla/fenix/HomeActivityTest.kt @@ -5,11 +5,14 @@ package org.mozilla.fenix import android.content.Intent +import android.os.Bundle import mozilla.components.support.test.robolectric.testContext import mozilla.components.support.utils.toSafeIntent import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse import org.junit.Assert.assertNotEquals import org.junit.Assert.assertNull +import org.junit.Assert.assertTrue import org.junit.Test import org.junit.runner.RunWith import org.mozilla.fenix.HomeActivity.Companion.PRIVATE_BROWSING_MODE @@ -58,4 +61,38 @@ class HomeActivityTest { assertNotEquals(testContext.settings().lastKnownMode, activity.getModeFromIntentOrLastKnown(intent)) assertEquals(BrowsingMode.Private, activity.getModeFromIntentOrLastKnown(intent)) } + + @Test + fun `isActivityColdStarted returns true for null savedInstanceState and not launched from history`() { + val activity = HomeActivity() + + assertTrue(activity.isActivityColdStarted(Intent(), null)) + } + + @Test + fun `isActivityColdStarted returns false for valid savedInstanceState and not launched from history`() { + val activity = HomeActivity() + + assertFalse(activity.isActivityColdStarted(Intent(), Bundle())) + } + + @Test + fun `isActivityColdStarted returns false for null savedInstanceState and launched from history`() { + val activity = HomeActivity() + val startingIntent = Intent().apply { + flags = flags or Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY + } + + assertFalse(activity.isActivityColdStarted(startingIntent, null)) + } + + @Test + fun `isActivityColdStarted returns false for null savedInstanceState and not launched from history`() { + val activity = HomeActivity() + val startingIntent = Intent().apply { + flags = flags or Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY + } + + assertFalse(activity.isActivityColdStarted(startingIntent, Bundle())) + } }