For #9488: Add experimentation support
parent
54df729fb3
commit
42f58a1984
|
@ -501,6 +501,7 @@ dependencies {
|
||||||
implementation Deps.mozilla_feature_webcompat
|
implementation Deps.mozilla_feature_webcompat
|
||||||
implementation Deps.mozilla_feature_webnotifications
|
implementation Deps.mozilla_feature_webnotifications
|
||||||
|
|
||||||
|
implementation Deps.mozilla_service_experiments
|
||||||
implementation Deps.mozilla_service_sync_logins
|
implementation Deps.mozilla_service_sync_logins
|
||||||
implementation Deps.mozilla_service_firefox_accounts
|
implementation Deps.mozilla_service_firefox_accounts
|
||||||
implementation Deps.mozilla_service_glean
|
implementation Deps.mozilla_service_glean
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
/* 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.settings
|
||||||
|
|
||||||
|
object ExperimentsManager {
|
||||||
|
|
||||||
|
fun optOutSearchWidgetExperiment(context: Context) {
|
||||||
|
// Release user has opted out of search widget CFR experiment, reset them to not see it.
|
||||||
|
context.settings().setSearchWidgetExperiment(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun initSearchWidgetExperiment(context: Context) {
|
||||||
|
// When the `search-widget-discoverability` experiment is active,set the pref to either
|
||||||
|
// show or hide the search widget CFR (given other criteria are met as well).
|
||||||
|
// 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-search-widget") { branchName ->
|
||||||
|
when (branchName) {
|
||||||
|
"control_no_cfr" -> {
|
||||||
|
context.settings().setSearchWidgetExperiment(false)
|
||||||
|
}
|
||||||
|
"treatment_cfr" -> {
|
||||||
|
context.settings().setSearchWidgetExperiment(true)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
// No branch matches so we're defaulting to no CFR
|
||||||
|
context.settings().setSearchWidgetExperiment(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,6 +23,7 @@ import mozilla.components.browser.session.Session
|
||||||
import mozilla.components.concept.push.PushProcessor
|
import mozilla.components.concept.push.PushProcessor
|
||||||
import mozilla.components.feature.addons.update.GlobalAddonDependencyProvider
|
import mozilla.components.feature.addons.update.GlobalAddonDependencyProvider
|
||||||
import mozilla.components.lib.crash.CrashReporter
|
import mozilla.components.lib.crash.CrashReporter
|
||||||
|
import mozilla.components.service.experiments.Experiments
|
||||||
import mozilla.components.service.glean.Glean
|
import mozilla.components.service.glean.Glean
|
||||||
import mozilla.components.service.glean.config.Configuration
|
import mozilla.components.service.glean.config.Configuration
|
||||||
import mozilla.components.service.glean.net.ConceptFetchHttpUploader
|
import mozilla.components.service.glean.net.ConceptFetchHttpUploader
|
||||||
|
@ -162,10 +163,31 @@ open class FenixApplication : LocaleAwareApplication() {
|
||||||
// runStorageMaintenance()
|
// runStorageMaintenance()
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
val taskQueue = components.performance.visualCompletenessQueue
|
||||||
registerActivityLifecycleCallbacks(
|
registerActivityLifecycleCallbacks(
|
||||||
PerformanceActivityLifecycleCallbacks(components.performance.visualCompletenessQueue)
|
PerformanceActivityLifecycleCallbacks(taskQueue)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Enable the service-experiments component to be initialized after visual completeness
|
||||||
|
// for performance wins.
|
||||||
|
if (settings().isExperimentationEnabled && Config.channel.isReleaseOrBeta) {
|
||||||
|
taskQueue.runIfReadyOrQueue {
|
||||||
|
Experiments.initialize(
|
||||||
|
applicationContext = applicationContext,
|
||||||
|
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
|
||||||
|
ExperimentsManager.optOutSearchWidgetExperiment(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
ExperimentsManager.initSearchWidgetExperiment(this)
|
||||||
|
|
||||||
components.performance.visualCompletenessQueue.runIfReadyOrQueue {
|
components.performance.visualCompletenessQueue.runIfReadyOrQueue {
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
logger.info("Running post-visual completeness tasks...")
|
logger.info("Running post-visual completeness tasks...")
|
||||||
|
@ -394,4 +416,8 @@ open class FenixApplication : LocaleAwareApplication() {
|
||||||
applicationContext.resources.configuration.uiMode = config.uiMode
|
applicationContext.resources.configuration.uiMode = config.uiMode
|
||||||
super.onConfigurationChanged(config)
|
super.onConfigurationChanged(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val KINTO_ENDPOINT_PROD = "https://firefox.settings.services.mozilla.com/v1"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@ import androidx.core.view.marginTop
|
||||||
import kotlinx.android.synthetic.main.search_widget_cfr.view.*
|
import kotlinx.android.synthetic.main.search_widget_cfr.view.*
|
||||||
import kotlinx.android.synthetic.main.tracking_protection_onboarding_popup.view.drop_down_triangle
|
import kotlinx.android.synthetic.main.tracking_protection_onboarding_popup.view.drop_down_triangle
|
||||||
import kotlinx.android.synthetic.main.tracking_protection_onboarding_popup.view.pop_up_triangle
|
import kotlinx.android.synthetic.main.tracking_protection_onboarding_popup.view.pop_up_triangle
|
||||||
import org.mozilla.fenix.FeatureFlags
|
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.components.SearchWidgetCreator
|
import org.mozilla.fenix.components.SearchWidgetCreator
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
|
@ -34,7 +33,8 @@ class SearchWidgetCFR(
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun displayIfNecessary() {
|
fun displayIfNecessary() {
|
||||||
if (!context.settings().shouldDisplaySearchWidgetCFR() || !FeatureFlags.searchWidgetCFR) { return }
|
if (!context.settings().isInSearchWidgetExperiment ||
|
||||||
|
!context.settings().shouldDisplaySearchWidgetCFR()) { return }
|
||||||
showSearchWidgetCFR()
|
showSearchWidgetCFR()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,11 +23,7 @@ object SearchWidgetCreator {
|
||||||
@TargetApi(Build.VERSION_CODES.O)
|
@TargetApi(Build.VERSION_CODES.O)
|
||||||
fun createSearchWidget(context: Context): Boolean {
|
fun createSearchWidget(context: Context): Boolean {
|
||||||
val appWidgetManager: AppWidgetManager = context.getSystemService(AppWidgetManager::class.java)
|
val appWidgetManager: AppWidgetManager = context.getSystemService(AppWidgetManager::class.java)
|
||||||
if (!appWidgetManager.isRequestPinAppWidgetSupported) { return false }
|
|
||||||
|
|
||||||
val myProvider = ComponentName(context, SearchWidgetProvider::class.java)
|
val myProvider = ComponentName(context, SearchWidgetProvider::class.java)
|
||||||
appWidgetManager.requestPinAppWidget(myProvider, null, null)
|
return appWidgetManager.requestPinAppWidget(myProvider, null, null)
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,6 +208,18 @@ class Settings private constructor(
|
||||||
).apply()
|
).apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val isInSearchWidgetExperiment by booleanPreference(
|
||||||
|
appContext.getPreferenceKey(R.string.pref_key_is_in_search_widget_experiment),
|
||||||
|
default = false
|
||||||
|
)
|
||||||
|
|
||||||
|
fun setSearchWidgetExperiment(value: Boolean) {
|
||||||
|
preferences.edit().putBoolean(
|
||||||
|
appContext.getPreferenceKey(R.string.pref_key_is_in_search_widget_experiment),
|
||||||
|
value
|
||||||
|
).apply()
|
||||||
|
}
|
||||||
|
|
||||||
var defaultSearchEngineName by stringPreference(
|
var defaultSearchEngineName by stringPreference(
|
||||||
appContext.getPreferenceKey(R.string.pref_key_search_engine),
|
appContext.getPreferenceKey(R.string.pref_key_search_engine),
|
||||||
default = ""
|
default = ""
|
||||||
|
|
|
@ -177,5 +177,6 @@
|
||||||
<string name="pref_key_search_widget_cfr_display_count" translatable="false">pref_key_search_widget_cfr_display_count</string>
|
<string name="pref_key_search_widget_cfr_display_count" translatable="false">pref_key_search_widget_cfr_display_count</string>
|
||||||
<string name="pref_key_search_widget_cfr_dismiss_count" translatable="false">pref_key_search_widget_cfr_dismiss_count</string>
|
<string name="pref_key_search_widget_cfr_dismiss_count" translatable="false">pref_key_search_widget_cfr_dismiss_count</string>
|
||||||
<string name="pref_key_search_widget_cfr_manually_dismissed" translatable="false">pref_key_search_widget_cfr_manually_dismissed</string>
|
<string name="pref_key_search_widget_cfr_manually_dismissed" translatable="false">pref_key_search_widget_cfr_manually_dismissed</string>
|
||||||
|
<string name="pref_key_is_in_search_widget_experiment" translatable="false">pref_key_is_in_search_widget_experiment</string>
|
||||||
<string name="pref_key_show_search_widget_cfr" translatable="false">pref_key_show_search_widget_cfr</string>
|
<string name="pref_key_show_search_widget_cfr" translatable="false">pref_key_show_search_widget_cfr</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -115,6 +115,8 @@ object Deps {
|
||||||
const val mozilla_feature_webcompat = "org.mozilla.components:feature-webcompat:${Versions.mozilla_android_components}"
|
const val mozilla_feature_webcompat = "org.mozilla.components:feature-webcompat:${Versions.mozilla_android_components}"
|
||||||
const val mozilla_feature_webnotifications = "org.mozilla.components:feature-webnotifications:${Versions.mozilla_android_components}"
|
const val mozilla_feature_webnotifications = "org.mozilla.components:feature-webnotifications:${Versions.mozilla_android_components}"
|
||||||
|
|
||||||
|
const val mozilla_service_experiments =
|
||||||
|
"org.mozilla.components:service-experiments:${Versions.mozilla_android_components}"
|
||||||
const val mozilla_service_sync_logins =
|
const val mozilla_service_sync_logins =
|
||||||
"org.mozilla.components:service-sync-logins:${Versions.mozilla_android_components}"
|
"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_firefox_accounts = "org.mozilla.components:service-firefox-accounts:${Versions.mozilla_android_components}"
|
||||||
|
|
Loading…
Reference in New Issue