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.crash; | 5 package org.chromium.chrome.browser.crash; |
| 6 | 6 |
| 7 import org.chromium.base.Log; | 7 import org.chromium.base.Log; |
| 8 import org.chromium.base.VisibleForTesting; | 8 import org.chromium.base.VisibleForTesting; |
| 9 | 9 |
| 10 import java.io.File; | 10 import java.io.File; |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 27 public class CrashFileManager { | 27 public class CrashFileManager { |
| 28 private static final String TAG = "CrashFileManager"; | 28 private static final String TAG = "CrashFileManager"; |
| 29 | 29 |
| 30 @VisibleForTesting | 30 @VisibleForTesting |
| 31 static final String CRASH_DUMP_DIR = "Crash Reports"; | 31 static final String CRASH_DUMP_DIR = "Crash Reports"; |
| 32 | 32 |
| 33 // This should mirror the C++ CrashUploadList::kReporterLogFilename variable . | 33 // This should mirror the C++ CrashUploadList::kReporterLogFilename variable . |
| 34 @VisibleForTesting | 34 @VisibleForTesting |
| 35 static final String CRASH_DUMP_LOGFILE = "uploads.log"; | 35 static final String CRASH_DUMP_LOGFILE = "uploads.log"; |
| 36 | 36 |
| 37 private static final Pattern MINIDUMP_FIRST_TRY_PATTERN = | 37 private static final Pattern MINIDUMP_FIRST_TRY_PATTERN = Pattern.compile("\ \.dmp([0-9]*)$\\z"); |
| 38 Pattern.compile("\\.dmp([0-9]*)$\\z"); | |
| 39 | 38 |
| 40 private static final Pattern MINIDUMP_MIME_FIRST_TRY_PATTERN = | 39 private static final Pattern MINIDUMP_MIME_FIRST_TRY_PATTERN = |
| 41 Pattern.compile("\\.dmp([0-9]+)$\\z"); | 40 Pattern.compile("\\.dmp([0-9]+)$\\z"); |
| 42 | 41 |
| 43 private static final Pattern MINIDUMP_PATTERN = | 42 private static final Pattern MINIDUMP_PATTERN = |
| 44 Pattern.compile("\\.dmp([0-9]*)(\\.try[0-9])?\\z"); | 43 Pattern.compile("\\.dmp([0-9]*)(\\.try[0-9])?\\z"); |
| 45 | 44 |
| 46 private static final Pattern UPLOADED_MINIDUMP_PATTERN = Pattern.compile("\\ .up([0-9]*)\\z"); | 45 private static final Pattern UPLOADED_MINIDUMP_PATTERN = Pattern.compile("\\ .up([0-9]*)\\z"); |
| 47 | 46 |
| 48 private static final String NOT_YET_UPLOADED_MINIDUMP_SUFFIX = ".dmp"; | 47 private static final String NOT_YET_UPLOADED_MINIDUMP_SUFFIX = ".dmp"; |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 69 // The maximum age, in days, considered acceptable for a crash report. Repor ts older than this | 68 // The maximum age, in days, considered acceptable for a crash report. Repor ts older than this |
| 70 // age will be removed. The constant is chosen to be quite conservative, whi le still allowing | 69 // age will be removed. The constant is chosen to be quite conservative, whi le still allowing |
| 71 // users to eventually reclaim filesystem storage space from obsolete crash reports. | 70 // users to eventually reclaim filesystem storage space from obsolete crash reports. |
| 72 private static final int MAX_CRASH_REPORT_AGE_IN_DAYS = 30; | 71 private static final int MAX_CRASH_REPORT_AGE_IN_DAYS = 30; |
| 73 | 72 |
| 74 /** | 73 /** |
| 75 * Comparator used for sorting files by modification date. | 74 * Comparator used for sorting files by modification date. |
| 76 * @return Comparator for prioritizing the more recently modified file | 75 * @return Comparator for prioritizing the more recently modified file |
| 77 */ | 76 */ |
| 78 @VisibleForTesting | 77 @VisibleForTesting |
| 79 protected static final Comparator<File> sFileComparator = new Comparator<Fi le>() { | 78 protected static final Comparator<File> sFileComparator = new Comparator<Fil e>() { |
| 80 @Override | 79 @Override |
| 81 public int compare(File lhs, File rhs) { | 80 public int compare(File lhs, File rhs) { |
| 82 if (lhs.lastModified() == rhs.lastModified()) { | 81 if (lhs.lastModified() == rhs.lastModified()) { |
| 83 return lhs.compareTo(rhs); | 82 return lhs.compareTo(rhs); |
| 84 } else if (lhs.lastModified() < rhs.lastModified()) { | 83 } else if (lhs.lastModified() < rhs.lastModified()) { |
| 85 return 1; | 84 return 1; |
| 86 } else { | 85 } else { |
| 87 return -1; | 86 return -1; |
| 88 } | 87 } |
| 89 } | 88 } |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 165 } | 164 } |
| 166 | 165 |
| 167 @VisibleForTesting | 166 @VisibleForTesting |
| 168 public static int readAttemptNumber(String filename) { | 167 public static int readAttemptNumber(String filename) { |
| 169 int tryIndex = filename.lastIndexOf(UPLOAD_ATTEMPT_DELIMITER); | 168 int tryIndex = filename.lastIndexOf(UPLOAD_ATTEMPT_DELIMITER); |
| 170 if (tryIndex >= 0) { | 169 if (tryIndex >= 0) { |
| 171 tryIndex += UPLOAD_ATTEMPT_DELIMITER.length(); | 170 tryIndex += UPLOAD_ATTEMPT_DELIMITER.length(); |
| 172 // To avoid out of bound exceptions | 171 // To avoid out of bound exceptions |
| 173 if (tryIndex < filename.length()) { | 172 if (tryIndex < filename.length()) { |
| 174 // We don't try more than 3 times. | 173 // We don't try more than 3 times. |
| 175 String numTriesString = filename.substring( | 174 String numTriesString = filename.substring(tryIndex, tryIndex + 1); |
| 176 tryIndex, tryIndex + 1); | |
| 177 try { | 175 try { |
| 178 return Integer.parseInt(numTriesString); | 176 return Integer.parseInt(numTriesString); |
| 179 } catch (NumberFormatException ignored) { | 177 } catch (NumberFormatException ignored) { |
| 180 return 0; | 178 return 0; |
| 181 } | 179 } |
| 182 } | 180 } |
| 183 } | 181 } |
| 184 return 0; | 182 return 0; |
| 185 } | 183 } |
| 186 | 184 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 219 boolean renamed = crashDumpFile.renameTo(new File(newName)); | 217 boolean renamed = crashDumpFile.renameTo(new File(newName)); |
| 220 if (!renamed) { | 218 if (!renamed) { |
| 221 Log.w(TAG, "Failed to rename " + crashDumpFile); | 219 Log.w(TAG, "Failed to rename " + crashDumpFile); |
| 222 if (!crashDumpFile.delete()) { | 220 if (!crashDumpFile.delete()) { |
| 223 Log.w(TAG, "Failed to delete " + crashDumpFile); | 221 Log.w(TAG, "Failed to delete " + crashDumpFile); |
| 224 } | 222 } |
| 225 } | 223 } |
| 226 } | 224 } |
| 227 | 225 |
| 228 private final File mCacheDir; | 226 private final File mCacheDir; |
| 227 /** | |
| 228 * The number of times we will try to upload a crash. | |
| 229 */ | |
| 230 @VisibleForTesting | |
| 231 public static final int MAX_TRIES_ALLOWED = 3; | |
|
Ilya Sherman
2016/10/07 07:08:39
This concept seems more appropriate for the minidu
gsennton
2016/10/07 09:58:13
Alright, so I chatted a bit with Toby (tobiasjs@)
| |
| 229 | 232 |
| 230 public CrashFileManager(File cacheDir) { | 233 public CrashFileManager(File cacheDir) { |
| 231 if (cacheDir == null) { | 234 if (cacheDir == null) { |
| 232 throw new NullPointerException("Specified context cannot be null."); | 235 throw new NullPointerException("Specified context cannot be null."); |
| 233 } else if (!cacheDir.isDirectory()) { | 236 } else if (!cacheDir.isDirectory()) { |
| 234 throw new IllegalArgumentException(cacheDir.getAbsolutePath() | 237 throw new IllegalArgumentException(cacheDir.getAbsolutePath() + " is not a directory."); |
| 235 + " is not a directory."); | |
| 236 } | 238 } |
| 237 mCacheDir = cacheDir; | 239 mCacheDir = cacheDir; |
| 238 } | 240 } |
| 239 | 241 |
| 240 public File[] getAllMinidumpFiles() { | 242 public File[] getAllMinidumpFiles() { |
| 241 return getMatchingFiles(MINIDUMP_PATTERN); | 243 return getMatchingFiles(MINIDUMP_PATTERN); |
| 242 } | 244 } |
| 243 | 245 |
| 244 public File[] getAllMinidumpFilesSorted() { | 246 public File[] getAllMinidumpFilesSorted() { |
| 245 File[] minidumps = getAllMinidumpFiles(); | 247 File[] minidumps = getAllMinidumpFiles(); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 302 // chrome::DIR_CRASH_DUMPS). | 304 // chrome::DIR_CRASH_DUMPS). |
| 303 File crashDir = getCrashDirectoryIfExists(); | 305 File crashDir = getCrashDirectoryIfExists(); |
| 304 if (crashDir == null) { | 306 if (crashDir == null) { |
| 305 return new File[] {}; | 307 return new File[] {}; |
| 306 } | 308 } |
| 307 File[] minidumps = crashDir.listFiles(new FilenameFilter() { | 309 File[] minidumps = crashDir.listFiles(new FilenameFilter() { |
| 308 @Override | 310 @Override |
| 309 public boolean accept(File dir, String filename) { | 311 public boolean accept(File dir, String filename) { |
| 310 Matcher match = pattern.matcher(filename); | 312 Matcher match = pattern.matcher(filename); |
| 311 int tries = readAttemptNumber(filename); | 313 int tries = readAttemptNumber(filename); |
| 312 return match.find() && tries < MinidumpUploadService.MAX_TRIES_A LLOWED; | 314 return match.find() && tries < MAX_TRIES_ALLOWED; |
| 313 } | 315 } |
| 314 }); | 316 }); |
| 315 return minidumps; | 317 return minidumps; |
| 316 } | 318 } |
| 317 | 319 |
| 318 @VisibleForTesting | 320 @VisibleForTesting |
| 319 File[] getAllUploadedFiles() { | 321 File[] getAllUploadedFiles() { |
| 320 return getMatchingFiles(UPLOADED_MINIDUMP_PATTERN); | 322 return getMatchingFiles(UPLOADED_MINIDUMP_PATTERN); |
| 321 } | 323 } |
| 322 | 324 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 338 } | 340 } |
| 339 return crashDirectory; | 341 return crashDirectory; |
| 340 } | 342 } |
| 341 | 343 |
| 342 public File createNewTempFile(String name) throws IOException { | 344 public File createNewTempFile(String name) throws IOException { |
| 343 File f = new File(getCrashDirectory(), name); | 345 File f = new File(getCrashDirectory(), name); |
| 344 if (f.exists()) { | 346 if (f.exists()) { |
| 345 if (f.delete()) { | 347 if (f.delete()) { |
| 346 f = new File(getCrashDirectory(), name); | 348 f = new File(getCrashDirectory(), name); |
| 347 } else { | 349 } else { |
| 348 Log.w(TAG, "Unable to delete previous logfile" | 350 Log.w(TAG, "Unable to delete previous logfile" + f.getAbsolutePa th()); |
| 349 + f.getAbsolutePath()); | |
| 350 } | 351 } |
| 351 } | 352 } |
| 352 return f; | 353 return f; |
| 353 } | 354 } |
| 354 | 355 |
| 355 File getCrashFile(String filename) { | 356 File getCrashFile(String filename) { |
| 356 return new File(getCrashDirectory(), filename); | 357 return new File(getCrashDirectory(), filename); |
| 357 } | 358 } |
| 358 | 359 |
| 359 /** | 360 /** |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 384 } | 385 } |
| 385 | 386 |
| 386 File getCrashUploadLogFile() { | 387 File getCrashUploadLogFile() { |
| 387 return new File(getCrashDirectory(), CRASH_DUMP_LOGFILE); | 388 return new File(getCrashDirectory(), CRASH_DUMP_LOGFILE); |
| 388 } | 389 } |
| 389 | 390 |
| 390 private File[] getAllTempFiles() { | 391 private File[] getAllTempFiles() { |
| 391 return getMatchingFiles(TMP_PATTERN); | 392 return getMatchingFiles(TMP_PATTERN); |
| 392 } | 393 } |
| 393 } | 394 } |
| OLD | NEW |