Unverified Commit e7ff11cc authored by Jonathan Almeida's avatar Jonathan Almeida
Browse files

Close #6837: Update class name to SyncedTabsStorage

We also introduce a `SyncedDeviceTabs` data class to make the result API
easier to work with for consumers.
parent 9113a20a
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@ import mozilla.components.concept.storage.Storage
import mozilla.components.concept.sync.SyncableStore
import mozilla.components.support.base.log.logger.Logger
import mozilla.appservices.remotetabs.RemoteTabsProvider
import mozilla.components.concept.sync.Device
import mozilla.appservices.remotetabs.SyncAuthInfo as RustSyncAuthInfo
import mozilla.components.concept.sync.SyncAuthInfo
import mozilla.components.concept.sync.SyncStatus
@@ -145,6 +146,14 @@ data class Tab(
    }
}

/**
 * A synced device and the list of tabs.
 */
data class SyncedDeviceTabs(
    val device: Device,
    val tabs: List<Tab>
)

/**
 * A Tab history entry.
 */
+6 −0
Original line number Diff line number Diff line
@@ -27,6 +27,12 @@ android {
    }
}

tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
    kotlinOptions.freeCompilerArgs += [
            "-Xuse-experimental=kotlinx.coroutines.ExperimentalCoroutinesApi"
    ]
}

dependencies {
    implementation project(':service-firefox-accounts')
    implementation project(':browser-icons')
+13 −12
Original line number Diff line number Diff line
@@ -6,12 +6,12 @@ package mozilla.components.feature.syncedtabs

import androidx.annotation.VisibleForTesting
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.map
import mozilla.components.browser.state.store.BrowserStore
import mozilla.components.browser.storage.sync.RemoteTabsStorage
import mozilla.components.browser.storage.sync.SyncedDeviceTabs
import mozilla.components.browser.storage.sync.Tab
import mozilla.components.browser.storage.sync.TabEntry
import mozilla.components.concept.sync.Device
@@ -21,11 +21,10 @@ import mozilla.components.service.fxa.manager.ext.withConstellation
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged

/**
 * A feature that listens to the [BrowserStore] changes to update the local remote tabs state
 * in [RemoteTabsStorage].
 * A storage that listens to the [BrowserStore] changes to synchronize the local tabs state
 * with [RemoteTabsStorage].
 */
@ExperimentalCoroutinesApi
class SyncedTabsFeature(
class SyncedTabsStorage(
    private val accountManager: FxaAccountManager,
    private val store: BrowserStore,
    private val tabsStorage: RemoteTabsStorage = RemoteTabsStorage()
@@ -61,14 +60,16 @@ class SyncedTabsFeature(
    }

    /**
     * Get the list of remote tabs.
     * Get the list of synced tabs.
     */
    suspend fun getSyncedTabs(): Map<Device, List<Tab>> {
        val otherDevices = syncClients() ?: return emptyMap()
        return tabsStorage.getAll().mapNotNull { (client, tabs) ->
    suspend fun getSyncedTabs(): List<SyncedDeviceTabs> {
        val otherDevices = syncClients() ?: return emptyList()
        return tabsStorage.getAll()
            .mapNotNull { (client, tabs) ->
                val fxaDevice = otherDevices.find { it.id == client.id }
            fxaDevice?.let { fxaDevice to tabs }
        }.toMap()

                fxaDevice?.let { SyncedDeviceTabs(fxaDevice, tabs) }
            }
    }

    /**
+2 −3
Original line number Diff line number Diff line
@@ -14,11 +14,10 @@ import java.util.UUID

/**
 * A [AwesomeBar.SuggestionProvider] implementation that provides suggestions for remote tabs
 * based on [SyncedTabsFeature].
 * based on [SyncedTabsStorage].
 */
@ExperimentalCoroutinesApi
class SyncedTabsStorageSuggestionProvider(
    private val syncedTabs: SyncedTabsFeature,
    private val syncedTabs: SyncedTabsStorage,
    private val loadUrlUseCase: SessionUseCases.LoadUrlUseCase,
    private val icons: BrowserIcons? = null
) : AwesomeBar.SuggestionProvider {
+52 −38
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ package mozilla.components.feature.syncedtabs
import androidx.test.ext.junit.runners.AndroidJUnit4
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.runBlocking
import mozilla.components.browser.storage.sync.SyncedDeviceTabs
import mozilla.components.browser.storage.sync.Tab
import mozilla.components.browser.storage.sync.TabEntry
import mozilla.components.concept.sync.Device
@@ -18,10 +19,9 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith

@ExperimentalCoroutinesApi
@RunWith(AndroidJUnit4::class)
class SyncedTabsStorageSuggestionProviderTest {
    private lateinit var syncedTabs: SyncedTabsFeature
    private lateinit var syncedTabs: SyncedTabsStorage

    @Before
    fun setup() {
@@ -31,7 +31,8 @@ class SyncedTabsStorageSuggestionProviderTest {
    @Test
    fun `matches remote tabs`() = runBlocking {
        val provider = SyncedTabsStorageSuggestionProvider(syncedTabs, mock())
        val deviceTabs1 = Device(
        val deviceTabs1 = SyncedDeviceTabs(
            Device(
                id = "client1",
                displayName = "Foo Client",
                deviceType = DeviceType.DESKTOP,
@@ -40,20 +41,29 @@ class SyncedTabsStorageSuggestionProviderTest {
                capabilities = listOf(),
                subscriptionExpired = false,
                subscription = null
        ) to listOf(
            Tab(listOf(
            ),
            listOf(
                Tab(
                    listOf(
                        TabEntry("Foo", "https://foo.bar", null), /* active tab */
                        TabEntry("Bobo", "https://foo.bar", null),
                        TabEntry("Foo", "https://bobo.bar", null)
            ), 0, 1),
            Tab(listOf(
                    ), 0, 1
                ),
                Tab(
                    listOf(
                        TabEntry("Hello Bobo", "https://foo.bar", null) /* active tab */
            ), 0, 5),
            Tab(listOf(
                    ), 0, 5
                ),
                Tab(
                    listOf(
                        TabEntry("In URL", "https://bobo.bar", null) /* active tab */
            ), 0, 2)
                    ), 0, 2
                )
        val deviceTabs2 = Device(
            )
        )
        val deviceTabs2 = SyncedDeviceTabs(
            Device(
                id = "client2",
                displayName = "Bar Client",
                deviceType = DeviceType.MOBILE,
@@ -62,13 +72,17 @@ class SyncedTabsStorageSuggestionProviderTest {
                capabilities = listOf(),
                subscriptionExpired = false,
                subscription = null
        ) to listOf(
            Tab(listOf(
            ),
            listOf(
                Tab(
                    listOf(
                        TabEntry("Bar", "https://bar.bar", null),
                        TabEntry("BOBO in CAPS", "https://obob.bar", null) /* active tab */
            ), 1, 1)
                    ), 1, 1
                )
            )
        )
        whenever(syncedTabs.getSyncedTabs()).thenReturn(mapOf(deviceTabs1, deviceTabs2))
        whenever(syncedTabs.getSyncedTabs()).thenReturn(listOf(deviceTabs1, deviceTabs2))

        val suggestions = provider.onInputChanged("bobo")
        assertEquals(3, suggestions.size)
Loading