Skip to content

Commit 2af7989

Browse files
committed
Bug 1973324 - Part 2: Refactor setting the appropriate browsing mode into BrowsingModeManger r=Roger,android-reviewers
- Refactors `HomeActivity.getModeFromIntentOrLastKnown` into `BrowsingModeManger`. This moves more of the logic related to computing the browsing mode from the provided intent, last known mode settings and number of private tabs opened into BrowsingModeManger and out of the HomeActivity. - Introduces a public `BrowsingModeManager.updateMode` function for updating the browsing mode with a new Intent. Differential Revision: https://phabricator.services.mozilla.com/D255455
1 parent 6a8d3ef commit 2af7989

File tree

8 files changed

+207
-110
lines changed

8 files changed

+207
-110
lines changed

mobile/android/fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt

Lines changed: 6 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
321321
// There is disk read violations on some devices such as samsung and pixel for android 9/10
322322
components.strictMode.resetAfter(StrictMode.allowThreadDiskReads()) {
323323
// Browsing mode & theme setup should always be called before super.onCreate.
324-
setupBrowsingMode(getModeFromIntentOrLastKnown(intent))
324+
browsingModeManager = createBrowsingModeManager(intent)
325325
setupTheme()
326326

327327
super.onCreate(savedInstanceState)
@@ -887,7 +887,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
887887
) + externalSourceIntentProcessors
888888
val intentHandled =
889889
intentProcessors.any { it.process(intent, navHost.navController, this.intent, settings()) }
890-
browsingModeManager.mode = getModeFromIntentOrLastKnown(intent)
890+
browsingModeManager.updateMode(intent)
891891

892892
if (intentHandled) {
893893
supportFragmentManager
@@ -1104,29 +1104,6 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
11041104
super.onUserLeaveHint()
11051105
}
11061106

1107-
/**
1108-
* External sources such as 3rd party links and shortcuts use this function to enter
1109-
* private mode directly before the content view is created. Returns the mode set by the intent
1110-
* otherwise falls back to normal browsing mode.
1111-
*/
1112-
@VisibleForTesting
1113-
internal fun getModeFromIntentOrLastKnown(intent: Intent?): BrowsingMode {
1114-
intent?.toSafeIntent()?.let {
1115-
if (it.hasExtra(PRIVATE_BROWSING_MODE)) {
1116-
val startPrivateMode = it.getBooleanExtra(PRIVATE_BROWSING_MODE, false)
1117-
return BrowsingMode.fromBoolean(isPrivate = startPrivateMode)
1118-
}
1119-
}
1120-
1121-
if (settings().lastKnownMode.isPrivate &&
1122-
components.core.store.state.getNormalOrPrivateTabs(private = true).isNotEmpty()
1123-
) {
1124-
return BrowsingMode.Private
1125-
}
1126-
1127-
return BrowsingMode.Normal
1128-
}
1129-
11301107
/**
11311108
* Determines whether the activity should be pushed to be backstack (i.e., 'minimized' to the recents
11321109
* screen) upon starting.
@@ -1140,11 +1117,6 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
11401117
return false
11411118
}
11421119

1143-
private fun setupBrowsingMode(mode: BrowsingMode) {
1144-
settings().lastKnownMode = mode
1145-
browsingModeManager = createBrowsingModeManager(mode)
1146-
}
1147-
11481120
private fun setupTheme() {
11491121
themeManager = createThemeManager()
11501122
// ExternalAppBrowserActivity exclusively handles it's own theming unless in private mode.
@@ -1295,9 +1267,10 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
12951267
return super.getSystemService(name)
12961268
}
12971269

1298-
private fun createBrowsingModeManager(initialMode: BrowsingMode): BrowsingModeManager {
1270+
private fun createBrowsingModeManager(intent: Intent?): BrowsingModeManager {
12991271
return DefaultBrowsingModeManager(
1300-
initialMode = initialMode,
1272+
intent = intent,
1273+
store = components.core.store,
13011274
settings = components.settings,
13021275
modeDidChange = { newMode ->
13031276
updateSecureWindowFlags(newMode)
@@ -1308,7 +1281,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
13081281
components.appStore.dispatch(AppAction.BrowsingModeManagerModeChanged(mode = newMode))
13091282
},
13101283
).also {
1311-
updateSecureWindowFlags(initialMode)
1284+
updateSecureWindowFlags(it.mode)
13121285
}
13131286
}
13141287

mobile/android/fenix/app/src/main/java/org/mozilla/fenix/browser/browsingmode/BrowsingModeManager.kt

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44

55
package org.mozilla.fenix.browser.browsingmode
66

7+
import android.content.Intent
8+
import mozilla.components.browser.state.selector.getNormalOrPrivateTabs
9+
import mozilla.components.browser.state.store.BrowserStore
10+
import mozilla.components.support.utils.toSafeIntent
11+
import org.mozilla.fenix.HomeActivity.Companion.PRIVATE_BROWSING_MODE
712
import org.mozilla.fenix.components.AppStore
813
import org.mozilla.fenix.components.appstate.AppState
914
import org.mozilla.fenix.utils.Settings
@@ -31,28 +36,64 @@ enum class BrowsingMode {
3136

3237
interface BrowsingModeManager {
3338
var mode: BrowsingMode
39+
40+
/**
41+
* Updates the [BrowsingMode] based on the [Intent] that started the activity.
42+
*
43+
* @param intent The [Intent] that started the activity.
44+
*/
45+
fun updateMode(intent: Intent? = null)
3446
}
3547

3648
/**
3749
* Default implementation of [BrowsingModeManager] that tracks the current [BrowsingMode],
3850
* persists it to [Settings], and synchronizes it with [AppStore].
3951
*
40-
* @param initialMode The initial [BrowsingMode]
52+
* @param intent The [Intent] that started the activity.
53+
* @param store The [BrowserStore] to observe the private tabs state from.
4154
* @param settings Used to persist the last known mode across sessions.
4255
* @param modeDidChange Callback that is invoked whenever the browsing mode changes.
4356
* @param updateAppStateMode Callback used to update the [AppState.mode].
4457
*/
4558
class DefaultBrowsingModeManager(
46-
private var initialMode: BrowsingMode,
59+
intent: Intent?,
60+
private val store: BrowserStore,
4761
private val settings: Settings,
4862
private val modeDidChange: (BrowsingMode) -> Unit,
4963
private val updateAppStateMode: (BrowsingMode) -> Unit,
5064
) : BrowsingModeManager {
51-
override var mode: BrowsingMode = initialMode
65+
override var mode: BrowsingMode = getModeFromIntentOrLastKnown(intent)
5266
set(value) {
5367
field = value
5468
modeDidChange(value)
5569
settings.lastKnownMode = value
5670
updateAppStateMode(value)
5771
}
72+
73+
override fun updateMode(intent: Intent?) {
74+
val mode = getModeFromIntentOrLastKnown(intent)
75+
if (this.mode != mode) {
76+
this.mode = mode
77+
}
78+
}
79+
80+
/**
81+
* Returns the [BrowsingMode] set by the [intent] or the last known browsing mode based on
82+
* whether or not the user was in private mode and has any private tabs, otherwise fallback to
83+
* [BrowsingMode.Normal].
84+
*/
85+
private fun getModeFromIntentOrLastKnown(intent: Intent?): BrowsingMode {
86+
intent?.toSafeIntent()?.let {
87+
if (it.hasExtra(PRIVATE_BROWSING_MODE)) {
88+
val startPrivateMode = it.getBooleanExtra(PRIVATE_BROWSING_MODE, false)
89+
return BrowsingMode.fromBoolean(isPrivate = startPrivateMode)
90+
}
91+
}
92+
93+
if (settings.lastKnownMode.isPrivate && store.state.getNormalOrPrivateTabs(private = true).isNotEmpty()) {
94+
return BrowsingMode.Private
95+
}
96+
97+
return BrowsingMode.Normal
98+
}
5899
}

mobile/android/fenix/app/src/test/java/org/mozilla/fenix/HomeActivityTest.kt

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import mozilla.components.support.test.robolectric.testContext
2020
import mozilla.components.support.utils.toSafeIntent
2121
import org.junit.Assert.assertEquals
2222
import org.junit.Assert.assertFalse
23-
import org.junit.Assert.assertNotEquals
2423
import org.junit.Assert.assertNotNull
2524
import org.junit.Assert.assertNull
2625
import org.junit.Assert.assertTrue
@@ -29,7 +28,6 @@ import org.junit.Rule
2928
import org.junit.Test
3029
import org.junit.runner.RunWith
3130
import org.mozilla.fenix.GleanMetrics.Metrics
32-
import org.mozilla.fenix.HomeActivity.Companion.PRIVATE_BROWSING_MODE
3331
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
3432
import org.mozilla.fenix.browser.browsingmode.BrowsingModeManager
3533
import org.mozilla.fenix.components.AppStore
@@ -85,54 +83,6 @@ class HomeActivityTest {
8583
assertNull(activity.getIntentSource(otherIntent))
8684
}
8785

88-
@Test
89-
fun `GIVEN browsing mode is not set by intent and private mode with a tab persisted WHEN getModeFromIntentOrLastKnown is called THEN returns normal browsing mode`() {
90-
val browserStore = BrowserStore(
91-
BrowserState(
92-
tabs = listOf(
93-
createTab(url = "https://mozilla.org", private = true),
94-
),
95-
),
96-
)
97-
98-
every { testContext.settings() } returns Settings(testContext)
99-
every { activity.applicationContext } returns testContext
100-
every { testContext.components.core.store } returns browserStore
101-
102-
testContext.settings().lastKnownMode = BrowsingMode.Private
103-
104-
assertEquals(BrowsingMode.Private, activity.getModeFromIntentOrLastKnown(null))
105-
106-
testContext.settings().lastKnownMode = BrowsingMode.Normal
107-
108-
assertEquals(BrowsingMode.Normal, activity.getModeFromIntentOrLastKnown(null))
109-
}
110-
111-
@Test
112-
fun `GIVEN last known mode is private mode and no tabs persisted WHEN getModeFromIntentOrLastKnown is called THEN returns normal browsing mode`() {
113-
val browserStore = BrowserStore()
114-
115-
every { testContext.settings() } returns Settings(testContext)
116-
every { activity.applicationContext } returns testContext
117-
every { testContext.components.core.store } returns browserStore
118-
119-
testContext.settings().lastKnownMode = BrowsingMode.Private
120-
121-
assertEquals(BrowsingMode.Normal, activity.getModeFromIntentOrLastKnown(null))
122-
}
123-
124-
@Test
125-
fun `getModeFromIntentOrLastKnown returns mode from intent when set`() {
126-
every { testContext.settings() } returns Settings(testContext)
127-
testContext.settings().lastKnownMode = BrowsingMode.Normal
128-
129-
val intent = Intent()
130-
intent.putExtra(PRIVATE_BROWSING_MODE, true)
131-
132-
assertNotEquals(testContext.settings().lastKnownMode, activity.getModeFromIntentOrLastKnown(intent))
133-
assertEquals(BrowsingMode.Private, activity.getModeFromIntentOrLastKnown(intent))
134-
}
135-
13686
@Test
13787
fun `isActivityColdStarted returns true for null savedInstanceState and not launched from history`() {
13888
assertTrue(activity.isActivityColdStarted(Intent(), null))

0 commit comments

Comments
 (0)