| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |