For #12062 - Launch back to browser if we previoulsy had tabs
This commit is contained in:
parent
4597e0d8ff
commit
cbe293d3e4
|
@ -39,6 +39,7 @@ import kotlinx.coroutines.delay
|
|||
import kotlinx.coroutines.launch
|
||||
import mozilla.components.browser.search.SearchEngine
|
||||
import mozilla.components.browser.session.SessionManager
|
||||
import mozilla.components.browser.state.selector.getNormalOrPrivateTabs
|
||||
import mozilla.components.browser.state.state.SessionState
|
||||
import mozilla.components.browser.state.state.WebExtensionState
|
||||
import mozilla.components.concept.engine.EngineSession
|
||||
|
@ -126,7 +127,8 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
|
|||
|
||||
private var isVisuallyComplete = false
|
||||
|
||||
private var privateNotificationObserver: PrivateNotificationFeature<PrivateNotificationService>? = null
|
||||
private var privateNotificationObserver: PrivateNotificationFeature<PrivateNotificationService>? =
|
||||
null
|
||||
|
||||
private var isToolbarInflated = false
|
||||
|
||||
|
@ -192,14 +194,18 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
|
|||
it.start()
|
||||
}
|
||||
|
||||
if (isActivityColdStarted(intent, savedInstanceState)) {
|
||||
externalSourceIntentProcessors.any {
|
||||
if (isActivityColdStarted(
|
||||
intent,
|
||||
savedInstanceState
|
||||
) && !externalSourceIntentProcessors.any {
|
||||
it.process(
|
||||
intent,
|
||||
navHost.navController,
|
||||
this.intent
|
||||
)
|
||||
}
|
||||
) {
|
||||
navigateToBrowserOnColdStart()
|
||||
}
|
||||
|
||||
Performance.processIntentIfPerformanceTest(intent, this)
|
||||
|
@ -240,7 +246,10 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
|
|||
StartupTimeline.onActivityCreateEndHome(this) // DO NOT MOVE ANYTHING BELOW HERE.
|
||||
}
|
||||
|
||||
protected open fun startupTelemetryOnCreateCalled(safeIntent: SafeIntent, hasSavedInstanceState: Boolean) {
|
||||
protected open fun startupTelemetryOnCreateCalled(
|
||||
safeIntent: SafeIntent,
|
||||
hasSavedInstanceState: Boolean
|
||||
) {
|
||||
components.appStartupTelemetry.onHomeActivityOnCreate(
|
||||
safeIntent,
|
||||
hasSavedInstanceState,
|
||||
|
@ -322,6 +331,10 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
|
|||
}
|
||||
|
||||
final override fun onPause() {
|
||||
// We should return to the browser if there were normal tabs when we left the app
|
||||
settings().shouldReturnToBrowser =
|
||||
components.core.store.state.getNormalOrPrivateTabs(private = false).isNotEmpty()
|
||||
|
||||
if (settings().lastKnownMode.isPrivate) {
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
|
||||
}
|
||||
|
@ -763,6 +776,14 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
|
|||
}
|
||||
}
|
||||
|
||||
open fun navigateToBrowserOnColdStart() {
|
||||
// Normal tabs + cold start -> Should go back to browser if we had any tabs open when we left last
|
||||
// except for PBM + Cold Start there won't be any tabs since they're evicted so we never will navigate
|
||||
if (settings().shouldReturnToBrowser && !browsingModeManager.mode.isPrivate) {
|
||||
openToBrowser(BrowserDirection.FromGlobal, null)
|
||||
}
|
||||
}
|
||||
|
||||
override fun attachBaseContext(base: Context) {
|
||||
base.components.strictMode.resetAfter(StrictMode.allowThreadDiskReads()) {
|
||||
super.attachBaseContext(base)
|
||||
|
|
|
@ -32,6 +32,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
|
|||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.mapNotNull
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
@ -41,6 +42,7 @@ import mozilla.components.browser.session.SessionManager
|
|||
import mozilla.components.browser.state.action.ContentAction
|
||||
import mozilla.components.browser.state.selector.findTab
|
||||
import mozilla.components.browser.state.selector.findTabOrCustomTabOrSelectedTab
|
||||
import mozilla.components.browser.state.selector.getNormalOrPrivateTabs
|
||||
import mozilla.components.browser.state.state.SessionState
|
||||
import mozilla.components.browser.state.state.content.DownloadState
|
||||
import mozilla.components.browser.state.store.BrowserStore
|
||||
|
@ -189,6 +191,28 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
|
|||
val view = inflater.inflate(R.layout.fragment_browser, container, false)
|
||||
|
||||
val activity = activity as HomeActivity
|
||||
components = requireComponents
|
||||
|
||||
if (customTabSessionId == null) {
|
||||
// Once tab restoration is complete, if there are no tabs to show in the browser, go home
|
||||
components.core.store.flowScoped(viewLifecycleOwner) { flow ->
|
||||
flow.map { state -> state.restoreComplete }
|
||||
.ifChanged()
|
||||
.collect { restored ->
|
||||
if (restored) {
|
||||
val tabs =
|
||||
components.core.store.state.getNormalOrPrivateTabs(
|
||||
activity.browsingModeManager.mode.isPrivate
|
||||
)
|
||||
if (tabs.isEmpty()) findNavController().popBackStack(
|
||||
R.id.homeFragment,
|
||||
false
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
activity.themeManager.applyStatusBarTheme(activity)
|
||||
|
||||
browserFragmentStore = StoreProvider.get(this) {
|
||||
|
@ -197,8 +221,6 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
|
|||
)
|
||||
}
|
||||
|
||||
components = requireComponents
|
||||
|
||||
return view
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ import mozilla.components.browser.session.SessionManager
|
|||
import mozilla.components.browser.session.engine.EngineMiddleware
|
||||
import mozilla.components.browser.session.storage.SessionStorage
|
||||
import mozilla.components.browser.session.undo.UndoMiddleware
|
||||
import mozilla.components.browser.state.action.RestoreCompleteAction
|
||||
import mozilla.components.browser.state.action.RecentlyClosedAction
|
||||
import mozilla.components.browser.state.state.BrowserState
|
||||
import mozilla.components.browser.state.store.BrowserStore
|
||||
|
@ -231,6 +232,8 @@ class Core(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
store.dispatch(RestoreCompleteAction)
|
||||
}
|
||||
|
||||
WebNotificationFeature(
|
||||
|
|
|
@ -46,6 +46,10 @@ open class ExternalAppBrowserActivity : HomeActivity() {
|
|||
)
|
||||
}
|
||||
|
||||
override fun navigateToBrowserOnColdStart() {
|
||||
// No-op for external app
|
||||
}
|
||||
|
||||
override fun getNavDirections(
|
||||
from: BrowserDirection,
|
||||
customTabSessionId: String?
|
||||
|
|
|
@ -182,6 +182,11 @@ class Settings(private val appContext: Context) : PreferencesHolder {
|
|||
true
|
||||
)
|
||||
|
||||
var shouldReturnToBrowser by booleanPreference(
|
||||
appContext.getString(R.string.pref_key_return_to_browser),
|
||||
false
|
||||
)
|
||||
|
||||
// If any of the prefs have been modified, quit displaying the fenix moved tip
|
||||
fun shouldDisplayFenixMovingTip(): Boolean =
|
||||
preferences.getBoolean(
|
||||
|
|
|
@ -235,4 +235,6 @@
|
|||
<string name="pref_key_show_grid_view_tabs_settings" translatable="false">pref_key_show_grid_view_tabs_settings</string>
|
||||
|
||||
<string name="pref_key_camera_permissions_needed" translatable="false">pref_key_camera_permissions_needed</string>
|
||||
|
||||
<string name="pref_key_return_to_browser" translatable="false">pref_key_return_to_browser</string>
|
||||
</resources>
|
||||
|
|
|
@ -7,7 +7,9 @@ package org.mozilla.fenix
|
|||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import io.mockk.spyk
|
||||
import io.mockk.verify
|
||||
import mozilla.components.support.test.robolectric.testContext
|
||||
import mozilla.components.support.utils.toSafeIntent
|
||||
import org.junit.Assert.assertEquals
|
||||
|
@ -20,9 +22,12 @@ import org.junit.Test
|
|||
import org.junit.runner.RunWith
|
||||
import org.mozilla.fenix.HomeActivity.Companion.PRIVATE_BROWSING_MODE
|
||||
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
|
||||
import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
|
||||
import org.mozilla.fenix.components.metrics.Event
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.ext.settings
|
||||
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
|
||||
@RunWith(FenixRobolectricTestRunner::class)
|
||||
class HomeActivityTest {
|
||||
|
@ -32,8 +37,6 @@ class HomeActivityTest {
|
|||
@Before
|
||||
fun setup() {
|
||||
activity = spyk(HomeActivity())
|
||||
|
||||
every { activity.applicationContext } returns testContext
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -52,6 +55,7 @@ class HomeActivityTest {
|
|||
|
||||
@Test
|
||||
fun `getModeFromIntentOrLastKnown returns mode from settings when intent does not set`() {
|
||||
every { activity.applicationContext } returns testContext
|
||||
testContext.settings().lastKnownMode = BrowsingMode.Private
|
||||
|
||||
assertEquals(testContext.settings().lastKnownMode, activity.getModeFromIntentOrLastKnown(null))
|
||||
|
@ -87,6 +91,38 @@ class HomeActivityTest {
|
|||
assertFalse(activity.isActivityColdStarted(startingIntent, null))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `navigateToBrowserOnColdStart in normal mode navigates to browser`() {
|
||||
val browsingModeManager: BrowsingModeManager = mockk()
|
||||
every { browsingModeManager.mode } returns BrowsingMode.Normal
|
||||
|
||||
val settings: Settings = mockk()
|
||||
every { settings.shouldReturnToBrowser } returns true
|
||||
every { activity.components.settings.shouldReturnToBrowser } returns true
|
||||
every { activity.openToBrowser(any(), any()) } returns Unit
|
||||
|
||||
activity.browsingModeManager = browsingModeManager
|
||||
activity.navigateToBrowserOnColdStart()
|
||||
|
||||
verify(exactly = 1) { activity.openToBrowser(BrowserDirection.FromGlobal, null) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `navigateToBrowserOnColdStart in private mode does not navigate to browser`() {
|
||||
val browsingModeManager: BrowsingModeManager = mockk()
|
||||
every { browsingModeManager.mode } returns BrowsingMode.Private
|
||||
|
||||
val settings: Settings = mockk()
|
||||
every { settings.shouldReturnToBrowser } returns true
|
||||
every { activity.components.settings.shouldReturnToBrowser } returns true
|
||||
every { activity.openToBrowser(any(), any()) } returns Unit
|
||||
|
||||
activity.browsingModeManager = browsingModeManager
|
||||
activity.navigateToBrowserOnColdStart()
|
||||
|
||||
verify(exactly = 0) { activity.openToBrowser(BrowserDirection.FromGlobal, null) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `isActivityColdStarted returns false for null savedInstanceState and not launched from history`() {
|
||||
val startingIntent = Intent().apply {
|
||||
|
|
|
@ -17,7 +17,11 @@ import org.junit.Assert.assertNotNull
|
|||
import org.junit.Assert.assertNull
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.BrowserDirection
|
||||
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
|
||||
import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
|
||||
import org.mozilla.fenix.components.metrics.Event
|
||||
import org.mozilla.fenix.ext.components
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
|
||||
class ExternalAppBrowserActivityTest {
|
||||
|
||||
|
@ -37,6 +41,23 @@ class ExternalAppBrowserActivityTest {
|
|||
assertEquals(Event.OpenedApp.Source.CUSTOM_TAB, activity.getIntentSource(otherIntent))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `navigateToBrowserOnColdStart does nothing for external app browser activity`() {
|
||||
val activity = spyk(ExternalAppBrowserActivity())
|
||||
val browsingModeManager: BrowsingModeManager = mockk()
|
||||
every { browsingModeManager.mode } returns BrowsingMode.Normal
|
||||
|
||||
val settings: Settings = mockk()
|
||||
every { settings.shouldReturnToBrowser } returns true
|
||||
every { activity.components.settings.shouldReturnToBrowser } returns true
|
||||
every { activity.openToBrowser(any(), any()) } returns Unit
|
||||
|
||||
activity.browsingModeManager = browsingModeManager
|
||||
activity.navigateToBrowserOnColdStart()
|
||||
|
||||
verify(exactly = 0) { activity.openToBrowser(BrowserDirection.FromGlobal, null) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getNavDirections finishes activity if session ID is null`() {
|
||||
val activity = spyk(object : ExternalAppBrowserActivity() {
|
||||
|
|
|
@ -53,6 +53,19 @@ class SettingsTest {
|
|||
assertTrue(settings.openLinksInAPrivateTab)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldReturnToBrowser() {
|
||||
// When just created
|
||||
// Then
|
||||
assertFalse(settings.shouldReturnToBrowser)
|
||||
|
||||
// When
|
||||
settings.shouldReturnToBrowser = true
|
||||
|
||||
// Then
|
||||
assertTrue(settings.shouldReturnToBrowser)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun clearDataOnQuit() {
|
||||
// When just created
|
||||
|
|
Loading…
Reference in New Issue