mirror of
https://github.com/fork-maintainers/iceraven-browser
synced 2024-11-11 13:11:01 +00:00
Extract and test crash reporter code
This commit is contained in:
parent
89a9b5057b
commit
172a9cf06c
@ -0,0 +1,70 @@
|
|||||||
|
/* 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.crashes
|
||||||
|
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
import mozilla.components.browser.session.Session
|
||||||
|
import mozilla.components.lib.crash.Crash
|
||||||
|
import org.mozilla.fenix.R
|
||||||
|
import org.mozilla.fenix.components.Components
|
||||||
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
|
import org.mozilla.fenix.ext.nav
|
||||||
|
import org.mozilla.fenix.utils.Settings
|
||||||
|
|
||||||
|
class CrashReporterController(
|
||||||
|
private val crash: Crash,
|
||||||
|
private val session: Session?,
|
||||||
|
private val navController: NavController,
|
||||||
|
private val components: Components,
|
||||||
|
private val settings: Settings
|
||||||
|
) {
|
||||||
|
|
||||||
|
init {
|
||||||
|
components.analytics.metrics.track(Event.CrashReporterOpened)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the crash reporter fragment and tries to recover the session.
|
||||||
|
*
|
||||||
|
* @param sendCrash If true, submit a crash report.
|
||||||
|
*/
|
||||||
|
fun handleCloseAndRestore(sendCrash: Boolean) {
|
||||||
|
submitReportIfNecessary(sendCrash)
|
||||||
|
|
||||||
|
components.useCases.sessionUseCases.crashRecovery.invoke()
|
||||||
|
navController.popBackStack()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the crash reporter fragment and the tab.
|
||||||
|
*
|
||||||
|
* @param sendCrash If true, submit a crash report.
|
||||||
|
*/
|
||||||
|
fun handleCloseAndRemove(sendCrash: Boolean) {
|
||||||
|
session ?: return
|
||||||
|
submitReportIfNecessary(sendCrash)
|
||||||
|
|
||||||
|
components.useCases.tabsUseCases.removeTab(session)
|
||||||
|
components.useCases.sessionUseCases.crashRecovery.invoke()
|
||||||
|
navController.nav(
|
||||||
|
R.id.crashReporterFragment,
|
||||||
|
CrashReporterFragmentDirections.actionCrashReporterFragmentToHomeFragment()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Submits the crash report if the "Send crash" checkbox was checked and the setting is enabled.
|
||||||
|
*/
|
||||||
|
private fun submitReportIfNecessary(sendCrash: Boolean) {
|
||||||
|
val didSubmitReport = if (sendCrash && settings.isCrashReportingEnabled) {
|
||||||
|
components.analytics.crashReporter.submitReport(crash)
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
components.analytics.metrics.track(Event.CrashReporterClosed(didSubmitReport))
|
||||||
|
}
|
||||||
|
}
|
@ -10,19 +10,19 @@ import android.view.View
|
|||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.navigation.Navigation
|
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
|
import androidx.navigation.fragment.navArgs
|
||||||
import kotlinx.android.synthetic.main.fragment_crash_reporter.*
|
import kotlinx.android.synthetic.main.fragment_crash_reporter.*
|
||||||
import mozilla.components.browser.session.Session
|
|
||||||
import mozilla.components.lib.crash.Crash
|
import mozilla.components.lib.crash.Crash
|
||||||
import org.mozilla.fenix.R
|
import org.mozilla.fenix.R
|
||||||
import org.mozilla.fenix.components.metrics.Event
|
|
||||||
import org.mozilla.fenix.ext.components
|
|
||||||
import org.mozilla.fenix.ext.nav
|
|
||||||
import org.mozilla.fenix.ext.requireComponents
|
import org.mozilla.fenix.ext.requireComponents
|
||||||
import org.mozilla.fenix.ext.settings
|
import org.mozilla.fenix.ext.settings
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fragment shown when a tab crashes.
|
||||||
|
*/
|
||||||
class CrashReporterFragment : Fragment() {
|
class CrashReporterFragment : Fragment() {
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
@ -31,21 +31,25 @@ class CrashReporterFragment : Fragment() {
|
|||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
val crash = Crash.fromIntent(CrashReporterFragmentArgs.fromBundle(arguments!!).crashIntent)
|
|
||||||
|
|
||||||
title.text =
|
val args: CrashReporterFragmentArgs by navArgs()
|
||||||
getString(R.string.tab_crash_title_2, context!!.getString(R.string.app_name))
|
val crash = Crash.fromIntent(args.crashIntent)
|
||||||
|
|
||||||
requireContext().components.analytics.metrics.track(Event.CrashReporterOpened)
|
title.text = getString(R.string.tab_crash_title_2, getString(R.string.app_name))
|
||||||
|
|
||||||
val selectedSession = requireComponents.core.sessionManager.selectedSession
|
val controller = CrashReporterController(
|
||||||
|
crash,
|
||||||
|
session = requireComponents.core.sessionManager.selectedSession,
|
||||||
|
navController = findNavController(),
|
||||||
|
components = requireComponents,
|
||||||
|
settings = requireContext().settings
|
||||||
|
)
|
||||||
|
|
||||||
restoreTabButton.setOnClickListener {
|
restoreTabButton.setOnClickListener {
|
||||||
selectedSession?.let { session -> closeFragment(true, session, crash) }
|
controller.handleCloseAndRestore(sendCrashCheckbox.isChecked)
|
||||||
}
|
}
|
||||||
|
|
||||||
closeTabButton.setOnClickListener {
|
closeTabButton.setOnClickListener {
|
||||||
selectedSession?.let { session -> closeFragment(false, session, crash) }
|
controller.handleCloseAndRemove(sendCrashCheckbox.isChecked)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,31 +57,4 @@ class CrashReporterFragment : Fragment() {
|
|||||||
super.onResume()
|
super.onResume()
|
||||||
(activity as AppCompatActivity).supportActionBar?.hide()
|
(activity as AppCompatActivity).supportActionBar?.hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun closeFragment(shouldRestore: Boolean, session: Session, crash: Crash) {
|
|
||||||
submitReportIfNecessary(crash)
|
|
||||||
|
|
||||||
if (shouldRestore) {
|
|
||||||
requireComponents.useCases.sessionUseCases.crashRecovery.invoke()
|
|
||||||
Navigation.findNavController(view!!).popBackStack()
|
|
||||||
} else {
|
|
||||||
requireComponents.useCases.tabsUseCases.removeTab.invoke(session)
|
|
||||||
requireComponents.useCases.sessionUseCases.crashRecovery.invoke()
|
|
||||||
navigateHome()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun submitReportIfNecessary(crash: Crash) {
|
|
||||||
var didSubmitCrashReport = false
|
|
||||||
if (requireContext().settings.isCrashReportingEnabled && sendCrashCheckbox.isChecked) {
|
|
||||||
requireComponents.analytics.crashReporter.submitReport(crash)
|
|
||||||
didSubmitCrashReport = true
|
|
||||||
}
|
|
||||||
requireContext().components.analytics.metrics.track(Event.CrashReporterClosed(didSubmitCrashReport))
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun navigateHome() {
|
|
||||||
val directions = CrashReporterFragmentDirections.actionCrashReporterFragmentToHomeFragment()
|
|
||||||
findNavController().nav(R.id.crashReporterFragment, directions)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,90 @@
|
|||||||
|
/* 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.crashes
|
||||||
|
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
import androidx.navigation.NavDestination
|
||||||
|
import io.mockk.every
|
||||||
|
import io.mockk.mockk
|
||||||
|
import io.mockk.verify
|
||||||
|
import mozilla.components.browser.session.Session
|
||||||
|
import mozilla.components.lib.crash.Crash
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import org.mozilla.fenix.R
|
||||||
|
import org.mozilla.fenix.components.Components
|
||||||
|
import org.mozilla.fenix.components.metrics.Event
|
||||||
|
import org.mozilla.fenix.utils.Settings
|
||||||
|
|
||||||
|
class CrashReporterControllerTest {
|
||||||
|
|
||||||
|
private lateinit var components: Components
|
||||||
|
private lateinit var crash: Crash
|
||||||
|
private lateinit var session: Session
|
||||||
|
private lateinit var navContoller: NavController
|
||||||
|
private lateinit var settings: Settings
|
||||||
|
|
||||||
|
@Before
|
||||||
|
fun setup() {
|
||||||
|
components = mockk(relaxed = true)
|
||||||
|
crash = mockk()
|
||||||
|
session = mockk()
|
||||||
|
navContoller = mockk(relaxed = true)
|
||||||
|
settings = mockk()
|
||||||
|
|
||||||
|
val currentDest: NavDestination = mockk()
|
||||||
|
every { navContoller.currentDestination } returns currentDest
|
||||||
|
every { currentDest.id } returns R.id.crashReporterFragment
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `reports crash reporter opened`() {
|
||||||
|
CrashReporterController(crash, session, navContoller, components, settings)
|
||||||
|
|
||||||
|
verify { components.analytics.metrics.track(Event.CrashReporterOpened) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `handle close and restore tab`() {
|
||||||
|
val controller = CrashReporterController(crash, session, navContoller, components, settings)
|
||||||
|
controller.handleCloseAndRestore(sendCrash = false)
|
||||||
|
|
||||||
|
verify { components.analytics.metrics.track(Event.CrashReporterClosed(false)) }
|
||||||
|
verify { components.useCases.sessionUseCases.crashRecovery.invoke() }
|
||||||
|
verify { navContoller.popBackStack() }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `handle close and remove tab`() {
|
||||||
|
val controller = CrashReporterController(crash, session, navContoller, components, settings)
|
||||||
|
controller.handleCloseAndRemove(sendCrash = false)
|
||||||
|
|
||||||
|
verify { components.analytics.metrics.track(Event.CrashReporterClosed(false)) }
|
||||||
|
verify { components.useCases.tabsUseCases.removeTab(session) }
|
||||||
|
verify { components.useCases.sessionUseCases.crashRecovery.invoke() }
|
||||||
|
verify { navContoller.navigate(CrashReporterFragmentDirections.actionCrashReporterFragmentToHomeFragment()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `don't submit report if setting is turned off`() {
|
||||||
|
every { settings.isCrashReportingEnabled } returns false
|
||||||
|
|
||||||
|
val controller = CrashReporterController(crash, session, navContoller, components, settings)
|
||||||
|
controller.handleCloseAndRestore(sendCrash = true)
|
||||||
|
|
||||||
|
verify { components.analytics.metrics.track(Event.CrashReporterClosed(false)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `submit report if setting is turned on`() {
|
||||||
|
every { settings.isCrashReportingEnabled } returns true
|
||||||
|
|
||||||
|
val controller = CrashReporterController(crash, session, navContoller, components, settings)
|
||||||
|
controller.handleCloseAndRestore(sendCrash = true)
|
||||||
|
|
||||||
|
verify { components.analytics.crashReporter.submitReport(crash) }
|
||||||
|
verify { components.analytics.metrics.track(Event.CrashReporterClosed(true)) }
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user