Bug 1848139 - Remove unnecessary glean-gradle-plugin step from crash and nimbus builds
[gecko.git] / mobile / android / android-components / components / lib / crash / README.md
blob43208dd3ceb4c6afb8b5de41f1c2079602df986f
1 # [Android Components](../../../README.md) > Libraries > Crash
3 A generic crash reporter component that can report crashes to multiple services.
5 Main features:
7 * Support for multiple crash reporting services (included is support for [Sentry](https://sentry.io) and [Socorro](https://wiki.mozilla.org/Socorro)).
8 * Support for crashes caused by uncaught exceptions.
9 * Support for native code crashes (currently primarily focused on GeckoView crashes).
10 * Can optionally prompt the user for confirmation before sending a crash report.
11 * Support for showing in-app confirmation UI for non-fatal crashes.
13 ## Usage
15 ### Setting up the dependency
17 Use Gradle to download the library from [maven.mozilla.org](https://maven.mozilla.org/) ([Setup repository](../../../README.md#maven-repository)):
19 ```Groovy
20 implementation "org.mozilla.components:lib-crash:{latest-version}"
21 ```
23 ### Setting up crash reporting
25 In the `onCreate()` method of your Application class create a `CrashReporter` instance and call `install()`:
27 ```Kotlin
28 CrashReporter(
29     services = listOf(
30         // List the crash reporting services you want to use
31     )
32 ).install(this)
33 ```
35 With this minimal setup the crash reporting library will capture "uncaught exception" crashes and "native code" crashes and forward them to the configured crash reporting services.
37 ⚠️ Note: To avoid conflicting setups do not use any other crash reporting libraries/services independently from this library.
39 ### Recording crash breadcrumbs to supported services
41 Using the `CrashReporter` instance to record crash breadcrumbs.  These breadcrumbs will then be sent when a crash occurs to aid in debugging.  Breadcrumbs are reported only if the underlying crash reporter service supports it.
43 ⚠️ Note: Directly using Sentry's breadcrumb will not work as expected on Android 10 or above.  Using the `CrashReporter` breadcrumb is preferred.
45 ```Kotlin
46 crashReporter.recordCrashBreadcrumb(
47   CrashBreadcrumb("Settings button clicked", data, "UI", Level.INFO, Type.USER)
49 ```
51 ### Sending crash reports to Sentry
53 ⚠️ Note: The crash reporter library is compiled against the Sentry SDK but it doesn't require it as a dependency. The app using the component is responsible for adding the Sentry dependency to its build files in order to use Sentry crash reporting.
55 Add a `SentryService` instance to your `CrashReporter` in order to upload crashes to Sentry:
57 ```Kotlin
58 CrashReporter(
59     services = listOf(
60         SentryService(applicationContext, "your sentry DSN")
61     )
62 ).install(applicationContext)
63 ```
65 By default only the `DSN` is needed. But there are additional option configuration parameters:
67 ```Kotlin
68 SentryService(
69         applicationContext,
70         "your sentry DSN",
72         // Optionally add tags that will be sent with every crash report
73         tags = mapOf(
74                 "build_flavor" to BuildConfig.FLAVOR,
75                 "build_type" to BuildConfig.BUILD_TYPE
76         ),
78         // Send an event to Sentry for every native code crash. Native code crashes
79         // can't be uploaded to Sentry currently. But sending an event to Sentry
80         // gives you an idea about how often native code crashes. For sending native
81         // crash reports add additional services like Socorro.
82         sendEventForNativeCrashes = true
84 ```
86 ### Sending crash reports to Mozilla Socorro
88 [Socorro](https://wiki.mozilla.org/Socorro) is the name for the [Mozilla Crash Stats](https://crash-stats.mozilla.org/) project.
90 ⚠️ Note: Socorro filters crashes by "app name". New app names need to be safelisted for the server to accept the crash. [File a bug](https://bugzilla.mozilla.org/enter_bug.cgi?product=Socorro) if you would like to get your app added to the safelist.
92 Add a `MozillaSocorroService` instance to your `CrashReporter` in order to upload crashes to Socorro:
94 ```Kotlin
95 CrashReporter(
96     services = listOf(
97                 MozillaSocorroService(applicationContext, "your app name")
98     )
99 ).install(applicationContext)
102 `MozillaSocorroService` will report version information such as App version, Android Component version, Glean version, Application Services version, GeckoView version and Build ID
103 ⚠️ Note: Currently only native code crashes get uploaded to Socorro. Socorro has limited support for "uncaught exception" crashes too, but it is recommended to use a more elaborate solution like Sentry for that.
105 ### Sending crash reports to Glean
107 [Glean](https://docs.telemetry.mozilla.org/concepts/glean/glean.html) is a new way to collect telemetry by Mozilla.
108 This will record crash counts as a labeled counter with each label corresponding to a specific type of crash (`fatal_native_code_crash`, `nonfatal_native_code_crash`, `caught_exception`, `uncaught_exception`, currently).
109 The list of collected metrics is available in the [metrics.yaml file](metrics.yaml), with their documentation [living here](https://dictionary.telemetry.mozilla.org/apps/fenix/pings/crash).
110 Due to the fact that Glean can only be recorded to in the main process and lib-crash runs in a separate process when it runs to handle the crash,
111 lib-crash persists the data in a file format and then reads and records the data from the main process when the application is next run since the `GleanCrashReporterService`
112 constructor is loaded from the main process.
114 Add a `GleanCrashReporterService` instance to your `CrashReporter` in order to record crashes in Glean:
116 ```Kotlin
117 CrashReporter(
118     services = listOf(
119                 GleanCrashReporterService()
120     )
121 ).install(applicationContext)
124 ⚠️ Note: Applications using the `GleanCrashReporterService` are **required** to undergo [Data Collection Review](https://wiki.mozilla.org/Firefox/Data_Collection) for the crash counts that they will be collecting.
126 ### Showing a crash reporter prompt
128 ![](images/crash-dialog.png)
130 Optionally the library can show a prompt asking the user for confirmation before sending a crash report.
132 The behavior can be controlled using the `shouldPrompt` parameter:
134 ```Kotlin
135 CrashReporter(
136     // Always prompt
137     shouldPrompt = CrashReporter.Prompt.ALWAYS,
139     // Or: Only prompt for native crashes
140     shouldPrompt = CrashReporter.Prompt.ONLY_NATIVE_CRASH,
142     // Or: Never show the prompt
143     shouldPrompt = CrashReporter.Prompt.NEVER,
145     // ..
146 ).install(applicationContext)
149 #### Customizing the prompt
151 The crash reporter prompt can be customized by providing a `PromptConfiguration` object:
153 ```Kotlin
154 CrashReporter(
155         promptConfiguration = CrashReporter.PromptConfiguration(
156                 appName = "My App",
157                 organizationName = "My Organization",
159                 // An additional message that will be shown in the prompt
160                 message = "We are very sorry!"
162                 // Use a custom theme for the prompt (Extend Theme.Mozac.CrashReporter)
163                 theme = android.R.style.Theme_Holo_Dialog
164         ),
166         // ..
167 ).install(applicationContext)
170 #### Handling non-fatal crashes
172 A native code crash can be non-fatal. In this situation a child process crashed but the main process (in which the application runs) is not affected. In this situation a crash can be handled more gracefully and instead of using the crash reporter prompt of the component an app may want to show an in-app UI for asking the user for confirmation.
174 ![](images/crash-in-app.png)
176 Provide a `PendingIntent` that will be invoked when a non-fatal crash occurs:
178 ```Kotlin
179 // Launch this activity when a crash occurs.
180 val pendingIntent = PendingIntent.getActivity(
181     context,
182     0,
183     Intent(this, MyActivity::class.java).apply {
184         addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
185     },
186     PendingIntentUtils.defaultFlags
189 CrashReporter(
190     shouldPrompt = CrashReporter.Prompt.ALWAYS,
191     services = listOf(
192         // ...
193     ),
194     nonFatalCrashIntent = pendingIntent
195 ).install(this)
198 In your component that receives the Intent (e.g. `Activity`) you can use `Crash.fromIntent()` to receive the `Crash` object. Once the user has approved sending a report call `submitReport()` on your `CrashReporter` instance.
200 ```Kotlin
201 // In your crash handling component (e.g. Activity)
202 if (Crash.isCrashIntent(intent) {
203         val crash = Crash.fromIntent(intent)
205         ...
208 // Once the user has confirmed sending a crash report:
209 crashReporter.submitReport(crash)
212 ⚠️ Note: `submitReport()` may block and perform I/O on the calling thread.
214 ### Sending GeckoView crash reports
216 ⚠️ Note: For sending GeckoView crash reports GeckoView **64.0** or higher is required!
218 Register `CrashHandlerService` as crash handler for GeckoView:
220 ```Kotlin
221 val settings = GeckoRuntimeSettings.Builder()
222     .crashHandler(CrashHandlerService::class.java)
223     .build()
225 // Crashes of this runtime will be forwarded to the crash reporter component
226 val runtime = GeckoRuntime.create(applicationContext, settings)
228 // If you are using the browser-engine-gecko component then pass the runtime
229 // to your code initializing the engine:
230 val engine = GeckoEngine(applicationContext, defaultSettings, runtime)
233 ℹ️ You can force a child process crash (non fatal!) using a multi-process (E10S) GeckoView by loading the test URL `about:crashcontent`. Using a non-multi-process GeckoView you can use `about:crashparent` to force a fatal crash.
235 ## License
237     This Source Code Form is subject to the terms of the Mozilla Public
238     License, v. 2.0. If a copy of the MPL was not distributed with this
239     file, You can obtain one at http://mozilla.org/MPL/2.0/