1
0
Fork 0

For #9488: Add experimentation support

master
Sawyer Blatz 2020-05-28 09:37:45 -07:00
parent 54df729fb3
commit 42f58a1984
8 changed files with 85 additions and 8 deletions

View File

@ -501,6 +501,7 @@ dependencies {
implementation Deps.mozilla_feature_webcompat
implementation Deps.mozilla_feature_webnotifications
implementation Deps.mozilla_service_experiments
implementation Deps.mozilla_service_sync_logins
implementation Deps.mozilla_service_firefox_accounts
implementation Deps.mozilla_service_glean

View File

@ -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)
}
}
}
}
}

View File

@ -23,6 +23,7 @@ import mozilla.components.browser.session.Session
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
@ -162,10 +163,31 @@ open class FenixApplication : LocaleAwareApplication() {
// runStorageMaintenance()
// }
val taskQueue = components.performance.visualCompletenessQueue
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 {
GlobalScope.launch(Dispatchers.IO) {
logger.info("Running post-visual completeness tasks...")
@ -394,4 +416,8 @@ open class FenixApplication : LocaleAwareApplication() {
applicationContext.resources.configuration.uiMode = config.uiMode
super.onConfigurationChanged(config)
}
companion object {
private const val KINTO_ENDPOINT_PROD = "https://firefox.settings.services.mozilla.com/v1"
}
}

View File

@ -17,7 +17,6 @@ import androidx.core.view.marginTop
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.pop_up_triangle
import org.mozilla.fenix.FeatureFlags
import org.mozilla.fenix.R
import org.mozilla.fenix.components.SearchWidgetCreator
import org.mozilla.fenix.components.metrics.Event
@ -34,7 +33,8 @@ class SearchWidgetCFR(
) {
fun displayIfNecessary() {
if (!context.settings().shouldDisplaySearchWidgetCFR() || !FeatureFlags.searchWidgetCFR) { return }
if (!context.settings().isInSearchWidgetExperiment ||
!context.settings().shouldDisplaySearchWidgetCFR()) { return }
showSearchWidgetCFR()
}

View File

@ -23,11 +23,7 @@ object SearchWidgetCreator {
@TargetApi(Build.VERSION_CODES.O)
fun createSearchWidget(context: Context): Boolean {
val appWidgetManager: AppWidgetManager = context.getSystemService(AppWidgetManager::class.java)
if (!appWidgetManager.isRequestPinAppWidgetSupported) { return false }
val myProvider = ComponentName(context, SearchWidgetProvider::class.java)
appWidgetManager.requestPinAppWidget(myProvider, null, null)
return true
return appWidgetManager.requestPinAppWidget(myProvider, null, null)
}
}

View File

@ -208,6 +208,18 @@ class Settings private constructor(
).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(
appContext.getPreferenceKey(R.string.pref_key_search_engine),
default = ""

View File

@ -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_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_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>
</resources>

View File

@ -115,6 +115,8 @@ object Deps {
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_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}"