commit 5e7833fdea31106939bf8f832f8606af5c3945ab
parent 26db74bf911e80ea02ef30365d3438fc98aa090a
Author: John Oberhauser <j.git-global@obez.io>
Date: Tue, 21 Oct 2025 14:15:20 +0000
Bug 1993323: Adding nimbus configurations for the default browser prompt r=android-reviewers,gmalekpour,twhite
Differential Revision: https://phabricator.services.mozilla.com/D268031
Diffstat:
4 files changed, 109 insertions(+), 27 deletions(-)
diff --git a/mobile/android/fenix/app/nimbus.fml.yaml b/mobile/android/fenix/app/nimbus.fml.yaml
@@ -1037,6 +1037,26 @@ features:
type: Boolean
default: false
+ default-browser-prompt:
+ description: Feature that controls when the default browser prompt is shown.
+ variables:
+ enabled:
+ description: Whether or not to enable the default browser prompt.
+ type: Boolean
+ default: true
+ daysBetweenPrompts:
+ description: The minimum number of days between showing the prompt.
+ type: Option<Int>
+ default: 14
+ maxPromptsShown:
+ description: The maximum number of times the prompt can shown to the user.
+ type: Option<Int>
+ default: 3
+ coldStartsBetweenPrompts:
+ description: The minimum number of cold starts between showing the prompt.
+ type: Option<Int>
+ default: 4
+
types:
objects:
GleanServerKnobsConfiguration:
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/HomeActivity.kt
@@ -605,7 +605,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
@VisibleForTesting
internal fun maybeShowSetAsDefaultBrowserPrompt(
- shouldShowSetAsDefaultPrompt: Boolean = settings().shouldShowSetAsDefaultPrompt,
+ shouldShowSetAsDefaultPrompt: Boolean = settings().shouldShowSetAsDefaultPrompt(),
isDefaultBrowser: Boolean = BrowsersCache.all(applicationContext).isDefaultBrowser,
isTheCorrectBuildVersion: Boolean = Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q,
) {
diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt
@@ -55,6 +55,7 @@ import org.mozilla.fenix.ext.pixelSizeFor
import org.mozilla.fenix.home.pocket.ContentRecommendationsFeatureHelper
import org.mozilla.fenix.home.topsites.TopSitesConfigConstants.TOP_SITES_MAX_COUNT
import org.mozilla.fenix.nimbus.CookieBannersSection
+import org.mozilla.fenix.nimbus.DefaultBrowserPrompt
import org.mozilla.fenix.nimbus.FxNimbus
import org.mozilla.fenix.nimbus.HomeScreenSection
import org.mozilla.fenix.nimbus.Mr2022Section
@@ -112,21 +113,6 @@ class Settings(private val appContext: Context) : PreferencesHolder {
@VisibleForTesting
internal var searchGroupMinimumSites: Int = 2
- /**
- * Minimum number of days between Set as default Browser prompt displays in home page.
- */
- const val DAYS_BETWEEN_DEFAULT_BROWSER_PROMPTS: Int = 14
-
- /**
- * Maximum number of times the Set as default Browser prompt from home page can be displayed to the user.
- */
- const val MAX_NUMBER_OF_DEFAULT_BROWSER_PROMPTS: Int = 3
-
- /**
- * Number of app cold starts before displaying the Set as default Browser prompt from home page.
- */
- const val APP_COLD_STARTS_TO_SHOW_DEFAULT_PROMPT: Int = 4
-
private fun Action.toInt() = when (this) {
Action.BLOCKED -> BLOCKED_INT
Action.ASK_TO_ALLOW -> ASK_TO_ALLOW_INT
@@ -2560,12 +2546,27 @@ class Settings(private val appContext: Context) : PreferencesHolder {
/**
* Indicates if the Set as default Browser prompt should be displayed to the user.
*/
- val shouldShowSetAsDefaultPrompt: Boolean
- get() =
- (System.currentTimeMillis() - lastSetAsDefaultPromptShownTimeInMillis) >
- DAYS_BETWEEN_DEFAULT_BROWSER_PROMPTS * ONE_DAY_MS &&
- numberOfSetAsDefaultPromptShownTimes < MAX_NUMBER_OF_DEFAULT_BROWSER_PROMPTS &&
- coldStartsBetweenSetAsDefaultPrompts >= APP_COLD_STARTS_TO_SHOW_DEFAULT_PROMPT
+ fun shouldShowSetAsDefaultPrompt(
+ nimbusFeature: DefaultBrowserPrompt = FxNimbus.features.defaultBrowserPrompt.value(),
+ ): Boolean {
+ if (!nimbusFeature.enabled) return false
+
+ val now = System.currentTimeMillis()
+
+ val daysOk = nimbusFeature.daysBetweenPrompts?.let { intervalDays ->
+ (now - lastSetAsDefaultPromptShownTimeInMillis) > intervalDays * ONE_DAY_MS
+ } ?: true
+
+ val maxOk = nimbusFeature.maxPromptsShown?.let { max ->
+ numberOfSetAsDefaultPromptShownTimes < max
+ } ?: true
+
+ val coldStartsOk = nimbusFeature.coldStartsBetweenPrompts?.let { minColdStarts ->
+ coldStartsBetweenSetAsDefaultPrompts >= minColdStarts
+ } ?: true
+
+ return daysOk && maxOk && coldStartsOk
+ }
/**
* Updates the relevant settings when the "Set as Default Browser" prompt is shown.
diff --git a/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/utils/SettingsTest.kt b/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/utils/SettingsTest.kt
@@ -25,6 +25,7 @@ import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.toolbar.ToolbarPosition
+import org.mozilla.fenix.nimbus.DefaultBrowserPrompt
import org.mozilla.fenix.nimbus.FakeNimbusEventStore
import org.mozilla.fenix.settings.PhoneFeature
import org.mozilla.fenix.settings.deletebrowsingdata.DeleteBrowsingDataOnQuitType
@@ -1152,7 +1153,7 @@ class SettingsTest {
settings.lastSetAsDefaultPromptShownTimeInMillis = System.currentTimeMillis()
settings.coldStartsBetweenSetAsDefaultPrompts = 5
- assertFalse(settings.shouldShowSetAsDefaultPrompt)
+ assertFalse(settings.shouldShowSetAsDefaultPrompt())
}
@Test
@@ -1161,7 +1162,7 @@ class SettingsTest {
settings.lastSetAsDefaultPromptShownTimeInMillis = 0L
settings.coldStartsBetweenSetAsDefaultPrompts = 5
- assertFalse(settings.shouldShowSetAsDefaultPrompt)
+ assertFalse(settings.shouldShowSetAsDefaultPrompt())
}
@Test
@@ -1170,7 +1171,7 @@ class SettingsTest {
settings.lastSetAsDefaultPromptShownTimeInMillis = System.currentTimeMillis() - 1000
settings.coldStartsBetweenSetAsDefaultPrompts = 5
- assertFalse(settings.shouldShowSetAsDefaultPrompt)
+ assertFalse(settings.shouldShowSetAsDefaultPrompt())
}
@Test
@@ -1179,7 +1180,7 @@ class SettingsTest {
settings.lastSetAsDefaultPromptShownTimeInMillis = 0L
settings.coldStartsBetweenSetAsDefaultPrompts = 1
- assertFalse(settings.shouldShowSetAsDefaultPrompt)
+ assertFalse(settings.shouldShowSetAsDefaultPrompt())
}
@Test
@@ -1188,7 +1189,67 @@ class SettingsTest {
settings.lastSetAsDefaultPromptShownTimeInMillis = 0L
settings.coldStartsBetweenSetAsDefaultPrompts = 5 // More than required cold starts
- assertTrue(settings.shouldShowSetAsDefaultPrompt)
+ assertTrue(settings.shouldShowSetAsDefaultPrompt())
+ }
+
+ @Test
+ fun `GIVEN other conditions are valid WHEN the default browser prompt is disabled THEN shouldShowSetAsDefaultPrompt is false`() {
+ settings.numberOfSetAsDefaultPromptShownTimes = 1
+ settings.lastSetAsDefaultPromptShownTimeInMillis = 0L
+ settings.coldStartsBetweenSetAsDefaultPrompts = 5 // More than required cold starts
+
+ assertFalse(
+ settings.shouldShowSetAsDefaultPrompt(
+ DefaultBrowserPrompt(
+ enabled = false,
+ ),
+ ),
+ )
+ }
+
+ @Test
+ fun `GIVEN other conditions are valid WHEN the days between prompts is null THEN the value is ignored`() {
+ settings.numberOfSetAsDefaultPromptShownTimes = 1
+ settings.lastSetAsDefaultPromptShownTimeInMillis = System.currentTimeMillis()
+ settings.coldStartsBetweenSetAsDefaultPrompts = 5
+
+ assertTrue(
+ settings.shouldShowSetAsDefaultPrompt(
+ DefaultBrowserPrompt(
+ daysBetweenPrompts = null,
+ ),
+ ),
+ )
+ }
+
+ @Test
+ fun `GIVEN other conditions are valid WHEN max prompts shown is null THEN the value is ignored`() {
+ settings.numberOfSetAsDefaultPromptShownTimes = 10
+ settings.lastSetAsDefaultPromptShownTimeInMillis = 0L
+ settings.coldStartsBetweenSetAsDefaultPrompts = 5
+
+ assertTrue(
+ settings.shouldShowSetAsDefaultPrompt(
+ DefaultBrowserPrompt(
+ maxPromptsShown = null,
+ ),
+ ),
+ )
+ }
+
+ @Test
+ fun `GIVEN other conditions are valid WHEN cold starts between prompts is null THEN the value is ignored`() {
+ settings.numberOfSetAsDefaultPromptShownTimes = 1
+ settings.lastSetAsDefaultPromptShownTimeInMillis = 0L
+ settings.coldStartsBetweenSetAsDefaultPrompts = 0
+
+ assertTrue(
+ settings.shouldShowSetAsDefaultPrompt(
+ DefaultBrowserPrompt(
+ coldStartsBetweenPrompts = null,
+ ),
+ ),
+ )
}
@Test