diff --git a/app/src/main/java/org/mozilla/reference/browser/BrowserApplication.kt b/app/src/main/java/org/mozilla/reference/browser/BrowserApplication.kt index 859a92b94..93e3d025a 100644 --- a/app/src/main/java/org/mozilla/reference/browser/BrowserApplication.kt +++ b/app/src/main/java/org/mozilla/reference/browser/BrowserApplication.kt @@ -8,9 +8,7 @@ import android.app.Application import java.util.concurrent.TimeUnit import kotlinx.coroutines.CoroutineExceptionHandler import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import mozilla.components.browser.state.action.SystemAction @@ -112,16 +110,15 @@ open class BrowserApplication : Application() { PushProcessor.install(it) // WebPush integration to observe and deliver push messages to engine. - WebPushEngineIntegration(components.core.engine, it).start() + WebPushEngineIntegration(components.core.engine, it, applicationScope).start() // Perform a one-time initialization of the account manager if a message is received. - PushFxaIntegration(it, lazy { components.backgroundServices.accountManager }).launch() + PushFxaIntegration(it, lazy { components.backgroundServices.accountManager }, applicationScope).launch() // Initialize the push feature and service. it.initialize() } - @OptIn(DelicateCoroutinesApi::class) - GlobalScope.launch(Dispatchers.IO) { + applicationScope.launch(Dispatchers.IO) { components.core.fileUploadsDirCleaner.cleanUploadsDirectory() } } @@ -134,22 +131,20 @@ open class BrowserApplication : Application() { } } - @OptIn(DelicateCoroutinesApi::class) - private fun restoreBrowserState() = - GlobalScope.launch(Dispatchers.Main) { - val store = components.core.store - val sessionStorage = components.core.sessionStorage - - components.useCases.tabsUseCases.restore(sessionStorage) - - // Now that we have restored our previous state (if there's one) let's setup auto saving the state while - // the app is used. - sessionStorage - .autoSave(store) - .periodicallyInForeground(interval = 30, unit = TimeUnit.SECONDS) - .whenGoingToBackground() - .whenSessionsChange() - } + private fun restoreBrowserState() = applicationScope.launch { + val store = components.core.store + val sessionStorage = components.core.sessionStorage + + components.useCases.tabsUseCases.restore(sessionStorage) + + // Now that we have restored our previous state (if there's one) let's setup auto saving the state while + // the app is used. + sessionStorage + .autoSave(store) + .periodicallyInForeground(interval = 30, unit = TimeUnit.SECONDS) + .whenGoingToBackground() + .whenSessionsChange() + } companion object { const val NON_FATAL_CRASH_BROADCAST = "org.mozilla.reference.browser" diff --git a/app/src/main/java/org/mozilla/reference/browser/Components.kt b/app/src/main/java/org/mozilla/reference/browser/Components.kt index 71a523989..1d0132ef7 100644 --- a/app/src/main/java/org/mozilla/reference/browser/Components.kt +++ b/app/src/main/java/org/mozilla/reference/browser/Components.kt @@ -64,7 +64,9 @@ class Components( applicationScope, ) } - val services by lazy { Services(context, backgroundServices.accountManager, useCases.tabsUseCases) } + val services by lazy { + Services(context, backgroundServices.accountManager, useCases.tabsUseCases, applicationScope) + } val push by lazy { Push(context, analytics.crashReporter) } @delegate:SuppressLint("NewApi") diff --git a/app/src/main/java/org/mozilla/reference/browser/IntentReceiverActivity.kt b/app/src/main/java/org/mozilla/reference/browser/IntentReceiverActivity.kt index 9c025d03d..7ba5840d0 100644 --- a/app/src/main/java/org/mozilla/reference/browser/IntentReceiverActivity.kt +++ b/app/src/main/java/org/mozilla/reference/browser/IntentReceiverActivity.kt @@ -7,8 +7,6 @@ package org.mozilla.reference.browser import android.app.Activity import android.content.Intent import android.os.Bundle -import kotlinx.coroutines.MainScope -import kotlinx.coroutines.launch import org.mozilla.reference.browser.ext.components class IntentReceiverActivity : Activity() { @@ -27,20 +25,18 @@ class IntentReceiverActivity : Activity() { val utils = components.utils - MainScope().launch { - val processor = utils.intentProcessors.firstOrNull { it.process(intent) } + val processor = utils.intentProcessors.firstOrNull { it.process(intent) } - val className = - if (processor in utils.externalIntentProcessors) { - ExternalAppBrowserActivity::class - } else { - BrowserActivity::class - } + val className = + if (processor in utils.externalIntentProcessors) { + ExternalAppBrowserActivity::class + } else { + BrowserActivity::class + } - intent.setClassName(applicationContext, className.java.name) + intent.setClassName(applicationContext, className.java.name) - startActivity(intent) - finish() - } + startActivity(intent) + finish() } } diff --git a/app/src/main/java/org/mozilla/reference/browser/addons/AddonsFragment.kt b/app/src/main/java/org/mozilla/reference/browser/addons/AddonsFragment.kt index 15738f8c1..f78b9281c 100644 --- a/app/src/main/java/org/mozilla/reference/browser/addons/AddonsFragment.kt +++ b/app/src/main/java/org/mozilla/reference/browser/addons/AddonsFragment.kt @@ -11,25 +11,27 @@ import android.view.View import android.view.ViewGroup import android.widget.Toast import androidx.fragment.app.Fragment +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView -import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import mozilla.components.feature.addons.Addon import mozilla.components.feature.addons.AddonManagerException import mozilla.components.feature.addons.R as addonsR import mozilla.components.feature.addons.ui.AddonsManagerAdapter import mozilla.components.feature.addons.ui.AddonsManagerAdapterDelegate import mozilla.components.support.base.feature.ViewBoundFeatureWrapper +import mozilla.components.support.base.log.logger.Logger import org.mozilla.reference.browser.R import org.mozilla.reference.browser.ext.components /** Fragment use for managing add-ons. */ class AddonsFragment : Fragment(), AddonsManagerAdapterDelegate { + private val logger = Logger("AddonsFragment") private val webExtensionPromptFeature = ViewBoundFeatureWrapper() private lateinit var recyclerView: RecyclerView - private val scope = CoroutineScope(Dispatchers.IO) private lateinit var addons: List private var adapter: AddonsManagerAdapter? = null @@ -47,7 +49,6 @@ class AddonsFragment : Fragment(), AddonsManagerAdapterDelegate { savedInstanceState: Bundle?, ) { super.onViewCreated(rootView, savedInstanceState) - bindRecyclerView(rootView) webExtensionPromptFeature.set( feature = WebExtensionPromptFeature( @@ -73,28 +74,25 @@ class AddonsFragment : Fragment(), AddonsManagerAdapterDelegate { private fun bindRecyclerView(rootView: View) { recyclerView = rootView.findViewById(R.id.add_ons_list) recyclerView.layoutManager = LinearLayoutManager(requireContext()) - scope.launch { + viewLifecycleOwner.lifecycleScope.launch { try { - addons = requireContext().components.core.addonManager.getAddons() + addons = withContext(Dispatchers.IO) { requireContext().components.core.addonManager.getAddons() } - scope.launch(Dispatchers.Main) { - adapter = - AddonsManagerAdapter( - this@AddonsFragment, - addons, - store = requireContext().components.core.store, - ) - recyclerView.adapter = adapter - } + adapter = + AddonsManagerAdapter( + this@AddonsFragment, + addons, + store = requireContext().components.core.store, + ) + recyclerView.adapter = adapter } catch (e: AddonManagerException) { - scope.launch(Dispatchers.Main) { - Toast.makeText( - activity, - addonsR.string.mozac_feature_addons_failed_to_load_extensions, - Toast.LENGTH_SHORT, - ) - .show() - } + logger.error("Failed to load add-ons", e) + Toast.makeText( + activity, + addonsR.string.mozac_feature_addons_failed_to_load_extensions, + Toast.LENGTH_SHORT, + ) + .show() } } } diff --git a/app/src/main/java/org/mozilla/reference/browser/addons/InstalledAddonDetailsActivity.kt b/app/src/main/java/org/mozilla/reference/browser/addons/InstalledAddonDetailsActivity.kt index acd575019..360d73af2 100644 --- a/app/src/main/java/org/mozilla/reference/browser/addons/InstalledAddonDetailsActivity.kt +++ b/app/src/main/java/org/mozilla/reference/browser/addons/InstalledAddonDetailsActivity.kt @@ -14,13 +14,15 @@ import androidx.activity.enableEdgeToEdge import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.SwitchCompat import androidx.core.view.isVisible -import kotlinx.coroutines.CoroutineScope +import androidx.lifecycle.lifecycleScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext import mozilla.components.feature.addons.Addon import mozilla.components.feature.addons.AddonManagerException import mozilla.components.feature.addons.R as addonsR import mozilla.components.feature.addons.ui.translateName +import mozilla.components.support.base.log.logger.Logger import mozilla.components.support.ktx.android.view.setupPersistentInsets import mozilla.components.support.utils.ext.getParcelableExtraCompat import org.mozilla.reference.browser.R @@ -28,7 +30,7 @@ import org.mozilla.reference.browser.ext.components /** An activity to show the details of a installed add-on. */ class InstalledAddonDetailsActivity : AppCompatActivity() { - private val scope = CoroutineScope(Dispatchers.IO) + private val logger = Logger("InstalledAddonDetailsActivity") override fun onCreate(savedInstanceState: Bundle?) { enableEdgeToEdge(SystemBarStyle.dark(Color.TRANSPARENT)) @@ -45,29 +47,22 @@ class InstalledAddonDetailsActivity : AppCompatActivity() { } private fun bindAddon(addon: Addon) { - scope.launch { + lifecycleScope.launch { try { - val addons = baseContext.components.core.addonManager.getAddons() - scope.launch(Dispatchers.Main) { - addons - .find { addon.id == it.id } - .let { - if (it == null) { - throw AddonManagerException(Exception("Addon ${addon.id} not found")) - } else { - bindUI(it) - } - } - } + val addons = withContext(Dispatchers.IO) { baseContext.components.core.addonManager.getAddons() } + val installed = + addons.find { addon.id == it.id } + ?: throw AddonManagerException(Exception("Addon ${addon.id} not found")) + + bindUI(installed) } catch (e: AddonManagerException) { - scope.launch(Dispatchers.Main) { - Toast.makeText( - baseContext, - addonsR.string.mozac_feature_addons_failed_to_load_extensions, - Toast.LENGTH_SHORT, - ) - .show() - } + logger.error("Failed to load add-on ${addon.id}", e) + Toast.makeText( + baseContext, + addonsR.string.mozac_feature_addons_failed_to_load_extensions, + Toast.LENGTH_SHORT, + ) + .show() } } } diff --git a/app/src/main/java/org/mozilla/reference/browser/browser/BrowserFragment.kt b/app/src/main/java/org/mozilla/reference/browser/browser/BrowserFragment.kt index 7ae99b750..cef793f41 100644 --- a/app/src/main/java/org/mozilla/reference/browser/browser/BrowserFragment.kt +++ b/app/src/main/java/org/mozilla/reference/browser/browser/BrowserFragment.kt @@ -9,7 +9,6 @@ import android.view.View import androidx.lifecycle.lifecycleScope import androidx.preference.PreferenceManager import com.google.android.material.floatingactionbutton.FloatingActionButton -import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import mozilla.components.browser.thumbnails.BrowserThumbnails @@ -168,7 +167,6 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler { } } - @OptIn(DelicateCoroutinesApi::class) private fun deleteHistorySuggestion(suggestion: Suggestion) { lifecycleScope.launch(Dispatchers.IO) { suggestion.description?.let { diff --git a/app/src/main/java/org/mozilla/reference/browser/browser/CrashIntegration.kt b/app/src/main/java/org/mozilla/reference/browser/browser/CrashIntegration.kt index 58797cb96..12f99a487 100644 --- a/app/src/main/java/org/mozilla/reference/browser/browser/CrashIntegration.kt +++ b/app/src/main/java/org/mozilla/reference/browser/browser/CrashIntegration.kt @@ -11,13 +11,12 @@ import android.content.IntentFilter import androidx.core.content.ContextCompat import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.LifecycleOwner -import kotlinx.coroutines.DelicateCoroutinesApi -import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import mozilla.components.lib.crash.Crash import mozilla.components.lib.crash.CrashReporter import mozilla.components.support.utils.ext.registerReceiverCompat import org.mozilla.reference.browser.BrowserApplication.Companion.NON_FATAL_CRASH_BROADCAST +import org.mozilla.reference.browser.ext.components class CrashIntegration( private val context: Context, @@ -53,9 +52,8 @@ class CrashIntegration( context.unregisterReceiver(receiver) } - @OptIn(DelicateCoroutinesApi::class) fun sendCrashReport(crash: Crash) { - GlobalScope.launch { + context.components.applicationScope.launch { crashReporter.submitReport(crash) } } diff --git a/app/src/main/java/org/mozilla/reference/browser/browser/ToolbarIntegration.kt b/app/src/main/java/org/mozilla/reference/browser/browser/ToolbarIntegration.kt index 0b8ac7e15..483eb32f8 100644 --- a/app/src/main/java/org/mozilla/reference/browser/browser/ToolbarIntegration.kt +++ b/app/src/main/java/org/mozilla/reference/browser/browser/ToolbarIntegration.kt @@ -10,6 +10,7 @@ import android.view.View import android.view.ViewGroup import androidx.core.content.ContextCompat import androidx.core.content.res.ResourcesCompat +import kotlinx.coroutines.Job import kotlinx.coroutines.MainScope import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map @@ -52,7 +53,7 @@ class ToolbarIntegration( toolbar: BrowserToolbar, toolbarParentView: View, historyStorage: PlacesHistoryStorage, - store: BrowserStore, + private val store: BrowserStore, private val sessionUseCases: SessionUseCases, private val tabsUseCases: TabsUseCases, private val webAppUseCases: WebAppUseCases, @@ -64,6 +65,7 @@ class ToolbarIntegration( } private val scope = MainScope() + private var menuUpdateJob: Job? = null private fun menuToolbar(session: SessionState?): RowMenuCandidate { val tint = ContextCompat.getColor(context, R.color.icons) @@ -217,16 +219,6 @@ class ToolbarIntegration( } }, ) - - scope.launch { - store - .flow() - .map { state -> state.selectedTab } - .distinctUntilChanged() - .collect { tab -> - browserMenuController.submitList(menuItems(tab)) - } - } } private val toolbarFeature: ToolbarFeature = @@ -246,10 +238,24 @@ class ToolbarIntegration( override fun start() { toolbarFeature.start() + + menuUpdateJob?.cancel() + menuUpdateJob = scope.launch { + store + .flow() + .map { state -> state.selectedTab } + .distinctUntilChanged() + .collect { tab -> + browserMenuController.submitList(menuItems(tab)) + } + } } override fun stop() { toolbarFeature.stop() + + menuUpdateJob?.cancel() + menuUpdateJob = null } override fun onBackPressed(): Boolean = toolbarFeature.onBackPressed() diff --git a/app/src/main/java/org/mozilla/reference/browser/components/BackgroundServices.kt b/app/src/main/java/org/mozilla/reference/browser/components/BackgroundServices.kt index 146e44141..88ec088cb 100644 --- a/app/src/main/java/org/mozilla/reference/browser/components/BackgroundServices.kt +++ b/app/src/main/java/org/mozilla/reference/browser/components/BackgroundServices.kt @@ -8,7 +8,6 @@ import android.content.Context import android.os.Build import java.util.concurrent.TimeUnit import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import mozilla.appservices.fxaclient.FxaServer import mozilla.components.browser.storage.sync.PlacesHistoryStorage @@ -96,7 +95,7 @@ class BackgroundServices( SyncedTabsIntegration(context, accountManager).launch() - CoroutineScope(Dispatchers.Main).launch { accountManager.start() } + applicationScope.launch { accountManager.start() } } } diff --git a/app/src/main/java/org/mozilla/reference/browser/components/Services.kt b/app/src/main/java/org/mozilla/reference/browser/components/Services.kt index 6cb641d02..92fa9f964 100644 --- a/app/src/main/java/org/mozilla/reference/browser/components/Services.kt +++ b/app/src/main/java/org/mozilla/reference/browser/components/Services.kt @@ -6,7 +6,7 @@ package org.mozilla.reference.browser.components import android.content.Context import androidx.preference.PreferenceManager -import kotlinx.coroutines.MainScope +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import mozilla.components.feature.accounts.FirefoxAccountsAuthFeature import mozilla.components.feature.app.links.AppLinksInterceptor @@ -20,6 +20,7 @@ class Services( private val context: Context, private val accountManager: FxaAccountManager, private val tabsUseCases: TabsUseCases, + private val applicationScope: CoroutineScope, ) { private val prefs = PreferenceManager.getDefaultSharedPreferences(context) val accountsAuthFeature by lazy { @@ -27,7 +28,7 @@ class Services( accountManager, redirectUrl = BackgroundServices.REDIRECT_URL, ) { _, authUrl -> - MainScope().launch { + applicationScope.launch { tabsUseCases.addTab.invoke(authUrl) } } diff --git a/app/src/main/java/org/mozilla/reference/browser/push/PushFxaIntegration.kt b/app/src/main/java/org/mozilla/reference/browser/push/PushFxaIntegration.kt index b0acf8040..6fb68ec79 100644 --- a/app/src/main/java/org/mozilla/reference/browser/push/PushFxaIntegration.kt +++ b/app/src/main/java/org/mozilla/reference/browser/push/PushFxaIntegration.kt @@ -5,8 +5,6 @@ package org.mozilla.reference.browser.push import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.MainScope import kotlinx.coroutines.launch import mozilla.components.concept.sync.AccountObserver import mozilla.components.concept.sync.AuthType @@ -52,11 +50,13 @@ import org.mozilla.reference.browser.components.Push class PushFxaIntegration( private val pushFeature: AutoPushFeature, lazyAccountManager: Lazy, + applicationScope: CoroutineScope, ) { private val observer = OneTimePushMessageObserver( lazyAccountManager, pushFeature, + applicationScope, ) /** @@ -73,6 +73,7 @@ class PushFxaIntegration( internal class OneTimePushMessageObserver( private val lazyAccountManager: Lazy, private val pushFeature: AutoPushFeature, + private val applicationScope: CoroutineScope, ) : AutoPushFeature.Observer { override fun onMessageReceived( scope: PushScope, @@ -85,8 +86,8 @@ internal class OneTimePushMessageObserver( if (scope.contains(FxaPushSupportFeature.PUSH_SCOPE_PREFIX)) { // If we aren't initialized, then we should do the initialization and message delivery. if (!lazyAccountManager.isInitialized()) { - CoroutineScope(Dispatchers.Main).launch { - val fxaObserver = OneTimeMessageDeliveryObserver(lazyAccountManager, rawBytes) + applicationScope.launch { + val fxaObserver = OneTimeMessageDeliveryObserver(lazyAccountManager, rawBytes, applicationScope) // Start observing the account manager, so that we can deliver our message // only when we are authenticated and are capable of processing it. @@ -94,7 +95,7 @@ internal class OneTimePushMessageObserver( } } - MainScope().launch { + applicationScope.launch { // Remove ourselves when we're done. pushFeature.unregister(this@OneTimePushMessageObserver) } @@ -109,12 +110,13 @@ internal class OneTimePushMessageObserver( internal class OneTimeMessageDeliveryObserver( private val lazyAccount: Lazy, private val message: ByteArray, + private val applicationScope: CoroutineScope, ) : AccountObserver { override fun onAuthenticated( account: OAuthAccount, authType: AuthType, ) { - MainScope().launch { + applicationScope.launch { lazyAccount.value.withConstellationIfExists { processRawEvent(String(message)) } diff --git a/app/src/main/java/org/mozilla/reference/browser/push/WebPushEngineIntegration.kt b/app/src/main/java/org/mozilla/reference/browser/push/WebPushEngineIntegration.kt index d0b5d0634..6d8d68b2b 100644 --- a/app/src/main/java/org/mozilla/reference/browser/push/WebPushEngineIntegration.kt +++ b/app/src/main/java/org/mozilla/reference/browser/push/WebPushEngineIntegration.kt @@ -6,7 +6,6 @@ package org.mozilla.reference.browser.push import android.util.Base64 import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import mozilla.components.concept.engine.Engine import mozilla.components.concept.engine.webpush.WebPushDelegate @@ -20,6 +19,7 @@ import mozilla.components.support.base.log.logger.Logger class WebPushEngineIntegration( private val engine: Engine, private val pushFeature: AutoPushFeature, + private val applicationScope: CoroutineScope, ) : AutoPushFeature.Observer { private var handler: WebPushHandler? = null private val delegate = WebPushEngineDelegate(pushFeature) @@ -38,13 +38,13 @@ class WebPushEngineIntegration( scope: PushScope, message: ByteArray?, ) { - CoroutineScope(Dispatchers.Main).launch { + applicationScope.launch { handler?.onPushMessage(scope, message) } } override fun onSubscriptionChanged(scope: PushScope) { - CoroutineScope(Dispatchers.Main).launch { + applicationScope.launch { handler?.onSubscriptionChanged(scope) } } diff --git a/app/src/main/java/org/mozilla/reference/browser/settings/AccountSettingsFragment.kt b/app/src/main/java/org/mozilla/reference/browser/settings/AccountSettingsFragment.kt index 8b7df9b3b..7bb0ec490 100644 --- a/app/src/main/java/org/mozilla/reference/browser/settings/AccountSettingsFragment.kt +++ b/app/src/main/java/org/mozilla/reference/browser/settings/AccountSettingsFragment.kt @@ -15,7 +15,6 @@ import androidx.preference.CheckBoxPreference import androidx.preference.Preference import androidx.preference.Preference.OnPreferenceClickListener import androidx.preference.PreferenceFragmentCompat -import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import mozilla.components.concept.sync.SyncEngine @@ -40,7 +39,7 @@ class AccountSettingsFragment : PreferenceFragmentCompat() { private val syncStatusObserver = object : SyncStatusObserver { override fun onStarted() { - CoroutineScope(Dispatchers.Main).launch { + lifecycleScope.launch(Dispatchers.Main) { val pref = findPreference(requireContext().getPreferenceKey(pref_key_sync_now)) pref?.title = getString(R.string.syncing) @@ -50,7 +49,7 @@ class AccountSettingsFragment : PreferenceFragmentCompat() { // Sync stopped successfully. override fun onIdle() { - CoroutineScope(Dispatchers.Main).launch { + lifecycleScope.launch(Dispatchers.Main) { val pref = findPreference(requireContext().getPreferenceKey(pref_key_sync_now)) pref?.title = getString(R.string.sync_now) pref?.isEnabled = true @@ -61,7 +60,7 @@ class AccountSettingsFragment : PreferenceFragmentCompat() { // Sync stopped after encountering a problem. override fun onError(error: Exception?) { - CoroutineScope(Dispatchers.Main).launch { + lifecycleScope.launch(Dispatchers.Main) { val pref = findPreference(requireContext().getPreferenceKey(pref_key_sync_now)) pref?.title = getString(R.string.sync_now) pref?.isEnabled = true @@ -146,7 +145,7 @@ class AccountSettingsFragment : PreferenceFragmentCompat() { } private fun getClickListenerForSignOut(): OnPreferenceClickListener = OnPreferenceClickListener { - CoroutineScope(Dispatchers.Main).launch { + viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main) { requireComponents.backgroundServices.accountManager.logout() activity?.onBackPressedDispatcher?.onBackPressed() } @@ -154,7 +153,7 @@ class AccountSettingsFragment : PreferenceFragmentCompat() { } private fun getClickListenerForSyncNow(): OnPreferenceClickListener = OnPreferenceClickListener { - CoroutineScope(Dispatchers.Main).launch { + viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main) { // Trigger a sync & update devices. requireComponents.backgroundServices.accountManager.syncNow(SyncReason.User) // Poll for device events. @@ -196,7 +195,7 @@ class AccountSettingsFragment : PreferenceFragmentCompat() { engine: SyncEngine, newState: Boolean, ) { - CoroutineScope(Dispatchers.Main).launch { + viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main) { requireComponents.backgroundServices.accountManager.setEngineEnabled(engine, newState) } } diff --git a/config/detekt-baseline.xml b/config/detekt-baseline.xml index 37ffd6643..9ec92b0c8 100644 --- a/config/detekt-baseline.xml +++ b/config/detekt-baseline.xml @@ -61,7 +61,7 @@ UndocumentedPublicFunction:Config.kt$Config$@JvmStatic fun generateDebugVersionName(): String UndocumentedPublicFunction:Config.kt$Config$@JvmStatic fun releaseVersionName(project: Project): String UndocumentedPublicFunction:Context.kt$fun Context.getPreferenceKey(@StringRes resourceId: Int): String - UndocumentedPublicFunction:CrashIntegration.kt$CrashIntegration$@OptIn(DelicateCoroutinesApi::class) fun sendCrashReport(crash: Crash) + UndocumentedPublicFunction:CrashIntegration.kt$CrashIntegration$fun sendCrashReport(crash: Crash) UndocumentedPublicFunction:EngineProvider.kt$EngineProvider$@Synchronized fun getOrCreateRuntime(context: Context): GeckoRuntime UndocumentedPublicFunction:EngineProvider.kt$EngineProvider$fun createClient(context: Context): Client UndocumentedPublicFunction:EngineProvider.kt$EngineProvider$fun createEngine( context: Context, defaultSettings: DefaultSettings, ): Engine