2
0
mirror of https://github.com/fork-maintainers/iceraven-browser synced 2024-11-09 19:10:42 +00:00

Add an experiment to demontrate the Feature API

This is not visible in production, but only debug. It shows three variables
being used to change the settings screen (title, icon and title-punctuation).
This commit is contained in:
James Hugman 2021-05-21 20:11:35 +01:00 committed by Christian Sadilek
parent 4851bf7545
commit ab678a21ff
11 changed files with 371 additions and 76 deletions

View File

@ -0,0 +1,236 @@
{
"data": [{
"slug": "feature-text-variables-validation-android",
"appId": "org.mozilla.fenix",
"appName": "fenix",
"channel": "nightly",
"branches": [{
"slug": "control",
"ratio": 100,
"feature": {
"value": {},
"enabled": true,
"featureId": "nimbus-validation"
}
},
{
"slug": "a1",
"ratio": 0,
"feature": {
"value": {
"settings-title": "settings_title",
"settings-title-punctuation": "…"
},
"enabled": true,
"featureId": "nimbus-validation"
}
},
{
"slug": "a2",
"ratio": 0,
"feature": {
"value": {
"settings-title": "preferences_category_general",
"settings-title-punctuation": "!"
},
"enabled": true,
"featureId": "nimbus-validation"
}
}
],
"outcomes": [],
"arguments": {},
"probeSets": [],
"startDate": null,
"targeting": "true",
"featureIds": [
"nimbus-validation"
],
"application": "org.mozilla.firefox_beta",
"bucketConfig": {
"count": 0,
"start": 0,
"total": 10000,
"namespace": "nimbus-validation-2",
"randomizationUnit": "nimbus_id"
},
"schemaVersion": "1.5.0",
"userFacingName": "Nimbus Text Variables Validation",
"referenceBranch": "control",
"proposedDuration": 14,
"isEnrollmentPaused": false,
"proposedEnrollment": 7,
"userFacingDescription": "Demonstration experiment to make trivial visible changes to text in Settings",
"last_modified": 1621443780172
},
{
"slug": "feature-icon-variables-validation-android",
"appId": "org.mozilla.fenix",
"appName": "fenix",
"channel": "nightly",
"branches": [{
"slug": "control",
"ratio": 100,
"feature": {
"value": {},
"enabled": true,
"featureId": "nimbus-validation"
}
},
{
"slug": "treatment",
"ratio": 0,
"feature": {
"value": {
"settings-title": "Fancy Settings",
"settings-icon": "ic_edit"
},
"enabled": true,
"featureId": "nimbus-validation"
}
}
],
"outcomes": [],
"arguments": {},
"probeSets": [],
"startDate": null,
"targeting": "true",
"featureIds": [
"nimbus-validation"
],
"application": "org.mozilla.firefox_beta",
"bucketConfig": {
"count": 0,
"start": 0,
"total": 10000,
"namespace": "nimbus-validation-2",
"randomizationUnit": "nimbus_id"
},
"schemaVersion": "1.5.0",
"userFacingName": "Nimbus Icon Variables Validation",
"referenceBranch": "control",
"proposedDuration": 14,
"isEnrollmentPaused": false,
"proposedEnrollment": 7,
"userFacingDescription": "Demonstration experiment to make trivial visible changes to icons in Settings",
"last_modified": 1621443780172
},
{
"slug": "feature-text-variables-validation-ios",
"appId": "org.mozilla.ios.Fennec",
"appName": "firefox_ios",
"channel": "nightly",
"branches": [{
"slug": "control",
"ratio": 100,
"feature": {
"value": {},
"enabled": true,
"featureId": "nimbus-validation"
}
},
{
"slug": "a1",
"ratio": 0,
"feature": {
"value": {
"settings-title": "Menu/Menu.OpenSettingsAction.Title",
"settings-title-punctuation": "…"
},
"enabled": true,
"featureId": "nimbus-validation"
}
},
{
"slug": "a2",
"ratio": 0,
"feature": {
"value": {
"settings-title": "Settings.General.SectionName",
"settings-title-punctuation": "!"
},
"enabled": true,
"featureId": "nimbus-validation"
}
}
],
"outcomes": [],
"arguments": {},
"probeSets": [],
"startDate": null,
"targeting": "true",
"featureIds": [
"nimbus-validation"
],
"application": "org.mozilla.ios.Fennec",
"bucketConfig": {
"count": 0,
"start": 0,
"total": 10000,
"namespace": "nimbus-validation-2",
"randomizationUnit": "nimbus_id"
},
"schemaVersion": "1.5.0",
"userFacingName": "Nimbus Text Variables Validation",
"referenceBranch": "control",
"proposedDuration": 14,
"isEnrollmentPaused": false,
"proposedEnrollment": 7,
"userFacingDescription": "Demonstration experiment to make trivial visible changes to text in Settings",
"last_modified": 1621443780172
},
{
"slug": "feature-icon-variables-validation-ios",
"appId": "org.mozilla.ios.Fennec",
"appName": "firefox_ios",
"channel": "nightly",
"branches": [{
"slug": "control",
"ratio": 100,
"feature": {
"value": {},
"enabled": true,
"featureId": "nimbus-validation"
}
},
{
"slug": "treatment",
"ratio": 0,
"feature": {
"value": {
"settings-title": "Fancy Settings",
"settings-icon": "menu-ViewMobile"
},
"enabled": true,
"featureId": "nimbus-validation"
}
}
],
"outcomes": [],
"arguments": {},
"probeSets": [],
"startDate": null,
"targeting": "true",
"featureIds": [
"nimbus-validation"
],
"application": "org.mozilla.ios.Fennec",
"bucketConfig": {
"count": 0,
"start": 0,
"total": 10000,
"namespace": "nimbus-validation-2",
"randomizationUnit": "nimbus_id"
},
"schemaVersion": "1.5.0",
"userFacingName": "Nimbus Icon Variables Validation",
"referenceBranch": "control",
"proposedDuration": 14,
"isEnrollmentPaused": false,
"proposedEnrollment": 7,
"userFacingDescription": "Demonstration experiment to make trivial visible changes to icons in Settings",
"last_modified": 1621443780172
}
]
}

View File

@ -9,7 +9,7 @@ import android.os.Build
import mozilla.components.lib.dataprotect.SecurePrefsReliabilityExperiment import mozilla.components.lib.dataprotect.SecurePrefsReliabilityExperiment
import mozilla.components.service.nimbus.NimbusApi import mozilla.components.service.nimbus.NimbusApi
import org.mozilla.fenix.experiments.ExperimentBranch import org.mozilla.fenix.experiments.ExperimentBranch
import org.mozilla.fenix.experiments.Experiments import org.mozilla.fenix.experiments.FeatureId
import org.mozilla.fenix.ext.withExperiment import org.mozilla.fenix.ext.withExperiment
/** /**
@ -24,7 +24,7 @@ class SecurePrefsTelemetry(
// The Android Keystore is used to secure the shared prefs only on API 23+ // The Android Keystore is used to secure the shared prefs only on API 23+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// These tests should run only if the experiment is live // These tests should run only if the experiment is live
experiments.withExperiment(Experiments.ANDROID_KEYSTORE) { experimentBranch -> experiments.withExperiment(FeatureId.ANDROID_KEYSTORE) { experimentBranch ->
// .. and this device is not in the control group. // .. and this device is not in the control group.
if (experimentBranch == ExperimentBranch.TREATMENT) { if (experimentBranch == ExperimentBranch.TREATMENT) {
SecurePrefsReliabilityExperiment(appContext)() SecurePrefsReliabilityExperiment(appContext)()

View File

@ -41,7 +41,7 @@ import org.mozilla.fenix.R
import org.mozilla.fenix.browser.browsingmode.BrowsingMode import org.mozilla.fenix.browser.browsingmode.BrowsingMode
import org.mozilla.fenix.components.accounts.FenixAccountManager import org.mozilla.fenix.components.accounts.FenixAccountManager
import org.mozilla.fenix.experiments.ExperimentBranch import org.mozilla.fenix.experiments.ExperimentBranch
import org.mozilla.fenix.experiments.Experiments import org.mozilla.fenix.experiments.FeatureId
import org.mozilla.fenix.ext.asActivity import org.mozilla.fenix.ext.asActivity
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.settings
@ -632,7 +632,7 @@ open class DefaultToolbarMenu(
val experiments = context.components.analytics.experiments val experiments = context.components.analytics.experiments
val browsers = BrowsersCache.all(context) val browsers = BrowsersCache.all(context)
return experiments.withExperiment(Experiments.DEFAULT_BROWSER) { experimentBranch -> return experiments.withExperiment(FeatureId.DEFAULT_BROWSER) { experimentBranch ->
if (experimentBranch == ExperimentBranch.DEFAULT_BROWSER_TOOLBAR_MENU && if (experimentBranch == ExperimentBranch.DEFAULT_BROWSER_TOOLBAR_MENU &&
!browsers.isFirefoxDefaultBrowser !browsers.isFirefoxDefaultBrowser
) { ) {

View File

@ -4,14 +4,23 @@
package org.mozilla.fenix.experiments package org.mozilla.fenix.experiments
class Experiments { /**
companion object { * Enums to identify features in the app. These will likely grow and shrink depending
const val A_A_NIMBUS_VALIDATION = "fenix-nimbus-validation-v3" * on the experiments we want to perform.
const val ANDROID_KEYSTORE = "fenix-android-keystore" *
const val DEFAULT_BROWSER = "fenix-default-browser" * @property jsonName the kebab-case version of the feature id as represented in the Nimbus
} * experiment JSON.
*/
enum class FeatureId(val jsonName: String) {
NIMBUS_VALIDATION("nimbus-validation"),
ANDROID_KEYSTORE("fenix-android-keystore"),
DEFAULT_BROWSER("fenix-default-browser")
} }
/**
* Experiment branches are becoming less interesting, though we collect some well
* defined ones here.
*/
class ExperimentBranch { class ExperimentBranch {
companion object { companion object {
const val TREATMENT = "treatment" const val TREATMENT = "treatment"

View File

@ -15,6 +15,7 @@ import mozilla.components.service.nimbus.NimbusDisabled
import mozilla.components.service.nimbus.NimbusServerSettings import mozilla.components.service.nimbus.NimbusServerSettings
import mozilla.components.support.base.log.logger.Logger import mozilla.components.support.base.log.logger.Logger
import org.mozilla.fenix.BuildConfig import org.mozilla.fenix.BuildConfig
import org.mozilla.fenix.R
import org.mozilla.fenix.components.isSentryEnabled import org.mozilla.fenix.components.isSentryEnabled
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.settings
@ -66,6 +67,10 @@ fun createNimbus(context: Context, url: String?): NimbusApi =
globalUserParticipation = enabled globalUserParticipation = enabled
} }
if (url.isNullOrBlank()) {
setExperimentsLocally(R.raw.initial_experiments)
}
// We may have downloaded experiments on a previous run, so let's start using them // We may have downloaded experiments on a previous run, so let's start using them
// now. We didn't do this earlier, so as to make getExperimentBranch and friends returns // now. We didn't do this earlier, so as to make getExperimentBranch and friends returns
// the same thing throughout the session. This call does its work on the db thread. // the same thing throughout the session. This call does its work on the db thread.

View File

@ -5,38 +5,98 @@
package org.mozilla.fenix.ext package org.mozilla.fenix.ext
import mozilla.components.service.nimbus.NimbusApi import mozilla.components.service.nimbus.NimbusApi
import mozilla.components.support.base.log.logger.Logger import org.mozilla.experiments.nimbus.Variables
import org.mozilla.fenix.FeatureFlags import org.mozilla.fenix.experiments.FeatureId
/** /**
* Gets the branch of the given `experimentId` and transforms it with given closure. * Gets the branch name of an experiment acting on the feature given `featureId`, and transforms it
* with given closure.
* *
* If we're enrolled in the experiment, the transform is passed the branch id/slug as a `String`. * You are probably looking for `withVariables`.
*
* If we're enrolled in an experiment, the transform is passed the branch id/slug as a `String`.
* *
* If we're not enrolled in the experiment, or the experiment is not valid then the transform * If we're not enrolled in the experiment, or the experiment is not valid then the transform
* is passed a `null`. * is passed a `null`.
*/ */
@Suppress("TooGenericExceptionCaught") fun <T> NimbusApi.withExperiment(featureId: FeatureId, transform: (String?) -> T): T {
fun <T> NimbusApi.withExperiment(experimentId: String, transform: (String?) -> T): T { return transform(getExperimentBranch(featureId.jsonName))
val branch = if (FeatureFlags.nimbusExperiments) {
try {
getExperimentBranch(experimentId)
} catch (e: Throwable) {
Logger.error("Failed to getExperimentBranch($experimentId)", e)
null
}
} else {
null
}
return transform(branch)
} }
/** /**
* The degenerate case of `withExperiment(String, (String?) -> T))`, with an identity transform. * The synonym for [getExperimentBranch] to complement [withExperiment(String, (String?) -> T))].
* *
* Short-hand for `mozilla.components.service.nimbus.NimbusApi.getExperimentBranch`. * Short-hand for ` org.mozilla.experiments.nimbus.NimbusApi.getExperimentBranch`.
*/ */
fun NimbusApi.withExperiment(experimentId: String) = fun NimbusApi.withExperiment(featureId: FeatureId) =
this.withExperiment(experimentId, ::identity) getExperimentBranch(featureId.jsonName)
private fun <T> identity(value: T) = value /**
* Get the variables needed to configure the feature given by `featureId`.
*
* @param featureId The feature id that identifies the feature under experiment.
*
* @param sendExposureEvent Passing `true` to this parameter will record the exposure event
* automatically if the client is enrolled in an experiment for the given [featureId].
* Passing `false` here indicates that the application will manually record the exposure
* event by calling the `sendExposureEvent` function at the time of the exposure to the
* feature.
*
* See [sendExposureEvent] for more information on manually recording the event.
*
* @return a [Variables] object used to configure the feature.
*/
fun NimbusApi.getVariables(featureId: FeatureId, sendExposureEvent: Boolean = true) =
getVariables(featureId.jsonName, sendExposureEvent)
/**
* A synonym for `getVariables(featureId, sendExposureEvent)`.
*
* This exists as a complement to the `withVariable(featureId, sendExposureEvent, transform)` method.
*
* @param featureId the id of the feature as it appears in `Experimenter`
* @param sendExposureEvent by default `true`. This logs an event that the user was exposed to an experiment
* involving this feature.
* @return a `Variables` object providing typed accessors to a remotely configured JSON object.
*/
fun NimbusApi.withVariables(featureId: FeatureId, sendExposureEvent: Boolean = true) =
getVariables(featureId, sendExposureEvent)
/**
* Get a `Variables` object for this feature and use that to configure the feature itself or a more type safe configuration object.
*
* @param featureId the id of the feature as it appears in `Experimenter`
* @param sendExposureEvent by default `true`. This logs an event that the user was exposed to an experiment
* involving this feature.
*/
fun <T> NimbusApi.withVariables(featureId: FeatureId, sendExposureEvent: Boolean = true, transform: (Variables) -> T) =
transform(getVariables(featureId, sendExposureEvent))
/**
* Records the `exposure` event in telemetry.
*
* This is a manual function to accomplish the same purpose as passing `true` as the
* `sendExposureEvent` property of the `getVariables` function. It is intended to be used
* when requesting feature variables must occur at a different time than the actual user's
* exposure to the feature within the app.
*
* - Examples:
* - If the `Variables` are needed at a different time than when the exposure to the feature
* actually happens, such as constructing a menu happening at a different time than the
* user seeing the menu.
* - If `getVariables` is required to be called multiple times for the same feature and it is
* desired to only record the exposure once, such as if `getVariables` were called
* with every keystroke.
*
* In the case where the use of this function is required, then the `getVariables` function
* should be called with `false` so that the exposure event is not recorded when the variables
* are fetched.
*
* This function is safe to call even when there is no active experiment for the feature. The SDK
* will ensure that an event is only recorded for active experiments.
*
* @param featureId string representing the id of the feature for which to record the exposure
* event.
*/
fun NimbusApi.recordExposureEvent(featureId: FeatureId) =
recordExposureEvent(featureId.jsonName)

View File

@ -27,11 +27,10 @@ import org.mozilla.fenix.FeatureFlags
import org.mozilla.fenix.FeatureFlags.tabsTrayRewrite import org.mozilla.fenix.FeatureFlags.tabsTrayRewrite
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.components.accounts.FenixAccountManager import org.mozilla.fenix.components.accounts.FenixAccountManager
import org.mozilla.fenix.experiments.ExperimentBranch import org.mozilla.fenix.experiments.FeatureId
import org.mozilla.fenix.experiments.Experiments
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.getVariables
import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.withExperiment
import org.mozilla.fenix.theme.ThemeManager import org.mozilla.fenix.theme.ThemeManager
import org.mozilla.fenix.whatsnew.WhatsNew import org.mozilla.fenix.whatsnew.WhatsNew
@ -142,23 +141,9 @@ class HomeMenu(
onItemTapped.invoke(Item.Bookmarks) onItemTapped.invoke(Item.Bookmarks)
} }
// We want to validate that the Nimbus experiments library is working, from the android UI
// all the way back to the data science backend. We're not testing the user's preference
// or response, we're end-to-end testing the experiments platform.
// So here, we're running multiple identical branches with the same treatment, and if the
// user isn't targeted, then we get still get the same treatment.
// The `let` block is degenerate here, but left here so as to document the form of how experiments
// are implemented here.
val historyIcon = experiments.withExperiment(Experiments.A_A_NIMBUS_VALIDATION) {
when (it) {
ExperimentBranch.A1 -> R.drawable.ic_history
ExperimentBranch.A2 -> R.drawable.ic_history
else -> R.drawable.ic_history
}
}
val historyItem = BrowserMenuImageText( val historyItem = BrowserMenuImageText(
context.getString(R.string.library_history), context.getString(R.string.library_history),
historyIcon, R.drawable.ic_history,
primaryTextColor primaryTextColor
) { ) {
onItemTapped.invoke(Item.History) onItemTapped.invoke(Item.History)
@ -172,9 +157,11 @@ class HomeMenu(
onItemTapped.invoke(Item.Extensions) onItemTapped.invoke(Item.Extensions)
} }
// Use nimbus to set the icon and title.
val variables = experiments.getVariables(FeatureId.NIMBUS_VALIDATION)
val settingsItem = BrowserMenuImageText( val settingsItem = BrowserMenuImageText(
context.getString(R.string.browser_menu_settings), variables.getText("settings-title") ?: context.getString(R.string.browser_menu_settings),
R.drawable.ic_settings, variables.getDrawableResource("settings-icon") ?: R.drawable.ic_settings,
primaryTextColor primaryTextColor
) { ) {
onItemTapped.invoke(Item.Settings) onItemTapped.invoke(Item.Settings)
@ -252,23 +239,9 @@ class HomeMenu(
onItemTapped.invoke(Item.Bookmarks) onItemTapped.invoke(Item.Bookmarks)
} }
// We want to validate that the Nimbus experiments library is working, from the android UI
// all the way back to the data science backend. We're not testing the user's preference
// or response, we're end-to-end testing the experiments platform.
// So here, we're running multiple identical branches with the same treatment, and if the
// user isn't targeted, then we get still get the same treatment.
// The `let` block is degenerate here, but left here so as to document the form of how experiments
// are implemented here.
val historyIcon = experiments.withExperiment(Experiments.A_A_NIMBUS_VALIDATION) {
when (it) {
ExperimentBranch.A1 -> R.drawable.ic_history
ExperimentBranch.A2 -> R.drawable.ic_history
else -> R.drawable.ic_history
}
}
val historyItem = BrowserMenuImageText( val historyItem = BrowserMenuImageText(
context.getString(R.string.library_history), context.getString(R.string.library_history),
historyIcon, R.drawable.ic_history,
primaryTextColor primaryTextColor
) { ) {
onItemTapped.invoke(Item.History) onItemTapped.invoke(Item.History)
@ -310,9 +283,11 @@ class HomeMenu(
onItemTapped.invoke(Item.Help) onItemTapped.invoke(Item.Help)
} }
// Use nimbus to set the icon and title.
val variables = experiments.getVariables(FeatureId.NIMBUS_VALIDATION)
val settingsItem = BrowserMenuImageText( val settingsItem = BrowserMenuImageText(
context.getString(R.string.browser_menu_settings), variables.getText("settings-title") ?: context.getString(R.string.browser_menu_settings),
R.drawable.ic_settings, variables.getDrawableResource("settings-icon") ?: R.drawable.ic_settings,
primaryTextColor primaryTextColor
) { ) {
onItemTapped.invoke(Item.Settings) onItemTapped.invoke(Item.Settings)

View File

@ -79,7 +79,7 @@ class NimbusBranchesFragment : Fragment() {
try { try {
val experiments = requireContext().components.analytics.experiments val experiments = requireContext().components.analytics.experiments
val branches = experiments.getExperimentBranches(args.experimentId) ?: emptyList() val branches = experiments.getExperimentBranches(args.experimentId) ?: emptyList()
val selectedBranch = experiments.withExperiment(args.experimentId) ?: "" val selectedBranch = experiments.getExperimentBranch(args.experimentId) ?: ""
nimbusBranchesStore.dispatch( nimbusBranchesStore.dispatch(
NimbusBranchesAction.UpdateBranches( NimbusBranchesAction.UpdateBranches(

View File

@ -42,7 +42,7 @@ import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.experiments.ExperimentBranch import org.mozilla.fenix.experiments.ExperimentBranch
import org.mozilla.fenix.experiments.Experiments import org.mozilla.fenix.experiments.FeatureId
import org.mozilla.fenix.ext.application import org.mozilla.fenix.ext.application
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.getPreferenceKey import org.mozilla.fenix.ext.getPreferenceKey
@ -52,6 +52,7 @@ import org.mozilla.fenix.ext.navigateToNotificationsSettings
import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.REQUEST_CODE_BROWSER_ROLE import org.mozilla.fenix.ext.REQUEST_CODE_BROWSER_ROLE
import org.mozilla.fenix.ext.getVariables
import org.mozilla.fenix.ext.openSetDefaultBrowserOption import org.mozilla.fenix.ext.openSetDefaultBrowserOption
import org.mozilla.fenix.ext.showToolbar import org.mozilla.fenix.ext.showToolbar
import org.mozilla.fenix.ext.withExperiment import org.mozilla.fenix.ext.withExperiment
@ -161,7 +162,13 @@ class SettingsFragment : PreferenceFragmentCompat() {
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
showToolbar(getString(R.string.settings_title)) // Use nimbus to set the title, and a trivial addition
val experiments = requireContext().components.analytics.experiments
val variables = experiments.getVariables(FeatureId.NIMBUS_VALIDATION)
val title = variables.getText("settings-title") ?: getString(R.string.settings_title)
val suffix = variables.getString("settings-title-punctuation") ?: ""
showToolbar("$title$suffix")
// Account UI state is updated as part of `onCreate`. To not do it twice in a row, we only // Account UI state is updated as part of `onCreate`. To not do it twice in a row, we only
// update it here if we're not going through the `onCreate->onStart->onResume` lifecycle chain. // update it here if we're not going through the `onCreate->onStart->onResume` lifecycle chain.
@ -589,7 +596,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
private fun isDefaultBrowserExperimentBranch(): Boolean { private fun isDefaultBrowserExperimentBranch(): Boolean {
val experiments = context?.components?.analytics?.experiments val experiments = context?.components?.analytics?.experiments
return experiments?.withExperiment(Experiments.DEFAULT_BROWSER) { experimentBranch -> return experiments?.withExperiment(FeatureId.DEFAULT_BROWSER) { experimentBranch ->
(experimentBranch == ExperimentBranch.DEFAULT_BROWSER_SETTINGS_MENU) (experimentBranch == ExperimentBranch.DEFAULT_BROWSER_SETTINGS_MENU)
} == true } == true
} }

View File

@ -34,7 +34,7 @@ import org.mozilla.fenix.components.settings.counterPreference
import org.mozilla.fenix.components.settings.featureFlagPreference import org.mozilla.fenix.components.settings.featureFlagPreference
import org.mozilla.fenix.components.toolbar.ToolbarPosition import org.mozilla.fenix.components.toolbar.ToolbarPosition
import org.mozilla.fenix.experiments.ExperimentBranch import org.mozilla.fenix.experiments.ExperimentBranch
import org.mozilla.fenix.experiments.Experiments import org.mozilla.fenix.experiments.FeatureId
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.getPreferenceKey import org.mozilla.fenix.ext.getPreferenceKey
import org.mozilla.fenix.ext.withExperiment import org.mozilla.fenix.ext.withExperiment
@ -312,10 +312,10 @@ class Settings(private val appContext: Context) : PreferencesHolder {
val browsers = BrowsersCache.all(appContext) val browsers = BrowsersCache.all(appContext)
val experiments = appContext.components.analytics.experiments val experiments = appContext.components.analytics.experiments
val isExperimentBranch = val isExperimentBranch =
experiments.withExperiment(Experiments.DEFAULT_BROWSER) { experimentBranch -> experiments.withExperiment(FeatureId.DEFAULT_BROWSER) { experimentBranch ->
(experimentBranch == ExperimentBranch.DEFAULT_BROWSER_NEW_TAB_BANNER) (experimentBranch == ExperimentBranch.DEFAULT_BROWSER_NEW_TAB_BANNER)
} }
return isExperimentBranch && return isExperimentBranch == true &&
!userDismissedExperimentCard && !userDismissedExperimentCard &&
!browsers.isFirefoxDefaultBrowser && !browsers.isFirefoxDefaultBrowser &&
numberOfAppLaunches > APP_LAUNCHES_TO_SHOW_DEFAULT_BROWSER_CARD numberOfAppLaunches > APP_LAUNCHES_TO_SHOW_DEFAULT_BROWSER_CARD

View File

@ -0,0 +1,3 @@
{
"data": []
}