| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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.components.minidump_uploader; | 5 package org.chromium.components.minidump_uploader; |
| 6 | 6 |
| 7 import org.chromium.base.Log; | 7 import org.chromium.base.Log; |
| 8 import org.chromium.base.ThreadUtils; | 8 import org.chromium.base.ThreadUtils; |
| 9 import org.chromium.base.VisibleForTesting; | 9 import org.chromium.base.VisibleForTesting; |
| 10 | 10 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 * The thread used for the actual work of uploading minidumps. | 41 * The thread used for the actual work of uploading minidumps. |
| 42 */ | 42 */ |
| 43 private Thread mWorkerThread; | 43 private Thread mWorkerThread; |
| 44 | 44 |
| 45 @VisibleForTesting | 45 @VisibleForTesting |
| 46 public static final int MAX_UPLOAD_TRIES_ALLOWED = 3; | 46 public static final int MAX_UPLOAD_TRIES_ALLOWED = 3; |
| 47 | 47 |
| 48 @VisibleForTesting | 48 @VisibleForTesting |
| 49 public MinidumpUploaderImpl(MinidumpUploaderDelegate delegate) { | 49 public MinidumpUploaderImpl(MinidumpUploaderDelegate delegate) { |
| 50 mDelegate = delegate; | 50 mDelegate = delegate; |
| 51 mFileManager = createCrashFileManager(mDelegate.createCrashDir()); | 51 mFileManager = createCrashFileManager(mDelegate.getCrashParentDir()); |
| 52 if (!mFileManager.ensureCrashDirExists()) { | 52 if (!mFileManager.ensureCrashDirExists()) { |
| 53 Log.e(TAG, "Crash directory doesn't exist!"); | 53 Log.e(TAG, "Crash directory doesn't exist!"); |
| 54 } | 54 } |
| 55 } | 55 } |
| 56 | 56 |
| 57 /** | 57 /** |
| 58 * Utility method to allow tests to customize the behavior of the crash file
manager. | 58 * Utility method to allow tests to customize the behavior of the crash file
manager. |
| 59 * @param {crashDir} The directory in which to store crash files (i.e. minid
umps). | 59 * @param {crashParentDir} The directory that contains the "Crash Reports" d
irectory, in which |
| 60 * crash files (i.e. minidumps) are stored. |
| 60 */ | 61 */ |
| 61 @VisibleForTesting | 62 @VisibleForTesting |
| 62 public CrashFileManager createCrashFileManager(File crashDir) { | 63 public CrashFileManager createCrashFileManager(File crashParentDir) { |
| 63 return new CrashFileManager(crashDir); | 64 return new CrashFileManager(crashParentDir); |
| 64 } | 65 } |
| 65 | 66 |
| 66 /** | 67 /** |
| 67 * Utility method to allow us to test the logic of this class by injecting | 68 * Utility method to allow us to test the logic of this class by injecting |
| 68 * test-specific MinidumpUploadCallables. | 69 * test-specific MinidumpUploadCallables. |
| 69 */ | 70 */ |
| 70 @VisibleForTesting | 71 @VisibleForTesting |
| 71 public MinidumpUploadCallable createMinidumpUploadCallable(File minidumpFile
, File logfile) { | 72 public MinidumpUploadCallable createMinidumpUploadCallable(File minidumpFile
, File logfile) { |
| 72 return new MinidumpUploadCallable( | 73 return new MinidumpUploadCallable( |
| 73 minidumpFile, logfile, mDelegate.createCrashReportingPermissionM
anager()); | 74 minidumpFile, logfile, mDelegate.createCrashReportingPermissionM
anager()); |
| 74 } | 75 } |
| 75 | 76 |
| 76 /** | 77 /** |
| 77 * Runnable that upload minidumps. | 78 * Runnable that upload minidumps. |
| 78 * This is where the actual uploading happens - an upload job consists of po
sting this Runnable | 79 * This is where the actual uploading happens - an upload job consists of po
sting this Runnable |
| 79 * to the worker thread. | 80 * to the worker thread. |
| 80 */ | 81 */ |
| 81 private class UploadRunnable implements Runnable { | 82 private class UploadRunnable implements Runnable { |
| 82 private final MinidumpUploader.UploadsFinishedCallback mUploadsFinishedC
allback; | 83 private final MinidumpUploader.UploadsFinishedCallback mUploadsFinishedC
allback; |
| 83 | 84 |
| 84 public UploadRunnable(MinidumpUploader.UploadsFinishedCallback uploadsFi
nishedCallback) { | 85 public UploadRunnable(MinidumpUploader.UploadsFinishedCallback uploadsFi
nishedCallback) { |
| 85 mUploadsFinishedCallback = uploadsFinishedCallback; | 86 mUploadsFinishedCallback = uploadsFinishedCallback; |
| 86 } | 87 } |
| 87 | 88 |
| 88 @Override | 89 @Override |
| 89 public void run() { | 90 public void run() { |
| 90 File[] minidumps = mFileManager.getAllMinidumpFiles(MAX_UPLOAD_TRIES
_ALLOWED); | 91 File[] minidumps = mFileManager.getAllMinidumpFiles(MAX_UPLOAD_TRIES
_ALLOWED); |
| 92 Log.i(TAG, "Attempting to upload %d minidumps.", minidumps.length); |
| 91 for (File minidump : minidumps) { | 93 for (File minidump : minidumps) { |
| 94 Log.i(TAG, "Attempting to upload " + minidump.getName()); |
| 92 MinidumpUploadCallable uploadCallable = createMinidumpUploadCall
able( | 95 MinidumpUploadCallable uploadCallable = createMinidumpUploadCall
able( |
| 93 minidump, mFileManager.getCrashUploadLogFile()); | 96 minidump, mFileManager.getCrashUploadLogFile()); |
| 94 int uploadResult = uploadCallable.call(); | 97 int uploadResult = uploadCallable.call(); |
| 95 | 98 |
| 99 // Record metrics about the upload. |
| 100 if (uploadResult == MinidumpUploadCallable.UPLOAD_SUCCESS) { |
| 101 mDelegate.recordUploadSuccess(minidump); |
| 102 } else if (uploadResult == MinidumpUploadCallable.UPLOAD_FAILURE
) { |
| 103 // Only record a failure after we have maxed out the allotte
d tries. |
| 104 // Note: Add 1 to include the most recent failure, since the
minidump's filename |
| 105 // is from before the failure. |
| 106 int numFailures = CrashFileManager.readAttemptNumber(minidum
p.getName()) + 1; |
| 107 if (numFailures == MAX_UPLOAD_TRIES_ALLOWED) { |
| 108 mDelegate.recordUploadFailure(minidump); |
| 109 } |
| 110 } |
| 111 |
| 96 // Bail if the job was canceled. Note that the cancelation statu
s is checked AFTER | 112 // Bail if the job was canceled. Note that the cancelation statu
s is checked AFTER |
| 97 // trying to upload a minidump. This is to ensure that the sched
uler attempts to | 113 // trying to upload a minidump. This is to ensure that the sched
uler attempts to |
| 98 // upload at least one minidump per job. Otherwise, it's possibl
e for a crash loop | 114 // upload at least one minidump per job. Otherwise, it's possibl
e for a crash loop |
| 99 // to continually write files to the crash directory; each such
write would | 115 // to continually write files to the crash directory; each such
write would |
| 100 // reschedule the job, and therefore cancel any pending jobs. In
such a scenario, | 116 // reschedule the job, and therefore cancel any pending jobs. In
such a scenario, |
| 101 // it's important to make at least *some* progress uploading min
idumps. | 117 // it's important to make at least *some* progress uploading min
idumps. |
| 102 // Note that other likely cancelation reasons are not a concern,
because the upload | 118 // Note that other likely cancelation reasons are not a concern,
because the upload |
| 103 // callable checks relevant state prior to uploading. For exampl
e, if the job is | 119 // callable checks relevant state prior to uploading. For exampl
e, if the job is |
| 104 // canceled because the network connection is lost, or because t
he user switches | 120 // canceled because the network connection is lost, or because t
he user switches |
| 105 // over to a metered connection, the callable will detect the ch
anged network state, | 121 // over to a metered connection, the callable will detect the ch
anged network state, |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 | 183 |
| 168 // Reschedule if there are still minidumps to upload. | 184 // Reschedule if there are still minidumps to upload. |
| 169 return mFileManager.getAllMinidumpFiles(MAX_UPLOAD_TRIES_ALLOWED).length
> 0; | 185 return mFileManager.getAllMinidumpFiles(MAX_UPLOAD_TRIES_ALLOWED).length
> 0; |
| 170 } | 186 } |
| 171 | 187 |
| 172 @VisibleForTesting | 188 @VisibleForTesting |
| 173 public void joinWorkerThreadForTesting() throws InterruptedException { | 189 public void joinWorkerThreadForTesting() throws InterruptedException { |
| 174 mWorkerThread.join(); | 190 mWorkerThread.join(); |
| 175 } | 191 } |
| 176 } | 192 } |
| OLD | NEW |