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

Side by Side 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: Rebase 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.chrome.browser; 5 package org.chromium.chrome.browser;
6 6
7 import android.content.Context; 7 import android.content.Context;
8 import android.content.Intent; 8 import android.content.Intent;
9 import android.content.SharedPreferences; 9 import android.content.SharedPreferences;
10 import android.content.pm.ResolveInfo; 10 import android.content.pm.ResolveInfo;
11 import android.net.Uri; 11 import android.net.Uri;
12 import android.os.AsyncTask; 12 import android.os.AsyncTask;
13 import android.os.Looper;
14 import android.os.MessageQueue;
13 import android.os.SystemClock; 15 import android.os.SystemClock;
14 import android.support.annotation.UiThread; 16 import android.support.annotation.UiThread;
15 import android.support.annotation.WorkerThread; 17 import android.support.annotation.WorkerThread;
16 import android.view.inputmethod.InputMethodInfo; 18 import android.view.inputmethod.InputMethodInfo;
17 import android.view.inputmethod.InputMethodManager; 19 import android.view.inputmethod.InputMethodManager;
18 import android.view.inputmethod.InputMethodSubtype; 20 import android.view.inputmethod.InputMethodSubtype;
19 21
20 import org.chromium.base.CommandLine; 22 import org.chromium.base.CommandLine;
21 import org.chromium.base.ContextUtils; 23 import org.chromium.base.ContextUtils;
22 import org.chromium.base.FieldTrialList; 24 import org.chromium.base.FieldTrialList;
(...skipping 15 matching lines...) Expand all
38 import org.chromium.chrome.browser.partnercustomizations.PartnerBrowserCustomiza tions; 40 import org.chromium.chrome.browser.partnercustomizations.PartnerBrowserCustomiza tions;
39 import org.chromium.chrome.browser.physicalweb.PhysicalWeb; 41 import org.chromium.chrome.browser.physicalweb.PhysicalWeb;
40 import org.chromium.chrome.browser.precache.PrecacheLauncher; 42 import org.chromium.chrome.browser.precache.PrecacheLauncher;
41 import org.chromium.chrome.browser.preferences.ChromePreferenceManager; 43 import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
42 import org.chromium.chrome.browser.preferences.privacy.PrivacyPreferencesManager ; 44 import org.chromium.chrome.browser.preferences.privacy.PrivacyPreferencesManager ;
43 import org.chromium.chrome.browser.share.ShareHelper; 45 import org.chromium.chrome.browser.share.ShareHelper;
44 import org.chromium.chrome.browser.webapps.WebApkVersionManager; 46 import org.chromium.chrome.browser.webapps.WebApkVersionManager;
45 import org.chromium.content.browser.ChildProcessLauncher; 47 import org.chromium.content.browser.ChildProcessLauncher;
46 48
47 import java.util.ArrayList; 49 import java.util.ArrayList;
50 import java.util.LinkedList;
48 import java.util.List; 51 import java.util.List;
49 import java.util.Locale; 52 import java.util.Locale;
53 import java.util.Queue;
50 import java.util.concurrent.TimeUnit; 54 import java.util.concurrent.TimeUnit;
51 55
52 /** 56 /**
53 * Handler for application level tasks to be completed on deferred startup. 57 * Handler for application level tasks to be completed on deferred startup.
54 */ 58 */
55 public class DeferredStartupHandler { 59 public class DeferredStartupHandler {
60 private static final String TAG = "DeferredStartupHandler";
56 /** Prevents race conditions when deleting snapshot database. */ 61 /** Prevents race conditions when deleting snapshot database. */
57 private static final Object SNAPSHOT_DATABASE_LOCK = new Object(); 62 private static final Object SNAPSHOT_DATABASE_LOCK = new Object();
58 private static final String SNAPSHOT_DATABASE_REMOVED = "snapshot_database_r emoved"; 63 private static final String SNAPSHOT_DATABASE_REMOVED = "snapshot_database_r emoved";
59 private static final String SNAPSHOT_DATABASE_NAME = "snapshots.db"; 64 private static final String SNAPSHOT_DATABASE_NAME = "snapshots.db";
60 65
61 private static class Holder { 66 private static class Holder {
62 private static final DeferredStartupHandler INSTANCE = new DeferredStart upHandler(); 67 private static final DeferredStartupHandler INSTANCE = new DeferredStart upHandler();
63 } 68 }
64 69
65 private boolean mDeferredStartupComplete; 70 private boolean mDeferredStartupInitialized;
71 private boolean mDeferredStartupCompleted;
72 private long mDeferredStartupDuration;
73 private long mMaxTaskDuration;
66 private final Context mAppContext; 74 private final Context mAppContext;
67 75
76 @VisibleForTesting
77 final Queue<Runnable> mDeferredTasks;
78
68 /** 79 /**
69 * This class is an application specific object that handles the deferred st artup. 80 * This class is an application specific object that handles the deferred st artup.
70 * @return The singleton instance of {@link DeferredStartupHandler}. 81 * @return The singleton instance of {@link DeferredStartupHandler}.
71 */ 82 */
72 public static DeferredStartupHandler getInstance() { 83 public static DeferredStartupHandler getInstance() {
73 return Holder.INSTANCE; 84 return Holder.INSTANCE;
74 } 85 }
75 86
76 private DeferredStartupHandler() { 87 private DeferredStartupHandler() {
77 mAppContext = ContextUtils.getApplicationContext(); 88 mAppContext = ContextUtils.getApplicationContext();
89 mDeferredTasks = new LinkedList<Runnable>();
90 }
91
92 /**
93 * Add the idle handler which will run deferred startup tasks in sequence wh en idle.
94 */
95 public void queueDeferredTasksOnIdleHandler() {
96 if (!mDeferredStartupInitialized) return;
97
98 Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
99 @Override
100 public boolean queueIdle() {
101 Runnable currentTask = mDeferredTasks.poll();
102 if (currentTask == null) {
103 mDeferredStartupCompleted = true;
104 recordDeferredStartupStats();
105 return false;
106 }
107
108 long startTime = SystemClock.uptimeMillis();
109 currentTask.run();
110 long timeTaken = SystemClock.uptimeMillis() - startTime;
111
112 mMaxTaskDuration = Math.max(mMaxTaskDuration, timeTaken);
113 mDeferredStartupDuration += timeTaken;
114 return true;
115 }
116 });
117 }
118
119 private void recordDeferredStartupStats() {
120 RecordHistogram.recordLongTimesHistogram(
121 "UMA.Debug.EnableCrashUpload.DeferredStartUpDuration",
122 mDeferredStartupDuration,
123 TimeUnit.MILLISECONDS);
124 RecordHistogram.recordLongTimesHistogram(
125 "UMA.Debug.EnableCrashUpload.DeferredStartUpMaxTaskDuration",
126 mMaxTaskDuration,
127 TimeUnit.MILLISECONDS);
128 RecordHistogram.recordLongTimesHistogram(
129 "UMA.Debug.EnableCrashUpload.DeferredStartUpCompleteTime",
130 SystemClock.uptimeMillis() - UmaUtils.getForegroundStartTime(),
131 TimeUnit.MILLISECONDS);
132 }
133
134 /**
135 * Adds a single deferred task to the queue.
136 *
137 * @param deferredTask The tasks to be run.
138 */
139 public void addDeferredTask(Runnable deferredTask) {
140 if (mDeferredStartupCompleted) {
141 throw new RuntimeException("Scheduling deferred startup task that wi ll never be run.");
142 }
143 ThreadUtils.assertOnUiThread();
144 mDeferredTasks.add(deferredTask);
78 } 145 }
79 146
80 /** 147 /**
81 * Handle application level deferred startup tasks that can be lazily done a fter all 148 * Handle application level deferred startup tasks that can be lazily done a fter all
82 * the necessary initialization has been completed. Any calls requiring netw ork access should 149 * the necessary initialization has been completed. Any calls requiring netw ork access should
83 * probably go here. 150 * probably go here.
151 *
152 * Keep these tasks short and break up long tasks into multiple smaller task s, as they run on
153 * the UI thread and are blocking. Remember to follow RAIL guidelines, as mu ch as possible, and
154 * that most devices are quite slow, so leave enough buffer.
84 */ 155 */
85 @UiThread 156 @UiThread
86 public void onDeferredStartupForApp() { 157 public void initDeferredStartupForApp() {
87 if (mDeferredStartupComplete) return; 158 if (mDeferredStartupInitialized) return;
159 mDeferredStartupInitialized = true;
88 ThreadUtils.assertOnUiThread(); 160 ThreadUtils.assertOnUiThread();
89 161
90 long startDeferredStartupTime = SystemClock.uptimeMillis(); 162 RecordHistogram.recordLongTimesHistogram(
91 163 "UMA.Debug.EnableCrashUpload.DeferredStartUptime2",
92 RecordHistogram.recordLongTimesHistogram("UMA.Debug.EnableCrashUpload.De ferredStartUptime", 164 SystemClock.uptimeMillis() - UmaUtils.getForegroundStartTime(),
93 startDeferredStartupTime - UmaUtils.getMainEntryPointTime(),
94 TimeUnit.MILLISECONDS); 165 TimeUnit.MILLISECONDS);
95 166
96 // Punt all tasks that may block the UI thread off onto a background thr ead. 167 mDeferredTasks.add(new Runnable() {
168 @Override
169 public void run() {
170 // Punt all tasks that may block on disk off onto a background t hread.
171 initAsyncDiskTask();
172
173 AfterStartupTaskUtils.setStartupComplete();
174
175 PartnerBrowserCustomizations.setOnInitializeAsyncFinished(new Ru nnable() {
176 @Override
177 public void run() {
178 String homepageUrl = HomepageManager.getHomepageUri(mApp Context);
179 LaunchMetrics.recordHomePageLaunchMetrics(
180 HomepageManager.isHomepageEnabled(mAppContext),
181 NewTabPage.isNTPUrl(homepageUrl), homepageUrl);
182 }
183 });
184
185 PartnerBookmarksShim.kickOffReading(mAppContext);
186
187 PowerMonitor.create(mAppContext);
188
189 ShareHelper.clearSharedImages(mAppContext);
190 }
191 });
192
193 mDeferredTasks.add(new Runnable() {
194 @Override
195 public void run() {
196 // Clear any media notifications that existed when Chrome was la st killed.
197 MediaCaptureNotificationService.clearMediaNotifications(mAppCont ext);
198
199 startModerateBindingManagementIfNeeded();
200
201 recordKeyboardLocaleUma();
202 }
203 });
204
205 mDeferredTasks.add(new Runnable() {
206 @Override
207 public void run() {
208 // Start or stop Physical Web
209 PhysicalWeb.onChromeStart();
210 }
211 });
212
213 final ChromeApplication application = (ChromeApplication) mAppContext;
214
215 mDeferredTasks.add(new Runnable() {
216 @Override
217 public void run() {
218 // Starts syncing with GSA.
219 application.createGsaHelper().startSync();
220 }
221 });
222
223 // This call will add its own tasks to the queue.
224 application.initializeSharedClasses();
225 }
226
227 private void initAsyncDiskTask() {
97 new AsyncTask<Void, Void, Void>() { 228 new AsyncTask<Void, Void, Void>() {
98 @Override 229 @Override
99 protected Void doInBackground(Void... params) { 230 protected Void doInBackground(Void... params) {
100 try { 231 try {
101 TraceEvent.begin("ChromeBrowserInitializer.onDeferredStartup .doInBackground"); 232 TraceEvent.begin("ChromeBrowserInitializer.onDeferredStartup .doInBackground");
102 long asyncTaskStartTime = SystemClock.uptimeMillis(); 233 long asyncTaskStartTime = SystemClock.uptimeMillis();
103 boolean crashDumpDisabled = CommandLine.getInstance().hasSwi tch( 234 boolean crashDumpDisabled = CommandLine.getInstance().hasSwi tch(
104 ChromeSwitches.DISABLE_CRASH_DUMP_UPLOAD); 235 ChromeSwitches.DISABLE_CRASH_DUMP_UPLOAD);
105 if (!crashDumpDisabled) { 236 if (!crashDumpDisabled) {
106 RecordHistogram.recordLongTimesHistogram( 237 RecordHistogram.recordLongTimesHistogram(
107 "UMA.Debug.EnableCrashUpload.Uptime2", 238 "UMA.Debug.EnableCrashUpload.Uptime3",
108 asyncTaskStartTime - UmaUtils.getMainEntryPointT ime(), 239 asyncTaskStartTime - UmaUtils.getForegroundStart Time(),
109 TimeUnit.MILLISECONDS); 240 TimeUnit.MILLISECONDS);
110 PrivacyPreferencesManager.getInstance().enablePotentialC rashUploading(); 241 PrivacyPreferencesManager.getInstance().enablePotentialC rashUploading();
111 MinidumpUploadService.tryUploadAllCrashDumps(mAppContext ); 242 MinidumpUploadService.tryUploadAllCrashDumps(mAppContext );
112 } 243 }
113 CrashFileManager crashFileManager = 244 CrashFileManager crashFileManager =
114 new CrashFileManager(mAppContext.getCacheDir()); 245 new CrashFileManager(mAppContext.getCacheDir());
115 crashFileManager.cleanOutAllNonFreshMinidumpFiles(); 246 crashFileManager.cleanOutAllNonFreshMinidumpFiles();
116 247
117 MinidumpUploadService.storeBreakpadUploadStatsInUma( 248 MinidumpUploadService.storeBreakpadUploadStatsInUma(
118 ChromePreferenceManager.getInstance(mAppContext)); 249 ChromePreferenceManager.getInstance(mAppContext));
(...skipping 18 matching lines...) Expand all
137 "UMA.Debug.EnableCrashUpload.DeferredStartUpDuration Async", 268 "UMA.Debug.EnableCrashUpload.DeferredStartUpDuration Async",
138 SystemClock.uptimeMillis() - asyncTaskStartTime, 269 SystemClock.uptimeMillis() - asyncTaskStartTime,
139 TimeUnit.MILLISECONDS); 270 TimeUnit.MILLISECONDS);
140 271
141 return null; 272 return null;
142 } finally { 273 } finally {
143 TraceEvent.end("ChromeBrowserInitializer.onDeferredStartup.d oInBackground"); 274 TraceEvent.end("ChromeBrowserInitializer.onDeferredStartup.d oInBackground");
144 } 275 }
145 } 276 }
146 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 277 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
147
148 AfterStartupTaskUtils.setStartupComplete();
149
150 PartnerBrowserCustomizations.setOnInitializeAsyncFinished(new Runnable() {
151 @Override
152 public void run() {
153 String homepageUrl = HomepageManager.getHomepageUri(mAppContext) ;
154 LaunchMetrics.recordHomePageLaunchMetrics(
155 HomepageManager.isHomepageEnabled(mAppContext),
156 NewTabPage.isNTPUrl(homepageUrl), homepageUrl);
157 }
158 });
159
160 // TODO(aruslan): http://b/6397072 This will be moved elsewhere
161 PartnerBookmarksShim.kickOffReading(mAppContext);
162
163 PowerMonitor.create(mAppContext);
164
165 ShareHelper.clearSharedImages(mAppContext);
166
167 // Clear any media notifications that existed when Chrome was last kille d.
168 MediaCaptureNotificationService.clearMediaNotifications(mAppContext);
169
170 startModerateBindingManagementIfNeeded();
171
172 recordKeyboardLocaleUma();
173
174 ChromeApplication application = (ChromeApplication) mAppContext;
175 // Starts syncing with GSA.
176 application.createGsaHelper().startSync();
177
178 application.initializeSharedClasses();
179
180 // Start or stop Physical Web
181 PhysicalWeb.onChromeStart();
182
183 mDeferredStartupComplete = true;
184
185 RecordHistogram.recordLongTimesHistogram(
186 "UMA.Debug.EnableCrashUpload.DeferredStartUpDuration",
187 SystemClock.uptimeMillis() - startDeferredStartupTime,
188 TimeUnit.MILLISECONDS);
189 } 278 }
190 279
191 private void startModerateBindingManagementIfNeeded() { 280 private void startModerateBindingManagementIfNeeded() {
192 // Moderate binding doesn't apply to low end devices. 281 // Moderate binding doesn't apply to low end devices.
193 if (SysUtils.isLowEndDevice()) return; 282 if (SysUtils.isLowEndDevice()) return;
194 283
195 boolean moderateBindingTillBackgrounded = 284 boolean moderateBindingTillBackgrounded =
196 FieldTrialList.findFullName("ModerateBindingOnBackgroundTabCreat ion") 285 FieldTrialList.findFullName("ModerateBindingOnBackgroundTabCreat ion")
197 .equals("Enabled"); 286 .equals("Enabled");
198 ChildProcessLauncher.startModerateBindingManagement( 287 ChildProcessLauncher.startModerateBindingManagement(
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 boolean match = systemLocale.getLanguage().equalsIgnoreCase(keyboard Language); 344 boolean match = systemLocale.getLanguage().equalsIgnoreCase(keyboard Language);
256 RecordHistogram.recordBooleanHistogram("InputMethod.MatchesSystemLan guage", match); 345 RecordHistogram.recordBooleanHistogram("InputMethod.MatchesSystemLan guage", match);
257 } 346 }
258 } 347 }
259 348
260 /** 349 /**
261 * @return Whether deferred startup has been completed. 350 * @return Whether deferred startup has been completed.
262 */ 351 */
263 @VisibleForTesting 352 @VisibleForTesting
264 public boolean isDeferredStartupComplete() { 353 public boolean isDeferredStartupComplete() {
265 return mDeferredStartupComplete; 354 return mDeferredStartupCompleted;
266 } 355 }
267 } 356 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698