Loading components/feature/syncedtabs/src/main/java/mozilla/components/feature/syncedtabs/SyncedTabsFeature.kt 0 → 100644 +72 −0 Original line number Diff line number Diff line /* 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 mozilla.components.feature.syncedtabs import androidx.lifecycle.LifecycleOwner import kotlinx.coroutines.Dispatchers import mozilla.components.browser.storage.sync.Tab import mozilla.components.feature.syncedtabs.controller.DefaultController import mozilla.components.feature.syncedtabs.controller.SyncedTabsController import mozilla.components.feature.syncedtabs.interactor.DefaultInteractor import mozilla.components.feature.syncedtabs.interactor.SyncedTabsInteractor import mozilla.components.feature.syncedtabs.presenter.DefaultPresenter import mozilla.components.feature.syncedtabs.presenter.SyncedTabsPresenter import mozilla.components.feature.syncedtabs.storage.SyncedTabsStorage import mozilla.components.feature.syncedtabs.view.SyncedTabsView import mozilla.components.service.fxa.manager.FxaAccountManager import mozilla.components.support.base.feature.LifecycleAwareFeature import kotlin.coroutines.CoroutineContext /** * Feature implementation that will keep a [SyncedTabsView] notified with other synced device tabs for * the Firefox Sync account. * * @param storage The synced tabs storage that stores the current device's and remote device tabs. * @param accountManager Firefox Account Manager that holds a Firefox Sync account. * @param view An implementor of [SyncedTabsView] that will be notified of changes. * @param lifecycleOwner Android Lifecycle Owner to bind observers onto. * @param coroutineContext A coroutine context that can be used to perform work off the main thread. * @param onTabClicked Invoked when a tab is selected by the user on the [SyncedTabsView]. * @param controller See [SyncedTabsController]. * @param presenter See [SyncedTabsPresenter]. * @param interactor See [SyncedTabsInteractor]. */ class SyncedTabsFeature( storage: SyncedTabsStorage, accountManager: FxaAccountManager, view: SyncedTabsView, lifecycleOwner: LifecycleOwner, coroutineContext: CoroutineContext = Dispatchers.IO, onTabClicked: (Tab) -> Unit, controller: SyncedTabsController = DefaultController( storage, accountManager, view, coroutineContext ), private val presenter: SyncedTabsPresenter = DefaultPresenter( controller, accountManager, view, lifecycleOwner ), private val interactor: SyncedTabsInteractor = DefaultInteractor( accountManager, view, coroutineContext, onTabClicked ) ) : LifecycleAwareFeature { override fun start() { presenter.start() interactor.start() } override fun stop() { presenter.stop() interactor.stop() } } components/feature/syncedtabs/src/main/java/mozilla/components/feature/syncedtabs/SyncedTabsStorageSuggestionProvider.kt +1 −1 Original line number Diff line number Diff line Loading @@ -4,12 +4,12 @@ package mozilla.components.feature.syncedtabs import kotlinx.coroutines.ExperimentalCoroutinesApi import mozilla.components.browser.icons.BrowserIcons import mozilla.components.browser.icons.IconRequest import mozilla.components.browser.storage.sync.TabEntry import mozilla.components.concept.awesomebar.AwesomeBar import mozilla.components.feature.session.SessionUseCases import mozilla.components.feature.syncedtabs.storage.SyncedTabsStorage import java.util.UUID /** Loading components/feature/syncedtabs/src/main/java/mozilla/components/feature/syncedtabs/controller/DefaultController.kt 0 → 100644 +48 −0 Original line number Diff line number Diff line /* 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 mozilla.components.feature.syncedtabs.controller import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import mozilla.components.feature.syncedtabs.storage.SyncedTabsProvider import mozilla.components.feature.syncedtabs.view.SyncedTabsView import mozilla.components.feature.syncedtabs.view.SyncedTabsView.ErrorType import mozilla.components.service.fxa.manager.FxaAccountManager import mozilla.components.service.fxa.manager.ext.withConstellation import kotlin.coroutines.CoroutineContext internal class DefaultController( override val provider: SyncedTabsProvider, override val accountManager: FxaAccountManager, override val view: SyncedTabsView, private val coroutineContext: CoroutineContext ) : SyncedTabsController { override fun syncTabs() { view.startLoading() val scope = CoroutineScope(coroutineContext) scope.launch { accountManager.withConstellation { val syncedTabs = provider.getSyncedTabs() val otherDevices = state()?.otherDevices scope.launch(Dispatchers.Main) { if (syncedTabs.isEmpty() && otherDevices?.isEmpty() == true) { view.onError(ErrorType.MULTIPLE_DEVICES_UNAVAILABLE) } else { view.displaySyncedTabs(syncedTabs) } } } scope.launch(Dispatchers.Main) { view.stopLoading() } } } } components/feature/syncedtabs/src/main/java/mozilla/components/feature/syncedtabs/controller/SyncedTabsController.kt 0 → 100644 +25 −0 Original line number Diff line number Diff line /* 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 mozilla.components.feature.syncedtabs.controller import mozilla.components.feature.syncedtabs.storage.SyncedTabsProvider import mozilla.components.feature.syncedtabs.view.SyncedTabsView import mozilla.components.service.fxa.manager.FxaAccountManager /** * A controller for making the appropriate request for remote tabs from [SyncedTabsProvider] when the * [FxaAccountManager] account is in the appropriate state. The [SyncedTabsView] can then be notified. */ interface SyncedTabsController { val provider: SyncedTabsProvider val accountManager: FxaAccountManager val view: SyncedTabsView /** * Requests for remote tabs and notifies the [SyncedTabsView] when available with [SyncedTabsView.displaySyncedTabs] * otherwise notifies the appropriate error to [SyncedTabsView.onError]. */ fun syncTabs() } components/feature/syncedtabs/src/main/java/mozilla/components/feature/syncedtabs/interactor/DefaultInteractor.kt 0 → 100644 +43 −0 Original line number Diff line number Diff line /* 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 mozilla.components.feature.syncedtabs.interactor import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import mozilla.components.browser.storage.sync.Tab import mozilla.components.feature.syncedtabs.view.SyncedTabsView import mozilla.components.service.fxa.manager.FxaAccountManager import mozilla.components.service.fxa.manager.ext.withConstellation import mozilla.components.service.fxa.sync.SyncReason import kotlin.coroutines.CoroutineContext internal class DefaultInteractor( override val accountManager: FxaAccountManager, override val view: SyncedTabsView, private val coroutineContext: CoroutineContext, override val tabClicked: (Tab) -> Unit ) : SyncedTabsInteractor { override fun start() { view.listener = this } override fun stop() { view.listener = null } override fun onTabClicked(tab: Tab) { tabClicked(tab) } override fun onRefresh() { CoroutineScope(coroutineContext).launch { accountManager.withConstellation { refreshDevicesAsync() } accountManager.syncNowAsync(SyncReason.User, true) } } } Loading
components/feature/syncedtabs/src/main/java/mozilla/components/feature/syncedtabs/SyncedTabsFeature.kt 0 → 100644 +72 −0 Original line number Diff line number Diff line /* 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 mozilla.components.feature.syncedtabs import androidx.lifecycle.LifecycleOwner import kotlinx.coroutines.Dispatchers import mozilla.components.browser.storage.sync.Tab import mozilla.components.feature.syncedtabs.controller.DefaultController import mozilla.components.feature.syncedtabs.controller.SyncedTabsController import mozilla.components.feature.syncedtabs.interactor.DefaultInteractor import mozilla.components.feature.syncedtabs.interactor.SyncedTabsInteractor import mozilla.components.feature.syncedtabs.presenter.DefaultPresenter import mozilla.components.feature.syncedtabs.presenter.SyncedTabsPresenter import mozilla.components.feature.syncedtabs.storage.SyncedTabsStorage import mozilla.components.feature.syncedtabs.view.SyncedTabsView import mozilla.components.service.fxa.manager.FxaAccountManager import mozilla.components.support.base.feature.LifecycleAwareFeature import kotlin.coroutines.CoroutineContext /** * Feature implementation that will keep a [SyncedTabsView] notified with other synced device tabs for * the Firefox Sync account. * * @param storage The synced tabs storage that stores the current device's and remote device tabs. * @param accountManager Firefox Account Manager that holds a Firefox Sync account. * @param view An implementor of [SyncedTabsView] that will be notified of changes. * @param lifecycleOwner Android Lifecycle Owner to bind observers onto. * @param coroutineContext A coroutine context that can be used to perform work off the main thread. * @param onTabClicked Invoked when a tab is selected by the user on the [SyncedTabsView]. * @param controller See [SyncedTabsController]. * @param presenter See [SyncedTabsPresenter]. * @param interactor See [SyncedTabsInteractor]. */ class SyncedTabsFeature( storage: SyncedTabsStorage, accountManager: FxaAccountManager, view: SyncedTabsView, lifecycleOwner: LifecycleOwner, coroutineContext: CoroutineContext = Dispatchers.IO, onTabClicked: (Tab) -> Unit, controller: SyncedTabsController = DefaultController( storage, accountManager, view, coroutineContext ), private val presenter: SyncedTabsPresenter = DefaultPresenter( controller, accountManager, view, lifecycleOwner ), private val interactor: SyncedTabsInteractor = DefaultInteractor( accountManager, view, coroutineContext, onTabClicked ) ) : LifecycleAwareFeature { override fun start() { presenter.start() interactor.start() } override fun stop() { presenter.stop() interactor.stop() } }
components/feature/syncedtabs/src/main/java/mozilla/components/feature/syncedtabs/SyncedTabsStorageSuggestionProvider.kt +1 −1 Original line number Diff line number Diff line Loading @@ -4,12 +4,12 @@ package mozilla.components.feature.syncedtabs import kotlinx.coroutines.ExperimentalCoroutinesApi import mozilla.components.browser.icons.BrowserIcons import mozilla.components.browser.icons.IconRequest import mozilla.components.browser.storage.sync.TabEntry import mozilla.components.concept.awesomebar.AwesomeBar import mozilla.components.feature.session.SessionUseCases import mozilla.components.feature.syncedtabs.storage.SyncedTabsStorage import java.util.UUID /** Loading
components/feature/syncedtabs/src/main/java/mozilla/components/feature/syncedtabs/controller/DefaultController.kt 0 → 100644 +48 −0 Original line number Diff line number Diff line /* 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 mozilla.components.feature.syncedtabs.controller import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import mozilla.components.feature.syncedtabs.storage.SyncedTabsProvider import mozilla.components.feature.syncedtabs.view.SyncedTabsView import mozilla.components.feature.syncedtabs.view.SyncedTabsView.ErrorType import mozilla.components.service.fxa.manager.FxaAccountManager import mozilla.components.service.fxa.manager.ext.withConstellation import kotlin.coroutines.CoroutineContext internal class DefaultController( override val provider: SyncedTabsProvider, override val accountManager: FxaAccountManager, override val view: SyncedTabsView, private val coroutineContext: CoroutineContext ) : SyncedTabsController { override fun syncTabs() { view.startLoading() val scope = CoroutineScope(coroutineContext) scope.launch { accountManager.withConstellation { val syncedTabs = provider.getSyncedTabs() val otherDevices = state()?.otherDevices scope.launch(Dispatchers.Main) { if (syncedTabs.isEmpty() && otherDevices?.isEmpty() == true) { view.onError(ErrorType.MULTIPLE_DEVICES_UNAVAILABLE) } else { view.displaySyncedTabs(syncedTabs) } } } scope.launch(Dispatchers.Main) { view.stopLoading() } } } }
components/feature/syncedtabs/src/main/java/mozilla/components/feature/syncedtabs/controller/SyncedTabsController.kt 0 → 100644 +25 −0 Original line number Diff line number Diff line /* 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 mozilla.components.feature.syncedtabs.controller import mozilla.components.feature.syncedtabs.storage.SyncedTabsProvider import mozilla.components.feature.syncedtabs.view.SyncedTabsView import mozilla.components.service.fxa.manager.FxaAccountManager /** * A controller for making the appropriate request for remote tabs from [SyncedTabsProvider] when the * [FxaAccountManager] account is in the appropriate state. The [SyncedTabsView] can then be notified. */ interface SyncedTabsController { val provider: SyncedTabsProvider val accountManager: FxaAccountManager val view: SyncedTabsView /** * Requests for remote tabs and notifies the [SyncedTabsView] when available with [SyncedTabsView.displaySyncedTabs] * otherwise notifies the appropriate error to [SyncedTabsView.onError]. */ fun syncTabs() }
components/feature/syncedtabs/src/main/java/mozilla/components/feature/syncedtabs/interactor/DefaultInteractor.kt 0 → 100644 +43 −0 Original line number Diff line number Diff line /* 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 mozilla.components.feature.syncedtabs.interactor import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import mozilla.components.browser.storage.sync.Tab import mozilla.components.feature.syncedtabs.view.SyncedTabsView import mozilla.components.service.fxa.manager.FxaAccountManager import mozilla.components.service.fxa.manager.ext.withConstellation import mozilla.components.service.fxa.sync.SyncReason import kotlin.coroutines.CoroutineContext internal class DefaultInteractor( override val accountManager: FxaAccountManager, override val view: SyncedTabsView, private val coroutineContext: CoroutineContext, override val tabClicked: (Tab) -> Unit ) : SyncedTabsInteractor { override fun start() { view.listener = this } override fun stop() { view.listener = null } override fun onTabClicked(tab: Tab) { tabClicked(tab) } override fun onRefresh() { CoroutineScope(coroutineContext).launch { accountManager.withConstellation { refreshDevicesAsync() } accountManager.syncNowAsync(SyncReason.User, true) } } }