Chromium Code Reviews| 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.SharedPreferences; | 8 import android.content.SharedPreferences; |
| 9 import android.os.AsyncTask; | 9 import android.os.AsyncTask; |
| 10 import android.os.Looper; | 10 import android.os.Looper; |
| 11 import android.os.MessageQueue; | 11 import android.os.MessageQueue; |
| 12 import android.os.SystemClock; | 12 import android.os.SystemClock; |
| 13 import android.support.annotation.UiThread; | 13 import android.support.annotation.UiThread; |
| 14 import android.support.annotation.WorkerThread; | 14 import android.support.annotation.WorkerThread; |
| 15 import android.view.inputmethod.InputMethodInfo; | 15 import android.view.inputmethod.InputMethodInfo; |
| 16 import android.view.inputmethod.InputMethodManager; | 16 import android.view.inputmethod.InputMethodManager; |
| 17 import android.view.inputmethod.InputMethodSubtype; | 17 import android.view.inputmethod.InputMethodSubtype; |
| 18 | 18 |
| 19 import org.chromium.base.CommandLine; | 19 import org.chromium.base.CommandLine; |
| 20 import org.chromium.base.ContextUtils; | 20 import org.chromium.base.ContextUtils; |
| 21 import org.chromium.base.FieldTrialList; | 21 import org.chromium.base.FieldTrialList; |
| 22 import org.chromium.base.Log; | |
| 22 import org.chromium.base.PowerMonitor; | 23 import org.chromium.base.PowerMonitor; |
| 23 import org.chromium.base.SysUtils; | 24 import org.chromium.base.SysUtils; |
| 24 import org.chromium.base.ThreadUtils; | 25 import org.chromium.base.ThreadUtils; |
| 25 import org.chromium.base.TraceEvent; | 26 import org.chromium.base.TraceEvent; |
| 26 import org.chromium.base.VisibleForTesting; | 27 import org.chromium.base.VisibleForTesting; |
| 27 import org.chromium.base.metrics.RecordHistogram; | 28 import org.chromium.base.metrics.RecordHistogram; |
| 28 import org.chromium.chrome.browser.bookmarkswidget.BookmarkWidgetProvider; | 29 import org.chromium.chrome.browser.bookmarkswidget.BookmarkWidgetProvider; |
| 30 import org.chromium.chrome.browser.crash.LogcatExtractionRunnable; | |
| 29 import org.chromium.chrome.browser.crash.MinidumpUploadService; | 31 import org.chromium.chrome.browser.crash.MinidumpUploadService; |
| 30 import org.chromium.chrome.browser.init.ProcessInitializationHandler; | 32 import org.chromium.chrome.browser.init.ProcessInitializationHandler; |
| 31 import org.chromium.chrome.browser.locale.LocaleManager; | 33 import org.chromium.chrome.browser.locale.LocaleManager; |
| 32 import org.chromium.chrome.browser.media.MediaCaptureNotificationService; | 34 import org.chromium.chrome.browser.media.MediaCaptureNotificationService; |
| 33 import org.chromium.chrome.browser.metrics.LaunchMetrics; | 35 import org.chromium.chrome.browser.metrics.LaunchMetrics; |
| 34 import org.chromium.chrome.browser.metrics.UmaUtils; | 36 import org.chromium.chrome.browser.metrics.UmaUtils; |
| 35 import org.chromium.chrome.browser.ntp.NewTabPage; | 37 import org.chromium.chrome.browser.ntp.NewTabPage; |
| 36 import org.chromium.chrome.browser.offlinepages.OfflinePageUtils; | 38 import org.chromium.chrome.browser.offlinepages.OfflinePageUtils; |
| 37 import org.chromium.chrome.browser.partnerbookmarks.PartnerBookmarksShim; | 39 import org.chromium.chrome.browser.partnerbookmarks.PartnerBookmarksShim; |
| 38 import org.chromium.chrome.browser.partnercustomizations.HomepageManager; | 40 import org.chromium.chrome.browser.partnercustomizations.HomepageManager; |
| 39 import org.chromium.chrome.browser.partnercustomizations.PartnerBrowserCustomiza tions; | 41 import org.chromium.chrome.browser.partnercustomizations.PartnerBrowserCustomiza tions; |
| 40 import org.chromium.chrome.browser.physicalweb.PhysicalWeb; | 42 import org.chromium.chrome.browser.physicalweb.PhysicalWeb; |
| 41 import org.chromium.chrome.browser.precache.PrecacheLauncher; | 43 import org.chromium.chrome.browser.precache.PrecacheLauncher; |
| 42 import org.chromium.chrome.browser.preferences.ChromePreferenceManager; | 44 import org.chromium.chrome.browser.preferences.ChromePreferenceManager; |
| 43 import org.chromium.chrome.browser.preferences.privacy.PrivacyPreferencesManager ; | 45 import org.chromium.chrome.browser.preferences.privacy.PrivacyPreferencesManager ; |
| 44 import org.chromium.chrome.browser.share.ShareHelper; | 46 import org.chromium.chrome.browser.share.ShareHelper; |
| 45 import org.chromium.chrome.browser.webapps.ChromeWebApkHost; | 47 import org.chromium.chrome.browser.webapps.ChromeWebApkHost; |
| 46 import org.chromium.chrome.browser.webapps.WebApkVersionManager; | 48 import org.chromium.chrome.browser.webapps.WebApkVersionManager; |
| 47 import org.chromium.chrome.browser.webapps.WebappRegistry; | 49 import org.chromium.chrome.browser.webapps.WebappRegistry; |
| 48 import org.chromium.components.minidump_uploader.CrashFileManager; | 50 import org.chromium.components.minidump_uploader.CrashFileManager; |
| 49 import org.chromium.content.browser.ChildProcessLauncher; | 51 import org.chromium.content.browser.ChildProcessLauncher; |
| 50 | 52 |
| 53 import java.io.File; | |
| 51 import java.util.ArrayList; | 54 import java.util.ArrayList; |
| 55 import java.util.Arrays; | |
| 56 import java.util.Date; | |
| 52 import java.util.LinkedList; | 57 import java.util.LinkedList; |
| 53 import java.util.List; | 58 import java.util.List; |
| 54 import java.util.Locale; | 59 import java.util.Locale; |
| 55 import java.util.Queue; | 60 import java.util.Queue; |
| 56 import java.util.concurrent.TimeUnit; | 61 import java.util.concurrent.TimeUnit; |
| 57 | 62 |
| 58 /** | 63 /** |
| 59 * Handler for application level tasks to be completed on deferred startup. | 64 * Handler for application level tasks to be completed on deferred startup. |
| 60 */ | 65 */ |
| 61 public class DeferredStartupHandler { | 66 public class DeferredStartupHandler { |
| 62 private static final String TAG = "DeferredStartupHandler"; | 67 private static final String TAG = "DeferredStartup"; |
| 63 /** Prevents race conditions when deleting snapshot database. */ | 68 /** Prevents race conditions when deleting snapshot database. */ |
| 64 private static final Object SNAPSHOT_DATABASE_LOCK = new Object(); | 69 private static final Object SNAPSHOT_DATABASE_LOCK = new Object(); |
| 65 private static final String SNAPSHOT_DATABASE_REMOVED = "snapshot_database_r emoved"; | 70 private static final String SNAPSHOT_DATABASE_REMOVED = "snapshot_database_r emoved"; |
| 66 private static final String SNAPSHOT_DATABASE_NAME = "snapshots.db"; | 71 private static final String SNAPSHOT_DATABASE_NAME = "snapshots.db"; |
| 67 | 72 |
| 68 private static class Holder { | 73 private static class Holder { |
| 69 private static final DeferredStartupHandler INSTANCE = new DeferredStart upHandler(); | 74 private static final DeferredStartupHandler INSTANCE = new DeferredStart upHandler(); |
| 70 } | 75 } |
| 71 | 76 |
| 72 private boolean mDeferredStartupInitializedForApp; | 77 private boolean mDeferredStartupInitializedForApp; |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 236 } | 241 } |
| 237 | 242 |
| 238 private void initAsyncDiskTask() { | 243 private void initAsyncDiskTask() { |
| 239 new AsyncTask<Void, Void, Void>() { | 244 new AsyncTask<Void, Void, Void>() { |
| 240 private long mAsyncTaskStartTime; | 245 private long mAsyncTaskStartTime; |
| 241 | 246 |
| 242 @Override | 247 @Override |
| 243 protected Void doInBackground(Void... params) { | 248 protected Void doInBackground(Void... params) { |
| 244 try { | 249 try { |
| 245 TraceEvent.begin("ChromeBrowserInitializer.onDeferredStartup .doInBackground"); | 250 TraceEvent.begin("ChromeBrowserInitializer.onDeferredStartup .doInBackground"); |
| 251 | |
| 246 mAsyncTaskStartTime = SystemClock.uptimeMillis(); | 252 mAsyncTaskStartTime = SystemClock.uptimeMillis(); |
| 247 | 253 |
| 248 boolean crashDumpDisabled = CommandLine.getInstance().hasSwi tch( | 254 initCrashReporting(); |
| 249 ChromeSwitches.DISABLE_CRASH_DUMP_UPLOAD); | |
| 250 if (!crashDumpDisabled) { | |
| 251 RecordHistogram.recordLongTimesHistogram( | |
| 252 "UMA.Debug.EnableCrashUpload.Uptime3", | |
| 253 mAsyncTaskStartTime - UmaUtils.getForegroundStar tTime(), | |
| 254 TimeUnit.MILLISECONDS); | |
| 255 PrivacyPreferencesManager.getInstance().enablePotentialC rashUploading(); | |
| 256 MinidumpUploadService.tryUploadAllCrashDumps(mAppContext ); | |
| 257 } | |
| 258 CrashFileManager crashFileManager = | |
| 259 new CrashFileManager(mAppContext.getCacheDir()); | |
| 260 crashFileManager.cleanOutAllNonFreshMinidumpFiles(); | |
| 261 | |
| 262 MinidumpUploadService.storeBreakpadUploadStatsInUma( | |
| 263 ChromePreferenceManager.getInstance()); | |
| 264 | 255 |
| 265 // Initialize the WebappRegistry if it's not already initial ized. Must be in | 256 // Initialize the WebappRegistry if it's not already initial ized. Must be in |
| 266 // async task due to shared preferences disk access on N. | 257 // async task due to shared preferences disk access on N. |
| 267 WebappRegistry.getInstance(); | 258 WebappRegistry.getInstance(); |
| 268 | 259 |
| 269 // Force a widget refresh in order to wake up any possible z ombie widgets. | 260 // Force a widget refresh in order to wake up any possible z ombie widgets. |
| 270 // This is needed to ensure the right behavior when the proc ess is suddenly | 261 // This is needed to ensure the right behavior when the proc ess is suddenly |
| 271 // killed. | 262 // killed. |
| 272 BookmarkWidgetProvider.refreshAllWidgets(mAppContext); | 263 BookmarkWidgetProvider.refreshAllWidgets(mAppContext); |
| 273 | 264 |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 293 @Override | 284 @Override |
| 294 protected void onPostExecute(Void params) { | 285 protected void onPostExecute(Void params) { |
| 295 // Must be run on the UI thread after the WebappRegistry has bee n completely warmed. | 286 // Must be run on the UI thread after the WebappRegistry has bee n completely warmed. |
| 296 WebappRegistry.getInstance().unregisterOldWebapps(System.current TimeMillis()); | 287 WebappRegistry.getInstance().unregisterOldWebapps(System.current TimeMillis()); |
| 297 | 288 |
| 298 RecordHistogram.recordLongTimesHistogram( | 289 RecordHistogram.recordLongTimesHistogram( |
| 299 "UMA.Debug.EnableCrashUpload.DeferredStartUpAsyncTaskDur ation", | 290 "UMA.Debug.EnableCrashUpload.DeferredStartUpAsyncTaskDur ation", |
| 300 SystemClock.uptimeMillis() - mAsyncTaskStartTime, | 291 SystemClock.uptimeMillis() - mAsyncTaskStartTime, |
| 301 TimeUnit.MILLISECONDS); | 292 TimeUnit.MILLISECONDS); |
| 302 } | 293 } |
| 294 | |
| 295 /** | |
| 296 * Initializes the crash reporting system. More specifically, enable s the crash | |
| 297 * reporting system if it is user-permitted, and initiates uploading of any pending | |
| 298 * crash reports. Also updates some UMA metrics and performs cleanup in the local crash | |
| 299 * minidump storage directory. | |
| 300 */ | |
| 301 private void initCrashReporting() { | |
| 302 // Perform cleanup prior to checking whether crash reporting is enabled, so that | |
| 303 // users who disable crash reporting are still able to eventuall y recover disk space | |
| 304 // dedicated to storing pending crash reports. | |
| 305 CrashFileManager crashFileManager = new CrashFileManager(mAppCon text.getCacheDir()); | |
| 306 crashFileManager.cleanOutAllNonFreshMinidumpFiles(); | |
| 307 | |
| 308 // Likewise, there might be pending metrics from previous runs w hen crash reporting | |
| 309 // was enabled. | |
| 310 MinidumpUploadService.storeBreakpadUploadStatsInUma( | |
| 311 ChromePreferenceManager.getInstance()); | |
| 312 | |
| 313 // Now check whether crash reporting is enabled. If it is, broad cast the appropriate | |
| 314 // permission. | |
| 315 boolean crashReportingDisabled = CommandLine.getInstance().hasSw itch( | |
| 316 ChromeSwitches.DISABLE_CRASH_DUMP_UPLOAD); | |
| 317 if (crashReportingDisabled) return; | |
| 318 | |
| 319 RecordHistogram.recordLongTimesHistogram("UMA.Debug.EnableCrashU pload.Uptime3", | |
| 320 mAsyncTaskStartTime - UmaUtils.getForegroundStartTime(), | |
| 321 TimeUnit.MILLISECONDS); | |
| 322 PrivacyPreferencesManager.getInstance().enablePotentialCrashUplo ading(); | |
| 323 | |
| 324 // Finally, uploading any pending crash reports. | |
| 325 File[] minidumps = crashFileManager.getAllMinidumpFiles( | |
| 326 MinidumpUploadService.MAX_TRIES_ALLOWED); | |
| 327 if (minidumps.length == 0) return; | |
| 328 | |
| 329 Log.i(TAG, "Attempting to upload %d accumulated crash dumps.", m inidumps.length); | |
| 330 File mostRecentMinidump = minidumps[0]; | |
| 331 boolean noLogcatExtractionNeeded = !doesCrashMinidumpNeedLogcat( mostRecentMinidump); | |
| 332 if (noLogcatExtractionNeeded) { | |
| 333 MinidumpUploadService.tryUploadAllCrashDumps(mAppContext); | |
| 334 } else { | |
| 335 AsyncTask.THREAD_POOL_EXECUTOR.execute( | |
| 336 new LogcatExtractionRunnable(mAppContext, mostRecent Minidump)); | |
| 337 | |
| 338 // TODO(isherman): Once there is support implemented for the JobScheduler API, | |
| 339 // we should only explicitly upload the remaining files here if not using that | |
| 340 // API. If we *are* using the JobScheduler API, then the Job Scheduler will | |
| 341 // schedule uploads for all of the available minidumps once the logcat is | |
| 342 // attached. | |
| 343 List<File> remainingMinidumps = | |
| 344 Arrays.asList(minidumps).subList(1, minidumps.length ); | |
| 345 for (File minidump : remainingMinidumps) { | |
| 346 MinidumpUploadService.tryUploadCrashDump(mAppContext, mi nidump); | |
| 347 } | |
| 348 } | |
| 349 } | |
| 350 | |
| 351 /** | |
| 352 * Returns whether or not it's appropriate to try to extract recent logcat output and | |
| 353 * include that logcat output alongside the given {@param minidump} in a crash report. | |
| 354 * Logcat output should only be extracted if (a) it hasn't already b een extracted for | |
| 355 * this minidump file, and (b) the minidump is fairly fresh. The fre shness check is | |
| 356 * important for two reasons: (1) First of all, it helps avoid inclu ding irrelevant | |
| 357 * logcat output for a crash report. (2) Secondly, it provides an es cape hatch that can | |
| 358 * help circumvent a possible infinite crash loop, if the code respo nsible for | |
| 359 * extracting and appending the logcat content is itself crashing. T hat is, the user can | |
| 360 * wait 15 minutes prior to relaunching Chrome, at which point this potential crash loop | |
| 361 * would be circumvented. | |
|
gsennton
2017/03/08 15:18:41
Cool, thanks for updating the explanation :).
nit:
Ilya Sherman
2017/03/09 01:08:45
Mmm, I think this is the "subjunctive" tense, and
| |
| 362 * @return Whether to try to include logcat output in the crash repo rt corresponding to | |
| 363 * the given minidump. | |
| 364 */ | |
| 365 private boolean doesCrashMinidumpNeedLogcat(File minidump) { | |
| 366 if (!CrashFileManager.isMinidumpMIMEFirstTry(minidump.getName()) ) return false; | |
| 367 | |
| 368 long ageInMillis = new Date().getTime() - minidump.lastModified( ); | |
| 369 long ageInMinutes = TimeUnit.MINUTES.convert(ageInMillis, TimeUn it.MILLISECONDS); | |
| 370 return ageInMinutes < 15; | |
| 371 } | |
| 303 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); | 372 }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); |
| 304 } | 373 } |
| 305 | 374 |
| 306 private void startModerateBindingManagementIfNeeded() { | 375 private void startModerateBindingManagementIfNeeded() { |
| 307 // Moderate binding doesn't apply to low end devices. | 376 // Moderate binding doesn't apply to low end devices. |
| 308 if (SysUtils.isLowEndDevice()) return; | 377 if (SysUtils.isLowEndDevice()) return; |
| 309 | 378 |
| 310 boolean moderateBindingTillBackgrounded = | 379 boolean moderateBindingTillBackgrounded = |
| 311 FieldTrialList.findFullName("ModerateBindingOnBackgroundTabCreat ion") | 380 FieldTrialList.findFullName("ModerateBindingOnBackgroundTabCreat ion") |
| 312 .equals("Enabled"); | 381 .equals("Enabled"); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 360 } | 429 } |
| 361 | 430 |
| 362 /** | 431 /** |
| 363 * @return Whether deferred startup has been completed. | 432 * @return Whether deferred startup has been completed. |
| 364 */ | 433 */ |
| 365 @VisibleForTesting | 434 @VisibleForTesting |
| 366 public boolean isDeferredStartupCompleteForApp() { | 435 public boolean isDeferredStartupCompleteForApp() { |
| 367 return mDeferredStartupCompletedForApp; | 436 return mDeferredStartupCompletedForApp; |
| 368 } | 437 } |
| 369 } | 438 } |
| OLD | NEW |