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 |