Skip to content
This repository has been archived by the owner on Jan 12, 2023. It is now read-only.

Commit

Permalink
For #6387 - Migrate multi-tabs experiment to feature manifest language
Browse files Browse the repository at this point in the history
  • Loading branch information
Ionut Cristian Bedregeanu authored and mergify[bot] committed May 4, 2022
1 parent 47bea07 commit e3869f7
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 41 deletions.
35 changes: 35 additions & 0 deletions .experimenter.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"tabs": {
"description": "Nimbus feature name intended to control the multiple tabs feature in the app.",
"hasExposure": true,
"exposureDescription": "",
"variables": {
"is_multi_tab": {
"description": "Nimbus variable of [FEATURE_TABS] allowing outside control of whether the multiple tabs feature should be enabled or not.",
"type": "boolean"
}
}
},
"onboarding-with-cfrs": {
"description": "Nimbus feature name intended to control the onboarding plus all CFRs in the app.",
"hasExposure": true,
"exposureDescription": "",
"variables": {
"is-onboarding-with-cfrs": {
"description": "If `true`, the app will show the new onboarding screen and all the cfrs",
"type": "boolean"
}
}
},
"onboarding-without-cfrs": {
"description": "Nimbus feature name intended to control the onboarding without CFRs in the app.",
"hasExposure": true,
"exposureDescription": "",
"variables": {
"is-onboarding-without-cfrs": {
"description": "If `true`, the app will show only the new onboarding screen",
"type": "boolean"
}
}
}
}
26 changes: 26 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,32 @@ tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
// Generate Kotlin code for the Focus Glean metrics.
// -------------------------------------------------------------------------------------------------
apply plugin: "org.mozilla.telemetry.glean-gradle-plugin"
apply plugin: "org.mozilla.components.nimbus-gradle-plugin"

nimbus {
// The path to the Nimbus feature manifest file
manifestFile = "nimbus.fml.yaml"
// The fully qualified class name for the generated features.
// If the classname begins with a '.' this is taken as a suffix to the app's package name
destinationClass = ".nimbus.FocusNimbus"
// Map from the variant name to the channel as experimenter and nimbus understand it.
// If nimbus's channels were accurately set up well for this project, then this
// shouldn't be needed.
channels = [
focusDebug: "debug",
focusNightly: "nightly",
focusBeta: "beta",
focusRelease: "release",
klarDebug: "debug",
klarNightly: "nightly",
klarBeta: "beta",
klarRelease: "release"
]
// This is generated by the FML and should be checked into git.
// It will be fetched by Experimenter (the Nimbus experiment website)
// and used to inform experiment configuration.
experimenterManifest = ".experimenter.json"
}

configurations {
// There's an interaction between Gradle's resolution of dependencies with different types
Expand Down
7 changes: 6 additions & 1 deletion app/src/main/java/org/mozilla/focus/Components.kt
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ import org.mozilla.focus.experiments.createNimbus
import org.mozilla.focus.ext.components
import org.mozilla.focus.ext.settings
import org.mozilla.focus.media.MediaSessionService
import org.mozilla.focus.nimbus.FocusNimbus
import org.mozilla.focus.notification.PrivateNotificationMiddleware
import org.mozilla.focus.search.SearchFilterMiddleware
import org.mozilla.focus.search.SearchMigration
Expand Down Expand Up @@ -186,7 +187,11 @@ class Components(

val metrics: GleanMetricsService by lazy { GleanMetricsService(context) }

val experiments: NimbusApi by lazy { createNimbus(context, BuildConfig.NIMBUS_ENDPOINT) }
val experiments: NimbusApi by lazy {
createNimbus(context, BuildConfig.NIMBUS_ENDPOINT).also { api ->
FocusNimbus.api = api
}
}

val adsTelemetry: AdsTelemetry by lazy { AdsTelemetry() }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ import mozilla.components.feature.contextmenu.ContextMenuCandidate
import mozilla.components.feature.contextmenu.ContextMenuUseCases
import mozilla.components.feature.contextmenu.DefaultSnackbarDelegate
import mozilla.components.feature.tabs.TabsUseCases
import org.mozilla.focus.ext.FEATURE_TABS
import org.mozilla.focus.ext.components
import org.mozilla.focus.ext.isMultiTabsEnabled
import org.mozilla.focus.nimbus.FocusNimbus

object ContextMenuCandidates {
@Suppress("LongParameterList")
Expand All @@ -25,8 +23,7 @@ object ContextMenuCandidates {
snackBarParentView: View,
snackbarDelegate: ContextMenuCandidate.SnackbarDelegate = DefaultSnackbarDelegate()
): List<ContextMenuCandidate> =
if (context.components.experiments.isMultiTabsEnabled) {
context.components.experiments.recordExposureEvent(FEATURE_TABS)
if (FocusNimbus.features.tabs.value().isMultiTab) {
listOf(
ContextMenuCandidate.createOpenInPrivateTabCandidate(
context,
Expand All @@ -42,8 +39,7 @@ object ContextMenuCandidates {
ContextMenuCandidate.createDownloadLinkCandidate(context, contextMenuUseCases),
ContextMenuCandidate.createShareLinkCandidate(context),
ContextMenuCandidate.createShareImageCandidate(context, contextMenuUseCases)
) + if (context.components.experiments.isMultiTabsEnabled) {
context.components.experiments.recordExposureEvent(FEATURE_TABS)
) + if (FocusNimbus.features.tabs.value().isMultiTab) {
listOf(
ContextMenuCandidate.createOpenImageInNewTabCandidate(
context,
Expand Down
26 changes: 0 additions & 26 deletions app/src/main/java/org/mozilla/focus/ext/Nimbus.kt
Original file line number Diff line number Diff line change
@@ -1,26 +0,0 @@
/* 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.focus.ext

import mozilla.components.service.nimbus.NimbusApi

/**
* Nimbus feature name intended to control the multiple tabs feature in the app.
*/
const val FEATURE_TABS = "tabs"

/**
* Nimbus variable of [FEATURE_TABS] allowing outside control of whether the multiple tabs feature
* should be enabled or not.
*/
private const val VARIABLE_IS_MULTI_TAB = "is_multi_tab"

/**
* Whether the multiple tabs feature support is enabled or not.
* Defaults to `true`. May be overridden by a Nimbus experiment.
*/
val NimbusApi.isMultiTabsEnabled
get() = getVariables(featureId = FEATURE_TABS, recordExposureEvent = false)
.getBool(VARIABLE_IS_MULTI_TAB) ?: true
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,12 @@ import org.mozilla.focus.ext.disableDynamicBehavior
import org.mozilla.focus.ext.enableDynamicBehavior
import org.mozilla.focus.ext.ifCustomTab
import org.mozilla.focus.ext.isCustomTab
import org.mozilla.focus.ext.isMultiTabsEnabled
import org.mozilla.focus.ext.requireComponents
import org.mozilla.focus.ext.settings
import org.mozilla.focus.ext.showAsFixed
import org.mozilla.focus.ext.titleOrDomain
import org.mozilla.focus.menu.browser.DefaultBrowserMenu
import org.mozilla.focus.nimbus.FocusNimbus
import org.mozilla.focus.open.OpenWithFragment
import org.mozilla.focus.session.ui.TabsPopup
import org.mozilla.focus.settings.permissions.permissionoptions.SitePermissionOptionsStorage
Expand Down Expand Up @@ -749,7 +749,7 @@ class BrowserFragment :

TelemetryWrapper.openFullBrowser()

if (requireComponents.experiments.isMultiTabsEnabled) {
if (FocusNimbus.features.tabs.value().isMultiTab) {
requireComponents.customTabsUseCases.migrate(tab.id)
requireComponents.experiments.recordExposureEvent(FEATURE_TABS)
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ import mozilla.components.browser.state.state.TabSessionState
import mozilla.components.concept.engine.EngineSession
import mozilla.components.lib.state.Middleware
import mozilla.components.lib.state.MiddlewareContext
import org.mozilla.focus.ext.FEATURE_TABS
import org.mozilla.focus.ext.components
import org.mozilla.focus.ext.isMultiTabsEnabled
import org.mozilla.focus.nimbus.FocusNimbus

/**
* If the tabs feature is disabled then this middleware will look at incoming [TabListAction.AddTabAction]
Expand All @@ -31,10 +29,9 @@ class MergeTabsMiddleware(
next: (BrowserAction) -> Unit,
action: BrowserAction
) {
if (this.context.components.experiments.isMultiTabsEnabled || action !is TabListAction.AddTabAction) {
if (FocusNimbus.features.tabs.value().isMultiTab || action !is TabListAction.AddTabAction) {
// If the feature flag for tabs is enabled then we can just let the reducer create a
// new tab.
this.context.components.experiments.recordExposureEvent(FEATURE_TABS)
next(action)
return
}
Expand Down
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ buildscript {
classpath Dependencies.android_gradle_plugin
classpath Dependencies.kotlin_gradle_plugin
classpath "org.mozilla.components:tooling-glean-gradle:${AndroidComponents.VERSION}"
classpath "org.mozilla.components:tooling-nimbus-gradle:${AndroidComponents.VERSION}"

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
Expand Down
30 changes: 30 additions & 0 deletions nimbus.fml.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
channels:
- debug
- nightly
- beta
- release
features:
tabs:
description: Nimbus feature name intended to control the multiple tabs feature in the app.
variables:
is_multi_tab:
description: Nimbus variable of [FEATURE_TABS] allowing outside control of whether the multiple tabs feature should be enabled or not.
type: Boolean
default: true
onboarding-with-cfrs:
description: Nimbus feature name intended to control the onboarding plus all CFRs in the app.
variables:
is-onboarding-with-cfrs:
description: If `true`, the app will show the new onboarding screen and all the cfrs
type: Boolean
default: true
onboarding-without-cfrs:
description: Nimbus feature name intended to control the onboarding without CFRs in the app.
variables:
is-onboarding-without-cfrs:
description: If `true`, the app will show only the new onboarding screen
type: Boolean
default: false
types:
objects: {}
enums: {}

0 comments on commit e3869f7

Please sign in to comment.