diff --git a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt index 64b0f1357..9df643b05 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt @@ -962,11 +962,9 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session private fun showQuickSettingsDialog() { val session = getSessionById() ?: return viewLifecycleOwner.lifecycleScope.launch(Main) { - val sitePermissions: SitePermissions? = withContext(IO) { - session.url.toUri().host?.let { host -> - val storage = requireContext().components.core.permissionStorage - storage.findSitePermissionsBy(host) - } + val sitePermissions: SitePermissions? = session.url.toUri().host?.let { host -> + val storage = requireComponents.core.permissionStorage + storage.findSitePermissionsBy(host) } view?.let { diff --git a/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationController.kt b/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationController.kt index b93775caa..0429f6b7c 100644 --- a/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationController.kt +++ b/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationController.kt @@ -69,7 +69,7 @@ fun List.toSessionBundle(sessionManager: SessionManager): List { * @param metrics Controller that handles telemetry events. * @param tabCollectionStorage Storage used to save tab collections to disk. * @param sessionManager Used to query and serialize tabs. - * @param ioScope Coroutine scope that launches on the IO thread. + * @param scope Coroutine scope to launch coroutines. */ class DefaultCollectionCreationController( private val store: CollectionCreationStore, @@ -77,7 +77,7 @@ class DefaultCollectionCreationController( private val metrics: MetricController, private val tabCollectionStorage: TabCollectionStorage, private val sessionManager: SessionManager, - private val ioScope: CoroutineScope + private val scope: CoroutineScope ) : CollectionCreationController { companion object { @@ -89,7 +89,7 @@ class DefaultCollectionCreationController( dismiss() val sessionBundle = tabs.toSessionBundle(sessionManager) - ioScope.launch { + scope.launch { tabCollectionStorage.createCollection(name, sessionBundle) } @@ -100,7 +100,7 @@ class DefaultCollectionCreationController( override fun renameCollection(collection: TabCollection, name: String) { dismiss() - ioScope.launch { + scope.launch { tabCollectionStorage.renameCollection(collection, name) } metrics.track(Event.CollectionRenamed) @@ -130,7 +130,7 @@ class DefaultCollectionCreationController( override fun selectCollection(collection: TabCollection, tabs: List) { dismiss() val sessionBundle = tabs.toList().toSessionBundle(sessionManager) - ioScope.launch { + scope.launch { tabCollectionStorage .addTabsToCollection(collection, sessionBundle) } diff --git a/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationFragment.kt b/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationFragment.kt index 264426c27..4e15537f7 100644 --- a/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/collections/CollectionCreationFragment.kt @@ -14,9 +14,7 @@ import androidx.fragment.app.DialogFragment import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.navArgs import kotlinx.android.synthetic.main.fragment_create_collection.view.* -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.plus import mozilla.components.browser.state.selector.findTab import mozilla.components.browser.state.state.BrowserState import mozilla.components.browser.state.state.TabSessionState @@ -80,7 +78,7 @@ class CollectionCreationFragment : DialogFragment() { requireComponents.analytics.metrics, requireComponents.core.tabCollectionStorage, requireComponents.core.sessionManager, - ioScope = lifecycleScope + Dispatchers.IO + scope = lifecycleScope ) ) collectionCreationView = CollectionCreationView( diff --git a/app/src/main/java/org/mozilla/fenix/components/PermissionStorage.kt b/app/src/main/java/org/mozilla/fenix/components/PermissionStorage.kt index 5d31c5a1e..8535cc7fc 100644 --- a/app/src/main/java/org/mozilla/fenix/components/PermissionStorage.kt +++ b/app/src/main/java/org/mozilla/fenix/components/PermissionStorage.kt @@ -6,6 +6,8 @@ package org.mozilla.fenix.components import android.content.Context import androidx.paging.DataSource +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext import mozilla.components.feature.sitepermissions.SitePermissions import mozilla.components.feature.sitepermissions.SitePermissions.Status import mozilla.components.feature.sitepermissions.SitePermissionsStorage @@ -38,11 +40,11 @@ class PermissionStorage(private val context: Context) { return sitePermissions } - fun findSitePermissionsBy(origin: String): SitePermissions? { - return permissionsStorage.findSitePermissionsBy(origin) + suspend fun findSitePermissionsBy(origin: String): SitePermissions? = withContext(Dispatchers.IO) { + permissionsStorage.findSitePermissionsBy(origin) } - fun updateSitePermissions(sitePermissions: SitePermissions) { + suspend fun updateSitePermissions(sitePermissions: SitePermissions) = withContext(Dispatchers.IO) { permissionsStorage.update(sitePermissions) } @@ -50,11 +52,11 @@ class PermissionStorage(private val context: Context) { return permissionsStorage.getSitePermissionsPaged() } - fun deleteSitePermissions(sitePermissions: SitePermissions) { + suspend fun deleteSitePermissions(sitePermissions: SitePermissions) = withContext(Dispatchers.IO) { permissionsStorage.remove(sitePermissions) } - fun deleteAllSitePermissions() { + suspend fun deleteAllSitePermissions() = withContext(Dispatchers.IO) { permissionsStorage.removeAll() } } diff --git a/app/src/main/java/org/mozilla/fenix/components/TabCollectionStorage.kt b/app/src/main/java/org/mozilla/fenix/components/TabCollectionStorage.kt index 6fe835e20..214012cba 100644 --- a/app/src/main/java/org/mozilla/fenix/components/TabCollectionStorage.kt +++ b/app/src/main/java/org/mozilla/fenix/components/TabCollectionStorage.kt @@ -9,6 +9,9 @@ import android.os.StrictMode import androidx.lifecycle.LiveData import androidx.lifecycle.asLiveData import androidx.paging.DataSource +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import mozilla.components.browser.session.Session import mozilla.components.browser.session.SessionManager import mozilla.components.feature.tab.collections.Tab @@ -49,6 +52,7 @@ class TabCollectionStorage( fun onCollectionRenamed(tabCollection: TabCollection, title: String) = Unit } + private val ioScope = CoroutineScope(Dispatchers.IO) var cachedTabCollections = listOf() private val collectionStorage by lazy { @@ -57,15 +61,15 @@ class TabCollectionStorage( } } - fun createCollection(title: String, sessions: List) { + suspend fun createCollection(title: String, sessions: List) = ioScope.launch { collectionStorage.createCollection(title, sessions) notifyObservers { onCollectionCreated(title, sessions) } - } + }.join() - fun addTabsToCollection(tabCollection: TabCollection, sessions: List) { + suspend fun addTabsToCollection(tabCollection: TabCollection, sessions: List) = ioScope.launch { collectionStorage.addTabsToCollection(tabCollection, sessions) notifyObservers { onTabsAdded(tabCollection, sessions) } - } + }.join() fun getTabCollectionsCount(): Int { return collectionStorage.getTabCollectionsCount() @@ -79,18 +83,18 @@ class TabCollectionStorage( return collectionStorage.getCollectionsPaged() } - fun removeCollection(tabCollection: TabCollection) { + suspend fun removeCollection(tabCollection: TabCollection) = ioScope.launch { collectionStorage.removeCollection(tabCollection) - } + }.join() - fun removeTabFromCollection(tabCollection: TabCollection, tab: Tab) { + suspend fun removeTabFromCollection(tabCollection: TabCollection, tab: Tab) = ioScope.launch { collectionStorage.removeTabFromCollection(tabCollection, tab) - } + }.join() - fun renameCollection(tabCollection: TabCollection, title: String) { + suspend fun renameCollection(tabCollection: TabCollection, title: String) = ioScope.launch { collectionStorage.renameCollection(tabCollection, title) notifyObservers { onCollectionRenamed(tabCollection, title) } - } + }.join() } fun TabCollection.description(context: Context): String { diff --git a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt index 7c927d2c5..db4ada0e0 100644 --- a/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt +++ b/app/src/main/java/org/mozilla/fenix/home/sessioncontrol/SessionControlController.kt @@ -240,7 +240,7 @@ class DefaultSessionControlController( handleSwipedItemDeletionCancel ) } else { - viewLifecycleScope.launch(Dispatchers.IO) { + viewLifecycleScope.launch { tabCollectionStorage.removeTabFromCollection(collection, tab) } } diff --git a/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsDetailsExceptionsFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsDetailsExceptionsFragment.kt index b9de6f84d..9ad2a5f1a 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsDetailsExceptionsFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsDetailsExceptionsFragment.kt @@ -18,6 +18,7 @@ import kotlinx.coroutines.withContext import mozilla.components.feature.sitepermissions.SitePermissions import org.mozilla.fenix.R import org.mozilla.fenix.ext.components +import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.showToolbar import org.mozilla.fenix.settings.PhoneFeature import org.mozilla.fenix.settings.PhoneFeature.CAMERA @@ -44,13 +45,10 @@ class SitePermissionsDetailsExceptionsFragment : PreferenceFragmentCompat() { override fun onResume() { super.onResume() showToolbar(sitePermissions.origin) - viewLifecycleOwner.lifecycleScope.launch(IO) { - val context = requireContext() + viewLifecycleOwner.lifecycleScope.launch(Main) { sitePermissions = - requireNotNull(context.components.core.permissionStorage.findSitePermissionsBy(sitePermissions.origin)) - withContext(Main) { - bindCategoryPhoneFeatures() - } + requireNotNull(requireComponents.core.permissionStorage.findSitePermissionsBy(sitePermissions.origin)) + bindCategoryPhoneFeatures() } } diff --git a/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsExceptionsFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsExceptionsFragment.kt index f941ce29b..2b73d4da2 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsExceptionsFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsExceptionsFragment.kt @@ -24,7 +24,6 @@ import androidx.paging.PagedListAdapter import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.launch import mozilla.components.feature.sitepermissions.SitePermissions @@ -108,13 +107,12 @@ class SitePermissionsExceptionsFragment : } private fun deleteAllSitePermissions() { - viewLifecycleOwner.lifecycleScope.launch(IO) { + viewLifecycleOwner.lifecycleScope.launch(Main) { requireContext().components.core.permissionStorage.deleteAllSitePermissions() - launch(Main) { - showEmptyListMessage() - // Reload the selected session. - requireContext().components.useCases.sessionUseCases.reload() - } + + showEmptyListMessage() + // Reload the selected session. + requireContext().components.useCases.sessionUseCases.reload() } } diff --git a/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsManageExceptionsPhoneFeatureFragment.kt b/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsManageExceptionsPhoneFeatureFragment.kt index b8ad9d170..110fc2bda 100644 --- a/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsManageExceptionsPhoneFeatureFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/settings/sitepermissions/SitePermissionsManageExceptionsPhoneFeatureFragment.kt @@ -18,7 +18,6 @@ import androidx.appcompat.app.AlertDialog import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import androidx.navigation.fragment.navArgs -import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.launch import mozilla.components.feature.sitepermissions.SitePermissions @@ -142,11 +141,9 @@ class SitePermissionsManageExceptionsPhoneFeatureFragment : Fragment() { private fun updatedSitePermissions(status: SitePermissions.Status) { val updatedSitePermissions = args.sitePermissions.update(args.phoneFeature, status) - viewLifecycleOwner.lifecycleScope.launch(IO) { + viewLifecycleOwner.lifecycleScope.launch(Main) { requireComponents.core.permissionStorage.updateSitePermissions(updatedSitePermissions) - launch(Main) { - requireComponents.tryReloadTabBy(updatedSitePermissions.origin) - } + requireComponents.tryReloadTabBy(updatedSitePermissions.origin) } } } diff --git a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayDialogFragment.kt b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayDialogFragment.kt index de7f3ec3e..9d3b72546 100644 --- a/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayDialogFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/tabtray/TabTrayDialogFragment.kt @@ -370,7 +370,7 @@ class TabTrayDialogFragment : AppCompatDialogFragment(), UserInteractionHandler val selectedCollection = (list.adapter as CollectionsAdapter).getSelectedCollection() val collection = tabCollectionStorage.cachedTabCollections[selectedCollection] - viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) { + viewLifecycleOwner.lifecycleScope.launch(Main) { tabCollectionStorage.addTabsToCollection(collection, sessionList) it.metrics.track( Event.CollectionTabsAdded( @@ -378,10 +378,8 @@ class TabTrayDialogFragment : AppCompatDialogFragment(), UserInteractionHandler sessionList.size ) ) - launch(Main) { - tabTrayDialogStore.dispatch(TabTrayDialogFragmentAction.ExitMultiSelectMode) - dialog.dismiss() - } + tabTrayDialogStore.dispatch(TabTrayDialogFragmentAction.ExitMultiSelectMode) + dialog.dismiss() } }.setNegativeButton(android.R.string.cancel) { dialog, _ -> tabTrayDialogStore.dispatch(TabTrayDialogFragmentAction.ExitMultiSelectMode) diff --git a/app/src/test/java/org/mozilla/fenix/collections/DefaultCollectionCreationControllerTest.kt b/app/src/test/java/org/mozilla/fenix/collections/DefaultCollectionCreationControllerTest.kt index ef4e2c5ed..f9e7df531 100644 --- a/app/src/test/java/org/mozilla/fenix/collections/DefaultCollectionCreationControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/collections/DefaultCollectionCreationControllerTest.kt @@ -1,6 +1,7 @@ package org.mozilla.fenix.collections import io.mockk.MockKAnnotations +import io.mockk.coVerify import io.mockk.every import io.mockk.impl.annotations.MockK import io.mockk.mockk @@ -69,7 +70,7 @@ class DefaultCollectionCreationControllerTest { controller.saveCollectionName(tabs, "name") verify { dismiss() } - verify { tabCollectionStorage.createCollection("name", listOf(session)) } + coVerify { tabCollectionStorage.createCollection("name", listOf(session)) } verify { metrics.track(Event.CollectionSaved(2, 1)) } } @@ -117,9 +118,9 @@ class DefaultCollectionCreationControllerTest { verifyAll { dismiss() - tabCollectionStorage.renameCollection(collection, "name") metrics.track(Event.CollectionRenamed) } + coVerify { tabCollectionStorage.renameCollection(collection, "name") } } @Test @@ -162,7 +163,7 @@ class DefaultCollectionCreationControllerTest { controller.selectCollection(collection, tabs) verify { dismiss() } - verify { tabCollectionStorage.addTabsToCollection(collection, listOf(session)) } + coVerify { tabCollectionStorage.addTabsToCollection(collection, listOf(session)) } verify { metrics.track(Event.CollectionTabsAdded(2, 1)) } } diff --git a/app/src/test/java/org/mozilla/fenix/settings/deletebrowsingdata/DefaultDeleteBrowsingDataControllerTest.kt b/app/src/test/java/org/mozilla/fenix/settings/deletebrowsingdata/DefaultDeleteBrowsingDataControllerTest.kt index 038d4be4f..0d300350b 100644 --- a/app/src/test/java/org/mozilla/fenix/settings/deletebrowsingdata/DefaultDeleteBrowsingDataControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/settings/deletebrowsingdata/DefaultDeleteBrowsingDataControllerTest.kt @@ -97,7 +97,7 @@ class DefaultDeleteBrowsingDataControllerTest { fun deleteSitePermissions() = runBlockingTest { controller.deleteSitePermissions() - verify { + coVerify { engine.clearData(Engine.BrowsingData.select(Engine.BrowsingData.ALL_SITE_SETTINGS)) permissionStorage.deleteAllSitePermissions() } diff --git a/app/src/test/java/org/mozilla/fenix/settings/deletebrowsingdata/DeleteAndQuitTest.kt b/app/src/test/java/org/mozilla/fenix/settings/deletebrowsingdata/DeleteAndQuitTest.kt index 5ae94620c..314015612 100644 --- a/app/src/test/java/org/mozilla/fenix/settings/deletebrowsingdata/DeleteAndQuitTest.kt +++ b/app/src/test/java/org/mozilla/fenix/settings/deletebrowsingdata/DeleteAndQuitTest.kt @@ -9,7 +9,6 @@ package org.mozilla.fenix.settings.deletebrowsingdata import io.mockk.coVerify import io.mockk.every import io.mockk.mockk -import io.mockk.verify import io.mockk.verifyOrder import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestCoroutineDispatcher @@ -72,7 +71,7 @@ class DeleteAndQuitTest { activity.finish() } - verify(exactly = 0) { + coVerify(exactly = 0) { engine.clearData( Engine.BrowsingData.select( Engine.BrowsingData.COOKIES @@ -100,7 +99,7 @@ class DeleteAndQuitTest { deleteAndQuit(activity, this, snackbar) - verify(exactly = 1) { + coVerify(exactly = 1) { snackbar.show() engine.clearData(Engine.BrowsingData.allCaches()) diff --git a/app/src/test/java/org/mozilla/fenix/settings/quicksettings/DefaultQuickSettingsControllerTest.kt b/app/src/test/java/org/mozilla/fenix/settings/quicksettings/DefaultQuickSettingsControllerTest.kt index 4b0924c15..f0df1e6b8 100644 --- a/app/src/test/java/org/mozilla/fenix/settings/quicksettings/DefaultQuickSettingsControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/settings/quicksettings/DefaultQuickSettingsControllerTest.kt @@ -7,12 +7,12 @@ package org.mozilla.fenix.settings.quicksettings import androidx.navigation.NavController import androidx.navigation.NavDirections import io.mockk.Runs +import io.mockk.coVerifyOrder import io.mockk.every import io.mockk.just import io.mockk.mockk import io.mockk.spyk import io.mockk.verify -import io.mockk.verifyOrder import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestCoroutineScope import kotlinx.coroutines.test.runBlockingTest @@ -179,7 +179,7 @@ class DefaultQuickSettingsControllerTest { controller.handlePermissionsChange(testPermissions) advanceUntilIdle() - verifyOrder { + coVerifyOrder { permissionStorage.updateSitePermissions(testPermissions) reload(browserSession) }