Skip to content
This repository was archived by the owner on Jul 22, 2024. It is now read-only.

Commit e984058

Browse files
authored
Write a file containing the crash files location. Fixes #1846 (#1847)
1 parent 5d08acb commit e984058

3 files changed

Lines changed: 132 additions & 32 deletions

File tree

app/src/common/shared/org/mozilla/vrbrowser/VRBrowserActivity.java

Lines changed: 97 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,14 @@
7272
import org.mozilla.vrbrowser.utils.ServoUtils;
7373
import org.mozilla.vrbrowser.utils.SystemUtils;
7474

75+
import java.io.BufferedReader;
76+
import java.io.File;
77+
import java.io.FileInputStream;
7578
import java.io.IOException;
79+
import java.io.InputStreamReader;
7680
import java.net.URISyntaxException;
81+
import java.nio.charset.StandardCharsets;
82+
import java.util.ArrayList;
7783
import java.util.Arrays;
7884
import java.util.HashMap;
7985
import java.util.HashSet;
@@ -88,7 +94,7 @@ public class VRBrowserActivity extends PlatformActivity implements WidgetManager
8894
public void onReceive(Context context, Intent intent) {
8995
if(intent.getAction().equals(CrashReporterService.CRASH_ACTION)) {
9096
Intent crashIntent = intent.getParcelableExtra(CrashReporterService.DATA_TAG);
91-
handleCrashIntent(crashIntent);
97+
handleContentCrashIntent(crashIntent);
9298
}
9399
}
94100
};
@@ -113,6 +119,7 @@ public void run() {
113119
static final int GestureSwipeRight = 1;
114120
static final int SwipeDelay = 1000; // milliseconds
115121
static final long RESET_CRASH_COUNT_DELAY = 5000;
122+
static final String CRASH_STATS_URL = "https://crash-stats.mozilla.com/report/index/";
116123

117124
static final String LOGTAG = SystemUtils.createLogtag(VRBrowserActivity.class);
118125
HashMap<Integer, Widget> mWidgets;
@@ -255,6 +262,7 @@ protected void onCreate(Bundle savedInstanceState) {
255262

256263
mConnectivityReceiver = new ConnectivityReceiver();
257264
mPoorPerformanceWhiteList = new HashSet<>();
265+
checkForCrash();
258266
}
259267

260268
protected void initializeWidgets() {
@@ -420,7 +428,7 @@ protected void onNewIntent(final Intent intent) {
420428
loadFromIntent(intent);
421429
}
422430
} else if (GeckoRuntime.ACTION_CRASHED.equals(intent.getAction())) {
423-
handleCrashIntent(intent);
431+
Log.e(LOGTAG, "Restarted after a crash");
424432
}
425433
}
426434

@@ -433,7 +441,7 @@ public void onConfigurationChanged(Configuration newConfig) {
433441

434442
void loadFromIntent(final Intent intent) {
435443
if (GeckoRuntime.ACTION_CRASHED.equals(intent.getAction())) {
436-
handleCrashIntent(intent);
444+
Log.e(LOGTAG,"Loading from crash Intent");
437445
}
438446

439447
Uri uri = intent.getData();
@@ -481,44 +489,104 @@ private void handleConnectivityChange() {
481489
mConnectionAvailable = connected;
482490
}
483491

484-
private void handleCrashIntent(@NonNull final Intent intent) {
485-
Log.e(LOGTAG, "======> Got crashed intent");
486-
Log.d(LOGTAG, "======> Dump File: " +
487-
intent.getStringExtra(GeckoRuntime.EXTRA_MINIDUMP_PATH));
488-
Log.d(LOGTAG, "======> Extras File: " +
489-
intent.getStringExtra(GeckoRuntime.EXTRA_EXTRAS_PATH));
490-
Log.d(LOGTAG, "======> Fatal: " +
491-
intent.getBooleanExtra(GeckoRuntime.EXTRA_CRASH_FATAL, false));
492-
492+
private void checkForCrash() {
493+
final ArrayList<String> files = CrashReporterService.findCrashFiles(getBaseContext());
494+
if (files.isEmpty()) {
495+
Log.d(LOGTAG, "No crash files found.");
496+
return;
497+
}
493498
boolean isCrashReportingEnabled = SettingsStore.getInstance(this).isCrashReportingEnabled();
494499
if (isCrashReportingEnabled) {
495-
sendCrashData(intent);
496-
500+
postCrashFiles(files);
497501
} else {
498502
if (mCrashDialog == null) {
499503
mCrashDialog = new CrashDialogWidget(this);
500-
mCrashDialog.setCrashDialogDelegate(() -> sendCrashData(intent));
501504
}
505+
mCrashDialog.setCrashDialogDelegate(
506+
new CrashDialogWidget.CrashDialogDelegate() {
507+
@Override
508+
public void onSendData() {
509+
postCrashFiles(files);
510+
}
502511

512+
@Override
513+
public void onDoNotSendData() {
514+
for (String file : files) {
515+
Log.e(LOGTAG, "Deleting crashfile: " + file);
516+
getBaseContext().deleteFile(file);
517+
}
518+
}
519+
}
520+
);
503521
mCrashDialog.show(UIWidget.REQUEST_FOCUS);
504522
}
505523
}
506524

507-
private void sendCrashData(final Intent intent) {
525+
private void handleContentCrashIntent(@NonNull final Intent intent) {
526+
Log.e(LOGTAG, "Got content crashed intent");
527+
final String dumpFile = intent.getStringExtra(GeckoRuntime.EXTRA_MINIDUMP_PATH);
528+
final String extraFile = intent.getStringExtra(GeckoRuntime.EXTRA_EXTRAS_PATH);
529+
Log.d(LOGTAG, "Dump File: " + dumpFile);
530+
Log.d(LOGTAG, "Extras File: " + extraFile);
531+
Log.d(LOGTAG, "Fatal: " + intent.getBooleanExtra(GeckoRuntime.EXTRA_CRASH_FATAL, false));
532+
533+
boolean isCrashReportingEnabled = SettingsStore.getInstance(this).isCrashReportingEnabled();
534+
if (isCrashReportingEnabled) {
535+
postCrashFiles(dumpFile, extraFile);
536+
} else {
537+
if (mCrashDialog == null) {
538+
mCrashDialog = new CrashDialogWidget(this);
539+
}
540+
mCrashDialog.setCrashDialogDelegate(() -> postCrashFiles(dumpFile, extraFile));
541+
mCrashDialog.show(UIWidget.REQUEST_FOCUS);
542+
}
543+
}
544+
545+
private void sendCrashFiles(@NonNull final String aDumpFile, @NonNull final String aExtraFile) {
546+
try {
547+
GeckoResult<String> result = CrashReporter.sendCrashReport(VRBrowserActivity.this, new File(aDumpFile), new File(aExtraFile), getString(R.string.crash_app_name));
548+
549+
result.accept(crashID -> {
550+
Log.e(LOGTAG, "Submitted crash report id: " + crashID);
551+
Log.e(LOGTAG, "Report available at: " + CRASH_STATS_URL + crashID);
552+
}, ex -> {
553+
Log.e(LOGTAG, "Failed to submit crash report: " + (ex != null ? ex.getMessage() : "Exception is NULL"));
554+
});
555+
} catch (IOException | URISyntaxException e) {
556+
Log.e(LOGTAG, "Failed to send crash report: " + e.toString());
557+
}
558+
}
559+
560+
private void postCrashFiles(@NonNull final String aDumpFile, @NonNull final String aExtraFile) {
508561
ThreadUtils.postToBackgroundThread(() -> {
509-
try {
510-
GeckoResult<String> result = CrashReporter.sendCrashReport(VRBrowserActivity.this, intent, getString(R.string.crash_app_name));
511-
512-
result.then(crashID -> {
513-
Log.e(LOGTAG, "Submitted crash report id: " + crashID);
514-
Log.e(LOGTAG, "Report available at: https://crash-stats.mozilla.com/report/index/" + crashID);
515-
return null;
516-
}, (GeckoResult.OnExceptionListener<Void>) ex -> {
517-
Log.e(LOGTAG, "Failed to submit crash report: " + ex.getMessage());
518-
return null;
519-
});
520-
} catch (IOException | URISyntaxException e) {
521-
Log.e(LOGTAG, "Failed to send crash report: " + e.toString());
562+
sendCrashFiles(aDumpFile, aExtraFile);
563+
});
564+
}
565+
566+
private void postCrashFiles(final ArrayList<String> aFiles) {
567+
ThreadUtils.postToBackgroundThread(() -> {
568+
for (String file: aFiles) {
569+
try {
570+
ArrayList<String> list = new ArrayList<>(2);
571+
try (FileInputStream in = getBaseContext().openFileInput(file)) {
572+
try(BufferedReader br = new BufferedReader(new InputStreamReader(in, StandardCharsets.UTF_8))) {
573+
String line;
574+
while((line = br.readLine()) != null) {
575+
list.add(line);
576+
}
577+
}
578+
} catch (IOException e) {
579+
e.printStackTrace();
580+
}
581+
if (list.size() < 2) {
582+
Log.e(LOGTAG, "Failed read crash dump file names from: " + file);
583+
return;
584+
}
585+
sendCrashFiles(list.get(0), list.get(1));
586+
} finally {
587+
Log.d(LOGTAG,"Removing crash file: " + file);
588+
getBaseContext().deleteFile(file);
589+
}
522590
}
523591
});
524592
}

app/src/common/shared/org/mozilla/vrbrowser/crashreporting/CrashReporterService.java

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import android.content.Context;
55
import android.content.Intent;
66
import android.os.Build;
7-
import android.os.Process;
87
import android.util.Log;
98

109
import org.mozilla.geckoview.GeckoRuntime;
@@ -14,6 +13,12 @@
1413
import org.mozilla.vrbrowser.browser.SettingsStore;
1514
import org.mozilla.vrbrowser.utils.SystemUtils;
1615

16+
17+
import java.io.FileOutputStream;
18+
import java.io.IOException;
19+
import java.util.ArrayList;
20+
import java.util.UUID;
21+
1722
import androidx.annotation.NonNull;
1823
import androidx.core.app.JobIntentService;
1924

@@ -23,6 +28,7 @@ public class CrashReporterService extends JobIntentService {
2328

2429
public static final String CRASH_ACTION = BuildConfig.APPLICATION_ID + ".CRASH_ACTION";
2530
public static final String DATA_TAG = "intent";
31+
public static final String CRASH_FILE_PREFIX = "crashfile-";
2632

2733
private static final int PID_CHECK_INTERVAL = 100;
2834
private static final int JOB_ID = 1000;
@@ -41,13 +47,24 @@ public int onStartCommand(Intent intent, int flags, int startId) {
4147
return super.onStartCommand(intent, flags, startId);
4248
}
4349

50+
@NonNull
51+
public static ArrayList<String> findCrashFiles(@NonNull Context aContext) {
52+
ArrayList<String> files = new ArrayList<>();
53+
String[] allFiles = aContext.fileList();
54+
for (String value: allFiles) {
55+
if (value.startsWith(CRASH_FILE_PREFIX)) {
56+
files.add(value);
57+
}
58+
}
59+
return files;
60+
}
61+
4462
@Override
4563
protected void onHandleWork(@NonNull Intent intent) {
4664
String action = intent.getAction();
4765
if (GeckoRuntime.ACTION_CRASHED.equals(action)) {
4866
final int activityPid = SettingsStore.getInstance(getBaseContext()).getPid();
4967
boolean fatal = intent.getBooleanExtra(GeckoRuntime.EXTRA_CRASH_FATAL, false);
50-
5168
long count = SettingsStore.getInstance(getBaseContext()).getCrashRestartCount();
5269
boolean cancelRestart = count > MAX_RESTART_COUNT;
5370
if (cancelRestart || BuildConfig.DISABLE_CRASH_RESTART) {
@@ -57,6 +74,16 @@ protected void onHandleWork(@NonNull Intent intent) {
5774

5875
if (fatal) {
5976
Log.d(LOGTAG, "Main process crash " + intent);
77+
final String dumpFile = intent.getStringExtra(GeckoRuntime.EXTRA_MINIDUMP_PATH) + "\n";
78+
final String extraFile = intent.getStringExtra(GeckoRuntime.EXTRA_EXTRAS_PATH);
79+
final String crashFile = CRASH_FILE_PREFIX + UUID.randomUUID().toString().replaceAll("-", "") + ".txt";
80+
try (FileOutputStream file = getBaseContext().openFileOutput(crashFile, 0)) {
81+
file.write(dumpFile.getBytes());
82+
file.write(extraFile.getBytes());
83+
Log.d(LOGTAG, "Wrote crashfile: " + crashFile);
84+
} catch (IOException e) {
85+
Log.e(LOGTAG, "Failed to create crash file: '" + crashFile + "' error: " + e.getMessage());
86+
}
6087
if (activityPid == 0) {
6188
Log.e(LOGTAG, "Application was quitting. Crash reporter will not trigger a restart.");
6289
return;
@@ -74,6 +101,8 @@ protected void onHandleWork(@NonNull Intent intent) {
74101
activityFound = true;
75102
Log.e(LOGTAG, "Main activity still running: " + activityPid);
76103
break;
104+
} else {
105+
Log.d(LOGTAG, "Main activity not found: " + activityPid);
77106
}
78107
}
79108

app/src/common/shared/org/mozilla/vrbrowser/ui/widgets/dialogs/CrashDialogWidget.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@
1717
import org.mozilla.vrbrowser.browser.SettingsStore;
1818
import org.mozilla.vrbrowser.ui.widgets.WidgetManagerDelegate;
1919
import org.mozilla.vrbrowser.ui.widgets.WidgetPlacement;
20-
import org.mozilla.vrbrowser.utils.SystemUtils;
2120

2221
public class CrashDialogWidget extends UIDialog {
2322

2423
public interface CrashDialogDelegate {
2524
void onSendData();
25+
default void onDoNotSendData() {}
2626
}
2727

2828
private Button mLearnMoreButton;
@@ -74,6 +74,9 @@ private void initialize(Context aContext) {
7474
mAudio.playSound(AudioEngine.Sound.CLICK);
7575
}
7676

77+
if(mCrashDialogDelegate != null) {
78+
mCrashDialogDelegate.onDoNotSendData();
79+
}
7780
onDismiss();
7881
});
7982

0 commit comments

Comments
 (0)