Chromecast: don't try to upload crash immediately.

This has already been the source of compounding issues after a crash and
isn't a great practice anyways.

To make the upload path cleaner, this also moves some internal code for
Cast ATV settings handling upstream.

R=slan@chromium.org,halliwell@chromium.org,lcwu@chromium.org
BUG=internal b/21664262

Review URL: https://codereview.chromium.org/1180633002

Cr-Commit-Position: refs/heads/master@{#334417}
diff --git a/chromecast/android/cast_jni_registrar.cc b/chromecast/android/cast_jni_registrar.cc
index bad2365..a91a4f3 100644
--- a/chromecast/android/cast_jni_registrar.cc
+++ b/chromecast/android/cast_jni_registrar.cc
@@ -8,6 +8,7 @@
 #include "base/android/jni_registrar.h"
 #include "chromecast/android/cast_metrics_helper_android.h"
 #include "chromecast/base/cast_sys_info_android.h"
+#include "chromecast/base/chromecast_config_android.h"
 #include "chromecast/browser/android/cast_window_android.h"
 #include "chromecast/browser/android/cast_window_manager.h"
 #include "chromecast/crash/android/crash_handler.h"
@@ -23,6 +24,7 @@
   { "CastSysInfoAndroid", CastSysInfoAndroid::RegisterJni },
   { "CastWindowAndroid", shell::CastWindowAndroid::RegisterJni },
   { "CastWindowManager", shell::RegisterCastWindowManager },
+  { "ChromecastConfigAndroid", ChromecastConfigAndroid::RegisterJni },
   { "CrashHandler", CrashHandler::RegisterCastCrashJni },
   { "ExternalVideoSurfaceContainer",
       external_video_surface::RegisterExternalVideoSurfaceJni },
diff --git a/chromecast/android/chromecast_config_android.cc b/chromecast/android/chromecast_config_android.cc
deleted file mode 100644
index d698b70a..0000000
--- a/chromecast/android/chromecast_config_android.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2014 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.
-
-#include "chromecast/android/chromecast_config_android.h"
-
-namespace chromecast {
-namespace android {
-
-namespace {
-base::LazyInstance<ChromecastConfigAndroid> g_instance =
-    LAZY_INSTANCE_INITIALIZER;
-}  // namespace
-
-// static
-ChromecastConfigAndroid* ChromecastConfigAndroid::GetInstance() {
-  return g_instance.Pointer();
-}
-
-ChromecastConfigAndroid::ChromecastConfigAndroid() {
-}
-
-ChromecastConfigAndroid::~ChromecastConfigAndroid() {
-}
-
-// Registers a handler to be notified when SendUsageStats is changed.
-void ChromecastConfigAndroid::SetSendUsageStatsChangedCallback(
-    const base::Callback<void(bool)>& callback) {
-  send_usage_stats_changed_callback_ = callback;
-}
-
-}  // namespace android
-}  // namespace chromecast
diff --git a/chromecast/android/chromecast_config_android_stub.cc b/chromecast/android/chromecast_config_android_stub.cc
deleted file mode 100644
index dc8bdca2..0000000
--- a/chromecast/android/chromecast_config_android_stub.cc
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2014 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.
-
-#include "chromecast/android/chromecast_config_android.h"
-
-namespace chromecast {
-namespace android {
-
-bool ChromecastConfigAndroid::CanSendUsageStats() {
-  return false;
-}
-
-}  // namespace android
-}  // namespace chromecast
diff --git a/chromecast/base/chromecast_config_android.cc b/chromecast/base/chromecast_config_android.cc
new file mode 100644
index 0000000..f16b473
--- /dev/null
+++ b/chromecast/base/chromecast_config_android.cc
@@ -0,0 +1,56 @@
+// Copyright 2014 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.
+
+#include "chromecast/base/chromecast_config_android.h"
+
+#include "base/android/jni_android.h"
+#include "base/lazy_instance.h"
+#include "jni/ChromecastConfigAndroid_jni.h"
+
+namespace chromecast {
+namespace android {
+
+namespace {
+base::LazyInstance<ChromecastConfigAndroid> g_instance =
+    LAZY_INSTANCE_INITIALIZER;
+}  // namespace
+
+// static
+ChromecastConfigAndroid* ChromecastConfigAndroid::GetInstance() {
+  return g_instance.Pointer();
+}
+
+// static
+bool ChromecastConfigAndroid::RegisterJni(JNIEnv* env) {
+  return RegisterNativesImpl(env);
+}
+
+ChromecastConfigAndroid::ChromecastConfigAndroid() {
+}
+
+ChromecastConfigAndroid::~ChromecastConfigAndroid() {
+}
+
+bool ChromecastConfigAndroid::CanSendUsageStats() {
+  // TODO(gunsch): make opt-in.stats pref the source of truth for this data,
+  // instead of Android prefs, then delete ChromecastConfigAndroid.
+  JNIEnv* env = base::android::AttachCurrentThread();
+  return Java_ChromecastConfigAndroid_canSendUsageStats(
+      env, base::android::GetApplicationContext());
+}
+
+// Registers a handler to be notified when SendUsageStats is changed.
+void ChromecastConfigAndroid::SetSendUsageStatsChangedCallback(
+    const base::Callback<void(bool)>& callback) {
+  send_usage_stats_changed_callback_ = callback;
+}
+
+// Called from Java.
+void SetSendUsageStatsEnabled(JNIEnv* env, jclass caller, jboolean enabled) {
+  ChromecastConfigAndroid::GetInstance()->
+      send_usage_stats_changed_callback().Run(enabled);
+}
+
+}  // namespace android
+}  // namespace chromecast
diff --git a/chromecast/android/chromecast_config_android.h b/chromecast/base/chromecast_config_android.h
similarity index 84%
rename from chromecast/android/chromecast_config_android.h
rename to chromecast/base/chromecast_config_android.h
index e09d657..1d9082f 100644
--- a/chromecast/android/chromecast_config_android.h
+++ b/chromecast/base/chromecast_config_android.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROMECAST_ANDROID_CHROMECAST_CONFIG_ANDROID_H_
-#define CHROMECAST_ANDROID_CHROMECAST_CONFIG_ANDROID_H_
+#ifndef CHROMECAST_BASE_CHROMECAST_CONFIG_ANDROID_H_
+#define CHROMECAST_BASE_CHROMECAST_CONFIG_ANDROID_H_
 
 #include <jni.h>
 
@@ -17,6 +17,7 @@
 class ChromecastConfigAndroid {
  public:
   static ChromecastConfigAndroid* GetInstance();
+  static bool RegisterJni(JNIEnv* env);
 
   // Returns whether or not the user has allowed sending usage stats and
   // crash reports.
@@ -44,4 +45,4 @@
 }  // namespace android
 }  // namespace chromecast
 
-#endif  // CHROMECAST_ANDROID_CHROMECAST_CONFIG_ANDROID_H_
+#endif  // CHROMECAST_BASE_CHROMECAST_CONFIG_ANDROID_H_
diff --git a/chromecast/base/java/src/org/chromium/chromecast/base/CastSettingsManager.java b/chromecast/base/java/src/org/chromium/chromecast/base/CastSettingsManager.java
new file mode 100644
index 0000000..3b4d5fe1
--- /dev/null
+++ b/chromecast/base/java/src/org/chromium/chromecast/base/CastSettingsManager.java
@@ -0,0 +1,145 @@
+// 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.chromecast.base;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.database.ContentObserver;
+import android.os.Build;
+import android.os.Handler;
+import android.provider.Settings;
+
+import org.chromium.base.Log;
+
+/**
+ * Manager for Cast settings.
+ */
+public final class CastSettingsManager {
+    private static final String TAG = "cr.CastSettingsManager";
+
+    private static final String PREFS_FILE_NAME = "CastSettings";
+
+    /** Key for the "send usage stats" boolean setting. */
+    private static final String SEND_USAGE_STATS_SETTING = "developer_support";
+
+    /** The default value for the "send usage stats" setting. */
+    private static final boolean SEND_USAGE_STATS_SETTING_DEFAULT = true;
+
+    /** The default device name, which is the model name. */
+    private static final String DEFAULT_DEVICE_NAME = Build.MODEL;
+
+    // TODO(gunsch): Switch to Settings.Global.DEVICE_NAME once it's in public SDK.
+    // private static final String DEVICE_NAME_SETTING_KEY = Settings.Global.DEVICE_NAME;
+    private static final String DEVICE_NAME_SETTING_KEY = "device_name";
+    private static final String DEVICE_PROVISIONED_SETTING_KEY = Settings.Global.DEVICE_PROVISIONED;
+
+    private final Context mContext;
+    private final SharedPreferences mSettings;
+    private SharedPreferences.OnSharedPreferenceChangeListener mSharedPreferenceListener;
+    private ContentObserver mDeviceNameObserver;
+    private ContentObserver mIsDeviceProvisionedObserver;
+
+    /**
+     * Can be implemented to receive notifications from a CastSettingsManager instance when
+     * settings have changed.
+     */
+    public static class OnSettingChangedListener {
+        public void onCastEnabledChanged(boolean enabled) {}
+        public void onSendUsageStatsChanged(boolean enabled) {}
+        public void onDeviceNameChanged(String deviceName) {}
+    }
+
+    private OnSettingChangedListener mListener;
+
+    /**
+     * Creates a fully-featured CastSettingsManager instance. Will fail if called from a
+     * sandboxed process.
+     */
+    public static CastSettingsManager createCastSettingsManager(Context context,
+            OnSettingChangedListener listener) {
+        return new CastSettingsManager(context, listener);
+    }
+
+    private CastSettingsManager(Context context) {
+        mContext = context;
+        mSettings = context.getSharedPreferences(PREFS_FILE_NAME, 0);
+    }
+
+    private CastSettingsManager(final Context context, OnSettingChangedListener listener) {
+        this(context);
+        mListener = listener;
+
+        mSharedPreferenceListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
+            @Override
+            public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
+                if (mListener == null) {
+                    return;
+                }
+
+                if (key.equals(SEND_USAGE_STATS_SETTING)) {
+                    mListener.onSendUsageStatsChanged(prefs.getBoolean(key,
+                                    SEND_USAGE_STATS_SETTING_DEFAULT));
+                }
+            }
+        };
+        mSettings.registerOnSharedPreferenceChangeListener(mSharedPreferenceListener);
+
+        mDeviceNameObserver = new ContentObserver(new Handler()) {
+            @Override
+            public void onChange(boolean selfChange) {
+                mListener.onDeviceNameChanged(getDeviceName());
+            }
+        };
+        mContext.getContentResolver().registerContentObserver(
+                Settings.Global.getUriFor(DEVICE_NAME_SETTING_KEY), true,
+                mDeviceNameObserver);
+
+        if (!isCastEnabled()) {
+            mIsDeviceProvisionedObserver = new ContentObserver(new Handler()) {
+                @Override
+                public void onChange(boolean selfChange) {
+                    Log.d(TAG, "Device provisioned");
+                    mListener.onCastEnabledChanged(isCastEnabled());
+                }
+            };
+            mContext.getContentResolver().registerContentObserver(
+                    Settings.Global.getUriFor(DEVICE_PROVISIONED_SETTING_KEY), true,
+                    mIsDeviceProvisionedObserver);
+        }
+    }
+
+    public void dispose() {
+        mSettings.unregisterOnSharedPreferenceChangeListener(mSharedPreferenceListener);
+        mSharedPreferenceListener = null;
+        mContext.getContentResolver().unregisterContentObserver(mDeviceNameObserver);
+        mDeviceNameObserver = null;
+
+        if (mIsDeviceProvisionedObserver != null) {
+            mContext.getContentResolver().unregisterContentObserver(mIsDeviceProvisionedObserver);
+            mIsDeviceProvisionedObserver = null;
+        }
+    }
+
+    public boolean isCastEnabled() {
+        // However, Cast is disabled until the device is provisioned (see b/18950240).
+        return Settings.Global.getInt(
+                mContext.getContentResolver(), DEVICE_PROVISIONED_SETTING_KEY, 0) == 1;
+    }
+
+    public boolean isSendUsageStatsEnabled() {
+        return mSettings.getBoolean(SEND_USAGE_STATS_SETTING, SEND_USAGE_STATS_SETTING_DEFAULT);
+    }
+
+    public void setSendUsageStatsEnabled(boolean enabled) {
+        mSettings.edit().putBoolean(SEND_USAGE_STATS_SETTING, enabled).apply();
+    }
+
+    public String getDeviceName() {
+        String deviceName = Settings.Global.getString(mContext.getContentResolver(),
+                DEVICE_NAME_SETTING_KEY);
+        return (deviceName != null) ? deviceName : DEFAULT_DEVICE_NAME;
+    }
+
+}
diff --git a/chromecast/base/java/src/org/chromium/chromecast/base/ChromecastConfigAndroid.java b/chromecast/base/java/src/org/chromium/chromecast/base/ChromecastConfigAndroid.java
new file mode 100644
index 0000000..ba714db
--- /dev/null
+++ b/chromecast/base/java/src/org/chromium/chromecast/base/ChromecastConfigAndroid.java
@@ -0,0 +1,37 @@
+// 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.chromecast.base;
+
+import android.content.Context;
+
+import org.chromium.base.CalledByNative;
+import org.chromium.base.JNINamespace;
+
+/**
+ * JNI wrapper class for calls from ChromecastConfigAndroid.
+ */
+@JNINamespace("chromecast::android")
+public final class ChromecastConfigAndroid {
+
+    private static CastSettingsManager sSettingsManager;
+
+    public static void initializeForBrowser(Context applicationContext) {
+        sSettingsManager = CastSettingsManager.createCastSettingsManager(
+                applicationContext,
+                new CastSettingsManager.OnSettingChangedListener() {
+                    @Override
+                    public void onSendUsageStatsChanged(boolean enabled) {
+                        nativeSetSendUsageStatsEnabled(enabled);
+                    }
+                });
+    }
+
+    @CalledByNative
+    public static boolean canSendUsageStats(Context context) {
+        return sSettingsManager.isSendUsageStatsEnabled();
+    }
+
+    private static native void nativeSetSendUsageStatsEnabled(boolean enabled);
+}
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastBrowserHelper.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastBrowserHelper.java
index 7b569732..4790cb9 100644
--- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastBrowserHelper.java
+++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastBrowserHelper.java
@@ -15,6 +15,7 @@
 import org.chromium.base.library_loader.LibraryLoader;
 import org.chromium.base.library_loader.LibraryProcessType;
 import org.chromium.base.library_loader.ProcessInitException;
+import org.chromium.chromecast.base.ChromecastConfigAndroid;
 import org.chromium.content.app.ContentApplication;
 import org.chromium.content.browser.BrowserStartupController;
 import org.chromium.content.browser.DeviceUtils;
@@ -43,6 +44,8 @@
 
         Log.d(TAG, "Performing one-time browser initialization");
 
+        ChromecastConfigAndroid.initializeForBrowser(context);
+
         // Initializing the command line must occur before loading the library.
         if (!CommandLine.isInitialized()) {
             ContentApplication.initCommandLine(context);
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashHandler.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashHandler.java
index d7cd644a..3919e7c 100644
--- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashHandler.java
+++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashHandler.java
@@ -4,31 +4,29 @@
 
 package org.chromium.chromecast.shell;
 
+import android.content.Context;
+
 import org.chromium.base.CalledByNative;
 import org.chromium.base.JNINamespace;
+import org.chromium.base.Log;
+import org.chromium.chromecast.base.ChromecastConfigAndroid;
 
 /**
  * JNI wrapper class for accessing CastCrashHandler.
  */
 @JNINamespace("chromecast")
 public final class CastCrashHandler {
-    private static CastCrashUploader sCrashUploader;
+    private static final String TAG = "cr.CastCrashHandler";
 
     @CalledByNative
-    public static void initializeUploader(String crashDumpPath, boolean uploadCrashToStaging) {
-        if (sCrashUploader == null) {
-            sCrashUploader = new CastCrashUploader(crashDumpPath, uploadCrashToStaging);
-            sCrashUploader.startPeriodicUpload();
+    public static void initializeUploader(Context context, String crashDumpPath,
+            boolean uploadCrashToStaging) {
+        CastCrashUploader uploader = new CastCrashUploader(crashDumpPath, uploadCrashToStaging);
+        if (ChromecastConfigAndroid.canSendUsageStats(context)) {
+            uploader.startPeriodicUpload();
+        } else {
+            Log.d(TAG, "Removing crash dumps instead of uploading");
+            uploader.removeCrashDumps();
         }
     }
-
-    @CalledByNative
-    public static void removeCrashDumps() {
-        sCrashUploader.removeCrashDumps();
-    }
-
-    @CalledByNative
-    public static void uploadCrashDumps(String logFilePath) {
-        sCrashUploader.uploadCrashDumps(logFilePath);
-    }
 }
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashUploader.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashUploader.java
index 5f40480..decce753 100644
--- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashUploader.java
+++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashUploader.java
@@ -69,10 +69,6 @@
                 TimeUnit.MINUTES);
     }
 
-    public void uploadCrashDumps(final String logFilePath) {
-        queueAllCrashDumpUploads(true /* synchronous */, logFilePath);
-    }
-
     public void removeCrashDumps() {
         File crashDumpDirectory = new File(mCrashDumpPath);
         for (File potentialDump : crashDumpDirectory.listFiles()) {
diff --git a/chromecast/browser/service/cast_service_android.cc b/chromecast/browser/service/cast_service_android.cc
index 8822c83e..507716c3 100644
--- a/chromecast/browser/service/cast_service_android.cc
+++ b/chromecast/browser/service/cast_service_android.cc
@@ -5,7 +5,7 @@
 #include "chromecast/browser/service/cast_service_android.h"
 
 #include "base/bind.h"
-#include "chromecast/android/chromecast_config_android.h"
+#include "chromecast/base/chromecast_config_android.h"
 #include "chromecast/browser/metrics/cast_metrics_service_client.h"
 
 namespace chromecast {
diff --git a/chromecast/chromecast.gyp b/chromecast/chromecast.gyp
index 325f47b..e345fdcb 100644
--- a/chromecast/chromecast.gyp
+++ b/chromecast/chromecast.gyp
@@ -453,12 +453,12 @@
           'sources': [
             'base/cast_sys_info_android.cc',
             'base/cast_sys_info_android.h',
+            'base/chromecast_config_android.cc',
+            'base/chromecast_config_android.h',
             'android/cast_jni_registrar.cc',
             'android/cast_jni_registrar.h',
             'android/cast_metrics_helper_android.cc',
             'android/cast_metrics_helper_android.h',
-            'android/chromecast_config_android.cc',
-            'android/chromecast_config_android.h',
             'android/platform_jni_loader.h',
             'app/android/cast_jni_loader.cc',
             'browser/android/cast_window_android.cc',
@@ -477,17 +477,28 @@
               ],
             }, {
               'sources': [
-                'android/chromecast_config_android_stub.cc',
                 'android/platform_jni_loader_stub.cc',
               ],
             }]
           ],
         },  # end of target 'libcast_shell_android'
         {
+          'target_name': 'cast_base_java',
+          'type': 'none',
+          'dependencies': [
+            '../base/base.gyp:base_java',
+          ],
+          'variables': {
+            'java_in_dir': 'base/java',
+          },
+          'includes': ['../build/java.gypi'],
+        },  # end of target 'cast_base_java'
+        {
           'target_name': 'cast_shell_java',
           'type': 'none',
           'dependencies': [
             '<(android_support_v13_target)',
+            'cast_base_java',
             '../base/base.gyp:base_java',
             '../components/components.gyp:external_video_surface_java',
             '../content/content.gyp:content_java',
@@ -541,6 +552,7 @@
           'target_name': 'cast_jni_headers',
           'type': 'none',
           'sources': [
+            'base/java/src/org/chromium/chromecast/base/ChromecastConfigAndroid.java',
             'browser/android/apk/src/org/chromium/chromecast/shell/CastCrashHandler.java',
             'browser/android/apk/src/org/chromium/chromecast/shell/CastMetricsHelper.java',
             'browser/android/apk/src/org/chromium/chromecast/shell/CastSysInfoAndroid.java',
diff --git a/chromecast/crash/android/cast_crash_reporter_client_android.cc b/chromecast/crash/android/cast_crash_reporter_client_android.cc
index 6e690dd80..af5ec8d 100644
--- a/chromecast/crash/android/cast_crash_reporter_client_android.cc
+++ b/chromecast/crash/android/cast_crash_reporter_client_android.cc
@@ -8,7 +8,7 @@
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/path_service.h"
-#include "chromecast/android/chromecast_config_android.h"
+#include "chromecast/base/chromecast_config_android.h"
 #include "chromecast/base/version.h"
 #include "chromecast/common/global_descriptors.h"
 #include "chromecast/crash/cast_crash_keys.h"
diff --git a/chromecast/crash/android/crash_handler.cc b/chromecast/crash/android/crash_handler.cc
index 4324b71d..12b1acd 100644
--- a/chromecast/crash/android/crash_handler.cc
+++ b/chromecast/crash/android/crash_handler.cc
@@ -26,16 +26,6 @@
 
 chromecast::CrashHandler* g_crash_handler = NULL;
 
-bool HandleCrash(void* /* crash_context */) {
-  DCHECK(g_crash_handler);
-  g_crash_handler->UploadCrashDumps();
-
-  // TODO(gunsch): clean up the ATV crash handling code.
-  // Don't write another minidump. Chrome's default ExceptionHandler has already
-  // written a minidump by this point in the crash handling sequence.
-  return false;
-}
-
 // Debug builds: always to crash-staging
 // Release builds: only to crash-staging for local/invalid build numbers
 bool UploadCrashToStaging() {
@@ -92,18 +82,7 @@
 void CrashHandler::Initialize() {
   if (process_type_.empty()) {
     InitializeUploader();
-
-    // ExceptionHandlers are called on crash in reverse order of
-    // instantiation. This ExceptionHandler will attempt to upload crashes
-    // and the log file written out by the main process.
-
-    // Dummy MinidumpDescriptor just to start up another ExceptionHandler.
-    google_breakpad::MinidumpDescriptor dummy(crash_dump_path_.value());
-    crash_uploader_.reset(new google_breakpad::ExceptionHandler(
-        dummy, &HandleCrash, NULL, NULL, true, -1));
-
     breakpad::InitCrashReporter(process_type_);
-
     return;
   }
 
@@ -118,28 +97,8 @@
       base::android::ConvertUTF8ToJavaString(env,
                                              crash_dump_path_.value());
   Java_CastCrashHandler_initializeUploader(
-      env, crash_dump_path_java.obj(), UploadCrashToStaging());
-}
-
-bool CrashHandler::CanUploadCrashDump() {
-  DCHECK(crash_reporter_client_);
-  return crash_reporter_client_->GetCollectStatsConsent();
-}
-
-void CrashHandler::UploadCrashDumps() {
-  VLOG(1) << "Attempting to upload current process crash";
-
-  if (CanUploadCrashDump()) {
-    JNIEnv* env = base::android::AttachCurrentThread();
-    // Current log file location
-    base::android::ScopedJavaLocalRef<jstring> log_file_path_java =
-        base::android::ConvertUTF8ToJavaString(env, log_file_path_.value());
-    Java_CastCrashHandler_uploadCrashDumps(env, log_file_path_java.obj());
-  } else {
-    VLOG(1) << "Removing crash dumps instead of uploading";
-    JNIEnv* env = base::android::AttachCurrentThread();
-    Java_CastCrashHandler_removeCrashDumps(env);
-  }
+      env, base::android::GetApplicationContext(),
+      crash_dump_path_java.obj(), UploadCrashToStaging());
 }
 
 }  // namespace chromecast
diff --git a/chromecast/crash/android/crash_handler.h b/chromecast/crash/android/crash_handler.h
index f78bcd0..c018339 100644
--- a/chromecast/crash/android/crash_handler.h
+++ b/chromecast/crash/android/crash_handler.h
@@ -12,10 +12,6 @@
 #include "base/macros.h"
 #include "base/memory/scoped_ptr.h"
 
-namespace google_breakpad {
-class ExceptionHandler;
-}
-
 namespace chromecast {
 class CastCrashReporterClientAndroid;
 
@@ -33,11 +29,6 @@
   // Registers JNI methods for this module.
   static bool RegisterCastCrashJni(JNIEnv* env);
 
-  // Returns whether or not the user has allowed for uploading crash dumps.
-  bool CanUploadCrashDump();
-
-  void UploadCrashDumps();
-
  private:
   CrashHandler(const std::string& process_type,
                const base::FilePath& log_file_path);
@@ -57,7 +48,6 @@
   std::string process_type_;
 
   scoped_ptr<CastCrashReporterClientAndroid> crash_reporter_client_;
-  scoped_ptr<google_breakpad::ExceptionHandler> crash_uploader_;
 
   DISALLOW_COPY_AND_ASSIGN(CrashHandler);
 };