1
0
Fork 0

Fix #1032: Crash altering sessions DB on main thread

master
Colin Lee 2019-03-15 11:26:07 -05:00 committed by Jeff Boek
parent 9255962219
commit 6e1655e935
4 changed files with 60 additions and 23 deletions

View File

@ -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()
}
}

View File

@ -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,7 +194,9 @@ class HomeFragment : Fragment() {
.subscribe {
when (it) {
is TabsAction.Archive -> {
requireComponents.core.sessionStorage.archive(requireComponents.core.sessionManager)
launch {
requireComponents.core.sessionStorage.archive(requireComponents.core.sessionManager)
}
}
is TabsAction.MenuTapped -> {
val isPrivate = (activity as HomeActivity).browsingModeManager.isPrivate
@ -228,14 +233,18 @@ class HomeFragment : Fragment() {
.subscribe {
when (it) {
is SessionsAction.Select -> {
requireComponents.core.sessionStorage.archive(requireComponents.core.sessionManager)
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 -> {
requireComponents.core.sessionStorage.remove(it.archivedSession.bundle)
launch(IO) {
requireComponents.core.sessionStorage.remove(it.archivedSession.bundle)
}
}
is SessionsAction.MenuTapped ->
openSessionMenu(SessionBottomSheetFragment.SessionType.Archived(it.archivedSession))
@ -358,17 +367,23 @@ class HomeFragment : Fragment() {
private fun openSessionMenu(sessionType: SessionBottomSheetFragment.SessionType) {
SessionBottomSheetFragment.create(sessionType).apply {
onArchive = {
requireComponents.core.sessionStorage.archive(requireComponents.core.sessionManager)
launch {
requireComponents.core.sessionStorage.archive(requireComponents.core.sessionManager)
}
}
onDelete = {
when (it) {
is SessionBottomSheetFragment.SessionType.Archived -> {
requireComponents.core.sessionStorage.remove(it.archivedSession.bundle)
launch(IO) {
requireComponents.core.sessionStorage.remove(it.archivedSession.bundle)
}
}
is SessionBottomSheetFragment.SessionType.Current -> {
requireComponents.useCases.tabsUseCases.removeAllTabsOfType.invoke(false)
requireComponents.core.sessionStorage.current()?.apply {
requireComponents.core.sessionStorage.remove(this)
launch(IO) {
requireComponents.core.sessionStorage.current()?.apply {
requireComponents.core.sessionStorage.remove(this)
}
}
}
is SessionBottomSheetFragment.SessionType.Private -> {

View File

@ -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"
}

View File

@ -46,7 +46,7 @@ object Deps {
const val tools_appservicesgradle = "org.mozilla.appservices:gradle-plugin:${Versions.appservices_gradle_plugin}"
const val kotlin_stdlib = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${Versions.kotlin}"
const val allopen = "org.jetbrains.kotlin:kotlin-allopen:${Versions.kotlin}"
const val allopen = "org.jetbrains.kotlin:kotlin-allopen:${Versions.kotlin}"
const val rxKotlin = "io.reactivex.rxjava2:rxkotlin:${Versions.rxKotlin}"
const val rxAndroid = "io.reactivex.rxjava2:rxandroid:${Versions.rxAndroid}"
@ -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}"
}