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

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

Issue 2121863002: Separate deferred startup into tasks. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix per review. Created 4 years, 5 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 1e73dc2ec94a3d73f5509e6e9b3036e0342facf1..d222b8e15a16b14bc88639480c3c1926f7b0ad88 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/DeferredStartupHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/DeferredStartupHandler.java
@@ -10,6 +10,8 @@ import android.content.SharedPreferences;
import android.content.pm.ResolveInfo;
import android.net.Uri;
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;
@@ -45,14 +47,17 @@ import org.chromium.chrome.browser.webapps.WebApkVersionManager;
import org.chromium.content.browser.ChildProcessLauncher;
import java.util.ArrayList;
+import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
+import java.util.Queue;
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";
/** 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";
@@ -62,8 +67,12 @@ public class DeferredStartupHandler {
private static final DeferredStartupHandler INSTANCE = new DeferredStartupHandler();
}
- private boolean mDeferredStartupComplete;
+ private boolean mDeferredStartupInitialized;
+ private boolean mDeferredStartupCompleted;
+ private long mDeferredStartupDuration;
+ private long mMaxTaskDuration;
private final Context mAppContext;
+ private final Queue<Runnable> mDeferredTasks;
/**
* This class is an application specific object that handles the deferred startup.
@@ -75,25 +84,147 @@ public class DeferredStartupHandler {
private DeferredStartupHandler() {
mAppContext = ContextUtils.getApplicationContext();
+ mDeferredTasks = new LinkedList<Runnable>();
+ }
+
+ /**
+ * Initialize and run the next deferred startup task in sequence on the idle handler.
+ */
+ public void runDeferredTasks() {
+ if (!mDeferredStartupInitialized) return;
+
+ // Add UMA task last so we get accurate timing.
+ mDeferredTasks.add(new Runnable() {
+ @Override
+ public void run() {
+ RecordHistogram.recordLongTimesHistogram(
+ "UMA.Debug.EnableCrashUpload.DeferredStartUpDuration",
+ mDeferredStartupDuration,
+ TimeUnit.MILLISECONDS);
+ RecordHistogram.recordLongTimesHistogram(
+ "UMA.Debug.EnableCrashUpload.DeferredStartUpMaxTaskDuration",
+ mMaxTaskDuration,
+ TimeUnit.MILLISECONDS);
+ RecordHistogram.recordLongTimesHistogram(
+ "UMA.Debug.EnableCrashUpload.DeferredStartUpCompleteTime",
+ SystemClock.uptimeMillis() - UmaUtils.getForegroundStartTime(),
+ TimeUnit.MILLISECONDS);
+ }
+ });
+
+ Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
+ @Override
+ public boolean queueIdle() {
+ Runnable currentTask = mDeferredTasks.poll();
+ if (currentTask == null) {
+ mDeferredStartupCompleted = true;
+ return false;
+ }
+
+ long startTime = SystemClock.uptimeMillis();
+ currentTask.run();
+ long timeTaken = SystemClock.uptimeMillis() - startTime;
+
+ mMaxTaskDuration = Math.max(mMaxTaskDuration, timeTaken);
+ mDeferredStartupDuration += timeTaken;
+ return true;
+ }
+ });
+ }
+
+ /**
+ * Adds a single deferred task to the queue.
+ *
+ * @param deferredTask The tasks to be run.
+ */
+ public void addDeferredTask(Runnable deferredTask) {
+ if (mDeferredStartupCompleted) {
+ throw new RuntimeException("Scheduling deferred startup task that will never be run.");
+ }
+ ThreadUtils.assertOnUiThread();
+ mDeferredTasks.add(deferredTask);
}
/**
* 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 onDeferredStartupForApp() {
- if (mDeferredStartupComplete) return;
+ public void initDeferredStartupForApp() {
+ if (mDeferredStartupInitialized) return;
+ mDeferredStartupInitialized = true;
ThreadUtils.assertOnUiThread();
- long startDeferredStartupTime = SystemClock.uptimeMillis();
-
- RecordHistogram.recordLongTimesHistogram("UMA.Debug.EnableCrashUpload.DeferredStartUptime",
- startDeferredStartupTime - UmaUtils.getMainEntryPointTime(),
+ RecordHistogram.recordLongTimesHistogram(
+ "UMA.Debug.EnableCrashUpload.DeferredStartUptime2",
+ SystemClock.uptimeMillis() - UmaUtils.getForegroundStartTime(),
TimeUnit.MILLISECONDS);
- // Punt all tasks that may block the UI thread off onto a background thread.
+ mDeferredTasks.add(new Runnable() {
+ @Override
+ public void run() {
+ // Punt all tasks that may block on disk off onto a background thread.
+ initAsyncDiskTask();
+
+ 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(mAppContext);
+
+ ShareHelper.clearSharedImages(mAppContext);
+ }
+ });
+
+ mDeferredTasks.add(new Runnable() {
+ @Override
+ public void run() {
+ // Clear any media notifications that existed when Chrome was last killed.
+ MediaCaptureNotificationService.clearMediaNotifications(mAppContext);
+
+ startModerateBindingManagementIfNeeded();
+
+ recordKeyboardLocaleUma();
+ }
+ });
+
+ final ChromeApplication application = (ChromeApplication) mAppContext;
+ mDeferredTasks.add(new Runnable() {
+ @Override
+ public void run() {
+ // Start or stop Physical Web
+ PhysicalWeb.onChromeStart(application);
+ }
+ });
+
+ mDeferredTasks.add(new Runnable() {
+ @Override
+ public void run() {
+ // Starts syncing with GSA.
+ application.createGsaHelper().startSync();
+ }
+ });
+
+ // This call will add its own tasks to the queue.
+ application.initializeSharedClasses();
+ }
+
+ private void initAsyncDiskTask() {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
@@ -104,8 +235,8 @@ public class DeferredStartupHandler {
ChromeSwitches.DISABLE_CRASH_DUMP_UPLOAD);
if (!crashDumpDisabled) {
RecordHistogram.recordLongTimesHistogram(
- "UMA.Debug.EnableCrashUpload.Uptime2",
- asyncTaskStartTime - UmaUtils.getMainEntryPointTime(),
+ "UMA.Debug.EnableCrashUpload.Uptime3",
+ asyncTaskStartTime - UmaUtils.getForegroundStartTime(),
TimeUnit.MILLISECONDS);
PrivacyPreferencesManager.getInstance().enablePotentialCrashUploading();
MinidumpUploadService.tryUploadAllCrashDumps(mAppContext);
@@ -144,48 +275,6 @@ public class DeferredStartupHandler {
}
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
-
- AfterStartupTaskUtils.setStartupComplete();
-
- PartnerBrowserCustomizations.setOnInitializeAsyncFinished(new Runnable() {
- @Override
- public void run() {
- String homepageUrl = HomepageManager.getHomepageUri(mAppContext);
- LaunchMetrics.recordHomePageLaunchMetrics(
- HomepageManager.isHomepageEnabled(mAppContext),
- NewTabPage.isNTPUrl(homepageUrl), homepageUrl);
- }
- });
-
- // TODO(aruslan): http://b/6397072 This will be moved elsewhere
- PartnerBookmarksShim.kickOffReading(mAppContext);
-
- PowerMonitor.create(mAppContext);
-
- ShareHelper.clearSharedImages(mAppContext);
-
- // Clear any media notifications that existed when Chrome was last killed.
- MediaCaptureNotificationService.clearMediaNotifications(mAppContext);
-
- startModerateBindingManagementIfNeeded();
-
- recordKeyboardLocaleUma();
-
- ChromeApplication application = (ChromeApplication) mAppContext;
- // Starts syncing with GSA.
- application.createGsaHelper().startSync();
-
- application.initializeSharedClasses();
-
- // Start or stop Physical Web
- PhysicalWeb.onChromeStart(application);
-
- mDeferredStartupComplete = true;
-
- RecordHistogram.recordLongTimesHistogram(
- "UMA.Debug.EnableCrashUpload.DeferredStartUpDuration",
- SystemClock.uptimeMillis() - startDeferredStartupTime,
- TimeUnit.MILLISECONDS);
}
private void startModerateBindingManagementIfNeeded() {
@@ -262,6 +351,6 @@ public class DeferredStartupHandler {
*/
@VisibleForTesting
public boolean isDeferredStartupComplete() {
- return mDeferredStartupComplete;
+ return mDeferredStartupCompleted;
}
}

Powered by Google App Engine
This is Rietveld 408576698