Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(174)

Side by Side Diff: chrome/android/java_staging/src/org/chromium/chrome/browser/crash/CrashFileManager.java

Issue 1141283003: Upstream oodles of Chrome for Android code into Chromium. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: final patch? Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 package org.chromium.chrome.browser.crash;
6
7 import android.util.Log;
8
9 import org.chromium.base.VisibleForTesting;
10
11 import java.io.File;
12 import java.io.FilenameFilter;
13 import java.util.Arrays;
14 import java.util.Comparator;
15 import java.util.regex.Matcher;
16 import java.util.regex.Pattern;
17
18 /**
19 * Responsible for the Crash Report directory. It routinely scans the directory
20 * for new Minidump files and takes appropriate actions by either uploading new
21 * crash dumps or deleting old ones.
22 */
23 public class CrashFileManager {
24 private static final String TAG = "CrashFileManager";
25
26 @VisibleForTesting
27 static final String CRASH_DUMP_DIR = "Crash Reports";
28
29 // This should mirror the C++ CrashUploadList::kReporterLogFilename variable .
30 @VisibleForTesting
31 static final String CRASH_DUMP_LOGFILE = CRASH_DUMP_DIR + "/uploads.log";
32
33 private static final Pattern MINIDUMP_PATTERN =
34 Pattern.compile("\\.dmp([0-9]*)(.try[0-9])?\\z");
35
36 private static final Pattern UPLOADED_MINIDUMP_PATTERN = Pattern.compile("\\ .up([0-9]*)\\z");
37
38 private static final String UPLOADED_MINIDUMP_SUFFIX = ".up";
39
40 private static final String UPLOAD_ATTEMPT_DELIMITER = ".try";
41
42 @VisibleForTesting
43 protected static final String TMP_SUFFIX = ".tmp";
44
45 private static final Pattern TMP_PATTERN = Pattern.compile("\\.tmp\\z");
46
47 private static Comparator<File> sFileComparator = new Comparator<File>() {
48 @Override
49 public int compare(File lhs, File rhs) {
50 if (lhs == rhs) {
51 return 0;
52 } else if (lhs.lastModified() < rhs.lastModified()) {
53 return -1;
54 } else {
55 return 1;
56 }
57 }
58 };
59
60 @VisibleForTesting
61 static boolean deleteFile(File fileToDelete) {
62 boolean isSuccess = fileToDelete.delete();
63 if (!isSuccess) {
64 Log.w(TAG, "Unable to delete " + fileToDelete.getAbsolutePath());
65 }
66 return isSuccess;
67 }
68
69 public static String tryIncrementAttemptNumber(File mFileToUpload) {
70 String newName = incrementAttemptNumber(mFileToUpload.getPath());
71 return mFileToUpload.renameTo(new File(newName)) ? newName : null;
72 }
73
74 /**
75 * @return The file name to rename to after an addition attempt to upload
76 */
77 @VisibleForTesting
78 public static String incrementAttemptNumber(String filename) {
79 int numTried = readAttemptNumber(filename);
80 if (numTried > 0) {
81 int newCount = numTried + 1;
82 return filename.replaceAll(UPLOAD_ATTEMPT_DELIMITER + numTried,
83 UPLOAD_ATTEMPT_DELIMITER + newCount);
84 } else {
85 return filename + UPLOAD_ATTEMPT_DELIMITER + "1";
86 }
87 }
88
89 @VisibleForTesting
90 public static int readAttemptNumber(String filename) {
91 int tryIndex = filename.lastIndexOf(UPLOAD_ATTEMPT_DELIMITER);
92 if (tryIndex >= 0) {
93 tryIndex += UPLOAD_ATTEMPT_DELIMITER.length();
94 // To avoid out of bound exceptions
95 if (tryIndex < filename.length()) {
96 // We don't try more than 3 times.
97 String numTriesString = filename.substring(
98 tryIndex, tryIndex + 1);
99 try {
100 return Integer.parseInt(numTriesString);
101 } catch (NumberFormatException ignored) {
102 return 0;
103 }
104 }
105 }
106 return 0;
107 }
108
109 public static boolean tryMarkAsUploaded(File mFileToUpload) {
110 return mFileToUpload.renameTo(
111 new File(mFileToUpload.getPath().replaceAll(
112 "\\.dmp", UPLOADED_MINIDUMP_SUFFIX)));
113 }
114
115 private final File mCacheDir;
116
117 public CrashFileManager(File cacheDir) {
118 if (cacheDir == null) {
119 throw new NullPointerException("Specified context cannot be null.");
120 } else if (!cacheDir.isDirectory()) {
121 throw new IllegalArgumentException(cacheDir.getAbsolutePath()
122 + " is not a directory.");
123 }
124 mCacheDir = cacheDir;
125 }
126
127 public File[] getAllMinidumpFiles() {
128 return getMatchingFiles(MINIDUMP_PATTERN);
129 }
130
131 public File[] getAllMinidumpFilesSorted() {
132 File[] minidumps = getAllMinidumpFiles();
133 Arrays.sort(minidumps, sFileComparator);
134 return minidumps;
135 }
136
137 public void cleanOutAllNonFreshMinidumpFiles() {
138 for (File f : getAllUploadedFiles()) {
139 deleteFile(f);
140 }
141 for (File f : getAllTempFiles()) {
142 deleteFile(f);
143 }
144 }
145
146 /**
147 * Deletes all files including unsent crash reports.
148 * Note: This method is called from multiple threads, but it is not thread-s afe. It will
149 * generate warning messages in logs if race condition occurs.
150 */
151 @VisibleForTesting
152 public void cleanAllMiniDumps() {
153 cleanOutAllNonFreshMinidumpFiles();
154
155 for (File f : getAllMinidumpFiles()) {
156 deleteFile(f);
157 }
158 }
159
160 @VisibleForTesting
161 File[] getMatchingFiles(final Pattern pattern) {
162 // Get dump dir and get all files with specified suffix.. The path
163 // constructed here must match chrome_paths.cc (see case
164 // chrome::DIR_CRASH_DUMPS).
165 File crashDir = getCrashDirectory();
166 if (!crashDir.exists()) {
167 Log.w(TAG, crashDir.getAbsolutePath() + " does not exist!");
168 return new File[] {};
169 }
170 if (!crashDir.isDirectory()) {
171 Log.w(TAG, crashDir.getAbsolutePath() + " is not a directory!");
172 return new File[] {};
173 }
174 File[] minidumps = crashDir.listFiles(new FilenameFilter() {
175 @Override
176 public boolean accept(File dir, String filename) {
177 Matcher match = pattern.matcher(filename);
178 int tries = readAttemptNumber(filename);
179 return match.find() && tries < MinidumpUploadService.MAX_TRIES_A LLOWED;
180 }
181 });
182 return minidumps;
183 }
184
185 @VisibleForTesting
186 File[] getAllUploadedFiles() {
187 return getMatchingFiles(UPLOADED_MINIDUMP_PATTERN);
188 }
189
190 @VisibleForTesting
191 File getCrashDirectory() {
192 return new File(mCacheDir, CRASH_DUMP_DIR);
193 }
194
195 File getCrashUploadLogFile() {
196 return new File(mCacheDir, CRASH_DUMP_LOGFILE);
197 }
198
199 private File[] getAllTempFiles() {
200 return getMatchingFiles(TMP_PATTERN);
201 }
202 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698