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.crash; | 5 package org.chromium.chrome.browser.crash; |
6 | 6 |
7 import android.annotation.SuppressLint; | 7 import android.annotation.SuppressLint; |
8 import android.app.IntentService; | 8 import android.app.IntentService; |
9 import android.app.job.JobInfo; | 9 import android.app.job.JobInfo; |
10 import android.content.ComponentName; | 10 import android.content.ComponentName; |
11 import android.content.Context; | |
12 import android.content.Intent; | 11 import android.content.Intent; |
13 import android.os.Build; | 12 import android.os.Build; |
14 import android.os.PersistableBundle; | 13 import android.os.PersistableBundle; |
15 import android.support.annotation.StringDef; | 14 import android.support.annotation.StringDef; |
16 | 15 |
| 16 import org.chromium.base.ContextUtils; |
17 import org.chromium.base.Log; | 17 import org.chromium.base.Log; |
18 import org.chromium.base.StreamUtil; | 18 import org.chromium.base.StreamUtil; |
19 import org.chromium.base.VisibleForTesting; | 19 import org.chromium.base.VisibleForTesting; |
20 import org.chromium.base.annotations.CalledByNative; | 20 import org.chromium.base.annotations.CalledByNative; |
21 import org.chromium.base.metrics.RecordHistogram; | 21 import org.chromium.base.metrics.RecordHistogram; |
22 import org.chromium.chrome.browser.preferences.ChromePreferenceManager; | 22 import org.chromium.chrome.browser.preferences.ChromePreferenceManager; |
23 import org.chromium.chrome.browser.preferences.privacy.PrivacyPreferencesManager
; | 23 import org.chromium.chrome.browser.preferences.privacy.PrivacyPreferencesManager
; |
24 import org.chromium.components.background_task_scheduler.TaskIds; | 24 import org.chromium.components.background_task_scheduler.TaskIds; |
25 import org.chromium.components.minidump_uploader.CrashFileManager; | 25 import org.chromium.components.minidump_uploader.CrashFileManager; |
26 import org.chromium.components.minidump_uploader.MinidumpUploadCallable; | 26 import org.chromium.components.minidump_uploader.MinidumpUploadCallable; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 */ | 80 */ |
81 public static boolean shouldUseJobSchedulerForUploads() { | 81 public static boolean shouldUseJobSchedulerForUploads() { |
82 // The JobScheduler API is only usable as of Android M. | 82 // The JobScheduler API is only usable as of Android M. |
83 return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M; | 83 return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M; |
84 } | 84 } |
85 | 85 |
86 /** | 86 /** |
87 * Schedules uploading of all pending minidumps, using the JobScheduler API. | 87 * Schedules uploading of all pending minidumps, using the JobScheduler API. |
88 */ | 88 */ |
89 @SuppressLint("NewApi") | 89 @SuppressLint("NewApi") |
90 public static void scheduleUploadJob(Context context) { | 90 public static void scheduleUploadJob() { |
91 assert shouldUseJobSchedulerForUploads(); | 91 assert shouldUseJobSchedulerForUploads(); |
92 | 92 |
93 CrashReportingPermissionManager permissionManager = PrivacyPreferencesMa
nager.getInstance(); | 93 CrashReportingPermissionManager permissionManager = PrivacyPreferencesMa
nager.getInstance(); |
94 PersistableBundle permissions = new PersistableBundle(); | 94 PersistableBundle permissions = new PersistableBundle(); |
95 permissions.putBoolean(ChromeMinidumpUploaderDelegate.IS_CLIENT_IN_METRI
CS_SAMPLE, | 95 permissions.putBoolean(ChromeMinidumpUploaderDelegate.IS_CLIENT_IN_METRI
CS_SAMPLE, |
96 permissionManager.isClientInMetricsSample()); | 96 permissionManager.isClientInMetricsSample()); |
97 permissions.putBoolean(ChromeMinidumpUploaderDelegate.IS_UPLOAD_ENABLED_
FOR_TESTS, | 97 permissions.putBoolean(ChromeMinidumpUploaderDelegate.IS_UPLOAD_ENABLED_
FOR_TESTS, |
98 permissionManager.isUploadEnabledForTests()); | 98 permissionManager.isUploadEnabledForTests()); |
99 | 99 |
100 JobInfo.Builder builder = | 100 JobInfo.Builder builder = |
101 new JobInfo | 101 new JobInfo |
102 .Builder(TaskIds.CHROME_MINIDUMP_UPLOADING_JOB_ID, | 102 .Builder(TaskIds.CHROME_MINIDUMP_UPLOADING_JOB_ID, |
103 new ComponentName(context, ChromeMinidumpUploadJ
obService.class)) | 103 new ComponentName(ContextUtils.getApplicationCon
text(), |
| 104 ChromeMinidumpUploadJobService.class)) |
104 .setExtras(permissions); | 105 .setExtras(permissions); |
105 MinidumpUploadJobService.scheduleUpload(context, builder); | 106 MinidumpUploadJobService.scheduleUpload(builder); |
106 } | 107 } |
107 | 108 |
108 /** | 109 /** |
109 * Stores the successes and failures from uploading crash to UMA, | 110 * Stores the successes and failures from uploading crash to UMA, |
110 */ | 111 */ |
111 public static void storeBreakpadUploadStatsInUma(ChromePreferenceManager pre
f) { | 112 public static void storeBreakpadUploadStatsInUma(ChromePreferenceManager pre
f) { |
112 for (String type : TYPES) { | 113 for (String type : TYPES) { |
113 for (int success = pref.getCrashSuccessUploadCount(type); success >
0; success--) { | 114 for (int success = pref.getCrashSuccessUploadCount(type); success >
0; success--) { |
114 RecordHistogram.recordEnumeratedHistogram( | 115 RecordHistogram.recordEnumeratedHistogram( |
115 HISTOGRAM_NAME_PREFIX + type, SUCCESS, HISTOGRAM_MAX); | 116 HISTOGRAM_NAME_PREFIX + type, SUCCESS, HISTOGRAM_MAX); |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
284 return new MinidumpUploadCallable( | 285 return new MinidumpUploadCallable( |
285 minidumpFile, logfile, getCrashReportingPermissionManager()); | 286 minidumpFile, logfile, getCrashReportingPermissionManager()); |
286 } | 287 } |
287 | 288 |
288 /** | 289 /** |
289 * Attempts to upload the specified {@param minidumpFile}. | 290 * Attempts to upload the specified {@param minidumpFile}. |
290 * | 291 * |
291 * Note that this method is asynchronous. All that is guaranteed is that an
upload attempt will | 292 * Note that this method is asynchronous. All that is guaranteed is that an
upload attempt will |
292 * be enqueued. | 293 * be enqueued. |
293 * | 294 * |
294 * @param context The application context, in which to initiate the crash re
port upload. | 295 * @throws SecurityException if the caller doesn't have permission to start
the upload |
295 * @throws A security excpetion if the caller doesn't have permission to sta
rt the upload | |
296 * service. This can only happen on KitKat and below, due to a frame
work bug. | 296 * service. This can only happen on KitKat and below, due to a frame
work bug. |
297 */ | 297 */ |
298 public static void tryUploadCrashDump(Context context, File minidumpFile) | 298 public static void tryUploadCrashDump(File minidumpFile) throws SecurityExce
ption { |
299 throws SecurityException { | |
300 assert !shouldUseJobSchedulerForUploads(); | 299 assert !shouldUseJobSchedulerForUploads(); |
301 CrashFileManager fileManager = new CrashFileManager(context.getCacheDir(
)); | 300 CrashFileManager fileManager = |
302 Intent intent = new Intent(context, MinidumpUploadService.class); | 301 new CrashFileManager(ContextUtils.getApplicationContext().getCac
heDir()); |
| 302 Intent intent = |
| 303 new Intent(ContextUtils.getApplicationContext(), MinidumpUploadS
ervice.class); |
303 intent.setAction(ACTION_UPLOAD); | 304 intent.setAction(ACTION_UPLOAD); |
304 intent.putExtra(FILE_TO_UPLOAD_KEY, minidumpFile.getAbsolutePath()); | 305 intent.putExtra(FILE_TO_UPLOAD_KEY, minidumpFile.getAbsolutePath()); |
305 intent.putExtra(UPLOAD_LOG_KEY, fileManager.getCrashUploadLogFile().getA
bsolutePath()); | 306 intent.putExtra(UPLOAD_LOG_KEY, fileManager.getCrashUploadLogFile().getA
bsolutePath()); |
306 context.startService(intent); | 307 ContextUtils.getApplicationContext().startService(intent); |
307 } | 308 } |
308 | 309 |
309 /** | 310 /** |
310 * Attempts to upload all minidump files using the given {@link android.cont
ent.Context}. | 311 * Attempts to upload all minidump files using the given {@link android.cont
ent.Context}. |
311 * | 312 * |
312 * Note that this method is asynchronous. All that is guaranteed is that | 313 * Note that this method is asynchronous. All that is guaranteed is that |
313 * upload attempts will be enqueued. | 314 * upload attempts will be enqueued. |
314 * | 315 * |
315 * This method is safe to call from the UI thread. | 316 * This method is safe to call from the UI thread. |
316 * | 317 * |
317 * @param context Context of the application. | |
318 */ | 318 */ |
319 public static void tryUploadAllCrashDumps(Context context) { | 319 public static void tryUploadAllCrashDumps() { |
320 assert !shouldUseJobSchedulerForUploads(); | 320 assert !shouldUseJobSchedulerForUploads(); |
321 CrashFileManager fileManager = new CrashFileManager(context.getCacheDir(
)); | 321 CrashFileManager fileManager = |
| 322 new CrashFileManager(ContextUtils.getApplicationContext().getCac
heDir()); |
322 File[] minidumps = fileManager.getAllMinidumpFiles(MAX_TRIES_ALLOWED); | 323 File[] minidumps = fileManager.getAllMinidumpFiles(MAX_TRIES_ALLOWED); |
323 Log.i(TAG, "Attempting to upload accumulated crash dumps."); | 324 Log.i(TAG, "Attempting to upload accumulated crash dumps."); |
324 for (File minidump : minidumps) { | 325 for (File minidump : minidumps) { |
325 tryUploadCrashDump(context, minidump); | 326 tryUploadCrashDump(minidump); |
326 } | 327 } |
327 } | 328 } |
328 | 329 |
329 /** | 330 /** |
330 * Attempts to upload the crash report with the given local ID. | 331 * Attempts to upload the crash report with the given local ID. |
331 * | 332 * |
332 * Note that this method is asynchronous. All that is guaranteed is that | 333 * Note that this method is asynchronous. All that is guaranteed is that |
333 * upload attempts will be enqueued. | 334 * upload attempts will be enqueued. |
334 * | 335 * |
335 * This method is safe to call from the UI thread. | 336 * This method is safe to call from the UI thread. |
336 * | 337 * |
337 * @param context the context to use for the intent. | |
338 * @param localId The local ID of the crash report. | 338 * @param localId The local ID of the crash report. |
339 */ | 339 */ |
340 @CalledByNative | 340 @CalledByNative |
341 public static void tryUploadCrashDumpWithLocalId(Context context, String loc
alId) { | 341 public static void tryUploadCrashDumpWithLocalId(String localId) { |
342 if (localId == null || localId.isEmpty()) { | 342 if (localId == null || localId.isEmpty()) { |
343 Log.w(TAG, "Cannot force crash upload since local crash id is absent
."); | 343 Log.w(TAG, "Cannot force crash upload since local crash id is absent
."); |
344 return; | 344 return; |
345 } | 345 } |
346 | 346 |
347 CrashFileManager fileManager = new CrashFileManager(context.getCacheDir(
)); | 347 CrashFileManager fileManager = |
| 348 new CrashFileManager(ContextUtils.getApplicationContext().getCac
heDir()); |
348 File minidumpFile = fileManager.getCrashFileWithLocalId(localId); | 349 File minidumpFile = fileManager.getCrashFileWithLocalId(localId); |
349 if (minidumpFile == null) { | 350 if (minidumpFile == null) { |
350 Log.w(TAG, "Could not find a crash dump with local ID " + localId); | 351 Log.w(TAG, "Could not find a crash dump with local ID " + localId); |
351 return; | 352 return; |
352 } | 353 } |
353 File renamedMinidumpFile = CrashFileManager.trySetForcedUpload(minidumpF
ile); | 354 File renamedMinidumpFile = CrashFileManager.trySetForcedUpload(minidumpF
ile); |
354 if (renamedMinidumpFile == null) { | 355 if (renamedMinidumpFile == null) { |
355 Log.w(TAG, "Could not rename the file " + minidumpFile.getName() + "
for re-upload"); | 356 Log.w(TAG, "Could not rename the file " + minidumpFile.getName() + "
for re-upload"); |
356 return; | 357 return; |
357 } | 358 } |
358 | 359 |
359 if (shouldUseJobSchedulerForUploads()) { | 360 if (shouldUseJobSchedulerForUploads()) { |
360 scheduleUploadJob(context); | 361 scheduleUploadJob(); |
361 } else { | 362 } else { |
362 tryUploadCrashDump(context, renamedMinidumpFile); | 363 tryUploadCrashDump(renamedMinidumpFile); |
363 } | 364 } |
364 } | 365 } |
365 } | 366 } |
OLD | NEW |