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

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/crash/MinidumpUploadCallable.java

Issue 2464943002: Componentize CrashFileManager and MinidumpUploadCallable. (Closed)
Patch Set: Update copyright year of moved files. Created 4 years, 1 month 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 side-by-side diff with in-line comments
Download patch
Index: chrome/android/java/src/org/chromium/chrome/browser/crash/MinidumpUploadCallable.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/crash/MinidumpUploadCallable.java b/chrome/android/java/src/org/chromium/chrome/browser/crash/MinidumpUploadCallable.java
deleted file mode 100644
index 71ee35f88f2de56ee5aa197be3362cbf1a01af54..0000000000000000000000000000000000000000
--- a/chrome/android/java/src/org/chromium/chrome/browser/crash/MinidumpUploadCallable.java
+++ /dev/null
@@ -1,319 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.crash;
-
-import android.content.SharedPreferences;
-import android.support.annotation.IntDef;
-
-import org.chromium.base.ContextUtils;
-import org.chromium.base.Log;
-import org.chromium.base.StreamUtil;
-import org.chromium.base.VisibleForTesting;
-import org.chromium.components.minidump_uploader.util.CrashReportingPermissionManager;
-import org.chromium.components.minidump_uploader.util.HttpURLConnectionFactory;
-import org.chromium.components.minidump_uploader.util.HttpURLConnectionFactoryImpl;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.HttpURLConnection;
-import java.util.Locale;
-import java.util.concurrent.Callable;
-import java.util.zip.GZIPOutputStream;
-
-/**
- * This class tries to upload a minidump to the crash server.
- *
- * It is implemented as a Callable<Boolean> and returns true on successful uploads,
- * and false otherwise.
- */
-public class MinidumpUploadCallable implements Callable<Integer> {
- private static final String TAG = "MDUploadCallable";
-
- // These preferences are obsolete and are kept only for removing from user preferences.
- protected static final String PREF_DAY_UPLOAD_COUNT = "crash_day_dump_upload_count";
- protected static final String PREF_LAST_UPLOAD_DAY = "crash_dump_last_upload_day";
- protected static final String PREF_LAST_UPLOAD_WEEK = "crash_dump_last_upload_week";
- protected static final String PREF_WEEK_UPLOAD_SIZE = "crash_dump_week_upload_size";
-
- @VisibleForTesting
- protected static final String CRASH_URL_STRING = "https://clients2.google.com/cr/report";
-
- @VisibleForTesting
- protected static final String CONTENT_TYPE_TMPL = "multipart/form-data; boundary=%s";
-
- @IntDef({
- UPLOAD_SUCCESS,
- UPLOAD_FAILURE,
- UPLOAD_USER_DISABLED,
- UPLOAD_COMMANDLINE_DISABLED,
- UPLOAD_DISABLED_BY_SAMPLING
- })
- public @interface MinidumpUploadStatus {}
- public static final int UPLOAD_SUCCESS = 0;
- public static final int UPLOAD_FAILURE = 1;
- public static final int UPLOAD_USER_DISABLED = 2;
- public static final int UPLOAD_COMMANDLINE_DISABLED = 3;
- public static final int UPLOAD_DISABLED_BY_SAMPLING = 4;
-
- private final File mFileToUpload;
- private final File mLogfile;
- private final HttpURLConnectionFactory mHttpURLConnectionFactory;
- private final CrashReportingPermissionManager mPermManager;
-
- public MinidumpUploadCallable(
- File fileToUpload, File logfile, CrashReportingPermissionManager permissionManager) {
- this(fileToUpload, logfile, new HttpURLConnectionFactoryImpl(), permissionManager);
- removeOutdatedPrefs(ContextUtils.getAppSharedPreferences());
- }
-
- public MinidumpUploadCallable(File fileToUpload, File logfile,
- HttpURLConnectionFactory httpURLConnectionFactory,
- CrashReportingPermissionManager permissionManager) {
- mFileToUpload = fileToUpload;
- mLogfile = logfile;
- mHttpURLConnectionFactory = httpURLConnectionFactory;
- mPermManager = permissionManager;
- }
-
- @Override
- public Integer call() {
- // TODO(jchinlee): address proper cleanup procedures for command line flag-disabled uploads.
- if (mPermManager.isCrashUploadDisabledByCommandLine()) {
- Log.i(TAG, "Minidump upload is disabled by command line flag. Retaining file.");
- return UPLOAD_COMMANDLINE_DISABLED;
- }
-
- if (mPermManager.isUploadEnabledForTests()) {
- Log.i(TAG, "Minidump upload enabled for tests, skipping other checks.");
- } else if (!CrashFileManager.isForcedUpload(mFileToUpload)) {
- if (!mPermManager.isUsageAndCrashReportingPermittedByUser()) {
- Log.i(TAG, "Minidump upload is not permitted by user. Marking file as skipped for "
- + "cleanup to prevent future uploads.");
- CrashFileManager.markUploadSkipped(mFileToUpload);
- return UPLOAD_USER_DISABLED;
- }
-
- if (!mPermManager.isClientInMetricsSample()) {
- Log.i(TAG, "Minidump upload skipped due to sampling. Marking file as skipped for "
- + "cleanup to prevent future uploads.");
- CrashFileManager.markUploadSkipped(mFileToUpload);
- return UPLOAD_DISABLED_BY_SAMPLING;
- }
-
- if (!mPermManager.isNetworkAvailableForCrashUploads()) {
- Log.i(TAG, "Minidump cannot currently be uploaded due to network constraints.");
- return UPLOAD_FAILURE;
- }
-
- // The above checks should be at least as strict as the requirements for UMA uploads.
- assert mPermManager.isMetricsUploadPermitted();
- }
-
- HttpURLConnection connection =
- mHttpURLConnectionFactory.createHttpURLConnection(CRASH_URL_STRING);
- if (connection == null) {
- return UPLOAD_FAILURE;
- }
-
- FileInputStream minidumpInputStream = null;
- try {
- if (!configureConnectionForHttpPost(connection)) {
- return UPLOAD_FAILURE;
- }
- minidumpInputStream = new FileInputStream(mFileToUpload);
- streamCopy(minidumpInputStream, new GZIPOutputStream(connection.getOutputStream()));
- boolean success = handleExecutionResponse(connection);
-
- return success ? UPLOAD_SUCCESS : UPLOAD_FAILURE;
- } catch (IOException e) {
- // For now just log the stack trace.
- Log.w(TAG, "Error while uploading " + mFileToUpload.getName(), e);
- return UPLOAD_FAILURE;
- } finally {
- connection.disconnect();
-
- if (minidumpInputStream != null) {
- StreamUtil.closeQuietly(minidumpInputStream);
- }
- }
- }
-
- /**
- * Configures a HttpURLConnection to send a HTTP POST request for uploading the minidump.
- *
- * This also reads the content-type from the minidump file.
- *
- * @param connection the HttpURLConnection to configure
- * @return true if successful.
- * @throws IOException
- */
- private boolean configureConnectionForHttpPost(HttpURLConnection connection)
- throws IOException {
- // Read the boundary which we need for the content type.
- String boundary = readBoundary();
- if (boundary == null) {
- return false;
- }
-
- connection.setDoOutput(true);
- connection.setRequestProperty("Connection", "Keep-Alive");
- connection.setRequestProperty("Content-Encoding", "gzip");
- connection.setRequestProperty("Content-Type", String.format(CONTENT_TYPE_TMPL, boundary));
- return true;
- }
-
- /**
- * Reads the HTTP response and cleans up successful uploads.
- *
- * @param connection the connection to read the response from
- * @return true if the upload was successful, false otherwise.
- * @throws IOException
- */
- private Boolean handleExecutionResponse(HttpURLConnection connection) throws IOException {
- int responseCode = connection.getResponseCode();
- if (isSuccessful(responseCode)) {
- String responseContent = getResponseContentAsString(connection);
- // The crash server returns the crash ID.
- String id = responseContent != null ? responseContent : "unknown";
- Log.i(TAG, "Minidump " + mFileToUpload.getName() + " uploaded successfully, id: " + id);
-
- // TODO(acleung): MinidumpUploadService is in charge of renaming while this class is
- // in charge of deleting. We should move all the file system operations into
- // MinidumpUploadService instead.
- CrashFileManager.markUploadSuccess(mFileToUpload);
-
- try {
- appendUploadedEntryToLog(id);
- } catch (IOException ioe) {
- Log.e(TAG, "Fail to write uploaded entry to log file");
- }
- return true;
- } else {
- // Log the results of the upload. Note that periodic upload failures aren't bad
- // because we will need to throttle uploads in the future anyway.
- String msg = String.format(Locale.US,
- "Failed to upload %s with code: %d (%s).",
- mFileToUpload.getName(), responseCode, connection.getResponseMessage());
- Log.i(TAG, msg);
-
- // TODO(acleung): The return status informs us about why an upload might be
- // rejected. The next logical step is to put the reasons in an UMA histogram.
- return false;
- }
- }
-
- /**
- * Records the upload entry to a log file
- * similar to what is done in chrome/app/breakpad_linux.cc
- *
- * @param id The crash ID return from the server.
- */
- private void appendUploadedEntryToLog(String id) throws IOException {
- FileWriter writer = new FileWriter(mLogfile, /* Appending */ true);
-
- // The log entries are formated like so:
- // seconds_since_epoch,crash_id
- StringBuilder sb = new StringBuilder();
- sb.append(System.currentTimeMillis() / 1000);
- sb.append(",");
- sb.append(id);
- sb.append('\n');
-
- try {
- // Since we are writing one line at a time, lets forget about BufferWriters.
- writer.write(sb.toString());
- } finally {
- writer.close();
- }
- }
-
- /**
- * Get the boundary from the file, we need it for the content-type.
- *
- * @return the boundary if found, else null.
- * @throws IOException
- */
- private String readBoundary() throws IOException {
- BufferedReader reader = new BufferedReader(new FileReader(mFileToUpload));
- String boundary = reader.readLine();
- reader.close();
- if (boundary == null || boundary.trim().isEmpty()) {
- Log.e(TAG, "Ignoring invalid crash dump: '" + mFileToUpload + "'");
- return null;
- }
- boundary = boundary.trim();
- if (!boundary.startsWith("--") || boundary.length() < 10) {
- Log.e(TAG, "Ignoring invalidly bound crash dump: '" + mFileToUpload + "'");
- return null;
- }
- boundary = boundary.substring(2); // Remove the initial --
- return boundary;
- }
-
- /**
- * Returns whether the response code indicates a successful HTTP request.
- *
- * @param responseCode the response code
- * @return true if response code indicates success, false otherwise.
- */
- private static boolean isSuccessful(int responseCode) {
- return responseCode == 200 || responseCode == 201 || responseCode == 202;
- }
-
- /**
- * Reads the response from |connection| as a String.
- *
- * @param connection the connection to read the response from.
- * @return the content of the response.
- * @throws IOException
- */
- private static String getResponseContentAsString(HttpURLConnection connection)
- throws IOException {
- String responseContent = null;
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- streamCopy(connection.getInputStream(), baos);
- if (baos.size() > 0) {
- responseContent = baos.toString();
- }
- return responseContent;
- }
-
- /**
- * Copies all available data from |inStream| to |outStream|. Closes both
- * streams when done.
- *
- * @param inStream the stream to read
- * @param outStream the stream to write to
- * @throws IOException
- */
- private static void streamCopy(InputStream inStream,
- OutputStream outStream) throws IOException {
- byte[] temp = new byte[4096];
- int bytesRead = inStream.read(temp);
- while (bytesRead >= 0) {
- outStream.write(temp, 0, bytesRead);
- bytesRead = inStream.read(temp);
- }
- inStream.close();
- outStream.close();
- }
-
- // TODO(gayane): Remove this function and unused prefs in M51. crbug.com/555022
- private void removeOutdatedPrefs(SharedPreferences sharedPreferences) {
- SharedPreferences.Editor editor = sharedPreferences.edit();
- editor.remove(PREF_DAY_UPLOAD_COUNT)
- .remove(PREF_LAST_UPLOAD_DAY)
- .remove(PREF_LAST_UPLOAD_WEEK)
- .remove(PREF_WEEK_UPLOAD_SIZE)
- .apply();
- }
-}

Powered by Google App Engine
This is Rietveld 408576698