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

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

Issue 2207933002: Reland of Separate deferred startup into tasks. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix one-line. Created 4 years, 4 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 50d60c9ebde3724d1a0caca45e8902cae3b8da09..9c36b82094f04b20ec9f5def6e953c65c571a46f 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,9 +67,14 @@ public class DeferredStartupHandler {
private static final DeferredStartupHandler INSTANCE = new DeferredStartupHandler();
}
- private boolean mDeferredStartupComplete;
+ private boolean mDeferredStartupInitializedForApp;
+ private boolean mDeferredStartupCompletedForApp;
+ 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.
* @return The singleton instance of {@link DeferredStartupHandler}.
@@ -75,25 +85,147 @@ public class DeferredStartupHandler {
private DeferredStartupHandler() {
mAppContext = ContextUtils.getApplicationContext();
+ mDeferredTasks = new LinkedList<>();
+ }
+
+ /**
+ * Add the idle handler which will run deferred startup tasks in sequence when idle. This can
+ * be called multiple times by different activities to schedule their own deferred startup
+ * tasks.
+ */
+ public void queueDeferredTasksOnIdleHandler() {
+ mMaxTaskDuration = 0;
+ mDeferredStartupDuration = 0;
+ Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
+ @Override
+ public boolean queueIdle() {
+ Runnable currentTask = mDeferredTasks.poll();
+ if (currentTask == null) {
+ if (mDeferredStartupInitializedForApp) {
+ mDeferredStartupCompletedForApp = true;
+ recordDeferredStartupStats();
+ }
+ return false;
+ }
+
+ long startTime = SystemClock.uptimeMillis();
+ currentTask.run();
+ long timeTaken = SystemClock.uptimeMillis() - startTime;
+
+ mMaxTaskDuration = Math.max(mMaxTaskDuration, timeTaken);
+ mDeferredStartupDuration += timeTaken;
+ return true;
+ }
+ });
+ }
+
+ private void recordDeferredStartupStats() {
+ 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);
+ }
+
+ /**
+ * Adds a single deferred task to the queue. The caller is responsible for calling
+ * queueDeferredTasksOnIdleHandler after adding tasks.
+ *
+ * @param deferredTask The tasks to be run.
+ */
+ public void addDeferredTask(Runnable deferredTask) {
+ 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 (mDeferredStartupInitializedForApp) return;
+ mDeferredStartupInitializedForApp = 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();
+ }
+ });
+
+ mDeferredTasks.add(new Runnable() {
+ @Override
+ public void run() {
+ // Start or stop Physical Web
+ PhysicalWeb.onChromeStart();
+ }
+ });
+
+ final ChromeApplication application = (ChromeApplication) mAppContext;
+
+ 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 +236,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 +276,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();
-
- mDeferredStartupComplete = true;
-
- RecordHistogram.recordLongTimesHistogram(
- "UMA.Debug.EnableCrashUpload.DeferredStartUpDuration",
- SystemClock.uptimeMillis() - startDeferredStartupTime,
- TimeUnit.MILLISECONDS);
}
private void startModerateBindingManagementIfNeeded() {
@@ -233,7 +323,7 @@ public class DeferredStartupHandler {
InputMethodManager imm =
(InputMethodManager) mAppContext.getSystemService(Context.INPUT_METHOD_SERVICE);
List<InputMethodInfo> ims = imm.getEnabledInputMethodList();
- ArrayList<String> uniqueLanguages = new ArrayList<String>();
+ ArrayList<String> uniqueLanguages = new ArrayList<>();
for (InputMethodInfo method : ims) {
List<InputMethodSubtype> submethods =
imm.getEnabledInputMethodSubtypeList(method, true);
@@ -261,7 +351,7 @@ public class DeferredStartupHandler {
* @return Whether deferred startup has been completed.
*/
@VisibleForTesting
- public boolean isDeferredStartupComplete() {
- return mDeferredStartupComplete;
+ public boolean isDeferredStartupCompleteForApp() {
+ return mDeferredStartupCompletedForApp;
}
}

Powered by Google App Engine
This is Rietveld 408576698