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

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

Issue 2858893002: Move final part of initialization tasks to ProcessInitializationHandler (Closed)
Patch Set: Addressed comments Created 3 years, 7 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 da9b5c71430d53507317473f94ca65faec56fbb5..a2b3aed6310c8feca9be0393bf9479e67c7b1316 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/DeferredStartupHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/DeferredStartupHandler.java
@@ -6,46 +6,17 @@ package org.chromium.chrome.browser;
import android.annotation.SuppressLint;
import android.content.Context;
-import android.content.SharedPreferences;
-import android.os.AsyncTask;
import android.os.Looper;
import android.os.MessageQueue;
import android.os.SystemClock;
-import android.support.annotation.UiThread;
-import android.support.annotation.WorkerThread;
import org.chromium.base.ContextUtils;
-import org.chromium.base.Log;
-import org.chromium.base.PowerMonitor;
import org.chromium.base.ThreadUtils;
-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.metrics.LaunchMetrics;
import org.chromium.chrome.browser.metrics.UmaUtils;
-import org.chromium.chrome.browser.notifications.ChannelsUpdater;
-import org.chromium.chrome.browser.ntp.NewTabPage;
-import org.chromium.chrome.browser.offlinepages.OfflinePageUtils;
-import org.chromium.chrome.browser.partnerbookmarks.PartnerBookmarksShim;
-import org.chromium.chrome.browser.partnercustomizations.HomepageManager;
-import org.chromium.chrome.browser.partnercustomizations.PartnerBrowserCustomizations;
-import org.chromium.chrome.browser.precache.PrecacheLauncher;
-import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
-import org.chromium.chrome.browser.share.ShareHelper;
-import org.chromium.chrome.browser.webapps.ChromeWebApkHost;
-import org.chromium.chrome.browser.webapps.WebApkVersionManager;
-import org.chromium.chrome.browser.webapps.WebappRegistry;
-import org.chromium.components.minidump_uploader.CrashFileManager;
-import java.io.File;
-import java.util.Arrays;
-import java.util.Date;
import java.util.LinkedList;
-import java.util.List;
import java.util.Queue;
import java.util.concurrent.TimeUnit;
@@ -53,18 +24,11 @@ import java.util.concurrent.TimeUnit;
* Handler for application level tasks to be completed on deferred startup.
*/
public class 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";
- private static final String SNAPSHOT_DATABASE_NAME = "snapshots.db";
-
private static class Holder {
@SuppressLint("StaticFieldLeak")
private static final DeferredStartupHandler INSTANCE = new DeferredStartupHandler();
}
- private boolean mDeferredStartupInitializedForApp;
private boolean mDeferredStartupCompletedForApp;
private long mDeferredStartupDuration;
private long mMaxTaskDuration;
@@ -106,7 +70,7 @@ public class DeferredStartupHandler {
public boolean queueIdle() {
Runnable currentTask = mDeferredTasks.poll();
if (currentTask == null) {
- if (mDeferredStartupInitializedForApp && !mDeferredStartupCompletedForApp) {
+ if (!mDeferredStartupCompletedForApp) {
mDeferredStartupCompletedForApp = true;
recordDeferredStartupStats();
}
@@ -149,246 +113,6 @@ public class DeferredStartupHandler {
}
/**
- * Handle application level deferred startup tasks that can be lazily done after all
- * the necessary initialization has been completed. Any calls requiring network access should
- * probably go here.
- *
- * Keep these tasks short and break up long tasks into multiple smaller tasks, as they run on
- * the UI thread and are blocking. Remember to follow RAIL guidelines, as much as possible, and
- * that most devices are quite slow, so leave enough buffer.
- */
- @UiThread
- public void initDeferredStartupForApp() {
- if (mDeferredStartupInitializedForApp) return;
- mDeferredStartupInitializedForApp = true;
- ThreadUtils.assertOnUiThread();
-
- RecordHistogram.recordLongTimesHistogram("UMA.Debug.EnableCrashUpload.DeferredStartUptime2",
- SystemClock.uptimeMillis() - UmaUtils.getForegroundStartTime(),
- TimeUnit.MILLISECONDS);
-
- mDeferredTasks.add(new Runnable() {
- @Override
- public void run() {
- // Punt all tasks that may block on disk off onto a background thread.
- initAsyncDiskTask();
-
- DefaultBrowserInfo.initBrowserFetcher();
-
- AfterStartupTaskUtils.setStartupComplete();
-
- PartnerBrowserCustomizations.setOnInitializeAsyncFinished(new Runnable() {
- @Override
- public void run() {
- String homepageUrl = HomepageManager.getHomepageUri(mAppContext);
- LaunchMetrics.recordHomePageLaunchMetrics(
- HomepageManager.isHomepageEnabled(mAppContext),
- NewTabPage.isNTPUrl(homepageUrl), homepageUrl);
- }
- });
-
- PartnerBookmarksShim.kickOffReading(mAppContext);
-
- PowerMonitor.create();
-
- ShareHelper.clearSharedImages();
-
- OfflinePageUtils.clearSharedOfflineFiles(mAppContext);
-
- if (ChannelsUpdater.getInstance().shouldUpdateChannels()) {
- initChannelsAsync();
- }
- }
- });
-
- ProcessInitializationHandler.getInstance().initializeDeferredStartupTasks();
- }
-
- private void initChannelsAsync() {
- new AsyncTask<Void, Void, Void>() {
- @Override
- protected Void doInBackground(Void... params) {
- ChannelsUpdater.getInstance().updateChannels();
- return null;
- }
-
- }
- .executeOnExecutor(AsyncTask.SERIAL_EXECUTOR);
- }
-
- private void initAsyncDiskTask() {
- new AsyncTask<Void, Void, Void>() {
- /**
- * The threshold after which it's no longer appropriate to try to attach logcat output
- * to a minidump file.
- * Note: This threshold of 12 hours was chosen fairly imprecisely, based on the
- * following intuition: On the one hand, Chrome can only access its own logcat output,
- * so the most recent lines should be relevant when available. On a typical device,
- * multiple hours of logcat output are available. On the other hand, it's important to
- * provide an escape hatch in case the logcat extraction code itself crashes, as
- * described in the doesCrashMinidumpNeedLogcat() documentation. Since this is a fairly
- * small and relatively frequently-executed piece of code, crashes are expected to be
- * unlikely; so it's okay for the escape hatch to be hard to use -- it's intended as an
- * extreme last resort.
- */
- private static final long LOGCAT_RELEVANCE_THRESHOLD_IN_HOURS = 12;
-
- private long mAsyncTaskStartTime;
-
- @Override
- protected Void doInBackground(Void... params) {
- try {
- TraceEvent.begin("ChromeBrowserInitializer.onDeferredStartup.doInBackground");
- mAsyncTaskStartTime = SystemClock.uptimeMillis();
-
- initCrashReporting();
-
- // Initialize the WebappRegistry if it's not already initialized. Must be in
- // async task due to shared preferences disk access on N.
- WebappRegistry.getInstance();
-
- // Force a widget refresh in order to wake up any possible zombie widgets.
- // This is needed to ensure the right behavior when the process is suddenly
- // killed.
- BookmarkWidgetProvider.refreshAllWidgets(mAppContext);
-
- // Initialize whether or not precaching is enabled.
- PrecacheLauncher.updatePrecachingEnabled(mAppContext);
-
- if (ChromeWebApkHost.isEnabled()) {
- WebApkVersionManager.updateWebApksIfNeeded();
- }
-
- removeSnapshotDatabase();
-
- // Warm up all web app shared prefs. This must be run after the WebappRegistry
- // instance is initialized.
- WebappRegistry.warmUpSharedPrefs();
-
- return null;
- } finally {
- TraceEvent.end("ChromeBrowserInitializer.onDeferredStartup.doInBackground");
- }
- }
-
- @Override
- protected void onPostExecute(Void params) {
- // Must be run on the UI thread after the WebappRegistry has been completely warmed.
- WebappRegistry.getInstance().unregisterOldWebapps(System.currentTimeMillis());
-
- RecordHistogram.recordLongTimesHistogram(
- "UMA.Debug.EnableCrashUpload.DeferredStartUpAsyncTaskDuration",
- SystemClock.uptimeMillis() - mAsyncTaskStartTime, TimeUnit.MILLISECONDS);
- }
-
- /**
- * 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() {
- RecordHistogram.recordLongTimesHistogram("UMA.Debug.EnableCrashUpload.Uptime3",
- mAsyncTaskStartTime - UmaUtils.getForegroundStartTime(),
- TimeUnit.MILLISECONDS);
-
- // Crash reports can be uploaded as part of a background service even while the main
- // Chrome activity is not running, and hence regular metrics reporting is not
- // possible. Instead, metrics are temporarily written to prefs; export those prefs
- // to UMA metrics here.
- MinidumpUploadService.storeBreakpadUploadStatsInUma(
- ChromePreferenceManager.getInstance());
-
- // Likewise, this is a good time to process and clean up any pending or stale crash
- // reports left behind by previous runs.
- CrashFileManager crashFileManager =
- new CrashFileManager(ContextUtils.getApplicationContext().getCacheDir());
- crashFileManager.cleanOutAllNonFreshMinidumpFiles();
-
- // Finally, uploading any pending crash reports.
- File[] minidumps = crashFileManager.getAllMinidumpFiles(
- MinidumpUploadService.MAX_TRIES_ALLOWED);
- int numMinidumpsSansLogcat = 0;
- for (File minidump : minidumps) {
- if (CrashFileManager.isMinidumpMIMEFirstTry(minidump.getName())) {
- ++numMinidumpsSansLogcat;
- }
- }
- // TODO(isherman): These two histograms are intended to be temporary, and can
- // probably be removed around the M60 timeframe: http://crbug.com/699785
- RecordHistogram.recordSparseSlowlyHistogram(
- "Stability.Android.PendingMinidumpsOnStartup", minidumps.length);
- RecordHistogram.recordSparseSlowlyHistogram(
- "Stability.Android.PendingMinidumpsOnStartup.SansLogcat",
- numMinidumpsSansLogcat);
- if (minidumps.length == 0) return;
-
- Log.i(TAG, "Attempting to upload %d accumulated crash dumps.", minidumps.length);
- File mostRecentMinidump = minidumps[0];
- if (doesCrashMinidumpNeedLogcat(mostRecentMinidump)) {
- AsyncTask.THREAD_POOL_EXECUTOR.execute(
- new LogcatExtractionRunnable(mostRecentMinidump));
-
- // The JobScheduler will schedule uploads for all of the available minidumps
- // once the logcat is attached. But if the JobScheduler API is not being used,
- // then the logcat extraction process will only initiate an upload for the first
- // minidump; it's required to manually initiate uploads for all of the remaining
- // minidumps.
- if (!MinidumpUploadService.shouldUseJobSchedulerForUploads()) {
- List<File> remainingMinidumps =
- Arrays.asList(minidumps).subList(1, minidumps.length);
- for (File minidump : remainingMinidumps) {
- MinidumpUploadService.tryUploadCrashDump(minidump);
- }
- }
- } else if (MinidumpUploadService.shouldUseJobSchedulerForUploads()) {
- MinidumpUploadService.scheduleUploadJob();
- } else {
- MinidumpUploadService.tryUploadAllCrashDumps();
- }
- }
-
- /**
- * 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 an escape hatch that can
- * help circumvent a possible infinite crash loop, if the code responsible for
- * extracting and appending the logcat content is itself crashing. That is, the user can
- * wait 12 hours prior to relaunching Chrome, at which point this potential crash loop
- * would be circumvented.
- * @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 < LOGCAT_RELEVANCE_THRESHOLD_IN_HOURS;
- }
- }
- .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
- }
-
- /**
- * Deletes the snapshot database which is no longer used because the feature has been removed
- * in Chrome M41.
- */
- @WorkerThread
- private void removeSnapshotDatabase() {
- synchronized (SNAPSHOT_DATABASE_LOCK) {
- SharedPreferences prefs = ContextUtils.getAppSharedPreferences();
- if (!prefs.getBoolean(SNAPSHOT_DATABASE_REMOVED, false)) {
- mAppContext.deleteDatabase(SNAPSHOT_DATABASE_NAME);
- prefs.edit().putBoolean(SNAPSHOT_DATABASE_REMOVED, true).apply();
- }
- }
- }
-
- /**
* @return Whether deferred startup has been completed.
*/
@VisibleForTesting

Powered by Google App Engine
This is Rietveld 408576698