Fix #1032: Crash altering sessions DB on main thread
parent
9255962219
commit
6e1655e935
|
@ -0,0 +1,23 @@
|
|||
/* 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 org.mozilla.fenix.ext
|
||||
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import mozilla.components.browser.session.SessionManager
|
||||
import mozilla.components.feature.session.bundling.SessionBundleStorage
|
||||
|
||||
suspend fun SessionBundleStorage.archive(sessionManager: SessionManager) {
|
||||
withContext(Dispatchers.IO) {
|
||||
save(sessionManager.createSnapshot())
|
||||
launch(Dispatchers.Main) {
|
||||
sessionManager.sessions.filter { !it.private }.forEach {
|
||||
sessionManager.remove(it)
|
||||
}
|
||||
}
|
||||
new()
|
||||
}
|
||||
}
|
|
@ -21,15 +21,20 @@ import androidx.lifecycle.Observer
|
|||
import androidx.navigation.Navigation
|
||||
import kotlinx.android.synthetic.main.fragment_home.*
|
||||
import kotlinx.android.synthetic.main.fragment_home.view.*
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Dispatchers.IO
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import mozilla.components.browser.menu.BrowserMenu
|
||||
import mozilla.components.browser.session.Session
|
||||
import mozilla.components.browser.session.SessionManager
|
||||
import mozilla.components.feature.session.bundling.SessionBundleStorage
|
||||
import org.mozilla.fenix.BrowserDirection
|
||||
import org.mozilla.fenix.BrowsingModeManager
|
||||
import org.mozilla.fenix.DefaultThemeManager
|
||||
import org.mozilla.fenix.HomeActivity
|
||||
import org.mozilla.fenix.BrowserDirection
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.ext.archive
|
||||
import org.mozilla.fenix.ext.requireComponents
|
||||
import org.mozilla.fenix.home.sessions.ArchivedSession
|
||||
import org.mozilla.fenix.home.sessions.SessionsAction
|
||||
|
@ -44,30 +49,27 @@ import org.mozilla.fenix.mvi.ActionBusFactory
|
|||
import org.mozilla.fenix.mvi.getAutoDisposeObservable
|
||||
import org.mozilla.fenix.mvi.getManagedEmitter
|
||||
import org.mozilla.fenix.settings.SupportUtils
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
fun SessionBundleStorage.archive(sessionManager: SessionManager) {
|
||||
save(sessionManager.createSnapshot())
|
||||
sessionManager.sessions.filter { !it.private }.forEach {
|
||||
sessionManager.remove(it)
|
||||
}
|
||||
new()
|
||||
}
|
||||
|
||||
@SuppressWarnings("TooManyFunctions")
|
||||
class HomeFragment : Fragment() {
|
||||
class HomeFragment : Fragment(), CoroutineScope {
|
||||
private val bus = ActionBusFactory.get(this)
|
||||
private var sessionObserver: SessionManager.Observer? = null
|
||||
private var homeMenu: HomeMenu? = null
|
||||
private lateinit var tabsComponent: TabsComponent
|
||||
private lateinit var sessionsComponent: SessionsComponent
|
||||
|
||||
private lateinit var job: Job
|
||||
override val coroutineContext: CoroutineContext
|
||||
get() = Dispatchers.Main + job
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
job = Job()
|
||||
val view = inflater.inflate(R.layout.fragment_home, container, false)
|
||||
val sessionManager = requireComponents.core.sessionManager
|
||||
tabsComponent = TabsComponent(
|
||||
|
@ -174,8 +176,9 @@ class HomeFragment : Fragment() {
|
|||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
homeMenu = null
|
||||
job.cancel()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
|
@ -191,8 +194,10 @@ class HomeFragment : Fragment() {
|
|||
.subscribe {
|
||||
when (it) {
|
||||
is TabsAction.Archive -> {
|
||||
launch {
|
||||
requireComponents.core.sessionStorage.archive(requireComponents.core.sessionManager)
|
||||
}
|
||||
}
|
||||
is TabsAction.MenuTapped -> {
|
||||
val isPrivate = (activity as HomeActivity).browsingModeManager.isPrivate
|
||||
val titles = requireComponents.core.sessionManager.sessions
|
||||
|
@ -228,15 +233,19 @@ class HomeFragment : Fragment() {
|
|||
.subscribe {
|
||||
when (it) {
|
||||
is SessionsAction.Select -> {
|
||||
launch {
|
||||
requireComponents.core.sessionStorage.archive(requireComponents.core.sessionManager)
|
||||
}
|
||||
it.archivedSession.bundle.restoreSnapshot()?.apply {
|
||||
requireComponents.core.sessionManager.restore(this)
|
||||
homeScrollView.smoothScrollTo(0, 0)
|
||||
}
|
||||
}
|
||||
is SessionsAction.Delete -> {
|
||||
launch(IO) {
|
||||
requireComponents.core.sessionStorage.remove(it.archivedSession.bundle)
|
||||
}
|
||||
}
|
||||
is SessionsAction.MenuTapped ->
|
||||
openSessionMenu(SessionBottomSheetFragment.SessionType.Archived(it.archivedSession))
|
||||
}
|
||||
|
@ -358,19 +367,25 @@ class HomeFragment : Fragment() {
|
|||
private fun openSessionMenu(sessionType: SessionBottomSheetFragment.SessionType) {
|
||||
SessionBottomSheetFragment.create(sessionType).apply {
|
||||
onArchive = {
|
||||
launch {
|
||||
requireComponents.core.sessionStorage.archive(requireComponents.core.sessionManager)
|
||||
}
|
||||
}
|
||||
onDelete = {
|
||||
when (it) {
|
||||
is SessionBottomSheetFragment.SessionType.Archived -> {
|
||||
launch(IO) {
|
||||
requireComponents.core.sessionStorage.remove(it.archivedSession.bundle)
|
||||
}
|
||||
}
|
||||
is SessionBottomSheetFragment.SessionType.Current -> {
|
||||
requireComponents.useCases.tabsUseCases.removeAllTabsOfType.invoke(false)
|
||||
launch(IO) {
|
||||
requireComponents.core.sessionStorage.current()?.apply {
|
||||
requireComponents.core.sessionStorage.remove(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
is SessionBottomSheetFragment.SessionType.Private -> {
|
||||
requireComponents.useCases.tabsUseCases.removeAllTabsOfType.invoke(true)
|
||||
}
|
||||
|
|
|
@ -68,5 +68,5 @@ task ktlint(type: JavaExec, group: "verification") {
|
|||
description = "Check Kotlin code style."
|
||||
classpath = configurations.ktlint
|
||||
main = "com.github.shyiko.ktlint.Main"
|
||||
args "app/**/*.kt", "architecture/**/*.kt"
|
||||
args "app/src/**/*.kt", "architecture/src/**/*.kt"
|
||||
}
|
|
@ -147,4 +147,3 @@ object Deps {
|
|||
const val glide = "com.github.bumptech.glide:glide:${Versions.glide}"
|
||||
const val glideAnnotationProcessor = "com.github.bumptech.glide:compiler:${Versions.glide}"
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue