Commit 956bc5f9 authored by MozLando's avatar MozLando
Browse files

Merge #6961

6961: Closes #6862: Migrate feature-accounts to browser-state r=grigoryk a=csadilek

For the FxA web channel, we don't need to connect to the content script if tabs are opened in the background (e.g. via long press->open in new tab) so I removed that code. The port is disconnected automatically when the window is "unloaded".

The actual change here is minimal, it's mostly the tests, which I refactored to reduce duplication.

Tested manually in Fenix as well.
Co-authored-by: default avatarChristian Sadilek <>
parents b37e56ca 324a32c3
......@@ -21,13 +21,19 @@ android {
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
kotlinOptions.freeCompilerArgs += [
dependencies {
implementation Dependencies.kotlin_coroutines
implementation Dependencies.androidx_work_runtime
implementation Dependencies.androidx_lifecycle_extensions
implementation project(':concept-engine')
implementation project(":browser-session")
implementation project(":browser-state")
implementation project(':feature-tabs')
implementation project(':service-firefox-accounts')
implementation project(':support-ktx')
......@@ -6,14 +6,18 @@ package mozilla.components.feature.accounts
import android.content.Context
import androidx.annotation.VisibleForTesting
import mozilla.components.browser.session.SelectionAwareSessionObserver
import mozilla.components.browser.session.Session
import mozilla.components.browser.session.SessionManager
import mozilla.components.browser.session.runWithSessionIdOrSelected
import mozilla.components.concept.engine.Engine
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.mapNotNull
import mozilla.components.browser.state.selector.findCustomTabOrSelectedTab
import mozilla.components.concept.engine.EngineSession
import mozilla.components.concept.engine.webextension.MessageHandler
import mozilla.components.concept.engine.webextension.Port
import mozilla.components.concept.engine.webextension.WebExtensionRuntime
import mozilla.components.concept.sync.AuthType
import mozilla.components.lib.state.ext.flowScoped
import mozilla.components.service.fxa.FxaAuthData
import mozilla.components.service.fxa.ServerConfig
import mozilla.components.service.fxa.SyncEngine
......@@ -23,6 +27,7 @@ import mozilla.components.service.fxa.toAuthType
import org.json.JSONArray
import org.json.JSONException
......@@ -45,43 +50,43 @@ enum class FxaCapability {
* @property context a reference to the context.
* @property customTabSessionId optional custom tab session ID, if feature is being used with a custom tab.
* @property engine a reference to application's browser engine.
* @property sessionManager a reference to application's [SessionManager].
* @property runtime the [WebExtensionRuntime] (e.g the browser engine) to use.
* @property store a reference to the application's [BrowserStore].
* @property accountManager a reference to application's [FxaAccountManager].
* @property fxaCapabilities a set of [FxaCapability] that client supports.
class FxaWebChannelFeature(
private val context: Context,
private val customTabSessionId: String?,
private val engine: Engine,
private val sessionManager: SessionManager,
private val runtime: WebExtensionRuntime,
private val store: BrowserStore,
private val accountManager: FxaAccountManager,
private val serverConfig: ServerConfig,
private val fxaCapabilities: Set<FxaCapability> = emptySet()
) : SelectionAwareSessionObserver(sessionManager), LifecycleAwareFeature {
) : LifecycleAwareFeature {
private var scope: CoroutineScope? = null
// This is an internal var to make it mutable for unit testing purposes only
internal var extensionController = WebExtensionController(WEB_CHANNEL_EXTENSION_ID, WEB_CHANNEL_EXTENSION_URL)
override fun start() {
// Runs observeSelected (if we're not in a custom tab) or observeFixed (if we are).
sessionManager.runWithSessionIdOrSelected(customTabSessionId) { session ->
scope = store.flowScoped { flow ->
flow.mapNotNull { state -> state.findCustomTabOrSelectedTab(customTabSessionId) }
.ifChanged { it.engineState.engineSession }
.collect {
it.engineState.engineSession?.let { engineSession ->
override fun onSessionAdded(session: Session) {
override fun onSessionRemoved(session: Session) {
override fun stop() {
@Suppress("MaxLineLength", "")
......@@ -151,8 +156,7 @@ class FxaWebChannelFeature(
private fun registerFxaContentMessageHandler(session: Session) {
val engineSession = sessionManager.getOrCreateEngineSession(session)
private fun registerFxaContentMessageHandler(engineSession: EngineSession) {
val messageHandler = WebChannelViewContentMessageHandler(accountManager, serverConfig, fxaCapabilities)
extensionController.registerContentMessageHandler(engineSession, messageHandler)
......@@ -46,6 +46,9 @@ permalink: /changelog/
* ⚠️ **This is a breaking change**: glinter errors found during code generation will now return an error code.
* The minimum and maximum values of a timing distribution can now be controlled by the `time_unit` parameter. See [bug 1630997]( for more details.
* **feature-accounts**
* ⚠️ **This is a breaking change**: Refactored component to use `browser-state` instead of `browser-session`. The `FxaWebChannelFeature` now requires a `BrowserStore` instance instead of a `SessionManager`.
* **browser-toolbar**
* It will only be animated for vertical scrolls inside the EngineView. Not for horizontal scrolls. Not for zoom gestures.
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment