From 4782705af9bdfc59b1c5f6cbc33ed1303c3206f0 Mon Sep 17 00:00:00 2001 From: Sebastian Kaspari Date: Wed, 26 Aug 2020 13:43:20 +0200 Subject: [PATCH] Add diagnostic breadcrumbs for debugging "Display already aquired" crashes. For: https://github.com/mozilla-mobile/android-components/issues/7960 --- .../java/org/mozilla/fenix/HomeActivity.kt | 89 +++++++++++++++++++ .../fenix/browser/BaseBrowserFragment.kt | 37 ++++++++ .../java/org/mozilla/fenix/ext/Activity.kt | 17 ++++ .../java/org/mozilla/fenix/ext/Fragment.kt | 21 +++++ 4 files changed, 164 insertions(+) diff --git a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt index c870dd394..fcff23ee2 100644 --- a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt @@ -6,6 +6,7 @@ package org.mozilla.fenix import android.content.Context import android.content.Intent +import android.content.res.Configuration import android.os.Build import android.os.Bundle import android.os.StrictMode @@ -69,6 +70,7 @@ import org.mozilla.fenix.components.metrics.BreadcrumbsRecorder import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.exceptions.trackingprotection.TrackingProtectionExceptionsFragmentDirections import org.mozilla.fenix.ext.alreadyOnDestination +import org.mozilla.fenix.ext.breadcrumb import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.metrics import org.mozilla.fenix.ext.nav @@ -155,6 +157,16 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { super.onCreate(savedInstanceState) } + // Diagnostic breadcrumb for "Display already aquired" crash: + // https://github.com/mozilla-mobile/android-components/issues/7960 + breadcrumb( + message = "onCreate()", + data = mapOf( + "recreated" to (savedInstanceState != null).toString(), + "intent" to (intent?.action ?: "null") + ) + ) + components.publicSuffixList.prefetch() setupThemeAndBrowsingMode(getModeFromIntentOrLastKnown(intent)) @@ -233,6 +245,12 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { override fun onResume() { super.onResume() + // Diagnostic breadcrumb for "Display already aquired" crash: + // https://github.com/mozilla-mobile/android-components/issues/7960 + breadcrumb( + message = "onResume()" + ) + components.backgroundServices.accountManagerAvailableQueue.runIfReadyOrQueue { lifecycleScope.launch { // Make sure accountManager is initialized. @@ -260,6 +278,29 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { } } + override fun onStart() { + super.onStart() + + // Diagnostic breadcrumb for "Display already aquired" crash: + // https://github.com/mozilla-mobile/android-components/issues/7960 + breadcrumb( + message = "onStart()" + ) + } + + override fun onStop() { + super.onStop() + + // Diagnostic breadcrumb for "Display already aquired" crash: + // https://github.com/mozilla-mobile/android-components/issues/7960 + breadcrumb( + message = "onStop()", + data = mapOf( + "finishing" to isFinishing.toString() + ) + ) + } + final override fun onPause() { if (settings().lastKnownMode.isPrivate) { window.addFlags(WindowManager.LayoutParams.FLAG_SECURE) @@ -267,6 +308,15 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { super.onPause() + // Diagnostic breadcrumb for "Display already aquired" crash: + // https://github.com/mozilla-mobile/android-components/issues/7960 + breadcrumb( + message = "onPause()", + data = mapOf( + "finishing" to isFinishing.toString() + ) + ) + // Every time the application goes into the background, it is possible that the user // is about to change the browsers installed on their system. Therefore, we reset the cache of // all the installed browsers. @@ -277,9 +327,39 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { override fun onDestroy() { super.onDestroy() + + // Diagnostic breadcrumb for "Display already aquired" crash: + // https://github.com/mozilla-mobile/android-components/issues/7960 + breadcrumb( + message = "onDestroy()", + data = mapOf( + "finishing" to isFinishing.toString() + ) + ) + privateNotificationObserver?.stop() } + override fun onConfigurationChanged(newConfig: Configuration) { + super.onConfigurationChanged(newConfig) + + // Diagnostic breadcrumb for "Display already aquired" crash: + // https://github.com/mozilla-mobile/android-components/issues/7960 + breadcrumb( + message = "onConfigurationChanged()" + ) + } + + override fun recreate() { + // Diagnostic breadcrumb for "Display already aquired" crash: + // https://github.com/mozilla-mobile/android-components/issues/7960 + breadcrumb( + message = "recreate()" + ) + + super.recreate() + } + /** * Handles intents received when the activity is open. */ @@ -287,6 +367,15 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity { super.onNewIntent(intent) intent ?: return + // Diagnostic breadcrumb for "Display already aquired" crash: + // https://github.com/mozilla-mobile/android-components/issues/7960 + breadcrumb( + message = "onNewIntent()", + data = mapOf( + "intent" to intent.action.toString() + ) + ) + val intentProcessors = listOf(CrashReporterIntentProcessor()) + externalSourceIntentProcessors val intentHandled = diff --git a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt index 631eefb22..f76fe4288 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BaseBrowserFragment.kt @@ -98,6 +98,7 @@ import org.mozilla.fenix.components.toolbar.ToolbarPosition import org.mozilla.fenix.downloads.DownloadService import org.mozilla.fenix.downloads.DynamicDownloadDialog import org.mozilla.fenix.ext.accessibilityManager +import org.mozilla.fenix.ext.breadcrumb import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.enterToImmersiveMode import org.mozilla.fenix.ext.getPreferenceKey @@ -170,6 +171,15 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session require(arguments != null) customTabSessionId = arguments?.getString(EXTRA_SESSION_ID) + // Diagnostic breadcrumb for "Display already aquired" crash: + // https://github.com/mozilla-mobile/android-components/issues/7960 + breadcrumb( + message = "onCreateView()", + data = mapOf( + "customTabSessionId" to customTabSessionId.toString() + ) + ) + val view = inflater.inflate(R.layout.fragment_browser, container, false) val activity = activity as HomeActivity @@ -1061,11 +1071,38 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session */ override fun onDestroyView() { super.onDestroyView() + + // Diagnostic breadcrumb for "Display already aquired" crash: + // https://github.com/mozilla-mobile/android-components/issues/7960 + breadcrumb( + message = "onDestroyView()" + ) + requireContext().accessibilityManager.removeAccessibilityStateChangeListener(this) _browserToolbarView = null _browserInteractor = null } + override fun onAttach(context: Context) { + super.onAttach(context) + + // Diagnostic breadcrumb for "Display already aquired" crash: + // https://github.com/mozilla-mobile/android-components/issues/7960 + breadcrumb( + message = "onAttach()" + ) + } + + override fun onDetach() { + super.onDetach() + + // Diagnostic breadcrumb for "Display already aquired" crash: + // https://github.com/mozilla-mobile/android-components/issues/7960 + breadcrumb( + message = "onDetach()" + ) + } + companion object { private const val KEY_CUSTOM_TAB_SESSION_ID = "custom_tab_session_id" private const val REQUEST_CODE_DOWNLOAD_PERMISSIONS = 1 diff --git a/app/src/main/java/org/mozilla/fenix/ext/Activity.kt b/app/src/main/java/org/mozilla/fenix/ext/Activity.kt index 7dd2b3dce..e65ad9f35 100644 --- a/app/src/main/java/org/mozilla/fenix/ext/Activity.kt +++ b/app/src/main/java/org/mozilla/fenix/ext/Activity.kt @@ -7,6 +7,7 @@ package org.mozilla.fenix.ext import android.app.Activity import android.view.View import android.view.WindowManager +import mozilla.components.support.base.crash.Breadcrumb /** * Attempts to call immersive mode using the View to hide the status bar and navigation buttons. @@ -22,3 +23,19 @@ fun Activity.enterToImmersiveMode() { or View.SYSTEM_UI_FLAG_FULLSCREEN or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY) } + +fun Activity.breadcrumb( + message: String, + data: Map = emptyMap() +) { + components.analytics.crashReporter.recordCrashBreadcrumb( + Breadcrumb( + category = this::class.java.simpleName, + message = message, + data = data + mapOf( + "instance" to this.hashCode().toString() + ), + level = Breadcrumb.Level.INFO + ) + ) +} diff --git a/app/src/main/java/org/mozilla/fenix/ext/Fragment.kt b/app/src/main/java/org/mozilla/fenix/ext/Fragment.kt index f4128e335..39c3f7bb4 100644 --- a/app/src/main/java/org/mozilla/fenix/ext/Fragment.kt +++ b/app/src/main/java/org/mozilla/fenix/ext/Fragment.kt @@ -12,6 +12,7 @@ import androidx.navigation.NavDirections import androidx.navigation.NavOptions import androidx.navigation.fragment.NavHostFragment.findNavController import androidx.navigation.fragment.findNavController +import mozilla.components.support.base.crash.Breadcrumb import org.mozilla.fenix.NavHostActivity import org.mozilla.fenix.R import org.mozilla.fenix.components.Components @@ -57,3 +58,23 @@ fun Fragment.redirectToReAuth(destinations: List, currentDestination: Int?) findNavController().popBackStack(R.id.savedLoginsAuthFragment, false) } } + +fun Fragment.breadcrumb( + message: String, + data: Map = emptyMap() +) { + val activityName = activity?.let { it::class.java.simpleName } ?: "null" + + requireComponents.analytics.crashReporter.recordCrashBreadcrumb( + Breadcrumb( + category = this::class.java.simpleName, + message = message, + data = data + mapOf( + "instance" to hashCode().toString(), + "activityInstance" to activity?.hashCode().toString(), + "activityName" to activityName + ), + level = Breadcrumb.Level.INFO + ) + ) +}