File: README.md

package info (click to toggle)
firefox-esr 140.3.1esr-2
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 4,539,016 kB
  • sloc: cpp: 7,380,478; javascript: 6,388,099; ansic: 3,710,142; python: 1,393,715; xml: 628,165; asm: 426,918; java: 184,025; sh: 65,742; makefile: 19,302; objc: 13,059; perl: 12,912; yacc: 4,583; cs: 3,846; pascal: 3,352; lex: 1,720; ruby: 1,226; exp: 762; php: 436; lisp: 258; awk: 247; sql: 66; sed: 54; csh: 10
file content (239 lines) | stat: -rw-r--r-- 9,330 bytes parent folder | download | duplicates (12)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# [Android Components](../../../README.md) > Libraries > Crash

A generic crash reporter component that can report crashes to multiple services.

Main features:

* Support for multiple crash reporting services (included is support for [Sentry](https://sentry.io) and [Socorro](https://wiki.mozilla.org/Socorro)).
* Support for crashes caused by uncaught exceptions.
* Support for native code crashes (currently primarily focused on GeckoView crashes).
* Can optionally prompt the user for confirmation before sending a crash report.
* Support for showing in-app confirmation UI for non-fatal crashes.

## Usage

### Setting up the dependency

Use Gradle to download the library from [maven.mozilla.org](https://maven.mozilla.org/) ([Setup repository](../../../README.md#maven-repository)):

```Groovy
implementation "org.mozilla.components:lib-crash:{latest-version}"
```

### Setting up crash reporting

In the `onCreate()` method of your Application class create a `CrashReporter` instance and call `install()`:

```Kotlin
CrashReporter(
    services = listOf(
        // List the crash reporting services you want to use
    )
).install(this)
```

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.

⚠️ Note: To avoid conflicting setups do not use any other crash reporting libraries/services independently from this library.

### Recording crash breadcrumbs to supported services

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.

⚠️ Note: Directly using Sentry's breadcrumb will not work as expected on Android 10 or above.  Using the `CrashReporter` breadcrumb is preferred.

```Kotlin
crashReporter.recordCrashBreadcrumb(
  CrashBreadcrumb("Settings button clicked", data, "UI", Level.INFO, Type.USER)
)
```

### Sending crash reports to Sentry

⚠️ 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.

Add a `SentryService` instance to your `CrashReporter` in order to upload crashes to Sentry:

```Kotlin
CrashReporter(
    services = listOf(
        SentryService(applicationContext, "your sentry DSN")
    )
).install(applicationContext)
```

By default only the `DSN` is needed. But there are additional option configuration parameters:

```Kotlin
SentryService(
	applicationContext,
	"your sentry DSN",

	// Optionally add tags that will be sent with every crash report
	tags = mapOf(
		"build_flavor" to BuildConfig.FLAVOR,
		"build_type" to BuildConfig.BUILD_TYPE
	),

	// Send an event to Sentry for every native code crash. Native code crashes
	// can't be uploaded to Sentry currently. But sending an event to Sentry
	// gives you an idea about how often native code crashes. For sending native
	// crash reports add additional services like Socorro.
	sendEventForNativeCrashes = true
)
```

### Sending crash reports to Mozilla Socorro

[Socorro](https://wiki.mozilla.org/Socorro) is the name for the [Mozilla Crash Stats](https://crash-stats.mozilla.org/) project.

⚠️ 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.

Add a `MozillaSocorroService` instance to your `CrashReporter` in order to upload crashes to Socorro:

```Kotlin
CrashReporter(
    services = listOf(
		MozillaSocorroService(applicationContext, "your app name")
    )
).install(applicationContext)
```

`MozillaSocorroService` will report version information such as App version, Android Component version, Glean version, Application Services version, GeckoView version and Build ID
⚠️ 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.

### Sending crash reports to Glean

[Glean](https://docs.telemetry.mozilla.org/concepts/glean/glean.html) is a new way to collect telemetry by Mozilla.
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).
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).
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,
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`
constructor is loaded from the main process.

Add a `GleanCrashReporterService` instance to your `CrashReporter` in order to record crashes in Glean:

```Kotlin
CrashReporter(
    services = listOf(
		GleanCrashReporterService()
    )
).install(applicationContext)
```

⚠️ 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.

### Showing a crash reporter prompt

![](images/crash-dialog.png)

Optionally the library can show a prompt asking the user for confirmation before sending a crash report.

The behavior can be controlled using the `shouldPrompt` parameter:

```Kotlin
CrashReporter(
    // Always prompt
    shouldPrompt = CrashReporter.Prompt.ALWAYS,

    // Or: Only prompt for native crashes
    shouldPrompt = CrashReporter.Prompt.ONLY_NATIVE_CRASH,

    // Or: Never show the prompt
    shouldPrompt = CrashReporter.Prompt.NEVER,

    // ..
).install(applicationContext)
```

#### Customizing the prompt

The crash reporter prompt can be customized by providing a `PromptConfiguration` object:

```Kotlin
CrashReporter(
	promptConfiguration = CrashReporter.PromptConfiguration(
		appName = "My App",
		organizationName = "My Organization",

		// An additional message that will be shown in the prompt
		message = "We are very sorry!"

		// Use a custom theme for the prompt (Extend Theme.Mozac.CrashReporter)
		theme = android.R.style.Theme_Holo_Dialog
	),

	// ..
).install(applicationContext)
```

#### Handling non-fatal crashes

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.

![](images/crash-in-app.png)

Provide a `PendingIntent` that will be invoked when a non-fatal crash occurs:

```Kotlin
// Launch this activity when a crash occurs.
val pendingIntent = PendingIntent.getActivity(
    context,
    0,
    Intent(this, MyActivity::class.java).apply {
        addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
    },
    PendingIntentUtils.defaultFlags
)

CrashReporter(
    shouldPrompt = CrashReporter.Prompt.ALWAYS,
    services = listOf(
        // ...
    ),
    nonFatalCrashIntent = pendingIntent
).install(this)
```

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.

```Kotlin
// In your crash handling component (e.g. Activity)
if (Crash.isCrashIntent(intent) {
	val crash = Crash.fromIntent(intent)

	...
}

// Once the user has confirmed sending a crash report:
crashReporter.submitReport(crash)
```

⚠️ Note: `submitReport()` may block and perform I/O on the calling thread.

### Sending GeckoView crash reports

⚠️ Note: For sending GeckoView crash reports GeckoView **64.0** or higher is required!

Register `CrashHandlerService` as crash handler for GeckoView:

```Kotlin
val settings = GeckoRuntimeSettings.Builder()
    .crashHandler(CrashHandlerService::class.java)
    .build()

// Crashes of this runtime will be forwarded to the crash reporter component
val runtime = GeckoRuntime.create(applicationContext, settings)

// If you are using the browser-engine-gecko component then pass the runtime
// to your code initializing the engine:
val engine = GeckoEngine(applicationContext, defaultSettings, runtime)
```

ℹ️ 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.

## License

    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/