diff --git a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt index 873b4acbb..da2a72325 100644 --- a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt @@ -19,6 +19,7 @@ import androidx.navigation.ui.NavigationUI import mozilla.components.browser.session.Session import mozilla.components.concept.engine.EngineView import mozilla.components.feature.intent.IntentProcessor +import mozilla.components.lib.crash.Crash import mozilla.components.support.base.feature.BackHandler import mozilla.components.support.ktx.kotlin.isUrl import mozilla.components.support.ktx.kotlin.toNormalizedUrl @@ -38,6 +39,10 @@ open class HomeActivity : AppCompatActivity() { } } + private val navHost by lazy { + supportFragmentManager.findFragmentById(R.id.container) as NavHostFragment + } + lateinit var browsingModeManager: DefaultBrowsingModeManager override fun onCreate(savedInstanceState: Bundle?) { @@ -50,12 +55,10 @@ open class HomeActivity : AppCompatActivity() { setContentView(R.layout.activity_home) - val host = supportFragmentManager.findFragmentById(R.id.container) as NavHostFragment - val hostNavController = host.navController val appBarConfiguration = AppBarConfiguration.Builder(setOf(R.id.libraryFragment)).build() val navigationToolbar = findViewById(R.id.navigationToolbar) setSupportActionBar(navigationToolbar) - NavigationUI.setupWithNavController(navigationToolbar, hostNavController, appBarConfiguration) + NavigationUI.setupWithNavController(navigationToolbar, navHost.navController, appBarConfiguration) handleOpenedFromExternalSourceIfNecessary(intent) } @@ -67,6 +70,7 @@ open class HomeActivity : AppCompatActivity() { override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) + handleCrashIfNecessary(intent) handleOpenedFromExternalSourceIfNecessary(intent) } @@ -104,6 +108,18 @@ open class HomeActivity : AppCompatActivity() { } } + private fun handleCrashIfNecessary(intent: Intent?) { + if (intent == null) { return } + if (!Crash.isCrashIntent(intent)) { return } + + openToCrashReporter(intent) + } + + private fun openToCrashReporter(intent: Intent) { + val directions = NavGraphDirections.actionGlobalCrashReporter(intent) + navHost.navController.navigate(directions) + } + private fun handleOpenedFromExternalSourceIfNecessary(intent: Intent?) { if (intent?.extras?.getBoolean(OPEN_TO_BROWSER) == true) { handleOpenedFromExternalSource() @@ -121,8 +137,6 @@ open class HomeActivity : AppCompatActivity() { } fun openToBrowser(sessionId: String?, from: BrowserDirection) { - val host = supportFragmentManager.findFragmentById(R.id.container) as NavHostFragment - val directions = when (from) { BrowserDirection.FromGlobal -> NavGraphDirections.actionGlobalBrowser(sessionId) BrowserDirection.FromHome -> HomeFragmentDirections.actionHomeFragmentToBrowserFragment(sessionId) @@ -131,7 +145,7 @@ open class HomeActivity : AppCompatActivity() { SettingsFragmentDirections.actionSettingsFragmentToBrowserFragment(sessionId) } - host.navController.navigate(directions) + navHost.navController.navigate(directions) } private fun load(text: String, sessionId: String?) { diff --git a/app/src/main/java/org/mozilla/fenix/components/Analytics.kt b/app/src/main/java/org/mozilla/fenix/components/Analytics.kt index fd69e280c..4588ad6f8 100644 --- a/app/src/main/java/org/mozilla/fenix/components/Analytics.kt +++ b/app/src/main/java/org/mozilla/fenix/components/Analytics.kt @@ -5,11 +5,14 @@ package org.mozilla.fenix.components import android.app.Application +import android.app.PendingIntent import android.content.Context +import android.content.Intent import mozilla.components.lib.crash.CrashReporter import mozilla.components.lib.crash.service.MozillaSocorroService import mozilla.components.lib.crash.service.SentryService import org.mozilla.fenix.BuildConfig +import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.R import org.mozilla.fenix.components.metrics.GleanMetricsService import org.mozilla.fenix.components.metrics.LeanplumMetricsService @@ -34,6 +37,17 @@ class Analytics( val socorroService = MozillaSocorroService(context, "Fenix") + val intent = Intent(context, HomeActivity::class.java).apply { + flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP + } + + val pendingIntent = PendingIntent.getActivity( + context, + 0, + intent, + 0 + ) + CrashReporter( services = listOf(sentryService, socorroService), shouldPrompt = CrashReporter.Prompt.ALWAYS, @@ -41,7 +55,8 @@ class Analytics( appName = context.getString(R.string.app_name), organizationName = "Mozilla" ), - enabled = true + enabled = true, + nonFatalCrashIntent = pendingIntent ) } diff --git a/app/src/main/java/org/mozilla/fenix/crashes/CrashReporterFragment.kt b/app/src/main/java/org/mozilla/fenix/crashes/CrashReporterFragment.kt new file mode 100644 index 000000000..40a018858 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/crashes/CrashReporterFragment.kt @@ -0,0 +1,56 @@ +/* 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 android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.navigation.Navigation +import kotlinx.android.synthetic.main.fragment_crash_reporter.* +import mozilla.components.lib.crash.Crash +import org.mozilla.fenix.R +import org.mozilla.fenix.ext.requireComponents + +class CrashReporterFragment : Fragment() { + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View? = inflater.inflate(R.layout.fragment_crash_reporter, container, false) + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + val crashIntent = CrashReporterFragmentArgs.fromBundle(arguments!!).crashIntent + + val crash = Crash.fromIntent(CrashReporterFragmentArgs.fromBundle(arguments!!).crashIntent) + // TODO TelemetryWrapper.crashReporterOpened() + + closeTabButton.setOnClickListener { + val wantsToSubmitCrashReport = sendCrashCheckbox.isChecked + val selectedSession = requireComponents.core.sessionManager.selectedSession + + selectedSession?.let { session -> requireComponents.useCases.tabsUseCases.removeTab.invoke(session) } + // TODO TelemetryWrapper.crashReporterClosed(wantsSubmitCrashReport) + + if (wantsToSubmitCrashReport) { + requireComponents.analytics.crashReporter.submitReport(crash) + } + + navigateHome(view) + } + } + + fun navigateHome(fromView: View) { + val directions = CrashReporterFragmentDirections.actionCrashReporterFragmentToHomeFragment() + Navigation.findNavController(fromView).navigate(directions) + } + + fun onBackPressed() { + // TODO TelemetryWrapper.crashReporterClosed(false) + } +} diff --git a/app/src/main/res/drawable/ic_error_session_crashed.png b/app/src/main/res/drawable/ic_error_session_crashed.png new file mode 100644 index 000000000..776cc05e1 Binary files /dev/null and b/app/src/main/res/drawable/ic_error_session_crashed.png differ diff --git a/app/src/main/res/layout/fragment_browser.xml b/app/src/main/res/layout/fragment_browser.xml index b821b73d9..7a53d81a5 100644 --- a/app/src/main/res/layout/fragment_browser.xml +++ b/app/src/main/res/layout/fragment_browser.xml @@ -11,6 +11,13 @@ android:layout_height="match_parent" tools:context="browser.BrowserFragment"> + + + + + + + + + + + + + +