For #5651 - Set up Standard vs Strict Tracking Protection Experiment

nightly-build-test
Emily Kager 5 years ago committed by Emily Kager
parent 19a2d9df4f
commit 2b19b28d25

@ -0,0 +1,43 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix
import android.content.Context
import mozilla.components.service.experiments.Experiments
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.settings
object ExperimentsManager {
fun initEtpExperiment(context: Context) {
// When the `fenix-etp-5651` experiment is active, set up ETP settings and GV policy.
// Note that this will not take effect the first time the application has launched,
// since there won't be enough time for the experiments library to get a list of experiments.
// It will take effect the second time the application is launched.
Experiments.withExperiment("fenix-etp-5651") { branchName ->
when (branchName) {
"control_strict" -> {
context.settings().setUseStrictTrackingProtection()
context.components.useCases.settingsUseCases.updateTrackingProtection(
context.components.core.createTrackingProtectionPolicy()
)
}
"treatment_standard" -> {
context.settings().setUseStandardTrackingProtection()
context.components.core.createTrackingProtectionPolicy()
context.components.useCases.settingsUseCases.updateTrackingProtection(
context.components.core.createTrackingProtectionPolicy()
)
}
else -> {
// No branch matches so we're defaulting to strict
context.settings().setUseStrictTrackingProtection()
context.components.useCases.settingsUseCases.updateTrackingProtection(
context.components.core.createTrackingProtectionPolicy()
)
}
}
}
}
}

@ -17,7 +17,6 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import mozilla.appservices.Megazord
import mozilla.components.concept.push.PushProcessor
import mozilla.components.service.experiments.Experiments
@ -101,6 +100,8 @@ open class FenixApplication : Application() {
ExperimentsMetrics.activeExperiment.set(branchName)
}
ExperimentsManager.initEtpExperiment(this)
setupLeakCanary()
if (settings().isTelemetryEnabled) {
components.analytics.metrics.start()
@ -145,37 +146,6 @@ open class FenixApplication : Application() {
}
}
/**
* Wait until all experiments are loaded
*
* This function will cause the caller to block until the experiments are loaded.
* It could be used in any number of reasons, but the most likely scenario is that
* a calling function needs to access the loaded experiments and wants to
* make sure that the experiments are loaded from the server before doing so.
*
* Because this function is synchronized, it can only be accessed by one thread
* at a time. Anyone trying to check the loaded status will wait if someone is
* already waiting. This is okay because the thread waiting for access to the
* function will immediately see that the loader is complete upon gaining the
* opportunity to run the function.
*/
@Synchronized
public fun waitForExperimentsToLoad() {
// Do we know that we are already complete?
if (!experimentLoaderComplete) {
// No? Have we completed since the last call?
if (!experimentLoader.isCompleted) {
// No? Well, let's wait.
runBlocking {
experimentLoader.await()
}
}
// Set this so we don't have to wait on the next call.
experimentLoaderComplete = true
}
}
protected open fun setupLeakCanary() {
// no-op, LeakCanary is disabled by default
}

@ -32,7 +32,7 @@ import java.security.InvalidParameterException
/**
* A simple wrapper for SharedPreferences that makes reading preference a little bit easier.
*/
@Suppress("LargeClass")
@Suppress("LargeClass", "TooManyFunctions")
class Settings private constructor(
context: Context,
private val isCrashReportEnabledInBuild: Boolean
@ -107,10 +107,10 @@ class Settings private constructor(
val isCrashReportingEnabled: Boolean
get() = isCrashReportEnabledInBuild &&
preferences.getBoolean(
appContext.getPreferenceKey(R.string.pref_key_crash_reporter),
true
)
preferences.getBoolean(
appContext.getPreferenceKey(R.string.pref_key_crash_reporter),
true
)
val isRemoteDebuggingEnabled by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_remote_debugging),
@ -136,7 +136,7 @@ class Settings private constructor(
val shouldShowTrackingProtectionOnboarding: Boolean
get() = trackingProtectionOnboardingCount < trackingProtectionOnboardingMaximumCount &&
!trackingProtectionOnboardingShownThisSession
!trackingProtectionOnboardingShownThisSession
val shouldAutoBounceQuickActionSheet: Boolean
get() = autoBounceQuickActionSheetCount < autoBounceMaximumCount
@ -201,6 +201,32 @@ class Settings private constructor(
true
)
fun setUseStrictTrackingProtection() {
preferences.edit()
.putBoolean(
appContext.getPreferenceKey(R.string.pref_key_tracking_protection_standard),
false
)
.putBoolean(
appContext.getPreferenceKey(R.string.pref_key_tracking_protection_strict),
true
)
.apply()
}
fun setUseStandardTrackingProtection() {
preferences.edit()
.putBoolean(
appContext.getPreferenceKey(R.string.pref_key_tracking_protection_standard),
true
)
.putBoolean(
appContext.getPreferenceKey(R.string.pref_key_tracking_protection_strict),
false
)
.apply()
}
var shouldDeleteBrowsingDataOnQuit by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_delete_browsing_data_on_quit),
default = false
@ -334,7 +360,7 @@ class Settings private constructor(
val showCondition =
(numTimesPrivateModeOpened == CFR_COUNT_CONDITION_FOCUS_INSTALLED && focusInstalled) ||
(numTimesPrivateModeOpened == CFR_COUNT_CONDITION_FOCUS_NOT_INSTALLED && !focusInstalled)
(numTimesPrivateModeOpened == CFR_COUNT_CONDITION_FOCUS_NOT_INSTALLED && !focusInstalled)
if (showCondition && !showedPrivateModeContextualFeatureRecommender) {
showedPrivateModeContextualFeatureRecommender = true

@ -0,0 +1,38 @@
# Experiments
Fenix uses Mozilla's [Experiments service for experimentation](https://github.com/mozilla-mobile/android-components/blob/master/components/service/experiments/README.md).
## Experiment Naming
Naming must be unique and under 100 characters.
Name experiments in the format of ""fenix_{experiment}_{issue}"", such as "fenix_etp_5651". Multiple word experiment titles should be snake cased.
Branches should be descriptive of the control and treatment.
Example:
Experiment: "fenix_buttonColor_1"
Branches: "control_blue", "treatment_green"
## Applying Experiment Branches
The Fenix engineer should [check for if a user is in and experiment and then apply the branches of this experiment](https://github.com/mozilla-mobile/android-components/blob/master/components/service/experiments/README.md#checking-if-a-user-is-part-of-an-experiment).
See [no-op experiment example](https://github.com/mozilla-mobile/fenix/pull/4551) and [ETP example](https://github.com/mozilla-mobile/fenix/pull/5723).
## Experimenter
[Experimenter](https://experimenter.services.mozilla.com/) is the web application for managing user experiments for Mozilla. It is intended to store information related to the design and status of experiments, and can be used to communicate about the experiment with other involved teams.
Once the Fenix engineer has added the experiment branches to Fenix, they should update the experiment in Experimenter with the unique experiment name, unique branch names, and version code for experiment to take place.
Once required steps have been completed and checked off, clicking the "ready to ship" button will alert the data team they can set up the experiment.
## Data Review
As long as the experiments is using existing telemetry probes, it does not need additional data review. If the experiment requires adding new telemetry/metrics, a data review will additionally have to be filled out and completed in Experimenter.
## QA
QA should test experiments before we turn them on and should verify opting out of experiments works as well. More details on testing experiments [here](https://github.com/mozilla-mobile/android-components/tree/master/components/service/experiments#testing-experiments)
## Experiment Opt Out
Users can opt out of experiments at any time via Settings -> Data collection
Loading…
Cancel
Save