summaryrefslogtreecommitdiffstats
path: root/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/ExampleCrashHandler.java
diff options
context:
space:
mode:
Diffstat (limited to 'mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/ExampleCrashHandler.java')
-rw-r--r--mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/ExampleCrashHandler.java137
1 files changed, 137 insertions, 0 deletions
diff --git a/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/ExampleCrashHandler.java b/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/ExampleCrashHandler.java
new file mode 100644
index 0000000000..1c66757483
--- /dev/null
+++ b/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/ExampleCrashHandler.java
@@ -0,0 +1,137 @@
+/* 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.geckoview_example;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Build;
+import android.os.IBinder;
+import android.os.StrictMode;
+import android.util.Log;
+import androidx.annotation.Nullable;
+import androidx.core.app.NotificationCompat;
+import org.mozilla.geckoview.BuildConfig;
+import org.mozilla.geckoview.CrashReporter;
+import org.mozilla.geckoview.GeckoRuntime;
+
+public class ExampleCrashHandler extends Service {
+ private static final String LOGTAG = "ExampleCrashHandler";
+
+ private static final String CHANNEL_ID = "geckoview_example_crashes";
+ private static final int NOTIFY_ID = 42;
+
+ private static final String ACTION_REPORT_CRASH =
+ "org.mozilla.geckoview_example.ACTION_REPORT_CRASH";
+ private static final String ACTION_DISMISS = "org.mozilla.geckoview_example.ACTION_DISMISS";
+
+ private Intent mCrashIntent;
+
+ public ExampleCrashHandler() {}
+
+ @Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ if (intent == null) {
+ stopSelf();
+ return Service.START_NOT_STICKY;
+ }
+
+ if (GeckoRuntime.ACTION_CRASHED.equals(intent.getAction())) {
+ mCrashIntent = intent;
+
+ Log.d(LOGTAG, "Dump File: " + mCrashIntent.getStringExtra(GeckoRuntime.EXTRA_MINIDUMP_PATH));
+ Log.d(LOGTAG, "Extras File: " + mCrashIntent.getStringExtra(GeckoRuntime.EXTRA_EXTRAS_PATH));
+ Log.d(
+ LOGTAG,
+ "Process Type: " + mCrashIntent.getStringExtra(GeckoRuntime.EXTRA_CRASH_PROCESS_TYPE));
+
+ String id = createNotificationChannel();
+
+ int intentFlag = 0;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+ intentFlag = PendingIntent.FLAG_IMMUTABLE;
+ }
+
+ PendingIntent reportIntent =
+ PendingIntent.getService(
+ this,
+ 0,
+ new Intent(ACTION_REPORT_CRASH, null, this, ExampleCrashHandler.class),
+ intentFlag);
+
+ PendingIntent dismissIntent =
+ PendingIntent.getService(
+ this,
+ 0,
+ new Intent(ACTION_DISMISS, null, this, ExampleCrashHandler.class),
+ intentFlag);
+
+ Notification notification =
+ new NotificationCompat.Builder(this, id)
+ .setSmallIcon(R.drawable.ic_crash)
+ .setContentTitle(getResources().getString(R.string.crashed_title))
+ .setContentText(getResources().getString(R.string.crashed_text))
+ .setDefaults(Notification.DEFAULT_ALL)
+ .addAction(0, getResources().getString(R.string.crashed_ignore), dismissIntent)
+ .addAction(0, getResources().getString(R.string.crashed_report), reportIntent)
+ .setAutoCancel(true)
+ .setOngoing(false)
+ .build();
+
+ startForeground(NOTIFY_ID, notification);
+ } else if (ACTION_REPORT_CRASH.equals(intent.getAction())) {
+ StrictMode.ThreadPolicy oldPolicy = null;
+ if (BuildConfig.DEBUG_BUILD) {
+ oldPolicy = StrictMode.getThreadPolicy();
+
+ // We do some disk I/O and network I/O on the main thread, but it's fine.
+ StrictMode.setThreadPolicy(
+ new StrictMode.ThreadPolicy.Builder(oldPolicy)
+ .permitDiskReads()
+ .permitDiskWrites()
+ .permitNetwork()
+ .build());
+ }
+
+ try {
+ CrashReporter.sendCrashReport(this, mCrashIntent, "GeckoViewExample");
+ } catch (Exception e) {
+ Log.e(LOGTAG, "Failed to send crash report", e);
+ }
+
+ if (oldPolicy != null) {
+ StrictMode.setThreadPolicy(oldPolicy);
+ }
+
+ stopSelf();
+ } else if (ACTION_DISMISS.equals(intent.getAction())) {
+ stopSelf();
+ }
+
+ return Service.START_NOT_STICKY;
+ }
+
+ @Nullable
+ @Override
+ public IBinder onBind(Intent intent) {
+ return null;
+ }
+
+ private String createNotificationChannel() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ NotificationChannel channel =
+ new NotificationChannel(
+ CHANNEL_ID, "GeckoView Example Crashes", NotificationManager.IMPORTANCE_LOW);
+ NotificationManager notificationManager = getSystemService(NotificationManager.class);
+ notificationManager.createNotificationChannel(channel);
+ return CHANNEL_ID;
+ }
+
+ return "";
+ }
+}