Nimbus Global Opt Out (#16543) r=gl

This commit is contained in:
jhugman 2020-11-19 11:17:25 +00:00 committed by GitHub
parent 359759753c
commit 9cdfb6db4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 50 additions and 29 deletions

View File

@ -435,11 +435,11 @@ dependencies {
implementation Deps.mozilla_feature_webcompat_reporter
implementation Deps.mozilla_service_digitalassetlinks
implementation Deps.mozilla_service_experiments
implementation Deps.mozilla_service_sync_logins
implementation Deps.mozilla_service_firefox_accounts
implementation Deps.mozilla_service_glean
implementation Deps.mozilla_service_location
implementation Deps.mozilla_service_nimbus
implementation Deps.mozilla_support_base
implementation Deps.mozilla_support_images

View File

@ -32,10 +32,13 @@ class SettingsSubMenuDataCollectionRobot {
fun verifyMarketingDataSwitchDefault() = assertMarketingDataValueSwitchDefault()
fun verifyExperimentsSwitchDefault() = assertExperimentsSwitchDefault()
fun verifyDataCollectionSubMenuItems() {
verifyDataCollectionOptions()
verifyUsageAndTechnicalDataSwitchDefault()
verifyMarketingDataSwitchDefault()
verifyExperimentsSwitchDefault()
}
class Transition {
@ -76,6 +79,9 @@ private fun assertDataCollectionOptions() {
onView(withText(marketingDataText))
.check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
onView(withText(R.string.preference_experiments_2)).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
onView(withText(R.string.preference_experiments_summary_2)).check(matches(withEffectiveVisibility(Visibility.VISIBLE)))
}
private fun usageAndTechnicalDataButton() = onView(withText(R.string.preference_usage_data))
@ -87,3 +93,8 @@ private fun marketingDataButton() = onView(withText(R.string.preferences_marketi
private fun assertMarketingDataValueSwitchDefault() = marketingDataButton()
.assertIsEnabled(isEnabled = true)
private fun experimentsButton() = onView(withText(R.string.preference_experiments_2))
private fun assertExperimentsSwitchDefault() = experimentsButton()
.assertIsEnabled(isEnabled = true)

View File

@ -35,4 +35,10 @@ object FeatureFlags {
* Enables ETP cookie purging
*/
val etpCookiePurging = Config.channel.isNightlyOrDebug
/**
* Enables the Nimbus experiments library, especially the settings toggle to opt-out of
* all experiments.
*/
val nimbusExperiments = Config.channel.isNightlyOrDebug
}

View File

@ -25,7 +25,6 @@ import mozilla.components.browser.state.action.SystemAction
import mozilla.components.concept.push.PushProcessor
import mozilla.components.feature.addons.update.GlobalAddonDependencyProvider
import mozilla.components.lib.crash.CrashReporter
import mozilla.components.service.experiments.Experiments
import mozilla.components.service.glean.Glean
import mozilla.components.service.glean.config.Configuration
import mozilla.components.service.glean.net.ConceptFetchHttpUploader
@ -170,25 +169,6 @@ open class FenixApplication : LocaleAwareApplication(), Provider {
registerActivityLifecycleCallbacks(PerformanceActivityLifecycleCallbacks(queue))
}
fun queueInitExperiments() {
@Suppress("ControlFlowWithEmptyBody")
if (settings().isExperimentationEnabled) {
queue.runIfReadyOrQueue {
Experiments.initialize(
applicationContext = applicationContext,
onExperimentsUpdated = null,
configuration = mozilla.components.service.experiments.Configuration(
httpClient = components.core.client,
kintoEndpoint = KINTO_ENDPOINT_PROD
)
)
}
} else {
// We should make a better way to opt out for when we have more experiments
// See https://github.com/mozilla-mobile/fenix/issues/6278
}
}
fun queueInitStorageAndServices() {
components.performance.visualCompletenessQueue.queue.runIfReadyOrQueue {
GlobalScope.launch(Dispatchers.IO) {
@ -229,7 +209,6 @@ open class FenixApplication : LocaleAwareApplication(), Provider {
// We init these items in the visual completeness queue to avoid them initing in the critical
// startup path, before the UI finishes drawing (i.e. visual completeness).
queueInitExperiments()
queueInitStorageAndServices()
queueMetrics()
queueReviewPrompt()

View File

@ -13,8 +13,10 @@ import mozilla.components.lib.crash.service.CrashReporterService
import mozilla.components.lib.crash.service.GleanCrashReporterService
import mozilla.components.lib.crash.service.MozillaSocorroService
import mozilla.components.lib.crash.service.SentryService
import mozilla.components.service.nimbus.Nimbus
import org.mozilla.fenix.BuildConfig
import org.mozilla.fenix.Config
import org.mozilla.fenix.FeatureFlags
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.ReleaseChannel
@ -98,6 +100,23 @@ class Analytics(
isMarketingDataTelemetryEnabled = { context.settings().isMarketingTelemetryEnabled }
)
}
val experiments by lazyMonitored {
Nimbus().apply {
if (FeatureFlags.nimbusExperiments) {
initialize(context)
// Global opt out state is stored in Nimbus, and shouldn't be toggled to `true`
// from the app unless the user does so from a UI control.
// However, the user may have opt-ed out of mako experiments already, so
// we should respect that setting here.
val enabled = context.settings().isExperimentationEnabled
if (!enabled) {
globalUserParticipation = enabled
}
context.settings().isExperimentationEnabled = globalUserParticipation
}
}
}
}
fun isSentryEnabled() = !BuildConfig.SENTRY_TOKEN.isNullOrEmpty()

View File

@ -7,7 +7,7 @@ package org.mozilla.fenix.settings
import android.os.Bundle
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreference
import org.mozilla.fenix.Config
import org.mozilla.fenix.FeatureFlags
import org.mozilla.fenix.R
import org.mozilla.fenix.components.metrics.MetricServiceType
import org.mozilla.fenix.ext.components
@ -37,6 +37,9 @@ class DataChoicesFragment : PreferenceFragmentCompat() {
} else {
context.components.analytics.metrics.stop(MetricServiceType.Marketing)
}
} else if (key == getPreferenceKey(R.string.pref_key_experimentation)) {
val enabled = context.settings().isExperimentationEnabled
context.components.analytics.experiments.globalUserParticipation = enabled
}
}
}
@ -72,7 +75,7 @@ class DataChoicesFragment : PreferenceFragmentCompat() {
requirePreference<SwitchPreference>(R.string.pref_key_experimentation).apply {
isChecked = context.settings().isExperimentationEnabled
isVisible = Config.channel.isReleaseOrBeta
isVisible = FeatureFlags.nimbusExperiments
onPreferenceChangeListener = SharedPreferenceUpdater()
}
}

View File

@ -231,7 +231,7 @@ class Settings(private val appContext: Context) : PreferencesHolder {
default = true
)
val isExperimentationEnabled by booleanPreference(
var isExperimentationEnabled by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_experimentation),
default = true
)

View File

@ -433,6 +433,10 @@
<string name="preferences_marketing_data">Marketing data</string>
<!-- Preference description for marketing data collection, parameter is the app name (e.g. Firefox) -->
<string name="preferences_marketing_data_description">Shares data about what features you use in %1$s with Leanplum, our mobile marketing vendor.</string>
<!-- Title for studies preferences -->
<string name="preference_experiments_2">Studies</string>
<!-- Summary for studies preferences -->
<string name="preference_experiments_summary_2">Allows Mozilla to install and run studies</string>
<!-- Title for experiments preferences -->
<string name="preference_experiments">Experiments</string>
<!-- Summary for experiments preferences -->

View File

@ -13,6 +13,6 @@
android:title="@string/preferences_marketing_data" />
<SwitchPreference
android:key="@string/pref_key_experimentation"
android:summary="@string/preference_experiments_summary"
android:title="@string/preference_experiments" />
android:summary="@string/preference_experiments_summary_2"
android:title="@string/preference_experiments_2" />
</PreferenceScreen>

View File

@ -129,13 +129,12 @@ object Deps {
const val mozilla_service_digitalassetlinks =
"org.mozilla.components:service-digitalassetlinks:${Versions.mozilla_android_components}"
const val mozilla_service_experiments =
"org.mozilla.components:service-experiments:${Versions.mozilla_android_components}"
const val mozilla_service_sync_logins =
"org.mozilla.components:service-sync-logins:${Versions.mozilla_android_components}"
const val mozilla_service_firefox_accounts = "org.mozilla.components:service-firefox-accounts:${Versions.mozilla_android_components}"
const val mozilla_service_glean = "org.mozilla.components:service-glean:${Versions.mozilla_android_components}"
const val mozilla_service_location = "org.mozilla.components:service-location:${Versions.mozilla_android_components}"
const val mozilla_service_nimbus = "org.mozilla.components:service-nimbus:${Versions.mozilla_android_components}"
const val mozilla_ui_colors = "org.mozilla.components:ui-colors:${Versions.mozilla_android_components}"
const val mozilla_ui_icons = "org.mozilla.components:ui-icons:${Versions.mozilla_android_components}"