Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()
}
}
Expand All @@ -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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -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()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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<WebExtensionPromptFeature>()
private lateinit var recyclerView: RecyclerView
private val scope = CoroutineScope(Dispatchers.IO)
private lateinit var addons: List<Addon>
private var adapter: AddonsManagerAdapter? = null

Expand All @@ -47,7 +49,6 @@ class AddonsFragment : Fragment(), AddonsManagerAdapterDelegate {
savedInstanceState: Bundle?,
) {
super.onViewCreated(rootView, savedInstanceState)
bindRecyclerView(rootView)
webExtensionPromptFeature.set(
feature =
WebExtensionPromptFeature(
Expand All @@ -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()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,23 @@ 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
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))
Expand All @@ -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()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -168,7 +167,6 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
}
}

@OptIn(DelicateCoroutinesApi::class)
private fun deleteHistorySuggestion(suggestion: Suggestion) {
lifecycleScope.launch(Dispatchers.IO) {
suggestion.description?.let {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand All @@ -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)
Expand Down Expand Up @@ -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 =
Expand All @@ -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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -96,7 +95,7 @@ class BackgroundServices(

SyncedTabsIntegration(context, accountManager).launch()

CoroutineScope(Dispatchers.Main).launch { accountManager.start() }
applicationScope.launch { accountManager.start() }
}
}

Expand Down
Loading