Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(851)

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/DeferredStartupHandler.java

Issue 2727573004: [Android Crash Reporting] Simplify crash report upload code. (Closed)
Patch Set: Simplify the test code exception handling a bit Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/java/src/org/chromium/chrome/browser/DeferredStartupHandler.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/DeferredStartupHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/DeferredStartupHandler.java
index 71d5da9513554c25f32587b26374b7d622060694..df22ec83e3b7e80700d738367014b4589f73b119 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/DeferredStartupHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/DeferredStartupHandler.java
@@ -19,6 +19,7 @@ import android.view.inputmethod.InputMethodSubtype;
import org.chromium.base.CommandLine;
import org.chromium.base.ContextUtils;
import org.chromium.base.FieldTrialList;
+import org.chromium.base.Log;
import org.chromium.base.PowerMonitor;
import org.chromium.base.SysUtils;
import org.chromium.base.ThreadUtils;
@@ -26,6 +27,7 @@ import org.chromium.base.TraceEvent;
import org.chromium.base.VisibleForTesting;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.chrome.browser.bookmarkswidget.BookmarkWidgetProvider;
+import org.chromium.chrome.browser.crash.LogcatExtractionRunnable;
import org.chromium.chrome.browser.crash.MinidumpUploadService;
import org.chromium.chrome.browser.init.ProcessInitializationHandler;
import org.chromium.chrome.browser.locale.LocaleManager;
@@ -48,7 +50,10 @@ import org.chromium.chrome.browser.webapps.WebappRegistry;
import org.chromium.components.minidump_uploader.CrashFileManager;
import org.chromium.content.browser.ChildProcessLauncher;
+import java.io.File;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
@@ -59,7 +64,7 @@ import java.util.concurrent.TimeUnit;
* Handler for application level tasks to be completed on deferred startup.
*/
public class DeferredStartupHandler {
- private static final String TAG = "DeferredStartupHandler";
+ private static final String TAG = "DeferredStartup";
/** Prevents race conditions when deleting snapshot database. */
private static final Object SNAPSHOT_DATABASE_LOCK = new Object();
private static final String SNAPSHOT_DATABASE_REMOVED = "snapshot_database_removed";
@@ -243,24 +248,13 @@ public class DeferredStartupHandler {
protected Void doInBackground(Void... params) {
try {
TraceEvent.begin("ChromeBrowserInitializer.onDeferredStartup.doInBackground");
- mAsyncTaskStartTime = SystemClock.uptimeMillis();
- boolean crashDumpDisabled = CommandLine.getInstance().hasSwitch(
- ChromeSwitches.DISABLE_CRASH_DUMP_UPLOAD);
- if (!crashDumpDisabled) {
- RecordHistogram.recordLongTimesHistogram(
- "UMA.Debug.EnableCrashUpload.Uptime3",
- mAsyncTaskStartTime - UmaUtils.getForegroundStartTime(),
- TimeUnit.MILLISECONDS);
- PrivacyPreferencesManager.getInstance().enablePotentialCrashUploading();
- MinidumpUploadService.tryUploadAllCrashDumps(mAppContext);
- }
- CrashFileManager crashFileManager =
- new CrashFileManager(mAppContext.getCacheDir());
- crashFileManager.cleanOutAllNonFreshMinidumpFiles();
+ mAsyncTaskStartTime = SystemClock.uptimeMillis();
+ RecordHistogram.recordLongTimesHistogram("UMA.Debug.EnableCrashUpload.Uptime3",
+ mAsyncTaskStartTime - UmaUtils.getForegroundStartTime(),
+ TimeUnit.MILLISECONDS);
Maria 2017/03/07 06:36:39 looks like you are changing the semantics of when
Ilya Sherman 2017/03/08 02:32:44 Done. Good catch! I misread when this histogram
- MinidumpUploadService.storeBreakpadUploadStatsInUma(
- ChromePreferenceManager.getInstance());
+ initCrashReporting();
// Initialize the WebappRegistry if it's not already initialized. Must be in
// async task due to shared preferences disk access on N.
@@ -303,6 +297,75 @@ public class DeferredStartupHandler {
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
+ /**
+ * Initializes the crash reporting system. More specifically, enables the crash reporting system
+ * if it is user-permitted, and initiates uploading of any pending crash reports. Also updates
+ * some UMA metrics and performs cleanup in the local crash minidump storage directory.
+ */
+ private void initCrashReporting() {
+ // Perform cleanup prior to checking whether crash reporting is enabled, so that users who
+ // disable crash reporting are still able to eventually recover disk space dedicated to
+ // storing pending crash reports.
+ CrashFileManager crashFileManager = new CrashFileManager(mAppContext.getCacheDir());
+ crashFileManager.cleanOutAllNonFreshMinidumpFiles();
+
+ // Likewise, there might be pending metrics from previous runs when crash reporting was
+ // enabled.
+ MinidumpUploadService.storeBreakpadUploadStatsInUma(ChromePreferenceManager.getInstance());
+
+ // Now check whether crash reporting is enable. If it is, broadcast the appropriate
Maria 2017/03/07 06:36:39 nit: enable -> enabled
Ilya Sherman 2017/03/08 02:32:44 Done.
+ // permisison.
gsennton 2017/03/07 18:32:04 nit: permisison -> permission
Ilya Sherman 2017/03/08 02:32:44 Done.
+ boolean crashReportingDisabled =
+ CommandLine.getInstance().hasSwitch(ChromeSwitches.DISABLE_CRASH_DUMP_UPLOAD);
+ if (crashReportingDisabled) {
Maria 2017/03/07 06:36:39 nit: feel free to use if (crashReportingDisabled
Ilya Sherman 2017/03/08 02:32:44 Done. Yay! This was bugging me, but I wasn't sur
+ return;
+ }
+ PrivacyPreferencesManager.getInstance().enablePotentialCrashUploading();
+
+ // Finally, uploading any pending crash reports.
+ File[] minidumps =
+ crashFileManager.getAllMinidumpFiles(MinidumpUploadService.MAX_TRIES_ALLOWED);
+ if (minidumps.length == 0) {
Maria 2017/03/07 06:36:39 ditto
Ilya Sherman 2017/03/08 02:32:44 Done.
+ return;
+ }
+
+ Log.i(TAG, "Attempting to upload accumulated crash dumps.");
Maria 2017/03/07 06:36:39 Might as well log how many there are
Ilya Sherman 2017/03/08 02:32:44 Done.
+ if (!doesCrashMinidumpNeedLogcat(minidumps[0])) {
Maria 2017/03/07 06:36:39 Do we have some sort of guarantee on what the firs
gsennton 2017/03/07 18:32:04 Please double-check whether the first minidump her
Ilya Sherman 2017/03/08 02:32:44 I've double-checked that this is indeed the freshe
gsennton 2017/03/08 15:18:41 I would say there are two different scenarios we c
Ilya Sherman 2017/03/09 01:08:45 It would have to be a crash that brings down the b
+ MinidumpUploadService.tryUploadAllCrashDumps(mAppContext);
+ } else {
gsennton 2017/03/07 18:32:04 Would you mind switching the if- and else-statemen
Ilya Sherman 2017/03/08 02:32:44 I can do that, but let me run this by you first: W
gsennton 2017/03/08 15:18:41 What do you mean by "some named variables extracte
Ilya Sherman 2017/03/09 01:08:45 I meant what I included in the latest patch set ;-
+ AsyncTask.THREAD_POOL_EXECUTOR.execute(
+ new LogcatExtractionRunnable(mAppContext, minidumps[0]));
+
+ // TODO(isherman): Once there is support implemented for the JobScheduler API, we should
+ // only explicitly upload the remaining files here if not using that API. If we *are*
+ // using the JobScheduler API, then the JobScheduler will schedule uploads for all of
+ // the available minidumps once the logcat is attached.
+ List<File> remainingMinidumps = Arrays.asList(minidumps).subList(1, minidumps.length);
+ for (File minidump : remainingMinidumps) {
+ MinidumpUploadService.tryUploadCrashDump(mAppContext, minidump);
+ }
+ }
+ }
+
+ /**
+ * Returns whether or not it's appropriate to try to extract recent logcat output and include
+ * that logcat output alongside the given {@param minidump} in a crash report. Logcat output
+ * should only be extracted if (a) it hasn't already been extracted for this minidump file, and
+ * (b) the minidump is fairly fresh. The freshness check is important for two reasons: (1) First
+ * of all, it helps avoid including irrelevant logcat output for a crash report. (2) Secondly,
+ * it provides a cool-off period that can help circumvent a possible infinite crash loop, if the
gsennton 2017/03/07 18:32:04 The cool-off period, is that the infinite period a
Ilya Sherman 2017/03/08 02:32:44 Right. I updated the comment to hopefully clarify
+ * code responsible for extracting and appending the logcat content is itself crashing.
+ * @return Whether to try to include logcat output in the crash report corresponding to the
+ * given minidump.
+ */
+ private boolean doesCrashMinidumpNeedLogcat(File minidump) {
+ if (!CrashFileManager.isMinidumpMIMEFirstTry(minidump.getName())) return false;
+
+ long ageInMillis = new Date().getTime() - minidump.lastModified();
+ long ageInHours = TimeUnit.HOURS.convert(ageInMillis, TimeUnit.MILLISECONDS);
+ return ageInHours < 1;
Maria 2017/03/07 06:36:39 How did you choose the duration? I would absolutel
gsennton 2017/03/07 18:32:04 What's the reasoning behind such a short duration?
Maria 2017/03/07 20:04:57 The problem is that we only grab 256 lines from th
Ilya Sherman 2017/03/08 02:32:44 I picked semi-randomly :P I'm happy to start with
Maria 2017/03/08 06:18:47 Hmm, one thing I thought of: logcat data returned
Ilya Sherman 2017/03/08 09:12:30 Okay, sounds good. Any specific suggestions on ho
gsennton 2017/03/08 15:18:41 Ideally we would just read the time-stamp of the f
Ilya Sherman 2017/03/09 01:08:45 I'm not sure whether it's brittle, but it's harder
+ }
+
private void startModerateBindingManagementIfNeeded() {
// Moderate binding doesn't apply to low end devices.
if (SysUtils.isLowEndDevice()) return;

Powered by Google App Engine
This is Rietveld 408576698