Enable Crashpad for Android

Overview:
This CL disables Breakpad for Chrome, Content Shell, WebView, and
Chromecast on Android and replaces it with Crashpad. When a crash
signal is received, the browser forks+execs a Crashpad handler process
either for itself or on behalf of a crashing child to create a crash
dump.

components/crash/
  - Remove CrashDumpManager. Minidump creation is handled entirely by
    Crashpad.
  - Remove OnChildStart from ChildExitObserver as it is no longer
    necessary.
  - ChildExitObserver observers CrashHandlerHost to be notified when
    child processes receive crash signals.
  - De-duplicate calls to ChildExitObserver::Client::OnChildExit when
    NOTIFICATION_RENDER_PROCESS_{CLOSED, TERMINATED} are both sent.

components/minidump_uploader/
  - Uploaders expect crash reports to already be MIME encoded since
    Breakpad was doing that in a signal handler call-back.
    CrashFileManager now automatically calls into native code to do
    the encoding and write to a directory of crash reports whenever it
    checks for reports without logcats.

chrome/app/*.{cc,h}
chrome/browser/*.cc
content/shell/app/*.{cc,h}
content/shell/browser/*.cc
  - Initialize Crashpad instead of Breakpad, with minor cleanup and
    adjustment for changes to CrashDumpObserver.

chrome/browser/metrics/oom/out_of_memory_reporter_unittest.cc
  - Simulate crashes/exits with NOTIFICATION_RENDER_PROCESS_{CREATED,
    CLOSED} and signals sent to ChildExitObserver instead of a crash
    dump.

android_webview/
  - AwBrowserTerminator now observes child process crashes via
    ChildExitObserver rather than its own pipe.
  - Crashpad always produces minidumps, and not microdumps.
  - Disabling Crashpad is not yet supported.

chromecast/
  - There are now two directories that crash report uploaders should
    be aware of: "Crashpad" contains a database of raw minidumps
    produced by Crashpad, and "Crash Reports" contains MIME encoded
    minidumps. MIME encoding is performed by a CrashReportMimeWriter
    in CastCrashUploader.java:checkForCrashDumps().

TBR=yfriedman@chromium.org,peter@chromium.org,isherman@chromium.org,jam@chromium.org,wnwen@chromium.org,torne@chromium.org,halliwell@chromium.org,tobiasjs@chromium.org,rsesek@chromium.org,sanfin@chromium.org,jperaza@chromium.org,mark@chromium.org

Bug: crashpad:30
Change-Id: Ib1b0fe085272a7e1e4a91462add50e41eecad746
Cq-Include-Trybots: master.tryserver.chromium.android:android_compile_x64_dbg;master.tryserver.chromium.android:android_compile_x86_dbg
Reviewed-on: https://chromium-review.googlesource.com/c/1388654
Commit-Queue: Joshua Peraza <jperaza@chromium.org>
Reviewed-by: Mark Mentovai <mark@chromium.org>
Reviewed-by: Luke Halliwell <halliwell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#619711}
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn
index 10a060a..3eb5dee0 100644
--- a/android_webview/BUILD.gn
+++ b/android_webview/BUILD.gn
@@ -736,6 +736,7 @@
     "//components/crash/android:crashpad_main",
     "//components/crash/content/app",
     "//components/crash/content/browser",
+    "//components/crash/core/common",
     "//components/download/public/common:public",
     "//components/embedder_support/android:web_contents_delegate",
     "//components/google/core/browser",
@@ -801,6 +802,7 @@
     "//storage/browser",
     "//storage/common",
     "//third_party/blink/public:blink",
+    "//third_party/crashpad/crashpad/client",
     "//ui/base",
     "//ui/events:gesture_detection",
     "//ui/gfx",
diff --git a/android_webview/browser/DEPS b/android_webview/browser/DEPS
index cbcd232..ca1bb07f 100644
--- a/android_webview/browser/DEPS
+++ b/android_webview/browser/DEPS
@@ -16,6 +16,7 @@
   "+components/crash/core",
   "+components/download/public/common",
   "+components/heap_profiling",
+  "+components/minidump_uploader",
   "+components/navigation_interception",
   "+components/policy/core/browser",
   "+components/policy/core/common",
@@ -61,6 +62,9 @@
   "+storage/browser/quota",
   "+storage/common/quota",
 
+  "+third_party/crashpad/crashpad/client",
+  "+third_party/crashpad/crashpad/util",
+
   "+ui/gfx",
   "+ui/gl",
   "+ui/touch_selection/touch_handle.h",
diff --git a/android_webview/browser/aw_browser_main_parts.cc b/android_webview/browser/aw_browser_main_parts.cc
index 42e713d..9db729b4 100644
--- a/android_webview/browser/aw_browser_main_parts.cc
+++ b/android_webview/browser/aw_browser_main_parts.cc
@@ -30,7 +30,6 @@
 #include "base/message_loop/message_loop_current.h"
 #include "base/path_service.h"
 #include "components/crash/content/browser/child_exit_observer_android.h"
-#include "components/crash/content/browser/crash_dump_manager_android.h"
 #include "components/heap_profiling/supervisor.h"
 #include "components/services/heap_profiling/public/cpp/settings.h"
 #include "components/user_prefs/user_prefs.h"
@@ -95,10 +94,9 @@
   }
 
   base::FilePath crash_dir;
-  if (crash_reporter::IsCrashReporterEnabled()) {
-    if (base::PathService::Get(android_webview::DIR_CRASH_DUMPS, &crash_dir)) {
-      if (!base::PathExists(crash_dir))
-        base::CreateDirectory(crash_dir);
+  if (base::PathService::Get(android_webview::DIR_CRASH_DUMPS, &crash_dir)) {
+    if (!base::PathExists(crash_dir)) {
+      base::CreateDirectory(crash_dir);
     }
   }
 
@@ -106,7 +104,7 @@
           switches::kWebViewSandboxedRenderer)) {
     // Create the renderers crash manager on the UI thread.
     ::crash_reporter::ChildExitObserver::GetInstance()->RegisterClient(
-        std::make_unique<AwBrowserTerminator>(crash_dir));
+        std::make_unique<AwBrowserTerminator>());
   }
 
   variations::InitCrashKeys();
diff --git a/android_webview/browser/aw_browser_terminator.cc b/android_webview/browser/aw_browser_terminator.cc
index 8347981..ef87bc6 100644
--- a/android_webview/browser/aw_browser_terminator.cc
+++ b/android_webview/browser/aw_browser_terminator.cc
@@ -9,14 +9,11 @@
 
 #include "android_webview/browser/aw_render_process_gone_delegate.h"
 #include "android_webview/common/aw_descriptors.h"
-#include "android_webview/common/crash_reporter/aw_crash_reporter_client.h"
-#include "base/bind.h"
 #include "base/logging.h"
 #include "base/stl_util.h"
-#include "base/sync_socket.h"
-#include "base/task/post_task.h"
-#include "components/crash/content/browser/crash_dump_manager_android.h"
-#include "content/public/browser/browser_task_traits.h"
+#include "base/strings/stringprintf.h"
+#include "components/crash/content/app/crashpad.h"
+#include "components/crash/content/browser/crash_metrics_reporter_android.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/child_process_data.h"
 #include "content/public/browser/child_process_launcher_utils.h"
@@ -36,13 +33,8 @@
 namespace {
 
 void GetAwRenderProcessGoneDelegatesForRenderProcess(
-    int render_process_id,
+    content::RenderProcessHost* rph,
     std::vector<AwRenderProcessGoneDelegate*>* delegates) {
-  content::RenderProcessHost* rph =
-      content::RenderProcessHost::FromID(render_process_id);
-  if (!rph)
-    return;
-
   std::unique_ptr<content::RenderWidgetHostIterator> widgets(
       content::RenderWidgetHost::GetRenderWidgetHosts());
   while (content::RenderWidgetHost* widget = widgets->GetNextHost()) {
@@ -59,28 +51,29 @@
   }
 }
 
-void OnRenderProcessGone(int process_host_id) {
+void OnRenderProcessGone(content::RenderProcessHost* host) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   std::vector<AwRenderProcessGoneDelegate*> delegates;
-  GetAwRenderProcessGoneDelegatesForRenderProcess(process_host_id, &delegates);
+  GetAwRenderProcessGoneDelegatesForRenderProcess(host, &delegates);
   for (auto* delegate : delegates)
-    delegate->OnRenderProcessGone(process_host_id);
+    delegate->OnRenderProcessGone(host->GetID());
 }
 
-void OnRenderProcessGoneDetail(int process_host_id,
-                               base::ProcessHandle child_process_pid,
+void OnRenderProcessGoneDetail(content::RenderProcessHost* host,
+                               base::ProcessId child_process_pid,
                                bool crashed) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   std::vector<AwRenderProcessGoneDelegate*> delegates;
-  GetAwRenderProcessGoneDelegatesForRenderProcess(process_host_id, &delegates);
+  GetAwRenderProcessGoneDelegatesForRenderProcess(host, &delegates);
   for (auto* delegate : delegates) {
     if (!delegate->OnRenderProcessGoneDetail(child_process_pid, crashed)) {
       if (crashed) {
-        crash_reporter::SuppressDumpGeneration();
         // Keeps this log unchanged, CTS test uses it to detect crash.
-        LOG(FATAL) << "Render process (" << child_process_pid << ")'s crash"
-                   << " wasn't handled by all associated  webviews, triggering"
-                   << " application crash.";
+        std::string message = base::StringPrintf(
+            "Render process (%d)'s crash wasn't handled by all associated  "
+            "webviews, triggering application crash.",
+            child_process_pid);
+        crash_reporter::CrashWithoutDumping(message);
       } else {
         // The render process was most likely killed for OOM or switching
         // WebView provider, to make WebView backward compatible, kills the
@@ -101,91 +94,26 @@
 
 }  // namespace
 
-AwBrowserTerminator::AwBrowserTerminator(base::FilePath crash_dump_dir)
-    : crash_dump_dir_(crash_dump_dir) {}
+AwBrowserTerminator::AwBrowserTerminator() = default;
 
-AwBrowserTerminator::~AwBrowserTerminator() {}
-
-void AwBrowserTerminator::OnChildStart(
-    int process_host_id,
-    content::PosixFileDescriptorInfo* mappings) {
-  DCHECK(content::CurrentlyOnProcessLauncherTaskRunner());
-
-  base::AutoLock auto_lock(process_host_id_to_pipe_lock_);
-  DCHECK(!ContainsKey(process_host_id_to_pipe_, process_host_id));
-
-  auto local_pipe = std::make_unique<base::SyncSocket>();
-  auto child_pipe = std::make_unique<base::SyncSocket>();
-  if (base::SyncSocket::CreatePair(local_pipe.get(), child_pipe.get())) {
-    process_host_id_to_pipe_[process_host_id] = std::move(local_pipe);
-    mappings->Transfer(kAndroidWebViewCrashSignalDescriptor,
-                       base::ScopedFD(dup(child_pipe->handle())));
-  }
-  if (crash_reporter::IsCrashReporterEnabled()) {
-    base::ScopedFD file(
-        breakpad::CrashDumpManager::GetInstance()->CreateMinidumpFileForChild(
-            process_host_id));
-    if (file != base::kInvalidPlatformFile)
-      mappings->Transfer(kAndroidMinidumpDescriptor, std::move(file));
-  }
-}
-
-void AwBrowserTerminator::OnChildExitAsync(
-    const ::crash_reporter::ChildExitObserver::TerminationInfo& info,
-    base::FilePath crash_dump_dir,
-    std::unique_ptr<base::SyncSocket> pipe) {
-  if (crash_reporter::IsCrashReporterEnabled()) {
-    breakpad::CrashDumpManager::GetInstance()->ProcessMinidumpFileFromChild(
-        crash_dump_dir, info);
-  }
-
-  if (!pipe.get() || info.normal_termination)
-    return;
-
-  bool crashed = false;
-
-  // If the child process hasn't written anything into the pipe. This implies
-  // that it was terminated via SIGKILL by the low memory killer.
-  if (pipe->Peek() >= sizeof(int)) {
-    int exit_code;
-    pipe->Receive(&exit_code, sizeof(exit_code));
-    LOG(ERROR) << "Renderer process (" << info.pid << ") crash detected (code "
-               << exit_code << ").";
-    crashed = true;
-  }
-
-  base::PostTaskWithTraits(
-      FROM_HERE, {BrowserThread::UI},
-      base::BindOnce(&OnRenderProcessGoneDetail, info.process_host_id, info.pid,
-                     crashed));
-}
+AwBrowserTerminator::~AwBrowserTerminator() = default;
 
 void AwBrowserTerminator::OnChildExit(
-    const ::crash_reporter::ChildExitObserver::TerminationInfo& info) {
-  std::unique_ptr<base::SyncSocket> pipe;
+    const crash_reporter::ChildExitObserver::TerminationInfo& info) {
+  content::RenderProcessHost* rph =
+      content::RenderProcessHost::FromID(info.process_host_id);
+  OnRenderProcessGone(rph);
 
-  {
-    base::AutoLock auto_lock(process_host_id_to_pipe_lock_);
-    // We might get a NOTIFICATION_RENDERER_PROCESS_TERMINATED and a
-    // NOTIFICATION_RENDERER_PROCESS_CLOSED. In that case we only want
-    // to process the first notification.
-    const auto& iter = process_host_id_to_pipe_.find(info.process_host_id);
-    if (iter != process_host_id_to_pipe_.end()) {
-      pipe = std::move(iter->second);
-      DCHECK(pipe->handle() != base::SyncSocket::kInvalidHandle);
-      process_host_id_to_pipe_.erase(iter);
-    }
-  }
-  if (pipe.get()) {
-    OnRenderProcessGone(info.process_host_id);
+  crash_reporter::CrashMetricsReporter::GetInstance()->ChildProcessExited(info);
+
+  if (info.normal_termination) {
+    return;
   }
 
-  base::PostTaskWithTraits(
-      FROM_HERE,
-      {base::MayBlock(), base::TaskPriority::USER_VISIBLE,
-       base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
-      base::BindOnce(&AwBrowserTerminator::OnChildExitAsync, info,
-                     crash_dump_dir_, std::move(pipe)));
+  LOG(ERROR) << "Renderer process (" << info.pid << ") crash detected (code "
+             << info.crash_signo << ").";
+
+  OnRenderProcessGoneDetail(rph, info.pid, info.is_crashed());
 }
 
 }  // namespace android_webview
diff --git a/android_webview/browser/aw_browser_terminator.h b/android_webview/browser/aw_browser_terminator.h
index e3f7e9d58..e75bf76 100644
--- a/android_webview/browser/aw_browser_terminator.h
+++ b/android_webview/browser/aw_browser_terminator.h
@@ -7,47 +7,24 @@
 
 #include <map>
 
-#include "base/synchronization/lock.h"
+#include "base/macros.h"
 #include "components/crash/content/browser/child_exit_observer_android.h"
 
-namespace base {
-class SyncSocket;
-}
-
 namespace android_webview {
 
-// This class manages behavior of the browser on renderer crashes when
-// microdumps are used for capturing the crash stack.  Normally, in this case
-// the browser doesn't need to do much, because a microdump is written into
-// Android log by the renderer process itself.  However, the browser may need to
-// crash itself on a renderer crash.  Since on Android renderers are not child
-// processes of the browser, it can't access the exit code. Instead, the browser
-// uses a dedicated pipe in order to receive the information about the renderer
-// crash status.
+// This class manages the browser's behavior in response to renderer exits. If
+// the application does not successfully handle a renderer crash/kill, the
+// browser needs to crash itself.
 class AwBrowserTerminator : public crash_reporter::ChildExitObserver::Client {
  public:
-  AwBrowserTerminator(base::FilePath crash_dump_dir);
+  AwBrowserTerminator();
   ~AwBrowserTerminator() override;
 
-  // crash_reporter::ChildExitObserver::Client implementation.
-  void OnChildStart(int process_host_id,
-                    content::PosixFileDescriptorInfo* mappings) override;
+  // crash_reporter::ChildExitObserver::Client
   void OnChildExit(
       const crash_reporter::ChildExitObserver::TerminationInfo& info) override;
 
  private:
-  static void OnChildExitAsync(
-      const crash_reporter::ChildExitObserver::TerminationInfo& info,
-      base::FilePath crash_dump_dir,
-      std::unique_ptr<base::SyncSocket> pipe);
-
-  base::FilePath crash_dump_dir_;
-
-  // This map should only be accessed with its lock aquired as it is accessed
-  // from the PROCESS_LAUNCHER, FILE, and UI threads.
-  base::Lock process_host_id_to_pipe_lock_;
-  std::map<int, std::unique_ptr<base::SyncSocket>> process_host_id_to_pipe_;
-
   DISALLOW_COPY_AND_ASSIGN(AwBrowserTerminator);
 };
 
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc
index ae5cc33..d8004476 100644
--- a/android_webview/browser/aw_content_browser_client.cc
+++ b/android_webview/browser/aw_content_browser_client.cc
@@ -31,7 +31,6 @@
 #include "android_webview/common/aw_content_client.h"
 #include "android_webview/common/aw_descriptors.h"
 #include "android_webview/common/aw_switches.h"
-#include "android_webview/common/crash_reporter/aw_crash_reporter_client.h"
 #include "android_webview/common/render_view_messages.h"
 #include "android_webview/common/url_constants.h"
 #include "android_webview/grit/aw_resources.h"
@@ -50,7 +49,7 @@
 #include "base/task/post_task.h"
 #include "components/autofill/content/browser/content_autofill_driver_factory.h"
 #include "components/cdm/browser/cdm_message_filter_android.h"
-#include "components/crash/content/browser/child_exit_observer_android.h"
+#include "components/crash/content/browser/crash_handler_host_linux.h"
 #include "components/navigation_interception/intercept_navigation_delegate.h"
 #include "components/policy/content/policy_blacklist_navigation_throttle.h"
 #include "components/policy/core/browser/browser_policy_connector_base.h"
@@ -73,6 +72,7 @@
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/browser/web_contents.h"
+#include "content/public/common/content_descriptors.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/common/service_names.mojom.h"
 #include "content/public/common/url_constants.h"
@@ -391,7 +391,8 @@
            process_type == switches::kUtilityProcess)
         << process_type;
     // Pass crash reporter enabled state to renderer processes.
-    if (crash_reporter::IsCrashReporterEnabled()) {
+    if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+            ::switches::kEnableCrashReporter)) {
       command_line->AppendSwitch(::switches::kEnableCrashReporter);
     }
   }
@@ -611,8 +612,11 @@
   fd = ui::GetLocalePackFd(&region);
   mappings->ShareWithRegion(kAndroidWebViewLocalePakDescriptor, fd, region);
 
-  ::crash_reporter::ChildExitObserver::GetInstance()
-      ->BrowserChildProcessStarted(child_process_id, mappings);
+  int crash_signal_fd =
+      crashpad::CrashHandlerHost::Get()->GetDeathSignalSocket();
+  if (crash_signal_fd >= 0) {
+    mappings->Share(service_manager::kCrashDumpSignal, crash_signal_fd);
+  }
 }
 
 void AwContentBrowserClient::OverrideWebkitPrefs(
diff --git a/android_webview/browser/aw_debug.cc b/android_webview/browser/aw_debug.cc
index d8afd23..0ebdd8a 100644
--- a/android_webview/browser/aw_debug.cc
+++ b/android_webview/browser/aw_debug.cc
@@ -11,12 +11,20 @@
 #include "base/debug/dump_without_crashing.h"
 #include "base/files/file.h"
 #include "base/files/file_path.h"
+#include "base/files/file_util.h"
 #include "base/threading/thread_restrictions.h"
 #include "components/crash/content/app/crash_reporter_client.h"
+#include "components/crash/content/app/crashpad.h"
 #include "components/crash/core/common/crash_key.h"
+#include "components/minidump_uploader/rewrite_minidumps_as_mimes.h"
 #include "components/version_info/version_info.h"
 #include "components/version_info/version_info_values.h"
 #include "jni/AwDebug_jni.h"
+#include "third_party/crashpad/crashpad/client/crash_report_database.h"
+#include "third_party/crashpad/crashpad/util/net/http_body.h"
+#include "third_party/crashpad/crashpad/util/net/http_multipart_builder.h"
+
+#include <memory>
 
 using base::android::ConvertJavaStringToUTF16;
 using base::android::ConvertUTF8ToJavaString;
@@ -62,6 +70,59 @@
   DISALLOW_COPY_AND_ASSIGN(AwDebugCrashReporterClient);
 };
 
+// Writes the most recent report in the database as a MIME to fd. Finishes by
+// deleting all reports from the database. Returns `true` if a report was
+// successfully found and written the file descriptor.
+bool WriteLastReportToFd(crashpad::CrashReportDatabase* db, int fd) {
+  std::vector<crashpad::CrashReportDatabase::Report> reports;
+  if (db->GetPendingReports(&reports) !=
+          crashpad::CrashReportDatabase::kNoError ||
+      !reports.size()) {
+    LOG(ERROR) << "no reports";
+    return false;
+  }
+
+  size_t most_recent_index = 0;
+  time_t most_recent_time = reports[0].creation_time;
+  for (size_t index = 1; index < reports.size(); ++index) {
+    if (reports[index].creation_time > most_recent_time) {
+      most_recent_index = index;
+      most_recent_time = reports[index].creation_time;
+    }
+  }
+
+  {
+    std::unique_ptr<const crashpad::CrashReportDatabase::UploadReport>
+        upload_report;
+    if (db->GetReportForUploading(reports[most_recent_index].uuid,
+                                  &upload_report,
+                                  /* report_metrics= */ false) !=
+        crashpad::CrashReportDatabase::kNoError) {
+      return false;
+    }
+
+    crashpad::HTTPMultipartBuilder builder;
+    pid_t pid;
+    if (!minidump_uploader::MimeifyReport(*upload_report.get(), &builder,
+                                          &pid)) {
+      return false;
+    }
+
+    crashpad::WeakFileHandleFileWriter writer(fd);
+    if (!minidump_uploader::WriteBodyToFile(builder.GetBodyStream().get(),
+                                            &writer)) {
+      return false;
+    }
+  }
+
+  for (size_t index = 0; index < reports.size(); ++index) {
+    db->DeleteReport(reports[index].uuid);
+  }
+  db->CleanDatabase(0);
+
+  return true;
+}
+
 }  // namespace
 
 static jboolean JNI_AwDebug_DumpWithoutCrashing(
@@ -76,8 +137,28 @@
                         base::File::FLAG_WRITE);
   if (!target.IsValid())
     return false;
-  // breakpad_linux::HandleCrashDump will close this fd once it is done.
-  return crash_reporter::DumpWithoutCrashingToFd(target.TakePlatformFile());
+
+  AwDebugCrashReporterClient client;
+  base::FilePath database_path;
+  if (!client.GetCrashDumpLocation(&database_path)) {
+    return false;
+  }
+
+  if (!base::CreateDirectory(database_path)) {
+    return false;
+  }
+
+  std::unique_ptr<crashpad::CrashReportDatabase> database =
+      crashpad::CrashReportDatabase::Initialize(database_path);
+  if (!database) {
+    return false;
+  }
+
+  if (!::crash_reporter::DumpWithoutCrashingForClient(&client)) {
+    return false;
+  }
+
+  return WriteLastReportToFd(database.get(), target.GetPlatformFile());
 }
 
 static void JNI_AwDebug_InitCrashKeysForWebViewTesting(JNIEnv* env) {
diff --git a/android_webview/common/aw_paths.cc b/android_webview/common/aw_paths.cc
index 99887b2..6b1bc92d 100644
--- a/android_webview/common/aw_paths.cc
+++ b/android_webview/common/aw_paths.cc
@@ -19,7 +19,7 @@
       if (!base::android::GetCacheDirectory(&cur))
         return false;
       cur = cur.Append(FILE_PATH_LITERAL("WebView"))
-                .Append(FILE_PATH_LITERAL("Crash Reports"));
+                .Append(FILE_PATH_LITERAL("Crashpad"));
       break;
     case DIR_SAFE_BROWSING:
       if (!base::android::GetCacheDirectory(&cur))
diff --git a/android_webview/common/crash_reporter/aw_crash_reporter_client.cc b/android_webview/common/crash_reporter/aw_crash_reporter_client.cc
index 3298bd1..84f83e9 100644
--- a/android_webview/common/crash_reporter/aw_crash_reporter_client.cc
+++ b/android_webview/common/crash_reporter/aw_crash_reporter_client.cc
@@ -4,70 +4,47 @@
 
 #include "android_webview/common/crash_reporter/aw_crash_reporter_client.h"
 
-#include <random>
+#include <stdint.h>
 
 #include "android_webview/common/aw_channel.h"
 #include "android_webview/common/aw_descriptors.h"
 #include "android_webview/common/aw_paths.h"
+#include "android_webview/common/aw_switches.h"
 #include "android_webview/common/crash_reporter/crash_keys.h"
 #include "base/android/build_info.h"
 #include "base/base_paths_android.h"
-#include "base/debug/crash_logging.h"
-#include "base/debug/dump_without_crashing.h"
-#include "base/files/file_path.h"
+#include "base/command_line.h"
 #include "base/lazy_instance.h"
+#include "base/logging.h"
 #include "base/path_service.h"
 #include "base/scoped_native_library.h"
-#include "base/synchronization/lock.h"
-#include "base/time/time.h"
 #include "build/build_config.h"
-#include "components/crash/content/app/breakpad_linux.h"
 #include "components/crash/content/app/crash_reporter_client.h"
+#include "components/crash/content/app/crashpad.h"
 #include "components/version_info/version_info.h"
 #include "components/version_info/version_info_values.h"
-#include "content/public/common/content_switches.h"
 
 namespace android_webview {
 namespace crash_reporter {
 
 namespace {
 
-// TODO(gsennton) lower the following value before pushing to stable:
-const double minidump_generation_user_fraction = 1.0;
-
-// Returns whether the current process should be reporting crashes through
-// minidumps. This function should only be called once per process - the return
-// value might differ between different calls to this function.
-bool is_process_in_crash_reporting_sample() {
-  // TODO(gsennton): update this method to depend on finch when that is
-  // implemented for WebView.
-  base::Time cur_time = base::Time::Now();
-  std::minstd_rand generator(cur_time.ToInternalValue() /* seed */);
-  std::uniform_real_distribution<double> distribution(0.0, 1.0);
-  return minidump_generation_user_fraction > distribution(generator);
-}
-
 class AwCrashReporterClient : public ::crash_reporter::CrashReporterClient {
  public:
-  AwCrashReporterClient()
-      : dump_fd_(kAndroidMinidumpDescriptor),
-        crash_signal_fd_(-1),
-        in_crash_reporting_sample_(is_process_in_crash_reporting_sample()) {}
-
-  // Does not use lock, can only be called immediately after creation.
-  void set_crash_signal_fd(int fd) { crash_signal_fd_ = fd; }
+  AwCrashReporterClient() {}
 
   // crash_reporter::CrashReporterClient implementation.
-  bool UseCrashKeysWhiteList() override { return true; }
-  const char* const* GetCrashKeyWhiteList() override;
-
   bool IsRunningUnattended() override { return false; }
-  bool GetCollectStatsConsent() override;
-  void GetProductNameAndVersion(const char** product_name,
-                                const char** version) override {
-    *product_name = "AndroidWebView";
-    *version = PRODUCT_VERSION;
+  bool GetCollectStatsConsent() override {
+    // TODO(jperaza): Crashpad uses GetCollectStatsConsent() to enable or
+    // disable upload of crash reports. However, Crashpad does not yet support
+    // upload on Android, so this return value currently has no effect and
+    // WebView's own uploader will determine consent before uploading. If and
+    // when Crashpad supports upload on Android, consent can be determined here,
+    // or WebView can continue uploading reports itself.
+    return false;
   }
+
   void GetProductNameAndVersion(std::string* product_name,
                                 std::string* version,
                                 std::string* channel) override {
@@ -76,20 +53,6 @@
     *channel =
         version_info::GetChannelString(android_webview::GetChannelOrStable());
   }
-  // Microdumps are always enabled in WebView builds, conversely to what happens
-  // in the case of the other Chrome for Android builds (where they are enabled
-  // only when NO_UNWIND_TABLES == 1).
-  bool ShouldEnableBreakpadMicrodumps() override { return true; }
-
-  int GetAndroidMinidumpDescriptor() override { return dump_fd_; }
-  int GetAndroidCrashSignalFD() override { return crash_signal_fd_; }
-
-  bool DumpWithoutCrashingToFd(int fd) {
-    // TODO(tobiasjs): figure out what to do with on demand minidump on the
-    // renderer process of webview.
-    breakpad::GenerateMinidumpOnDemandForAndroid(fd);
-    return true;
-  }
 
   bool GetCrashDumpLocation(base::FilePath* crash_dir) override {
     return base::PathService::Get(android_webview::DIR_CRASH_DUMPS, crash_dir);
@@ -109,36 +72,21 @@
 
   unsigned int GetCrashDumpPercentageForWebView() override { return 100; }
 
+  bool GetBrowserProcessType(std::string* ptype) override {
+    *ptype = base::CommandLine::ForCurrentProcess()->HasSwitch(
+                 switches::kWebViewSandboxedRenderer)
+                 ? "browser"
+                 : "webview";
+    return true;
+  }
+
  private:
-  int dump_fd_;
-  int crash_signal_fd_;
-  bool in_crash_reporting_sample_;
   DISALLOW_COPY_AND_ASSIGN(AwCrashReporterClient);
 };
 
-const char* const* AwCrashReporterClient::GetCrashKeyWhiteList() {
-  return crash_keys::kWebViewCrashKeyWhiteList;
-}
-
-bool AwCrashReporterClient::GetCollectStatsConsent() {
-#if defined(GOOGLE_CHROME_BUILD)
-  // TODO(gsennton): Enabling minidump-generation unconditionally means we
-  // will generate minidumps even if the user doesn't consent to minidump
-  // uploads. However, we will check user-consent before uploading any
-  // minidumps, if we do not have user consent we will delete the minidumps.
-  // We should investigate whether we can avoid generating minidumps
-  // altogether if we don't have user consent, see crbug.com/692485
-  return in_crash_reporting_sample_;
-#else
-  return false;
-#endif  // !defined(GOOGLE_CHROME_BUILD)
-}
-
 base::LazyInstance<AwCrashReporterClient>::Leaky g_crash_reporter_client =
     LAZY_INSTANCE_INITIALIZER;
 
-bool g_enabled = false;
-
 #if defined(ARCH_CPU_X86_FAMILY)
 bool SafeToUseSignalHandler() {
   // N+ shared library namespacing means that we are unable to dlopen
@@ -198,11 +146,13 @@
 
 }  // namespace
 
-void EnableCrashReporter(const std::string& process_type, int crash_signal_fd) {
-  if (g_enabled) {
+void EnableCrashReporter(const std::string& process_type) {
+  static bool enabled;
+  if (enabled) {
     NOTREACHED() << "EnableCrashReporter called more than once";
     return;
   }
+  enabled = true;
 
 #if defined(ARCH_CPU_X86_FAMILY)
   if (!SafeToUseSignalHandler()) {
@@ -212,52 +162,13 @@
 #endif
 
   AwCrashReporterClient* client = g_crash_reporter_client.Pointer();
-  if (process_type == switches::kRendererProcess && crash_signal_fd != -1) {
-    client->set_crash_signal_fd(crash_signal_fd);
-  }
   ::crash_reporter::SetCrashReporterClient(client);
-  breakpad::SanitizationInfo sanitization_info;
-  sanitization_info.should_sanitize_dumps = true;
-#if !defined(COMPONENT_BUILD)
-  sanitization_info.skip_dump_if_principal_mapping_not_referenced = true;
-  sanitization_info.address_within_principal_mapping =
-      reinterpret_cast<uintptr_t>(&EnableCrashReporter);
-#endif  // defined(COMPONENT_BUILD)
-
-  bool is_browser_process =
-      process_type.empty() ||
-      process_type == breakpad::kWebViewSingleProcessType ||
-      process_type == breakpad::kBrowserProcessType;
-  if (is_browser_process) {
-    breakpad::InitCrashReporter(process_type, sanitization_info);
-  } else {
-    breakpad::InitNonBrowserCrashReporterForAndroid(process_type,
-                                                    sanitization_info);
-  }
-  g_enabled = true;
+  ::crash_reporter::InitializeCrashpad(process_type.empty(), process_type);
 }
 
 bool GetCrashDumpLocation(base::FilePath* crash_dir) {
   return g_crash_reporter_client.Get().GetCrashDumpLocation(crash_dir);
 }
 
-void AddGpuFingerprintToMicrodumpCrashHandler(
-    const std::string& gpu_fingerprint) {
-  breakpad::AddGpuFingerprintToMicrodumpCrashHandler(gpu_fingerprint);
-}
-
-bool DumpWithoutCrashingToFd(int fd) {
-  ::crash_reporter::SetCrashReporterClient(g_crash_reporter_client.Pointer());
-  return g_crash_reporter_client.Pointer()->DumpWithoutCrashingToFd(fd);
-}
-
-bool IsCrashReporterEnabled() {
-  return breakpad::IsCrashReporterEnabled();
-}
-
-void SuppressDumpGeneration() {
-  breakpad::SuppressDumpGeneration();
-}
-
 }  // namespace crash_reporter
 }  // namespace android_webview
diff --git a/android_webview/common/crash_reporter/aw_crash_reporter_client.h b/android_webview/common/crash_reporter/aw_crash_reporter_client.h
index 63ceef37..05356d9 100644
--- a/android_webview/common/crash_reporter/aw_crash_reporter_client.h
+++ b/android_webview/common/crash_reporter/aw_crash_reporter_client.h
@@ -14,13 +14,9 @@
 namespace android_webview {
 namespace crash_reporter {
 
-void EnableCrashReporter(const std::string& process_type, int crash_signal_fd);
+void EnableCrashReporter(const std::string& process_type);
 bool GetCrashDumpLocation(base::FilePath* crash_dir);
-void AddGpuFingerprintToMicrodumpCrashHandler(
-    const std::string& gpu_fingerprint);
-bool DumpWithoutCrashingToFd(int fd);
-bool IsCrashReporterEnabled();
-void SuppressDumpGeneration();
+
 }  // namespace crash_reporter
 }  // namespace android_webview
 
diff --git a/android_webview/common/crash_reporter/crash_keys.cc b/android_webview/common/crash_reporter/crash_keys.cc
index e300c40..37d7f59a 100644
--- a/android_webview/common/crash_reporter/crash_keys.cc
+++ b/android_webview/common/crash_reporter/crash_keys.cc
@@ -4,7 +4,7 @@
 
 #include "android_webview/common/crash_reporter/crash_keys.h"
 
-#include "components/crash/content/app/breakpad_linux.h"
+#include "components/crash/core/common/crash_key.h"
 
 namespace android_webview {
 namespace crash_keys {
@@ -55,7 +55,7 @@
 // clang-format on
 
 void InitCrashKeysForWebViewTesting() {
-  breakpad::InitCrashKeysForTesting();
+  crash_reporter::InitializeCrashKeys();
 }
 
 }  // namespace crash_keys
diff --git a/android_webview/lib/aw_main_delegate.cc b/android_webview/lib/aw_main_delegate.cc
index ff7ebf08..0addc54 100644
--- a/android_webview/lib/aw_main_delegate.cc
+++ b/android_webview/lib/aw_main_delegate.cc
@@ -34,7 +34,6 @@
 #include "base/threading/thread_restrictions.h"
 #include "cc/base/switches.h"
 #include "components/autofill/core/common/autofill_features.h"
-#include "components/crash/content/app/breakpad_linux.h"
 #include "components/crash/core/common/crash_key.h"
 #include "components/safe_browsing/android/safe_browsing_api_handler_bridge.h"
 #include "components/services/heap_profiling/public/cpp/allocator_shim.h"
@@ -241,7 +240,6 @@
         command_line.GetSwitchValueASCII(switches::kLang));
   }
 
-  int crash_signal_fd = -1;
   if (process_type == switches::kRendererProcess) {
     auto* global_descriptors = base::GlobalDescriptors::GetInstance();
     int pak_fd = global_descriptors->Get(kAndroidWebViewLocalePakDescriptor);
@@ -260,19 +258,9 @@
       ui::ResourceBundle::GetSharedInstance().AddDataPackFromFileRegion(
           base::File(pak_fd), pak_region, pak_info.second);
     }
-
-    crash_signal_fd =
-        global_descriptors->Get(kAndroidWebViewCrashSignalDescriptor);
-  }
-  if (is_browser_process) {
-    if (command_line.HasSwitch(switches::kWebViewSandboxedRenderer)) {
-      process_type = breakpad::kBrowserProcessType;
-    } else {
-      process_type = breakpad::kWebViewSingleProcessType;
-    }
   }
 
-  crash_reporter::EnableCrashReporter(process_type, crash_signal_fd);
+  crash_reporter::EnableCrashReporter(process_type);
 
   base::android::BuildInfo* android_build_info =
       base::android::BuildInfo::GetInstance();
@@ -298,12 +286,6 @@
     int exit_code = browser_runner_->Initialize(main_function_params);
     DCHECK_LT(exit_code, 0);
 
-    // At this point the content client has received the GPU info required
-    // to create a GPU fingerpring, and we can pass it to the microdump
-    // crash handler on the same thread as the crash handler was initialized.
-    crash_reporter::AddGpuFingerprintToMicrodumpCrashHandler(
-        content_client_.gpu_fingerprint());
-
     // Return 0 so that we do NOT trigger the default behavior. On Android, the
     // UI message loop is managed by the Java application.
     return 0;
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 75d238e..62b79d31 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -663,7 +663,6 @@
     "//components/background_task_scheduler:background_task_scheduler_task_ids_java",
     "//components/bookmarks/common/android:bookmarks_java",
     "//components/crash/android:java",
-    "//components/crash/android:javatests",
     "//components/dom_distiller/core/android:dom_distiller_core_java",
     "//components/download/internal/background_service:internal_java",
     "//components/download/network:network_java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java
index 49b4d536..17602b22 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/init/ChromeBrowserInitializer.java
@@ -37,7 +37,8 @@
 import org.chromium.chrome.browser.tabmodel.document.DocumentTabModelImpl;
 import org.chromium.chrome.browser.webapps.ActivityAssigner;
 import org.chromium.chrome.browser.webapps.ChromeWebApkHost;
-import org.chromium.components.crash.browser.CrashDumpManager;
+import org.chromium.components.crash.browser.ChildProcessCrashObserver;
+import org.chromium.components.minidump_uploader.CrashFileManager;
 import org.chromium.content_public.browser.BrowserStartupController;
 import org.chromium.content_public.browser.DeviceUtils;
 import org.chromium.content_public.browser.SpeechRecognition;
@@ -407,15 +408,26 @@
         ContentUriUtils.setFileProviderUtil(new FileProviderHelper());
         ServiceManagerStartupUtils.registerEnabledFeatures();
 
-        // When a minidump is detected, extract and append a logcat to it, then upload it to the
-        // crash server. Note that the logcat extraction might fail. This is ok; in that case, the
-        // minidump will be found and uploaded upon the next browser launch.
-        CrashDumpManager.registerUploadCallback(new CrashDumpManager.UploadMinidumpCallback() {
-            @Override
-            public void tryToUploadMinidump(File minidump) {
-                AsyncTask.THREAD_POOL_EXECUTOR.execute(new LogcatExtractionRunnable(minidump));
-            }
-        });
+        // When a child process crashes, search for the most recent minidump for the child's process
+        // ID and attach a logcat to it. Then upload it to the crash server. Note that the logcat
+        // extraction might fail. This is ok; in that case, the minidump will be found and uploaded
+        // upon the next browser launch.
+        ChildProcessCrashObserver.registerCrashCallback(
+                new ChildProcessCrashObserver.ChildCrashedCallback() {
+                    @Override
+                    public void childCrashed(int pid) {
+                        CrashFileManager crashFileManager = new CrashFileManager(
+                                ContextUtils.getApplicationContext().getCacheDir());
+
+                        File minidump = crashFileManager.getMinidumpSansLogcatForPid(pid);
+                        if (minidump != null) {
+                            AsyncTask.THREAD_POOL_EXECUTOR.execute(
+                                    new LogcatExtractionRunnable(minidump));
+                        } else {
+                            Log.e(TAG, "Missing dump for child " + pid);
+                        }
+                    }
+                });
 
         MemoryPressureUma.initializeForBrowser();
         if (mTasksToRunWithNative != null) {
diff --git a/chrome/app/chrome_crash_reporter_client.cc b/chrome/app/chrome_crash_reporter_client.cc
index 691a2e1..34ac6e84 100644
--- a/chrome/app/chrome_crash_reporter_client.cc
+++ b/chrome/app/chrome_crash_reporter_client.cc
@@ -50,7 +50,7 @@
 
 ChromeCrashReporterClient::~ChromeCrashReporterClient() {}
 
-#if !defined(OS_MACOSX)
+#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
 void ChromeCrashReporterClient::SetCrashReporterClientIdFromGUID(
     const std::string& client_guid) {
   crash_keys::SetMetricsClientIdFromGUID(client_guid);
diff --git a/chrome/app/chrome_crash_reporter_client.h b/chrome/app/chrome_crash_reporter_client.h
index a98b8d4..fa5f6d7 100644
--- a/chrome/app/chrome_crash_reporter_client.h
+++ b/chrome/app/chrome_crash_reporter_client.h
@@ -20,7 +20,7 @@
   static void Create();
 
   // crash_reporter::CrashReporterClient implementation.
-#if !defined(OS_MACOSX)
+#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
   void SetCrashReporterClientIdFromGUID(
       const std::string& client_guid) override;
 #endif
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc
index 2d7e3f23..1b594a1 100644
--- a/chrome/app/chrome_main_delegate.cc
+++ b/chrome/app/chrome_main_delegate.cc
@@ -130,7 +130,7 @@
 #include "ui/base/x/x11_util.h"  // nogncheck
 #endif
 
-#if defined(OS_POSIX) && !defined(OS_MACOSX)
+#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
 #include "components/crash/content/app/breakpad_linux.h"
 #include "v8/include/v8.h"
 #endif
@@ -139,7 +139,7 @@
 #include "base/environment.h"
 #endif
 
-#if defined(OS_MACOSX) || defined(OS_WIN)
+#if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_ANDROID)
 #include "chrome/browser/policy/policy_path_parser.h"
 #include "components/crash/content/app/crashpad.h"
 #endif
@@ -922,12 +922,11 @@
   // Zygote needs to call InitCrashReporter() in RunZygote().
   if (process_type != service_manager::switches::kZygoteProcess) {
 #if defined(OS_ANDROID)
+    crash_reporter::InitializeCrashpad(process_type.empty(), process_type);
     if (process_type.empty()) {
-      breakpad::InitCrashReporter(process_type);
       base::android::InitJavaExceptionReporter();
       UninstallPureJavaExceptionHandler();
     } else {
-      breakpad::InitNonBrowserCrashReporterForAndroid(process_type);
       base::android::InitJavaExceptionReporterForChildProcess();
     }
 #else  // !defined(OS_ANDROID)
diff --git a/chrome/browser/chrome_browser_main_android.cc b/chrome/browser/chrome_browser_main_android.cc
index 02aac02..d92ad08e 100644
--- a/chrome/browser/chrome_browser_main_android.cc
+++ b/chrome/browser/chrome_browser_main_android.cc
@@ -4,9 +4,6 @@
 
 #include "chrome/browser/chrome_browser_main_android.h"
 
-#include "base/base_switches.h"
-#include "base/command_line.h"
-#include "base/files/file_path.h"
 #include "base/message_loop/message_loop.h"
 #include "base/message_loop/message_loop_current.h"
 #include "base/path_service.h"
@@ -17,9 +14,6 @@
 #include "chrome/browser/android/seccomp_support_detector.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/signin/signin_manager_factory.h"
-#include "chrome/common/chrome_paths.h"
-#include "chrome/common/descriptors_android.h"
-#include "components/crash/content/app/breakpad_linux.h"
 #include "components/crash/content/browser/child_exit_observer_android.h"
 #include "components/crash/content/browser/child_process_crash_observer_android.h"
 #include "components/metrics/stability_metrics_helper.h"
@@ -47,34 +41,11 @@
 
   int result_code = ChromeBrowserMainParts::PreCreateThreads();
 
-  // The ChildProcessCrashObserver must be registered before any child
-  // process is created (as it needs to be notified during child
-  // process creation). Such processes are created on the
-  // PROCESS_LAUNCHER thread, and so the observer is initialized and
-  // the manager registered before that thread is created.
+  // The ChildExitObserver needs to be created before any child process is
+  // created because it needs to be notified during process creation.
   crash_reporter::ChildExitObserver::Create();
-
-#if defined(GOOGLE_CHROME_BUILD)
-  // TODO(jcivelli): we should not initialize the crash-reporter when it was not
-  // enabled. Right now if it is disabled we still generate the minidumps but we
-  // do not upload them.
-  bool breakpad_enabled = true;
-#else
-  bool breakpad_enabled = false;
-#endif
-
-  // Allow Breakpad to be enabled in Chromium builds for testing purposes.
-  if (!breakpad_enabled)
-    breakpad_enabled = base::CommandLine::ForCurrentProcess()->HasSwitch(
-        switches::kEnableCrashReporterForTesting);
-
-  if (breakpad_enabled) {
-    base::FilePath crash_dump_dir;
-    base::PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_dump_dir);
-    crash_reporter::ChildExitObserver::GetInstance()->RegisterClient(
-        std::make_unique<crash_reporter::ChildProcessCrashObserver>(
-            crash_dump_dir, kAndroidMinidumpDescriptor));
-  }
+  crash_reporter::ChildExitObserver::GetInstance()->RegisterClient(
+      std::make_unique<crash_reporter::ChildProcessCrashObserver>());
 
   return result_code;
 }
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index ec2b2a5..ee3d340 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -429,8 +429,10 @@
 #endif
 
 #if defined(OS_POSIX) && !defined(OS_MACOSX)
+#if !defined(OS_ANDROID)
 #include "base/debug/leak_annotations.h"
 #include "components/crash/content/app/breakpad_linux.h"
+#endif  // !defined(OS_ANDROID)
 #include "components/crash/content/browser/crash_handler_host_linux.h"
 #endif
 
@@ -755,7 +757,11 @@
 }
 #endif
 
-#if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_MACOSX)
+#if defined(OS_ANDROID)
+int GetCrashSignalFD(const base::CommandLine& command_line) {
+  return crashpad::CrashHandlerHost::Get()->GetDeathSignalSocket();
+}
+#elif defined(OS_POSIX) && !defined(OS_MACOSX)
 breakpad::CrashHandlerHostLinux* CreateCrashHandlerHost(
     const std::string& process_type) {
   base::FilePath dumps_path;
@@ -830,7 +836,7 @@
 
   return -1;
 }
-#endif  // defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_MACOSX)
+#endif  // defined(OS_ANDROID)
 
 void SetApplicationLocaleOnIOThread(const std::string& locale) {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
@@ -1941,7 +1947,12 @@
                                     client_info->client_id);
   }
 #elif defined(OS_POSIX)
-  if (breakpad::IsCrashReporterEnabled()) {
+#if defined(OS_ANDROID)
+  bool enable_crash_reporter = true;
+#else
+  bool enable_crash_reporter = breakpad::IsCrashReporterEnabled();
+#endif
+  if (enable_crash_reporter) {
     std::string switch_value;
     std::unique_ptr<metrics::ClientInfo> client_info =
         GoogleUpdateSettings::LoadMetricsClientInfo();
@@ -3537,18 +3548,14 @@
     mappings->ShareWithRegion(kAndroidSecondaryLocalePakDescriptor, fd, region);
   }
 
-  crash_reporter::ChildExitObserver::GetInstance()->BrowserChildProcessStarted(
-      child_process_id, mappings);
-
   base::FilePath app_data_path;
   base::PathService::Get(base::DIR_ANDROID_APP_DATA, &app_data_path);
   DCHECK(!app_data_path.empty());
-#else
+#endif  // defined(OS_ANDROID)
   int crash_signal_fd = GetCrashSignalFD(command_line);
   if (crash_signal_fd >= 0) {
     mappings->Share(service_manager::kCrashDumpSignal, crash_signal_fd);
   }
-#endif  // defined(OS_ANDROID)
 }
 #endif  // defined(OS_POSIX) && !defined(OS_MACOSX)
 
diff --git a/chrome/browser/crash_upload_list/crash_upload_list.cc b/chrome/browser/crash_upload_list/crash_upload_list.cc
index c1bbfc7..a2073c0 100644
--- a/chrome/browser/crash_upload_list/crash_upload_list.cc
+++ b/chrome/browser/crash_upload_list/crash_upload_list.cc
@@ -17,21 +17,25 @@
 #endif
 
 #if defined(OS_ANDROID)
+#include "base/android/path_utils.h"
 #include "chrome/browser/crash_upload_list/crash_upload_list_android.h"
 #endif
 
 scoped_refptr<UploadList> CreateCrashUploadList() {
 #if defined(OS_MACOSX) || defined(OS_WIN)
   return new CrashUploadListCrashpad();
+#elif defined(OS_ANDROID)
+  base::FilePath cache_dir;
+  base::android::GetCacheDirectory(&cache_dir);
+  base::FilePath upload_log_path =
+      cache_dir.Append("Crash Reports")
+          .AppendASCII(CrashUploadList::kReporterLogFilename);
+  return new CrashUploadListAndroid(upload_log_path);
 #else
   base::FilePath crash_dir_path;
   base::PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_dir_path);
   base::FilePath upload_log_path =
       crash_dir_path.AppendASCII(CrashUploadList::kReporterLogFilename);
-#if defined(OS_ANDROID)
-  return new CrashUploadListAndroid(upload_log_path);
-#else
   return new TextLogUploadList(upload_log_path);
-#endif  // defined(OS_ANDROID)
 #endif  // defined(OS_MACOSX) || defined(OS_WIN)
 }
diff --git a/chrome/browser/metrics/oom/out_of_memory_reporter_unittest.cc b/chrome/browser/metrics/oom/out_of_memory_reporter_unittest.cc
index eadccef..f1d167b 100644
--- a/chrome/browser/metrics/oom/out_of_memory_reporter_unittest.cc
+++ b/chrome/browser/metrics/oom/out_of_memory_reporter_unittest.cc
@@ -27,6 +27,8 @@
 #include "components/ukm/content/source_url_recorder.h"
 #include "components/ukm/test_ukm_recorder.h"
 #include "content/public/browser/navigation_handle.h"
+#include "content/public/browser/notification_service.h"
+#include "content/public/browser/notification_types.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/browser/web_contents_observer.h"
@@ -42,9 +44,8 @@
 
 #if defined(OS_ANDROID)
 #include "chrome/common/descriptors_android.h"
-#include "components/crash/content/browser/child_process_crash_observer_android.h"
 #include "components/crash/content/browser/child_exit_observer_android.h"
-#include "components/crash/content/browser/crash_dump_manager_android.h"
+#include "components/crash/content/browser/child_process_crash_observer_android.h"
 #endif
 
 #if defined(OS_ANDROID)
@@ -83,62 +84,6 @@
 };
 #endif  // defined(OS_ANDROID)
 
-// This class ensures we always have an empty minidump file associated with the
-// process a navigation finishes in.
-class DumpCreator : public content::WebContentsObserver {
- public:
-  explicit DumpCreator(content::WebContents* contents)
-      : content::WebContentsObserver(contents) {
-    CreateDump(contents->GetRenderViewHost()->GetProcess()->GetID(),
-               true /*is_empty */);
-  }
-  ~DumpCreator() override = default;
-
-  void CreateDump(int render_process_id, bool is_empty) {
-#if defined(OS_ANDROID)
-    // Simulate a call to ChildStart and create an empty crash dump.
-    std::string contents = is_empty ? "" : "non empty minidump";
-    auto write_task =
-        [](int render_process_id, const std::string& contents,
-           std::map<int, base::ScopedFD>* rph_id_to_minidump_file) {
-          const auto it = rph_id_to_minidump_file->find(render_process_id);
-          int fd;
-          if (it == rph_id_to_minidump_file->end()) {
-            base::ScopedFD minidump =
-                breakpad::CrashDumpManager::GetInstance()
-                    ->CreateMinidumpFileForChild(render_process_id);
-            fd = minidump.get();
-            (*rph_id_to_minidump_file)[render_process_id] = std::move(minidump);
-          } else {
-            fd = it->second.get();
-          }
-          EXPECT_TRUE(
-              base::WriteFileDescriptor(fd, contents.data(), contents.size()));
-        };
-
-    base::RunLoop run_loop;
-    base::PostTaskWithTraitsAndReply(
-        FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
-        base::BindOnce(write_task, render_process_id, contents,
-                       &rph_id_to_minidump_file_),
-        run_loop.QuitClosure());
-    run_loop.Run();
-#endif
-  }
-
- private:
-  // content::WebContentsObserver:
-  void DidFinishNavigation(content::NavigationHandle* handle) override {
-    CreateDump(
-        handle->GetWebContents()->GetRenderViewHost()->GetProcess()->GetID(),
-        true /* is_empty */);
-  }
-
-#if defined(OS_ANDROID)
-  std::map<int, base::ScopedFD> rph_id_to_minidump_file_;
-#endif
-};
-
 class OutOfMemoryReporterTest : public ChromeRenderViewHostTestHarness,
                                 public OutOfMemoryReporter::Observer {
  public:
@@ -147,18 +92,14 @@
 
   // ChromeRenderViewHostTestHarness:
   void SetUp() override {
-    ChromeRenderViewHostTestHarness::SetUp();
-    EXPECT_NE(content::ChildProcessHost::kInvalidUniqueID, process()->GetID());
 #if defined(OS_ANDROID)
     crash_reporter::ChildExitObserver::Create();
-    base::FilePath crash_dump_dir;
-    base::PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_dump_dir);
     crash_reporter::ChildExitObserver::GetInstance()->RegisterClient(
-        std::make_unique<crash_reporter::ChildProcessCrashObserver>(
-            crash_dump_dir, kAndroidMinidumpDescriptor));
+        std::make_unique<crash_reporter::ChildProcessCrashObserver>());
 #endif
 
-    dump_creator_ = std::make_unique<DumpCreator>(web_contents());
+    ChromeRenderViewHostTestHarness::SetUp();
+    EXPECT_NE(content::ChildProcessHost::kInvalidUniqueID, process()->GetID());
 
     OutOfMemoryReporter::CreateForWebContents(web_contents());
     OutOfMemoryReporter* reporter =
@@ -180,8 +121,16 @@
     last_oom_url_ = url;
   }
 
+  void SimulateRendererCreated() {
+    content::NotificationService::current()->Notify(
+        content::NOTIFICATION_RENDERER_PROCESS_CREATED,
+        content::Source<content::RenderProcessHost>(process()),
+        content::NotificationService::NoDetails());
+  }
+
   void SimulateOOM() {
     test_tick_clock_->Advance(base::TimeDelta::FromSeconds(3));
+    SimulateRendererCreated();
 #if defined(OS_ANDROID)
     process()->SimulateRenderProcessExit(base::TERMINATION_STATUS_OOM_PROTECTED,
                                          0);
@@ -235,17 +184,11 @@
     }
   }
 
-  void WriteMinidumpFile(bool is_empty) {
-    dump_creator_->CreateDump(
-        web_contents()->GetRenderViewHost()->GetProcess()->GetID(), is_empty);
-  }
-
  protected:
   base::ShadowingAtExitManager at_exit_;
 
   base::Optional<GURL> last_oom_url_;
   std::unique_ptr<ukm::TestAutoSetUkmRecorder> test_ukm_recorder_;
-  std::unique_ptr<DumpCreator> dump_creator_;
 
  private:
   base::SimpleTestTickClock* test_tick_clock_;
@@ -266,8 +209,10 @@
 TEST_F(OutOfMemoryReporterTest, NormalCrash_NoOOM) {
   const GURL url("https://example.test/");
   NavigateAndCommit(url);
+  SimulateRendererCreated();
 #if defined(OS_ANDROID)
-  WriteMinidumpFile(false /*is_empty */);
+  crash_reporter::ChildExitObserver::GetInstance()->ChildReceivedCrashSignal(
+      process()->GetProcess().Handle(), SIGSEGV);
 #endif
   RunCrashClosureAndWait(
       base::BindOnce(&content::MockRenderProcessHost::SimulateRenderProcessExit,
diff --git a/chrome/common/chrome_paths.cc b/chrome/common/chrome_paths.cc
index 6cc2c913..cac96e6 100644
--- a/chrome/common/chrome_paths.cc
+++ b/chrome/common/chrome_paths.cc
@@ -232,7 +232,7 @@
       if (!GetDefaultUserDataDirectory(&cur))
         return false;
 #endif
-#if defined(OS_MACOSX) || defined(OS_WIN)
+#if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_ANDROID)
       cur = cur.Append(FILE_PATH_LITERAL("Crashpad"));
 #else
       cur = cur.Append(FILE_PATH_LITERAL("Crash Reports"));
diff --git a/chromecast/android/BUILD.gn b/chromecast/android/BUILD.gn
index 1e2ae17..154675f 100644
--- a/chromecast/android/BUILD.gn
+++ b/chromecast/android/BUILD.gn
@@ -26,6 +26,7 @@
     "//chromecast/base/metrics",
     "//chromecast/browser",
     "//components/crash/android:crash_android",
+    "//components/minidump_uploader",
     "//content/public/app:both",
     "//content/public/browser",
     "//skia",
diff --git a/chromecast/app/BUILD.gn b/chromecast/app/BUILD.gn
index 271343d..5166e88 100644
--- a/chromecast/app/BUILD.gn
+++ b/chromecast/app/BUILD.gn
@@ -64,7 +64,6 @@
       "//chromecast/base:cast_sys_info",
       "//chromecast/base:cast_version",
       "//chromecast/browser:jni_headers",
-      "//third_party/breakpad:client",
     ]
   }
 }
diff --git a/chromecast/app/android/DEPS b/chromecast/app/android/DEPS
index 8bb2b12..01e92c2 100644
--- a/chromecast/app/android/DEPS
+++ b/chromecast/app/android/DEPS
@@ -3,5 +3,4 @@
   "+chromecast/browser/android",
   "+jni",
   "+services/service_manager/embedder",
-  "+third_party/breakpad",
 ]
diff --git a/chromecast/app/android/cast_crash_reporter_client_android.cc b/chromecast/app/android/cast_crash_reporter_client_android.cc
index 005c554..42184357e 100644
--- a/chromecast/app/android/cast_crash_reporter_client_android.cc
+++ b/chromecast/app/android/cast_crash_reporter_client_android.cc
@@ -25,17 +25,6 @@
 }
 
 void CastCrashReporterClientAndroid::GetProductNameAndVersion(
-    const char** product_name,
-    const char** version) {
-  *product_name = "media_shell";
-  *version = PRODUCT_VERSION
-#if CAST_IS_DEBUG_BUILD()
-      ".debug"
-#endif
-      "." CAST_BUILD_REVISION;
-}
-
-void CastCrashReporterClientAndroid::GetProductNameAndVersion(
     std::string* product_name,
     std::string* version,
     std::string* channel) {
@@ -54,7 +43,7 @@
 }
 
 // static
-bool CastCrashReporterClientAndroid::GetCrashDumpLocation(
+bool CastCrashReporterClientAndroid::GetCrashReportsLocation(
     const std::string& process_type,
     base::FilePath* crash_dir) {
   base::FilePath crash_dir_local;
@@ -79,8 +68,13 @@
 
 bool CastCrashReporterClientAndroid::GetCrashDumpLocation(
     base::FilePath* crash_dir) {
-  return CastCrashReporterClientAndroid::GetCrashDumpLocation(process_type_,
-                                                              crash_dir);
+  base::FilePath app_data;
+  if (!base::PathService::Get(base::DIR_ANDROID_APP_DATA, &app_data)) {
+    return false;
+  }
+
+  *crash_dir = app_data.Append("Crashpad");
+  return true;
 }
 
 bool CastCrashReporterClientAndroid::GetCollectStatsConsent() {
diff --git a/chromecast/app/android/cast_crash_reporter_client_android.h b/chromecast/app/android/cast_crash_reporter_client_android.h
index 38557d0..139d4ba 100644
--- a/chromecast/app/android/cast_crash_reporter_client_android.h
+++ b/chromecast/app/android/cast_crash_reporter_client_android.h
@@ -19,12 +19,11 @@
   explicit CastCrashReporterClientAndroid(const std::string& process_type);
   ~CastCrashReporterClientAndroid() override;
 
-  static bool GetCrashDumpLocation(const std::string& process_type,
-                                   base::FilePath* crash_dir);
+  // Return the path to a directory of MIME-encoded crash reports.
+  static bool GetCrashReportsLocation(const std::string& process_type,
+                                      base::FilePath* crash_dir);
 
   // crash_reporter::CrashReporterClient implementation:
-  void GetProductNameAndVersion(const char** product_name,
-                                const char** version) override;
   void GetProductNameAndVersion(std::string* product_name,
                                 std::string* version,
                                 std::string* channel) override;
diff --git a/chromecast/app/android/crash_handler.cc b/chromecast/app/android/crash_handler.cc
index 56d0434..4bdef99 100644
--- a/chromecast/app/android/crash_handler.cc
+++ b/chromecast/app/android/crash_handler.cc
@@ -16,13 +16,10 @@
 #include "chromecast/app/android/cast_crash_reporter_client_android.h"
 #include "chromecast/base/chromecast_config_android.h"
 #include "chromecast/base/version.h"
-#include "components/crash/content/app/breakpad_linux.h"
 #include "components/crash/content/app/crash_reporter_client.h"
+#include "components/crash/content/app/crashpad.h"
 #include "content/public/common/content_switches.h"
 #include "jni/CastCrashHandler_jni.h"
-#include "services/service_manager/embedder/switches.h"
-#include "third_party/breakpad/breakpad/src/client/linux/handler/exception_handler.h"
-#include "third_party/breakpad/breakpad/src/client/linux/handler/minidump_descriptor.h"
 
 namespace {
 
@@ -47,6 +44,13 @@
       crash_dir);
 }
 
+// static
+bool CrashHandler::GetCrashReportsLocation(base::FilePath* reports_dir) {
+  DCHECK(g_crash_handler);
+  return g_crash_handler->crash_reporter_client_->GetCrashReportsLocation(
+      g_crash_handler->process_type_, reports_dir);
+}
+
 CrashHandler::CrashHandler(const std::string& process_type,
                            const base::FilePath& log_file_path)
     : log_file_path_(log_file_path),
@@ -64,22 +68,19 @@
 }
 
 void CrashHandler::Initialize() {
-  if (process_type_.empty()) {
-    breakpad::InitCrashReporter(process_type_);
-    return;
-  }
-  if (process_type_ != service_manager::switches::kZygoteProcess) {
-    breakpad::InitNonBrowserCrashReporterForAndroid(process_type_);
-  }
+  crash_reporter::InitializeCrashpad(process_type_.empty(), process_type_);
 }
 
 // static
 void CrashHandler::UploadDumps(const base::FilePath& crash_dump_path,
+                               const base::FilePath& reports_path,
                                const std::string& uuid,
                                const std::string& application_feedback) {
   JNIEnv* env = base::android::AttachCurrentThread();
   base::android::ScopedJavaLocalRef<jstring> crash_dump_path_java =
       base::android::ConvertUTF8ToJavaString(env, crash_dump_path.value());
+  base::android::ScopedJavaLocalRef<jstring> reports_path_java =
+      base::android::ConvertUTF8ToJavaString(env, reports_path.value());
   base::android::ScopedJavaLocalRef<jstring> uuid_java =
       base::android::ConvertUTF8ToJavaString(env, uuid);
   base::android::ScopedJavaLocalRef<jstring> application_feedback_java =
@@ -90,11 +91,13 @@
       android::ChromecastConfigAndroid::GetInstance()->CanSendUsageStats();
 
   if (can_send_usage_stats) {
-    Java_CastCrashHandler_uploadOnce(env, crash_dump_path_java, uuid_java,
+    Java_CastCrashHandler_uploadOnce(env, crash_dump_path_java,
+                                     reports_path_java, uuid_java,
                                      application_feedback_java,
                                      /* UploadToStaging = */ false);
   } else {
-    Java_CastCrashHandler_removeCrashDumps(env, crash_dump_path_java, uuid_java,
+    Java_CastCrashHandler_removeCrashDumps(env, crash_dump_path_java,
+                                           reports_path_java, uuid_java,
                                            application_feedback_java,
                                            /* UploadToStaging = */ false);
   }
diff --git a/chromecast/app/android/crash_handler.h b/chromecast/app/android/crash_handler.h
index 8a3c5b0..6af19a67 100644
--- a/chromecast/app/android/crash_handler.h
+++ b/chromecast/app/android/crash_handler.h
@@ -24,9 +24,17 @@
   static void Initialize(const std::string& process_type,
                          const base::FilePath& log_file_path);
 
-  // Returns the directory location for crash dumps.
+  // Returns the directory location to use for a crashpad::CrashReportDatabase
+  // of raw minidump files. Prior to upload, these files are re-written as MIME
+  // multipart messages allowing upload metadata and attachments to be included
+  // as parts of the message.
   static bool GetCrashDumpLocation(base::FilePath* crash_dir);
+
+  // Returns the directory of crash reports re-written as MIME messages.
+  static bool GetCrashReportsLocation(base::FilePath* reports_dir);
+
   static void UploadDumps(const base::FilePath& crash_dump_path,
+                          const base::FilePath& reports_path,
                           const std::string& uuid,
                           const std::string& application_feedback);
 
diff --git a/chromecast/app/cast_main_delegate.cc b/chromecast/app/cast_main_delegate.cc
index fce86db..1e43be0 100644
--- a/chromecast/app/cast_main_delegate.cc
+++ b/chromecast/app/cast_main_delegate.cc
@@ -99,7 +99,7 @@
   if (process_type.empty()) {
     // Get a listing of all of the crash dump files.
     base::FilePath crash_directory;
-    if (CastCrashReporterClientAndroid::GetCrashDumpLocation(
+    if (CastCrashReporterClientAndroid::GetCrashReportsLocation(
             process_type, &crash_directory)) {
       base::FileEnumerator crash_directory_list(crash_directory, false,
                                                 base::FileEnumerator::FILES);
diff --git a/chromecast/browser/android/BUILD.gn b/chromecast/browser/android/BUILD.gn
index e0c54182..93952de 100644
--- a/chromecast/browser/android/BUILD.gn
+++ b/chromecast/browser/android/BUILD.gn
@@ -143,6 +143,7 @@
     "//components/crash/android:java",
     "//components/embedder_support/android:content_view_java",
     "//components/embedder_support/android:view_java",
+    "//components/minidump_uploader:minidump_uploader_java",
     "//content/public/android:content_java",
     "//media/base/android:media_java",
     "//net/android:net_java",
diff --git a/chromecast/browser/android/DEPS b/chromecast/browser/android/DEPS
index 0a2a2f05..302002c 100644
--- a/chromecast/browser/android/DEPS
+++ b/chromecast/browser/android/DEPS
@@ -1,5 +1,6 @@
 include_rules = [
   "+components/embedder_support/android",
+  "+components/minidump_uploader",
   "+content/public/android",
   "+jni",
   "+ui/android",
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 7dc4268..f449108 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
@@ -15,18 +15,18 @@
     private static final String TAG = "cr_CastCrashHandler";
 
     @CalledByNative
-    public static void uploadOnce(String crashDumpPath, String uuid, String applicationFeedback,
-            boolean uploadCrashToStaging) {
+    public static void uploadOnce(String crashDumpPath, String crashReportsPath, String uuid,
+            String applicationFeedback, boolean uploadCrashToStaging) {
         CastCrashUploader uploader = CastCrashUploaderFactory.createCastCrashUploader(
-                crashDumpPath, uuid, applicationFeedback, uploadCrashToStaging);
+                crashDumpPath, crashReportsPath, uuid, applicationFeedback, uploadCrashToStaging);
         uploader.uploadOnce();
     }
 
     @CalledByNative
-    public static void removeCrashDumps(String crashDumpPath, String uuid,
+    public static void removeCrashDumps(String crashDumpPath, String crashReportsPath, String uuid,
             String applicationFeedback, boolean uploadCrashToStaging) {
         CastCrashUploader uploader = CastCrashUploaderFactory.createCastCrashUploader(
-                crashDumpPath, uuid, applicationFeedback, uploadCrashToStaging);
+                crashDumpPath, crashReportsPath, uuid, applicationFeedback, uploadCrashToStaging);
         uploader.removeCrashDumps();
     }
 }
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 14307bb2..53d247bd 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
@@ -5,6 +5,7 @@
 package org.chromium.chromecast.shell;
 
 import org.chromium.base.Log;
+import org.chromium.components.minidump_uploader.CrashReportMimeWriter;
 
 import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
@@ -44,17 +45,19 @@
     private final ScheduledExecutorService mExecutorService;
     private final ElidedLogcatProvider mLogcatProvider;
     private final String mCrashDumpPath;
+    private final String mCrashReportPath;
     private final String mCrashReportUploadUrl;
     private final String mUuid;
     private final String mApplicationFeedback;
     private final Runnable mQueueAllCrashDumpUploadsRunnable = () -> checkForCrashDumps();
 
     public CastCrashUploader(ScheduledExecutorService executorService,
-            ElidedLogcatProvider logcatProvider, String crashDumpPath, String uuid,
-            String applicationFeedback, boolean uploadCrashToStaging) {
+            ElidedLogcatProvider logcatProvider, String crashDumpPath, String crashReportPath,
+            String uuid, String applicationFeedback, boolean uploadCrashToStaging) {
         mExecutorService = executorService;
         mLogcatProvider = logcatProvider;
         mCrashDumpPath = crashDumpPath;
+        mCrashReportPath = crashReportPath;
         mUuid = uuid;
         mApplicationFeedback = applicationFeedback;
         mCrashReportUploadUrl = uploadCrashToStaging
@@ -69,8 +72,8 @@
 
     public void removeCrashDumps() {
         Log.i(TAG, "Remove crash dumps");
-        File crashDumpDirectory = new File(mCrashDumpPath);
-        for (File potentialDump : crashDumpDirectory.listFiles()) {
+        File crashReportDirectory = new File(mCrashReportPath);
+        for (File potentialDump : crashReportDirectory.listFiles()) {
             if (potentialDump.getName().matches(DUMP_FILE_REGEX)) {
                 potentialDump.delete();
             }
@@ -89,12 +92,19 @@
 
         Log.i(TAG, "Checking for crash dumps");
         File crashDumpDirectory = new File(mCrashDumpPath);
+        File crashReportDirectory = new File(mCrashReportPath);
 
-        int numCrashDumps = crashDumpDirectory.listFiles().length;
+        if (!crashDumpDirectory.isDirectory() || !crashReportDirectory.isDirectory()) {
+            return;
+        }
+
+        CrashReportMimeWriter.rewriteMinidumpsAsMIMEs(crashDumpDirectory, crashReportDirectory);
+
+        int numCrashDumps = crashReportDirectory.listFiles().length;
         if (numCrashDumps > 0) {
             Log.i(TAG, numCrashDumps + " crash dumps found");
             mLogcatProvider.getElidedLogcat(
-                    (String logs) -> queueAllCrashDumpUploadsWithLogs(crashDumpDirectory, logs));
+                    (String logs) -> queueAllCrashDumpUploadsWithLogs(crashReportDirectory, logs));
         }
     }
 
diff --git a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashUploaderFactory.java b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashUploaderFactory.java
index c1e1dcb..df3b4347 100644
--- a/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashUploaderFactory.java
+++ b/chromecast/browser/android/apk/src/org/chromium/chromecast/shell/CastCrashUploaderFactory.java
@@ -13,16 +13,17 @@
  */
 public final class CastCrashUploaderFactory {
     private static ScheduledExecutorService sExecutorService;
-    public static CastCrashUploader createCastCrashUploader(String crashDumpPath, String uuid,
-            String applicationFeedback, boolean uploadCrashToStaging) {
+    public static CastCrashUploader createCastCrashUploader(String crashDumpPath,
+            String crashReportsPath, String uuid, String applicationFeedback,
+            boolean uploadCrashToStaging) {
         if (sExecutorService == null) {
             sExecutorService = Executors.newScheduledThreadPool(1);
         }
         ElidedLogcatProvider logcatProvider = shouldUseRemoteServiceLogs()
                 ? new ExternalServiceDeviceLogcatProvider()
                 : new AndroidAppLogcatProvider();
-        return new CastCrashUploader(sExecutorService, logcatProvider, crashDumpPath, uuid,
-                applicationFeedback, uploadCrashToStaging);
+        return new CastCrashUploader(sExecutorService, logcatProvider, crashDumpPath,
+                crashReportsPath, uuid, applicationFeedback, uploadCrashToStaging);
     }
 
     private static boolean shouldUseRemoteServiceLogs() {
@@ -30,4 +31,4 @@
                 && !BuildConfig.DEVICE_LOGS_PROVIDER_PACKAGE.equals("")
                 && !BuildConfig.DEVICE_LOGS_PROVIDER_CLASS.equals("");
     }
-}
\ No newline at end of file
+}
diff --git a/chromecast/browser/cast_browser_main_parts.cc b/chromecast/browser/cast_browser_main_parts.cc
index add06dc..0e2759f 100644
--- a/chromecast/browser/cast_browser_main_parts.cc
+++ b/chromecast/browser/cast_browser_main_parts.cc
@@ -43,7 +43,6 @@
 #include "chromecast/browser/tts/tts_platform_stub.h"
 #include "chromecast/browser/url_request_context_factory.h"
 #include "chromecast/chromecast_buildflags.h"
-#include "chromecast/common/global_descriptors.h"
 #include "chromecast/graphics/cast_window_manager.h"
 #include "chromecast/media/base/key_systems_common.h"
 #include "chromecast/media/base/media_resource_tracker.h"
@@ -416,16 +415,9 @@
 
 int CastBrowserMainParts::PreCreateThreads() {
 #if defined(OS_ANDROID)
-  // GPU process is started immediately after threads are created,
-  // requiring ChildProcessCrashObserver to be initialized beforehand.
-  base::FilePath crash_dumps_dir;
-  if (!chromecast::CrashHandler::GetCrashDumpLocation(&crash_dumps_dir)) {
-    LOG(ERROR) << "Could not find crash dump location.";
-  }
   crash_reporter::ChildExitObserver::Create();
   crash_reporter::ChildExitObserver::GetInstance()->RegisterClient(
-      std::make_unique<crash_reporter::ChildProcessCrashObserver>(
-          crash_dumps_dir, kAndroidMinidumpDescriptor));
+      std::make_unique<crash_reporter::ChildProcessCrashObserver>());
 #endif
 
   cast_browser_process_->SetPrefService(
@@ -598,7 +590,9 @@
 void CastBrowserMainParts::OnStartPeriodicCrashReportUpload() {
   base::FilePath crash_dir;
   CrashHandler::GetCrashDumpLocation(&crash_dir);
-  CrashHandler::UploadDumps(crash_dir, "", "");
+  base::FilePath reports_dir;
+  CrashHandler::GetCrashReportsLocation(&reports_dir);
+  CrashHandler::UploadDumps(crash_dir, reports_dir, "", "");
 }
 #endif  // defined(OS_ANDROID)
 
diff --git a/chromecast/browser/cast_content_browser_client.cc b/chromecast/browser/cast_content_browser_client.cc
index 2ecb3e5..ce183fb 100644
--- a/chromecast/browser/cast_content_browser_client.cc
+++ b/chromecast/browser/cast_content_browser_client.cc
@@ -90,14 +90,17 @@
 #endif  // ENABLE_MOJO_MEDIA_IN_BROWSER_PROCESS
 
 #if defined(OS_LINUX) || defined(OS_ANDROID)
-#include "components/crash/content/app/breakpad_linux.h"
 #include "components/crash/content/browser/crash_handler_host_linux.h"
 #endif  // defined(OS_LINUX) || defined(OS_ANDROID)
 
+#if defined(OS_LINUX)
+#include "components/crash/content/app/breakpad_linux.h"
+#endif  // defined(OS_LINUX)
+
 #if defined(OS_ANDROID)
 #include "base/android/build_info.h"
 #include "components/cdm/browser/cdm_message_filter_android.h"
-#include "components/crash/content/browser/child_exit_observer_android.h"
+#include "components/crash/content/app/crashpad.h"
 #include "media/mojo/services/android_mojo_media_client.h"
 #if !BUILDFLAG(USE_CHROMECAST_CDMS)
 #include "components/cdm/browser/media_drm_storage_impl.h"
@@ -482,12 +485,19 @@
       base::CommandLine::ForCurrentProcess();
 
 #if !defined(OS_FUCHSIA)
+#if defined(OS_ANDROID)
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kEnableCrashReporter)) {
+    command_line->AppendSwitch(switches::kEnableCrashReporter);
+  }
+#else
   // IsCrashReporterEnabled() is set when InitCrashReporter() is called, and
   // controlled by GetBreakpadClient()->EnableBreakpadForProcess(), therefore
   // it's ok to add switch to every process here.
   if (breakpad::IsCrashReporterEnabled()) {
     command_line->AppendSwitch(switches::kEnableCrashReporter);
   }
+#endif  // defined(OS_ANDROID)
 #endif  // !defined(OS_FUCHSIA)
 
   // Command-line for different processes.
@@ -782,9 +792,8 @@
       kAndroidPakDescriptor,
       base::GlobalDescriptors::GetInstance()->Get(kAndroidPakDescriptor),
       base::GlobalDescriptors::GetInstance()->GetRegion(kAndroidPakDescriptor));
-  crash_reporter::ChildExitObserver::GetInstance()->BrowserChildProcessStarted(
-      child_process_id, mappings);
-#elif !defined(OS_FUCHSIA)
+#endif  // defined(OS_ANDROID)
+#if !defined(OS_FUCHSIA)
   // TODO(crbug.com/753619): Enable crash reporting on Fuchsia.
   int crash_signal_fd = GetCrashSignalFD(command_line);
   if (crash_signal_fd >= 0) {
@@ -828,7 +837,12 @@
   return nullptr;
 }
 
-#if !defined(OS_ANDROID) && !defined(OS_FUCHSIA)
+#if defined(OS_ANDROID)
+int CastContentBrowserClient::GetCrashSignalFD(
+    const base::CommandLine& command_line) {
+  return crashpad::CrashHandlerHost::Get()->GetDeathSignalSocket();
+}
+#elif !defined(OS_FUCHSIA)
 int CastContentBrowserClient::GetCrashSignalFD(
     const base::CommandLine& command_line) {
   std::string process_type =
@@ -866,7 +880,7 @@
   crash_handler->StartUploaderThread();
   return crash_handler;
 }
-#endif  // !defined(OS_ANDROID)
+#endif  // defined(OS_ANDROID)
 
 std::vector<std::unique_ptr<content::NavigationThrottle>>
 CastContentBrowserClient::CreateThrottlesForNavigation(
diff --git a/chromecast/browser/cast_content_browser_client.h b/chromecast/browser/cast_content_browser_client.h
index a1fb844e..67fceb5 100644
--- a/chromecast/browser/cast_content_browser_client.h
+++ b/chromecast/browser/cast_content_browser_client.h
@@ -234,10 +234,11 @@
                                 scoped_refptr<net::SSLPrivateKey>)>&
           continue_callback);
 
-#if !defined(OS_ANDROID)
+#if !defined(OS_FUCHSIA)
   // Returns the crash signal FD corresponding to the current process type.
   int GetCrashSignalFD(const base::CommandLine& command_line);
 
+#if !defined(OS_ANDROID)
   // Creates a CrashHandlerHost instance for the given process type.
   breakpad::CrashHandlerHostLinux* CreateCrashHandlerHost(
       const std::string& process_type);
@@ -249,6 +250,7 @@
   // with OS for this).
   std::unique_ptr<MemoryPressureControllerImpl> memory_pressure_controller_;
 #endif  // !defined(OS_ANDROID)
+#endif  // !defined(OS_FUCHSIA)
 
 #if BUILDFLAG(IS_CAST_USING_CMA_BACKEND)
   // CMA thread used by AudioManager, MojoRenderer, and MediaPipelineBackend.
diff --git a/components/crash/android/BUILD.gn b/components/crash/android/BUILD.gn
index 1212d3de..c61e671 100644
--- a/components/crash/android/BUILD.gn
+++ b/components/crash/android/BUILD.gn
@@ -6,7 +6,6 @@
 
 _jni_sources = [
   "java/src/org/chromium/components/crash/browser/ChildProcessCrashObserver.java",
-  "java/src/org/chromium/components/crash/browser/CrashDumpManager.java",
   "java/src/org/chromium/components/crash/browser/PackagePaths.java",
   "java/src/org/chromium/components/crash/CrashKeys.java",
 ]
@@ -42,18 +41,6 @@
   ]
 }
 
-android_library("javatests") {
-  testonly = true
-  deps = [
-    ":java",
-    "//base:base_java",
-    "//base:base_java_test_support",
-    "//third_party/android_support_test_runner:runner_java",
-    "//third_party/junit",
-  ]
-  java_files = [ "javatests/src/org/chromium/components/crash/browser/CrashDumpManagerTest.java" ]
-}
-
 source_set("unit_tests") {
   testonly = true
   sources = [
diff --git a/components/crash/android/java/src/org/chromium/components/crash/browser/CrashDumpManager.java b/components/crash/android/java/src/org/chromium/components/crash/browser/CrashDumpManager.java
deleted file mode 100644
index 4955561..0000000
--- a/components/crash/android/java/src/org/chromium/components/crash/browser/CrashDumpManager.java
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2017 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.components.crash.browser;
-
-import org.chromium.base.Log;
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.annotations.CalledByNative;
-
-import java.io.File;
-
-/**
- * A Java-side bridge for continuing the upload processing for child process crash minidumps.
- */
-public class CrashDumpManager {
-    private static final String TAG = "CrashDumpManager";
-
-    /**
-     * An interface for providing a callback that will try to upload a minidump. The callback should
-     * be registered on, and will be run on, the UI thread.
-     */
-    public interface UploadMinidumpCallback { public void tryToUploadMinidump(File minidump); }
-
-    /**
-     * The globally registered callback for uploading minidumps, or null if no callback has been
-     * registered yet.
-     */
-    private static UploadMinidumpCallback sCallback;
-
-    /**
-     * Registers a callback for uploading minidumps. May be called at most once, and only on the UI
-     * thread.
-     *
-     * @param callback The callback to trigger when a new minidump is generated by a child process.
-     */
-    public static void registerUploadCallback(UploadMinidumpCallback callback) {
-        ThreadUtils.assertOnUiThread();
-        assert sCallback == null;
-        sCallback = callback;
-    }
-
-    /**
-     * Attempts to upload the specified child process minidump (or a no-op if no observer has been
-     * registered).
-     *
-     * @param minidumpPath The file path for the generated minidump.
-     */
-    @CalledByNative
-    public static void tryToUploadMinidump(String minidumpPath) {
-        // The C++ code that calls into this method should be running on a background thread. It's
-        // important to be off the UI thread for the file operations done below.
-        ThreadUtils.assertOnBackgroundThread();
-
-        if (minidumpPath == null) {
-            Log.e(TAG, "Minidump path should be non-null! Bailing...");
-            return;
-        }
-
-        final File minidump = new File(minidumpPath);
-        if (!minidump.exists() || !minidump.isFile()) {
-            Log.e(TAG,
-                    "Minidump path '" + minidumpPath
-                            + "' should describe a file that exists! Bailing...");
-            return;
-        }
-
-        // The callback should only be accessed on the UI thread.
-        ThreadUtils.postOnUiThread(new Runnable() {
-            @Override
-            public void run() {
-                if (sCallback == null) {
-                    Log.w(TAG, "Ignoring crash observed before a callback was registered...");
-                    return;
-                }
-                sCallback.tryToUploadMinidump(minidump);
-            }
-        });
-    }
-}
diff --git a/components/crash/android/javatests/src/org/chromium/components/crash/browser/CrashDumpManagerTest.java b/components/crash/android/javatests/src/org/chromium/components/crash/browser/CrashDumpManagerTest.java
deleted file mode 100644
index cbcbaf1..0000000
--- a/components/crash/android/javatests/src/org/chromium/components/crash/browser/CrashDumpManagerTest.java
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2017 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.components.crash.browser;
-
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import org.chromium.base.ContextUtils;
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.test.BaseJUnit4ClassRunner;
-import org.chromium.base.test.util.DisabledTest;
-import org.chromium.base.test.util.Feature;
-import org.chromium.base.test.util.TestFileUtil;
-
-import java.io.File;
-import java.io.IOException;
-
-/**
- * Unittests for {@link CrashDumpManager}.
- */
-@RunWith(BaseJUnit4ClassRunner.class)
-public class CrashDumpManagerTest {
-    File mTempDir;
-
-    @Before
-    public void setUp() throws Exception {
-        ContextUtils.initApplicationContextForTests(InstrumentationRegistry.getInstrumentation()
-                                                            .getTargetContext()
-                                                            .getApplicationContext());
-        mTempDir = ContextUtils.getApplicationContext().getCacheDir();
-        assert mTempDir.exists();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        File[] files = mTempDir.listFiles();
-        if (files == null) return;
-
-        for (File file : files) {
-            TestFileUtil.deleteFile(file);
-        }
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Android-AppBase"})
-    @DisabledTest // Flaky, crbug.com/725379.
-    public void testUploadMinidump_NoCallback() throws IOException {
-        File minidump = new File(mTempDir, "mini.dmp");
-        Assert.assertTrue(minidump.createNewFile());
-
-        CrashDumpManager.tryToUploadMinidump(minidump.getAbsolutePath());
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Android-AppBase"})
-    @DisabledTest // Flaky, crbug.com/725379.
-    public void testUploadMinidump_NullMinidumpPath() {
-        registerUploadCallback(new CrashDumpManager.UploadMinidumpCallback() {
-            @Override
-            public void tryToUploadMinidump(File minidump) {
-                Assert.fail("The callback should not be called when the minidump path is null.");
-            }
-        });
-
-        CrashDumpManager.tryToUploadMinidump(null);
-    }
-
-    // @SmallTest
-    // @Feature({"Android-AppBase"})
-    @Test
-    @DisabledTest // Flaky, crbug.com/725379.
-    public void testUploadMinidump_FileDoesntExist() {
-        registerUploadCallback(new CrashDumpManager.UploadMinidumpCallback() {
-            @Override
-            public void tryToUploadMinidump(File minidump) {
-                Assert.fail(
-                        "The callback should not be called when the minidump file doesn't exist.");
-            }
-        });
-
-        CrashDumpManager.tryToUploadMinidump(
-                mTempDir.getAbsolutePath() + "/some/file/that/doesnt/exist");
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Android-AppBase"})
-    @DisabledTest // Flaky, crbug.com/725379.
-    public void testUploadMinidump_MinidumpPathIsDirectory() throws IOException {
-        File directory = new File(mTempDir, "a_directory");
-        Assert.assertTrue(directory.mkdir());
-
-        registerUploadCallback(new CrashDumpManager.UploadMinidumpCallback() {
-            @Override
-            public void tryToUploadMinidump(File minidump) {
-                Assert.fail(
-                        "The callback should not be called when the minidump path is not a file.");
-            }
-        });
-
-        CrashDumpManager.tryToUploadMinidump(directory.getAbsolutePath());
-    }
-
-    @Test
-    @SmallTest
-    @Feature({"Android-AppBase"})
-    @DisabledTest // Flaky, crbug.com/725379.
-    public void testUploadMinidump_MinidumpPathIsValid() throws IOException {
-        final File minidump = new File(mTempDir, "mini.dmp");
-        Assert.assertTrue(minidump.createNewFile());
-
-        registerUploadCallback(new CrashDumpManager.UploadMinidumpCallback() {
-            @Override
-            public void tryToUploadMinidump(File actualMinidump) {
-                Assert.assertEquals("Should call the callback with the correct filename.", minidump,
-                        actualMinidump);
-            }
-        });
-
-        CrashDumpManager.tryToUploadMinidump(minidump.getAbsolutePath());
-    }
-
-    /**
-     * A convenience wrapper that registers the upload {@param callback}, running the registration
-     * on the UI thread, as expected by the CrashDumpManager code.
-     * @param callback The callback for uploading minidumps.
-     */
-    private static void registerUploadCallback(
-            final CrashDumpManager.UploadMinidumpCallback callback) {
-        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
-            @Override
-            public void run() {
-                CrashDumpManager.registerUploadCallback(callback);
-            }
-        });
-    }
-}
diff --git a/components/crash/content/app/BUILD.gn b/components/crash/content/app/BUILD.gn
index 851190e3..cd4dac9 100644
--- a/components/crash/content/app/BUILD.gn
+++ b/components/crash/content/app/BUILD.gn
@@ -36,17 +36,17 @@
     sources += [ "crashpad.cc" ]
   }
 
-  if (is_android || is_linux) {
-    # Want these files on both Linux and Android.
+  if (is_android || (is_linux && !is_chromeos)) {
     set_sources_assignment_filter([])
+    sources += [ "crashpad_linux.cc" ]
+  }
+
+  if (is_linux) {
     sources += [
       "breakpad_linux.cc",
       "breakpad_linux.h",
       "breakpad_linux_impl.h",
     ]
-    if (!is_chromeos) {
-      sources += [ "crashpad_linux.cc" ]
-    }
   }
 
   defines = [ "CRASH_IMPLEMENTATION" ]
@@ -77,9 +77,12 @@
       "//content/public/common:content_descriptors",
       "//content/public/common:result_codes",
       "//sandbox",
-      "//third_party/breakpad:client",
       "//third_party/crashpad/crashpad/snapshot",
     ]
+
+    if (is_linux) {
+      deps += [ "//third_party/breakpad:client" ]
+    }
   }
 
   if (is_win) {
diff --git a/components/crash/content/app/crash_reporter_client.cc b/components/crash/content/app/crash_reporter_client.cc
index f08b9b24..b3b09cee 100644
--- a/components/crash/content/app/crash_reporter_client.cc
+++ b/components/crash/content/app/crash_reporter_client.cc
@@ -36,7 +36,7 @@
 CrashReporterClient::CrashReporterClient() {}
 CrashReporterClient::~CrashReporterClient() {}
 
-#if !defined(OS_MACOSX) && !defined(OS_WIN)
+#if !defined(OS_MACOSX) && !defined(OS_WIN) && !defined(OS_ANDROID)
 void CrashReporterClient::SetCrashReporterClientIdFromGUID(
     const std::string& client_guid) {}
 #endif
@@ -152,6 +152,10 @@
   return 100;
 }
 
+bool CrashReporterClient::GetBrowserProcessType(std::string* ptype) {
+  return false;
+}
+
 int CrashReporterClient::GetAndroidMinidumpDescriptor() {
   return 0;
 }
diff --git a/components/crash/content/app/crash_reporter_client.h b/components/crash/content/app/crash_reporter_client.h
index 33a946a..caebf67 100644
--- a/components/crash/content/app/crash_reporter_client.h
+++ b/components/crash/content/app/crash_reporter_client.h
@@ -36,14 +36,14 @@
   CrashReporterClient();
   virtual ~CrashReporterClient();
 
-#if !defined(OS_MACOSX) && !defined(OS_WIN)
+#if !defined(OS_MACOSX) && !defined(OS_WIN) && !defined(OS_ANDROID)
   // Sets the crash reporting client ID, a unique identifier for the client
   // that is sending crash reports. After it is set, it should not be changed.
   // |client_guid| may either be a full GUID or a GUID that was already stripped
   // from its dashes.
   //
-  // On Mac OS X and Windows, this is the responsibility of Crashpad, and can
-  // not be set directly by the client.
+  // On macOS, Windows, and Android this is the responsibility of Crashpad, and
+  // can not be set directly by the client.
   virtual void SetCrashReporterClientIdFromGUID(const std::string& client_guid);
 #endif
 
@@ -158,6 +158,10 @@
   // percentage.
   virtual unsigned int GetCrashDumpPercentageForWebView();
 
+  // Returns true if |ptype| was set to a value to override the default `ptype`
+  // annotation used for the browser process.
+  virtual bool GetBrowserProcessType(std::string* ptype);
+
   // Returns the descriptor key of the android minidump global descriptor.
   virtual int GetAndroidMinidumpDescriptor();
 
diff --git a/components/crash/content/app/crashpad.cc b/components/crash/content/app/crashpad.cc
index 0981ca31..a04a4d84 100644
--- a/components/crash/content/app/crashpad.cc
+++ b/components/crash/content/app/crashpad.cc
@@ -271,6 +271,12 @@
 }
 #endif
 
+#if defined(OS_LINUX) || defined(OS_ANDROID)
+void CrashWithoutDumping(const std::string& message) {
+  crashpad::CrashpadClient::CrashWithoutDump(message);
+}
+#endif  // defined(OS_LINUX) || defined(OS_ANDROID)
+
 void GetReports(std::vector<Report>* reports) {
 #if defined(OS_WIN)
   // On Windows, the crash client may be linked into another module, which
diff --git a/components/crash/content/app/crashpad.h b/components/crash/content/app/crashpad.h
index 847b6f0..c16f6b87 100644
--- a/components/crash/content/app/crashpad.h
+++ b/components/crash/content/app/crashpad.h
@@ -130,6 +130,12 @@
 
 void DumpWithoutCrashing();
 
+#if defined(OS_LINUX) || defined(OS_ANDROID)
+// Logs message and immediately crashes the current process without triggering a
+// crash dump.
+void CrashWithoutDumping(const std::string& message);
+#endif  // defined(OS_LINUX) || defined(OS_ANDROID)
+
 // Returns the Crashpad database path, only valid in the browser.
 base::FilePath GetCrashpadDatabasePath();
 
diff --git a/components/crash/content/app/crashpad_linux.cc b/components/crash/content/app/crashpad_linux.cc
index 79b19cc..d13f851 100644
--- a/components/crash/content/app/crashpad_linux.cc
+++ b/components/crash/content/app/crashpad_linux.cc
@@ -466,6 +466,13 @@
     BuildHandlerArgs(client, &database_path, &metrics_path, &url,
                      &process_annotations, &arguments);
 
+#if defined(OS_ANDROID)
+    std::string browser_ptype;
+    if (GetCrashReporterClient()->GetBrowserProcessType(&browser_ptype)) {
+      process_annotations["ptype"] = browser_ptype;
+    }
+#endif  // defined(OS_ANDROID)
+
     base::FilePath exe_dir;
     base::FilePath handler_path;
     if (!GetHandlerPath(&exe_dir, &handler_path)) {
diff --git a/components/crash/content/browser/BUILD.gn b/components/crash/content/browser/BUILD.gn
index d3dbf58..0f38a770 100644
--- a/components/crash/content/browser/BUILD.gn
+++ b/components/crash/content/browser/BUILD.gn
@@ -15,8 +15,6 @@
     "child_exit_observer_android.h",
     "child_process_crash_observer_android.cc",
     "child_process_crash_observer_android.h",
-    "crash_dump_manager_android.cc",
-    "crash_dump_manager_android.h",
     "crash_memory_metrics_collector_android.cc",
     "crash_memory_metrics_collector_android.h",
     "crash_metrics_reporter_android.cc",
@@ -28,7 +26,6 @@
     "//components/crash/content/app",
     "//content/public/browser",
     "//content/public/common",
-    "//third_party/breakpad:client",
   ]
 
   if (is_linux || is_android) {
@@ -39,10 +36,14 @@
       "crash_handler_host_linux.cc",
       "crash_handler_host_linux.h",
     ]
+  }
+
+  if (!is_chromeos) {
+    deps += [ "//third_party/crashpad/crashpad/client" ]
+  }
+
+  if (!is_android) {
     deps += [ "//third_party/breakpad:client" ]
-    if (!is_chromeos) {
-      deps += [ "//third_party/crashpad/crashpad/client" ]
-    }
   }
 
   # This is not in the GYP build but this target includes breakpad client
@@ -63,7 +64,6 @@
 source_set("unit_tests") {
   testonly = true
   sources = [
-    "crash_dump_manager_android_unittest.cc",
     "crash_metrics_reporter_android_unittest.cc",
   ]
   deps = [
diff --git a/components/crash/content/browser/child_exit_observer_android.cc b/components/crash/content/browser/child_exit_observer_android.cc
index 5d9aa4c6..cd62274d37 100644
--- a/components/crash/content/browser/child_exit_observer_android.cc
+++ b/components/crash/content/browser/child_exit_observer_android.cc
@@ -129,20 +129,6 @@
   }
 }
 
-void ChildExitObserver::BrowserChildProcessStarted(
-    int process_host_id,
-    content::PosixFileDescriptorInfo* mappings) {
-  std::vector<Client*> registered_clients_copy;
-  {
-    base::AutoLock auto_lock(registered_clients_lock_);
-    for (auto& client : registered_clients_)
-      registered_clients_copy.push_back(client.get());
-  }
-  for (auto* client : registered_clients_copy) {
-    client->OnChildStart(process_host_id, mappings);
-  }
-}
-
 void ChildExitObserver::BrowserChildProcessHostDisconnected(
     const content::ChildProcessData& data) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -230,12 +216,18 @@
       return;
   }
   const auto& iter = process_host_id_to_pid_.find(rph->GetID());
-  if (iter != process_host_id_to_pid_.end()) {
-    if (info.pid == base::kNullProcessHandle) {
-      info.pid = iter->second;
-    }
-    process_host_id_to_pid_.erase(iter);
+  // NOTIFICATION_RENDERER_PROCESS_CLOSED corresponds to death of an underlying
+  // RenderProcess. NOTIFICATION_RENDERER_PROCESS_TERMINATED corresponds to when
+  // the RenderProcessHost's lifetime is ending. Ideally, we'd only listen to
+  // the former, but if the RenderProcessHost is destroyed before the
+  // RenderProcess, then the former is never sent.
+  if (iter == process_host_id_to_pid_.end()) {
+    return;
   }
+  if (info.pid == base::kNullProcessHandle) {
+    info.pid = iter->second;
+  }
+  process_host_id_to_pid_.erase(iter);
   OnChildExit(&info);
 }
 
diff --git a/components/crash/content/browser/child_exit_observer_android.h b/components/crash/content/browser/child_exit_observer_android.h
index adbccc4..161d2e8 100644
--- a/components/crash/content/browser/child_exit_observer_android.h
+++ b/components/crash/content/browser/child_exit_observer_android.h
@@ -12,7 +12,6 @@
 #include "base/android/application_status_listener.h"
 #include "base/android/child_process_binding_types.h"
 #include "base/lazy_instance.h"
-#include "base/memory/ref_counted.h"
 #include "base/process/process.h"
 #include "base/scoped_observer.h"
 #include "base/synchronization/lock.h"
@@ -20,7 +19,6 @@
 #include "content/public/browser/browser_child_process_observer.h"
 #include "content/public/browser/notification_observer.h"
 #include "content/public/browser/notification_registrar.h"
-#include "content/public/browser/posix_file_descriptor_info.h"
 #include "content/public/common/child_process_host.h"
 #include "content/public/common/process_type.h"
 #include "third_party/blink/public/common/oom_intervention/oom_intervention_types.h"
@@ -46,7 +44,6 @@
     TerminationInfo(const TerminationInfo& other);
     TerminationInfo& operator=(const TerminationInfo& other);
 
-    // TODO(jperaza): Not valid until Crashpad is enabled.
     bool is_crashed() const { return crash_signo != kInvalidSigno; }
 
     int process_host_id = content::ChildProcessHost::kInvalidUniqueID;
@@ -55,7 +52,6 @@
     base::android::ApplicationState app_state =
         base::android::APPLICATION_STATE_UNKNOWN;
 
-    // TODO(jperaza): Not valid until Crashpad is enabled.
     // The crash signal the child process received before it exited.
     int crash_signo = kInvalidSigno;
 
@@ -109,9 +105,6 @@
   // process type.
   class Client {
    public:
-    // OnChildStart is called on the launcher thread.
-    virtual void OnChildStart(int process_host_id,
-                              content::PosixFileDescriptorInfo* mappings) = 0;
     // OnChildExit is called on the UI thread.
     // OnChildExit may be called twice for the same process.
     virtual void OnChildExit(const TerminationInfo& info) = 0;
@@ -134,14 +127,6 @@
   // crashpad::CrashHandlerHost::Observer
   void ChildReceivedCrashSignal(base::ProcessId pid, int signo) override;
 
-  // BrowserChildProcessStarted must be called from
-  // ContentBrowserClient::GetAdditionalMappedFilesForChildProcess
-  // overrides, to notify the ChildExitObserver of child process
-  // creation, and to allow clients to register any fd mappings they
-  // need.
-  void BrowserChildProcessStarted(int process_host_id,
-                                  content::PosixFileDescriptorInfo* mappings);
-
  private:
   friend struct base::LazyInstanceTraitsBase<ChildExitObserver>;
 
diff --git a/components/crash/content/browser/child_process_crash_observer_android.cc b/components/crash/content/browser/child_process_crash_observer_android.cc
index e235ba3..cd46b75b 100644
--- a/components/crash/content/browser/child_process_crash_observer_android.cc
+++ b/components/crash/content/browser/child_process_crash_observer_android.cc
@@ -4,47 +4,45 @@
 
 #include "components/crash/content/browser/child_process_crash_observer_android.h"
 
-#include <utility>
-
+#include "base/android/jni_android.h"
 #include "base/bind.h"
-#include "base/files/file_util.h"
 #include "base/task/post_task.h"
-#include "components/crash/content/app/breakpad_linux.h"
-#include "components/crash/content/browser/crash_dump_manager_android.h"
+#include "base/task/task_traits.h"
+#include "base/threading/scoped_blocking_call.h"
+#include "components/crash/content/browser/crash_metrics_reporter_android.h"
+#include "jni/ChildProcessCrashObserver_jni.h"
 
 namespace crash_reporter {
 
-ChildProcessCrashObserver::ChildProcessCrashObserver(
-    const base::FilePath crash_dump_dir,
-    int descriptor_id)
-    : crash_dump_dir_(crash_dump_dir), descriptor_id_(descriptor_id) {}
-
-ChildProcessCrashObserver::~ChildProcessCrashObserver() {}
-
-void ChildProcessCrashObserver::OnChildStart(
-    int process_host_id,
-    content::PosixFileDescriptorInfo* mappings) {
-  if (!breakpad::IsCrashReporterEnabled())
-    return;
-
-  base::ScopedFD file(
-      breakpad::CrashDumpManager::GetInstance()->CreateMinidumpFileForChild(
-          process_host_id));
-  if (file.is_valid())
-    mappings->Transfer(descriptor_id_, std::move(file));
+ChildProcessCrashObserver::ChildProcessCrashObserver() {
+  task_runner_ = base::CreateSequencedTaskRunnerWithTraits(
+      {base::MayBlock(), base::TaskPriority::BEST_EFFORT});
 }
 
+ChildProcessCrashObserver::~ChildProcessCrashObserver() = default;
+
 void ChildProcessCrashObserver::OnChildExit(
     const ChildExitObserver::TerminationInfo& info) {
-  // This might be called twice for a given child process, with a
-  // NOTIFICATION_RENDERER_PROCESS_TERMINATED and then with
-  // NOTIFICATION_RENDERER_PROCESS_CLOSED.
+  task_runner_->PostTask(
+      FROM_HERE, base::BindOnce(&ChildProcessCrashObserver::OnChildExitImpl,
+                                base::Unretained(this), info));
+}
 
-  base::PostTaskWithTraits(
-      FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
-      base::Bind(&breakpad::CrashDumpManager::ProcessMinidumpFileFromChild,
-                 base::Unretained(breakpad::CrashDumpManager::GetInstance()),
-                 crash_dump_dir_, info));
+void ChildProcessCrashObserver::OnChildExitImpl(
+    const ChildExitObserver::TerminationInfo& info) {
+  crash_reporter::CrashMetricsReporter::GetInstance()->ChildProcessExited(info);
+
+  if (!info.is_crashed()) {
+    return;
+  }
+
+  base::ScopedBlockingCall sbc(base::BlockingType::WILL_BLOCK);
+
+  // Hop over to Java to attempt to attach the logcat to the crash. This may
+  // fail, which is ok -- if it does, the crash will still be uploaded on the
+  // next browser start.
+  JNIEnv* env = base::android::AttachCurrentThread();
+  Java_ChildProcessCrashObserver_childCrashed(env, info.pid);
 }
 
 }  // namespace crash_reporter
diff --git a/components/crash/content/browser/child_process_crash_observer_android.h b/components/crash/content/browser/child_process_crash_observer_android.h
index 7710e6f..a401459 100644
--- a/components/crash/content/browser/child_process_crash_observer_android.h
+++ b/components/crash/content/browser/child_process_crash_observer_android.h
@@ -5,28 +5,28 @@
 #ifndef COMPONENTS_CRASH_CONTENT_BROWSER_CHILD_PROCESS_CRASH_OBSERVER_ANDROID_H_
 #define COMPONENTS_CRASH_CONTENT_BROWSER_CHILD_PROCESS_CRASH_OBSERVER_ANDROID_H_
 
-#include "base/files/file_path.h"
+#include "base/macros.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/sequenced_task_runner.h"
 #include "components/crash/content/browser/child_exit_observer_android.h"
 
 namespace crash_reporter {
 
+// Records metrics and initiates minidump upload in response to child process
+// crashes.
 class ChildProcessCrashObserver
     : public crash_reporter::ChildExitObserver::Client {
  public:
-  ChildProcessCrashObserver(const base::FilePath crash_dump_dir,
-                            int descriptor_id);
+  ChildProcessCrashObserver();
   ~ChildProcessCrashObserver() override;
 
   // crash_reporter::ChildExitObserver::Client implementation:
-  void OnChildStart(int process_host_id,
-                    content::PosixFileDescriptorInfo* mappings) override;
   void OnChildExit(const ChildExitObserver::TerminationInfo& info) override;
 
  private:
-  base::FilePath crash_dump_dir_;
-  // The id used to identify the file descriptor in the set of file
-  // descriptor mappings passed to the child process.
-  int descriptor_id_;
+  void OnChildExitImpl(const ChildExitObserver::TerminationInfo& info);
+
+  scoped_refptr<base::SequencedTaskRunner> task_runner_;
 
   DISALLOW_COPY_AND_ASSIGN(ChildProcessCrashObserver);
 };
diff --git a/components/crash/content/browser/crash_dump_manager_android.cc b/components/crash/content/browser/crash_dump_manager_android.cc
deleted file mode 100644
index 07132888..0000000
--- a/components/crash/content/browser/crash_dump_manager_android.cc
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright 2013 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 "components/crash/content/browser/crash_dump_manager_android.h"
-
-#include <stdint.h>
-
-#include <string>
-
-#include "base/android/jni_android.h"
-#include "base/android/jni_string.h"
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/files/file_util.h"
-#include "base/format_macros.h"
-#include "base/lazy_instance.h"
-#include "base/logging.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/process/process.h"
-#include "base/rand_util.h"
-#include "base/stl_util.h"
-#include "base/strings/stringprintf.h"
-#include "base/threading/scoped_blocking_call.h"
-#include "components/crash/content/app/breakpad_linux.h"
-#include "components/crash/content/browser/crash_metrics_reporter_android.h"
-#include "jni/CrashDumpManager_jni.h"
-
-namespace breakpad {
-
-namespace {
-
-base::LazyInstance<CrashDumpManager>::Leaky g_instance =
-    LAZY_INSTANCE_INITIALIZER;
-
-class DefaultUploader : public CrashDumpManager::Uploader {
- public:
-  DefaultUploader() = default;
-  ~DefaultUploader() override = default;
-
-  // CrashDumpManager::Uploader:
-  void TryToUploadCrashDump(const base::FilePath& crash_dump_path) override {
-    // Hop over to Java to attempt to attach the logcat to the crash. This may
-    // fail, which is ok -- if it does, the crash will still be uploaded on the
-    // next browser start.
-    JNIEnv* env = base::android::AttachCurrentThread();
-    base::android::ScopedJavaLocalRef<jstring> j_dump_path =
-        base::android::ConvertUTF8ToJavaString(env, crash_dump_path.value());
-    Java_CrashDumpManager_tryToUploadMinidump(env, j_dump_path);
-  }
-};
-
-}  // namespace
-
-// static
-CrashDumpManager* CrashDumpManager::GetInstance() {
-  return g_instance.Pointer();
-}
-
-CrashDumpManager::CrashDumpManager()
-    : uploader_(std::make_unique<DefaultUploader>()) {}
-
-CrashDumpManager::~CrashDumpManager() {}
-
-base::ScopedFD CrashDumpManager::CreateMinidumpFileForChild(
-    int process_host_id) {
-  base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
-  base::FilePath minidump_path;
-  if (!base::CreateTemporaryFile(&minidump_path)) {
-    LOG(ERROR) << "Failed to create temporary file, crash won't be reported.";
-    return base::ScopedFD();
-  }
-
-  // We need read permission as the minidump is generated in several phases
-  // and needs to be read at some point.
-  int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
-              base::File::FLAG_WRITE;
-  base::File minidump_file(minidump_path, flags);
-  if (!minidump_file.IsValid()) {
-    LOG(ERROR) << "Failed to open temporary file, crash won't be reported.";
-    return base::ScopedFD();
-  }
-
-  SetMinidumpPath(process_host_id, minidump_path);
-  return base::ScopedFD(minidump_file.TakePlatformFile());
-}
-
-void CrashDumpManager::ProcessMinidumpFileFromChild(
-    base::FilePath crash_dump_dir,
-    const crash_reporter::ChildExitObserver::TerminationInfo& info) {
-  CrashDumpManager::CrashDumpStatus status =
-      ProcessMinidumpFileFromChildInternal(crash_dump_dir, info);
-  crash_reporter::CrashMetricsReporter::GetInstance()->CrashDumpProcessed(
-      info, status);
-}
-
-CrashDumpManager::CrashDumpStatus
-CrashDumpManager::ProcessMinidumpFileFromChildInternal(
-    base::FilePath crash_dump_dir,
-    const crash_reporter::ChildExitObserver::TerminationInfo& info) {
-  base::FilePath minidump_path;
-  // If the minidump for a given child process has already been
-  // processed, then there is no more work to do.
-  if (!GetMinidumpPath(info.process_host_id, &minidump_path)) {
-    return CrashDumpStatus::kMissingDump;
-  }
-
-  int64_t file_size = 0;
-
-  base::ScopedBlockingCall scoped_blocking_call(base::BlockingType::MAY_BLOCK);
-  if (!base::PathExists(minidump_path)) {
-    LOG(ERROR) << "minidump does not exist " << minidump_path.value();
-    return CrashDumpStatus::kMissingDump;
-  }
-
-  int r = base::GetFileSize(minidump_path, &file_size);
-  DCHECK(r) << "Failed to retrieve size for minidump " << minidump_path.value();
-
-  if (file_size == 0) {
-    // Empty minidump, this process did not crash. Just remove the file.
-    r = base::DeleteFile(minidump_path, false);
-    DCHECK(r) << "Failed to delete temporary minidump file "
-              << minidump_path.value();
-    return CrashDumpStatus::kEmptyDump;
-  }
-
-  // We are dealing with a valid minidump. Copy it to the crash report
-  // directory from where Java code will upload it later on.
-  if (crash_dump_dir.empty()) {
-    NOTREACHED() << "Failed to retrieve the crash dump directory.";
-    return CrashDumpStatus::kDumpProcessingFailed;
-  }
-  const uint64_t rand = base::RandUint64();
-  const std::string filename =
-      base::StringPrintf("chromium-renderer-minidump-%016" PRIx64 ".dmp%d",
-                         rand, info.process_host_id);
-  base::FilePath dest_path = crash_dump_dir.Append(filename);
-  r = base::Move(minidump_path, dest_path);
-  if (!r) {
-    LOG(ERROR) << "Failed to move crash dump from " << minidump_path.value()
-               << " to " << dest_path.value();
-    base::DeleteFile(minidump_path, false);
-    return CrashDumpStatus::kDumpProcessingFailed;
-  }
-  VLOG(1) << "Crash minidump successfully generated: " << dest_path.value();
-
-  uploader_->TryToUploadCrashDump(dest_path);
-  return CrashDumpStatus::kValidDump;
-}
-
-void CrashDumpManager::SetMinidumpPath(int process_host_id,
-                                       const base::FilePath& minidump_path) {
-  base::AutoLock auto_lock(process_host_id_to_minidump_path_lock_);
-  DCHECK(
-      !base::ContainsKey(process_host_id_to_minidump_path_, process_host_id));
-  process_host_id_to_minidump_path_[process_host_id] = minidump_path;
-}
-
-bool CrashDumpManager::GetMinidumpPath(int process_host_id,
-                                       base::FilePath* minidump_path) {
-  base::AutoLock auto_lock(process_host_id_to_minidump_path_lock_);
-  ChildProcessIDToMinidumpPath::iterator iter =
-      process_host_id_to_minidump_path_.find(process_host_id);
-  if (iter == process_host_id_to_minidump_path_.end()) {
-    return false;
-  }
-  *minidump_path = iter->second;
-  process_host_id_to_minidump_path_.erase(iter);
-  return true;
-}
-
-}  // namespace breakpad
diff --git a/components/crash/content/browser/crash_dump_manager_android.h b/components/crash/content/browser/crash_dump_manager_android.h
deleted file mode 100644
index bc10af0..0000000
--- a/components/crash/content/browser/crash_dump_manager_android.h
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2013 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.
-
-#ifndef COMPONENTS_CRASH_CONTENT_BROWSER_CRASH_DUMP_MANAGER_ANDROID_H_
-#define COMPONENTS_CRASH_CONTENT_BROWSER_CRASH_DUMP_MANAGER_ANDROID_H_
-
-#include <map>
-#include <memory>
-#include <utility>
-
-#include "base/android/application_status_listener.h"
-#include "base/files/file_path.h"
-#include "base/files/platform_file.h"
-#include "base/lazy_instance.h"
-#include "base/memory/ref_counted.h"
-#include "base/synchronization/lock.h"
-#include "components/crash/content/browser/child_exit_observer_android.h"
-#include "content/public/common/child_process_host.h"
-#include "content/public/common/process_type.h"
-
-namespace breakpad {
-
-// This class manages the crash minidumps.
-// On Android, because of process isolation, each renderer process runs with a
-// different UID. As a result, we cannot generate the minidumps in the browser
-// (as the browser process does not have access to some system files for the
-// crashed process). So the minidump is generated in the renderer process.
-// Since the isolated process cannot open files, we provide it on creation with
-// a file descriptor into which to write the minidump in the event of a crash.
-// This class creates these file descriptors and associates them with render
-// processes and takes the appropriate action when the render process
-// terminates.
-class CrashDumpManager {
- public:
-  enum class CrashDumpStatus {
-    // The dump for this process did not have a path set. This can happen if the
-    // dump was already processed or if crash dump generation is not turned on.
-    kMissingDump,
-
-    // The crash dump was empty.
-    kEmptyDump,
-
-    // Minidump file was found, but could not be copied to crash dir.
-    kDumpProcessingFailed,
-
-    // The crash dump is valid.
-    kValidDump,
-  };
-
-  // Class which aids in uploading a crash dump.
-  class Uploader {
-   public:
-    virtual ~Uploader() = default;
-
-    // Attempts to upload the specified child process minidump.
-    virtual void TryToUploadCrashDump(
-        const base::FilePath& crash_dump_path) = 0;
-  };
-
-  static CrashDumpManager* GetInstance();
-
-  void ProcessMinidumpFileFromChild(
-      base::FilePath crash_dump_dir,
-      const crash_reporter::ChildExitObserver::TerminationInfo& info);
-
-  base::ScopedFD CreateMinidumpFileForChild(int process_host_id);
-
-  // Careful, |uploader_| is accessed on one of the task scheduler threads.
-  // Tests should set this before any other threads are spawned.
-  void set_uploader_for_testing(std::unique_ptr<Uploader> uploader) {
-    DCHECK(uploader);
-    uploader_ = std::move(uploader);
-  }
-
- private:
-  friend struct base::LazyInstanceTraitsBase<CrashDumpManager>;
-
-  CrashDumpManager();
-  ~CrashDumpManager();
-
-  CrashDumpStatus ProcessMinidumpFileFromChildInternal(
-      base::FilePath crash_dump_dir,
-      const crash_reporter::ChildExitObserver::TerminationInfo& info);
-
-  typedef std::map<int, base::FilePath> ChildProcessIDToMinidumpPath;
-
-  void SetMinidumpPath(int process_host_id,
-                       const base::FilePath& minidump_path);
-  bool GetMinidumpPath(int process_host_id, base::FilePath* minidump_path);
-
-  // Should never be nullptr.
-  std::unique_ptr<Uploader> uploader_;
-
-  // This map should only be accessed with its lock aquired as it is accessed
-  // from the PROCESS_LAUNCHER and UI threads.
-  base::Lock process_host_id_to_minidump_path_lock_;
-  ChildProcessIDToMinidumpPath process_host_id_to_minidump_path_;
-
-  DISALLOW_COPY_AND_ASSIGN(CrashDumpManager);
-};
-
-}  // namespace breakpad
-
-#endif  // COMPONENTS_CRASH_CONTENT_BROWSER_CRASH_DUMP_MANAGER_ANDROID_H_
diff --git a/components/crash/content/browser/crash_dump_manager_android_unittest.cc b/components/crash/content/browser/crash_dump_manager_android_unittest.cc
deleted file mode 100644
index 0b284e1..0000000
--- a/components/crash/content/browser/crash_dump_manager_android_unittest.cc
+++ /dev/null
@@ -1,160 +0,0 @@
-// Copyright 2017 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 "components/crash/content/browser/crash_dump_manager_android.h"
-
-#include <string>
-#include <utility>
-
-#include "base/at_exit.h"
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/callback.h"
-#include "base/files/file.h"
-#include "base/files/file_util.h"
-#include "base/files/scoped_file.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/macros.h"
-#include "base/memory/scoped_refptr.h"
-#include "base/optional.h"
-#include "base/run_loop.h"
-#include "base/sequenced_task_runner.h"
-#include "base/task/post_task.h"
-#include "base/test/metrics/histogram_tester.h"
-#include "base/test/scoped_task_environment.h"
-#include "base/threading/sequenced_task_runner_handle.h"
-#include "base/threading/thread_restrictions.h"
-#include "components/crash/content/browser/crash_metrics_reporter_android.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace breakpad {
-
-class CrashDumpManagerTest;
-
-class CrashMetricsReporterObserver
-    : public crash_reporter::CrashMetricsReporter::Observer {
- public:
-  CrashMetricsReporterObserver() {}
-  ~CrashMetricsReporterObserver() {}
-
-  // crash_reporter::CrashMetricsReporter::Observer:
-  void OnCrashDumpProcessed(
-      int rph_id,
-      const crash_reporter::CrashMetricsReporter::ReportedCrashTypeSet&
-          reported_counts) override {
-    wait_run_loop_.QuitClosure().Run();
-  }
-
-  void WaitForProcessed() { wait_run_loop_.Run(); }
-
- private:
-  base::RunLoop wait_run_loop_;
-  DISALLOW_COPY_AND_ASSIGN(CrashMetricsReporterObserver);
-};
-
-class NoOpUploader : public CrashDumpManager::Uploader {
- public:
-  NoOpUploader(scoped_refptr<base::SequencedTaskRunner> test_runner,
-               CrashDumpManagerTest* test_harness)
-      : test_runner_(std::move(test_runner)), test_harness_(test_harness) {}
-  ~NoOpUploader() override = default;
-
-  // CrashDumpManager::Uploader:
-  void TryToUploadCrashDump(const base::FilePath& crash_dump_path) override;
-
- private:
-  scoped_refptr<base::SequencedTaskRunner> test_runner_;
-  CrashDumpManagerTest* test_harness_;
-  DISALLOW_COPY_AND_ASSIGN(NoOpUploader);
-};
-
-class CrashDumpManagerTest : public testing::Test {
- public:
-  CrashDumpManagerTest()
-      : scoped_environment_(
-            base::test::ScopedTaskEnvironment::MainThreadType::UI) {}
-  ~CrashDumpManagerTest() override {}
-
-  void SetUp() override {
-    // Initialize the manager.
-    ASSERT_TRUE(CrashDumpManager::GetInstance());
-    CrashDumpManager::GetInstance()->set_uploader_for_testing(
-        std::make_unique<NoOpUploader>(base::SequencedTaskRunnerHandle::Get(),
-                                       this));
-  }
-
-  void OnUploadedCrashDump() {
-    dumps_uploaded_++;
-    if (!upload_waiter_.is_null())
-      std::move(upload_waiter_).Run();
-  }
-
-  void WaitForCrashDumpsUploaded(int num_dumps) {
-    EXPECT_LE(num_dumps, dumps_uploaded_);
-    while (num_dumps < dumps_uploaded_) {
-      base::RunLoop run_loop;
-      upload_waiter_ = run_loop.QuitClosure();
-      run_loop.Run();
-    }
-  }
-
-  static void CreateAndProcessCrashDump(
-      const crash_reporter::ChildExitObserver::TerminationInfo& info,
-      const std::string& data) {
-    base::ScopedFD fd =
-        CrashDumpManager::GetInstance()->CreateMinidumpFileForChild(
-            info.process_host_id);
-    EXPECT_TRUE(fd.is_valid());
-    base::WriteFileDescriptor(fd.get(), data.data(), data.size());
-    base::ScopedTempDir dump_dir;
-    EXPECT_TRUE(dump_dir.CreateUniqueTempDir());
-    CrashDumpManager::GetInstance()->ProcessMinidumpFileFromChild(
-        dump_dir.GetPath(), info);
-  }
-
- protected:
-  int dumps_uploaded_ = 0;
-
- private:
-  base::ShadowingAtExitManager at_exit_;
-  base::test::ScopedTaskEnvironment scoped_environment_;
-  base::OnceClosure upload_waiter_;
-  DISALLOW_COPY_AND_ASSIGN(CrashDumpManagerTest);
-};
-
-void NoOpUploader::TryToUploadCrashDump(const base::FilePath& crash_dump_path) {
-  test_runner_->PostTask(
-      FROM_HERE, base::BindOnce(&CrashDumpManagerTest::OnUploadedCrashDump,
-                                base::Unretained(test_harness_)));
-}
-
-TEST_F(CrashDumpManagerTest, NonOomCrash) {
-  base::HistogramTester histogram_tester;
-
-  CrashMetricsReporterObserver observer;
-  crash_reporter::CrashMetricsReporter::GetInstance()->AddObserver(&observer);
-
-  crash_reporter::ChildExitObserver::TerminationInfo termination_info;
-  termination_info.process_host_id = 1;
-  termination_info.pid = base::kNullProcessHandle;
-  termination_info.process_type = content::PROCESS_TYPE_RENDERER;
-  termination_info.app_state =
-      base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES;
-  termination_info.normal_termination = false;
-  termination_info.binding_state = base::android::ChildBindingState::STRONG;
-  termination_info.was_killed_intentionally_by_browser = false;
-  termination_info.was_oom_protected_status = true;
-  base::PostTaskWithTraits(
-      FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
-      base::BindOnce(&CrashDumpManagerTest::CreateAndProcessCrashDump,
-                     termination_info, "Some non-empty crash data"));
-  observer.WaitForProcessed();
-
-  histogram_tester.ExpectUniqueSample(
-      "Tab.RendererDetailedExitStatus",
-      crash_reporter::CrashMetricsReporter::VALID_MINIDUMP_WHILE_RUNNING, 1);
-  WaitForCrashDumpsUploaded(1);
-}
-
-}  // namespace breakpad
diff --git a/components/crash/content/browser/crash_metrics_reporter_android.cc b/components/crash/content/browser/crash_metrics_reporter_android.cc
index bf6d85a2..9ddeee9f 100644
--- a/components/crash/content/browser/crash_metrics_reporter_android.cc
+++ b/components/crash/content/browser/crash_metrics_reporter_android.cc
@@ -8,7 +8,7 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/metrics/user_metrics.h"
 #include "base/optional.h"
-#include "components/crash/content/browser/crash_dump_manager_android.h"
+#include "base/rand_util.h"
 
 namespace crash_reporter {
 namespace {
@@ -108,35 +108,17 @@
   async_observers_->RemoveObserver(observer);
 }
 
-void CrashMetricsReporter::CrashDumpProcessed(
-    const ChildExitObserver::TerminationInfo& info,
-    breakpad::CrashDumpManager::CrashDumpStatus status) {
+void CrashMetricsReporter::ChildProcessExited(
+    const ChildExitObserver::TerminationInfo& info) {
   ReportedCrashTypeSet reported_counts;
-
-  // Avoid duplicating processing for the same process.
-  if (status == breakpad::CrashDumpManager::CrashDumpStatus::kMissingDump)
-    return;
-
-  bool has_valid_dump = false;
-  switch (status) {
-    case breakpad::CrashDumpManager::CrashDumpStatus::kMissingDump:
-      NOTREACHED();
-      break;
-    case breakpad::CrashDumpManager::CrashDumpStatus::kEmptyDump:
-      has_valid_dump = false;
-      break;
-    case breakpad::CrashDumpManager::CrashDumpStatus::kValidDump:
-    case breakpad::CrashDumpManager::CrashDumpStatus::kDumpProcessingFailed:
-      has_valid_dump = true;
-      break;
-  }
+  const bool crashed = info.is_crashed();
   const bool app_foreground =
       info.app_state ==
           base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES ||
       info.app_state == base::android::APPLICATION_STATE_HAS_PAUSED_ACTIVITIES;
   const bool intentional_kill = info.was_killed_intentionally_by_browser;
   const bool android_oom_kill = !info.was_killed_intentionally_by_browser &&
-                                !has_valid_dump && !info.normal_termination;
+                                !crashed && !info.normal_termination;
   const bool renderer_visible = info.renderer_has_visible_clients;
   const bool renderer_subframe = info.renderer_was_subframe;
   const bool renderer_allocation_failed =
@@ -170,7 +152,7 @@
 
   if (info.process_type == content::PROCESS_TYPE_RENDERER && app_foreground) {
     if (renderer_visible) {
-      if (has_valid_dump) {
+      if (crashed) {
         ReportCrashCount(
             renderer_subframe
                 ? ProcessedCrashCounts::kRendererForegroundVisibleSubframeCrash
@@ -219,7 +201,7 @@
               vm_size_kb / 1024);
         }
       }
-    } else if (!has_valid_dump) {
+    } else if (!crashed) {
       // Record stats when renderer is not visible, but the process has oom
       // protected bindings. This case occurs when a tab is switched or closed,
       // the bindings are updated later than visibility on web contents.
@@ -267,7 +249,7 @@
                      &reported_counts);
   }
 
-  if (has_valid_dump) {
+  if (crashed) {
     if (info.process_type == content::PROCESS_TYPE_RENDERER) {
       ReportCrashCount(ProcessedCrashCounts::kRendererCrashAll,
                        &reported_counts);
@@ -305,7 +287,7 @@
         info.remaining_process_with_strong_binding, 20);
   }
 
-  ReportLegacyCrashUma(info, has_valid_dump);
+  ReportLegacyCrashUma(info, crashed);
   NotifyObservers(info.process_host_id, reported_counts);
 }
 
diff --git a/components/crash/content/browser/crash_metrics_reporter_android.h b/components/crash/content/browser/crash_metrics_reporter_android.h
index f098ac2..c2ededf 100644
--- a/components/crash/content/browser/crash_metrics_reporter_android.h
+++ b/components/crash/content/browser/crash_metrics_reporter_android.h
@@ -8,7 +8,6 @@
 #include "base/containers/flat_set.h"
 #include "base/observer_list_threadsafe.h"
 #include "components/crash/content/browser/child_exit_observer_android.h"
-#include "components/crash/content/browser/crash_dump_manager_android.h"
 
 namespace crash_reporter {
 
@@ -75,8 +74,8 @@
   void AddObserver(Observer* observer);
   void RemoveObserver(Observer* observer);
 
-  void CrashDumpProcessed(const ChildExitObserver::TerminationInfo& info,
-                          breakpad::CrashDumpManager::CrashDumpStatus status);
+  void ChildProcessExited(
+      const crash_reporter::ChildExitObserver::TerminationInfo& info);
 
  private:
   CrashMetricsReporter();
diff --git a/components/crash/content/browser/crash_metrics_reporter_android_unittest.cc b/components/crash/content/browser/crash_metrics_reporter_android_unittest.cc
index 380b9ab..a01347f 100644
--- a/components/crash/content/browser/crash_metrics_reporter_android_unittest.cc
+++ b/components/crash/content/browser/crash_metrics_reporter_android_unittest.cc
@@ -4,6 +4,8 @@
 
 #include "components/crash/content/browser/crash_metrics_reporter_android.h"
 
+#include <signal.h>
+
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/run_loop.h"
@@ -47,20 +49,6 @@
             base::test::ScopedTaskEnvironment::MainThreadType::UI) {}
   ~CrashMetricsReporterTest() override {}
 
-  static void CreateAndProcessCrashDump(
-      const ChildExitObserver::TerminationInfo& info,
-      const std::string& data) {
-    base::ScopedFD fd =
-        breakpad::CrashDumpManager::GetInstance()->CreateMinidumpFileForChild(
-            info.process_host_id);
-    EXPECT_TRUE(fd.is_valid());
-    base::WriteFileDescriptor(fd.get(), data.data(), data.size());
-    base::ScopedTempDir dump_dir;
-    EXPECT_TRUE(dump_dir.CreateUniqueTempDir());
-    breakpad::CrashDumpManager::GetInstance()->ProcessMinidumpFileFromChild(
-        dump_dir.GetPath(), info);
-  }
-
  protected:
   blink::OomInterventionMetrics InterventionMetrics(bool allocation_failed) {
     blink::OomInterventionMetrics metrics;
@@ -81,9 +69,7 @@
     CrashMetricsReporterObserver crash_dump_observer;
     CrashMetricsReporter::GetInstance()->AddObserver(&crash_dump_observer);
 
-    CrashMetricsReporter::GetInstance()->CrashDumpProcessed(
-        termination_info,
-        breakpad::CrashDumpManager::CrashDumpStatus::kEmptyDump);
+    CrashMetricsReporter::GetInstance()->ChildProcessExited(termination_info);
     crash_dump_observer.WaitForProcessed();
 
     EXPECT_EQ(expected_crash_types, crash_dump_observer.recorded_crash_types());
@@ -180,6 +166,7 @@
   termination_info.process_type = content::PROCESS_TYPE_UTILITY;
   termination_info.app_state =
       base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES;
+  termination_info.crash_signo = SIGSEGV;
   termination_info.normal_termination = false;
   termination_info.binding_state = base::android::ChildBindingState::STRONG;
   termination_info.was_killed_intentionally_by_browser = false;
@@ -189,9 +176,7 @@
   CrashMetricsReporterObserver crash_dump_observer;
   CrashMetricsReporter::GetInstance()->AddObserver(&crash_dump_observer);
 
-  CrashMetricsReporter::GetInstance()->CrashDumpProcessed(
-      termination_info,
-      breakpad::CrashDumpManager::CrashDumpStatus::kValidDump);
+  CrashMetricsReporter::GetInstance()->ChildProcessExited(termination_info);
   crash_dump_observer.WaitForProcessed();
 
   EXPECT_EQ(CrashMetricsReporter::ReportedCrashTypeSet(
@@ -329,6 +314,7 @@
   termination_info.process_type = content::PROCESS_TYPE_RENDERER;
   termination_info.app_state =
       base::android::APPLICATION_STATE_HAS_RUNNING_ACTIVITIES;
+  termination_info.crash_signo = SIGSEGV;
   termination_info.normal_termination = true;
   termination_info.binding_state = base::android::ChildBindingState::STRONG;
   termination_info.was_killed_intentionally_by_browser = true;
@@ -338,9 +324,7 @@
   CrashMetricsReporterObserver crash_dump_observer;
   CrashMetricsReporter::GetInstance()->AddObserver(&crash_dump_observer);
 
-  CrashMetricsReporter::GetInstance()->CrashDumpProcessed(
-      termination_info,
-      breakpad::CrashDumpManager::CrashDumpStatus::kValidDump);
+  CrashMetricsReporter::GetInstance()->ChildProcessExited(termination_info);
   crash_dump_observer.WaitForProcessed();
 
   EXPECT_EQ(
diff --git a/components/crash/core/common/BUILD.gn b/components/crash/core/common/BUILD.gn
index c8e02ebf..81912a5 100644
--- a/components/crash/core/common/BUILD.gn
+++ b/components/crash/core/common/BUILD.gn
@@ -20,7 +20,8 @@
   }
 }
 
-use_crashpad_annotation = (is_mac || is_win) && !use_crash_key_stubs
+use_crashpad_annotation =
+    (is_mac || is_win || is_android) && !use_crash_key_stubs
 
 buildflag_header("crash_buildflags") {
   header = "crash_buildflags.h"
@@ -143,7 +144,7 @@
     sources += [ "objc_zombie_unittest.mm" ]
   }
 
-  if (!is_mac && !is_win && !is_fuchsia) {
+  if (!is_mac && !is_win && !is_fuchsia && !is_android) {
     include_dirs = [ "//third_party/breakpad/breakpad/src/" ]
     sources += [ "crash_key_breakpad_unittest.cc" ]
   }
diff --git a/components/crash/core/common/crash_keys.cc b/components/crash/core/common/crash_keys.cc
index 0261928..6a3c9599 100644
--- a/components/crash/core/common/crash_keys.cc
+++ b/components/crash/core/common/crash_keys.cc
@@ -24,7 +24,7 @@
 
 namespace {
 
-#if defined(OS_MACOSX) || defined(OS_WIN)
+#if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_ANDROID)
 // When using Crashpad, the crash reporting client ID is the responsibility of
 // Crashpad. It is not set directly by Chrome. To make the metrics client ID
 // available on the server, it's stored in a distinct key.
@@ -51,7 +51,7 @@
 }
 
 void ClearMetricsClientId() {
-#if defined(OS_MACOSX) || defined(OS_WIN)
+#if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_ANDROID)
   // Crashpad always monitors for crashes, but doesn't upload them when
   // crash reporting is disabled. The preference to upload crash reports is
   // linked to the preference for metrics reporting. When metrics reporting is
diff --git a/components/minidump_uploader/BUILD.gn b/components/minidump_uploader/BUILD.gn
index 6742e9c8..dbf3c437 100644
--- a/components/minidump_uploader/BUILD.gn
+++ b/components/minidump_uploader/BUILD.gn
@@ -14,6 +14,7 @@
 static_library("minidump_uploader") {
   sources = [
     "rewrite_minidumps_as_mimes.cc",
+    "rewrite_minidumps_as_mimes.h",
   ]
 
   deps = [
diff --git a/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/CrashFileManager.java b/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/CrashFileManager.java
index 5ac81f2..520c84f 100644
--- a/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/CrashFileManager.java
+++ b/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/CrashFileManager.java
@@ -28,26 +28,21 @@
 
 /**
  * The CrashFileManager is responsible for managing the "Crash Reports" directory containing
- * minidump files and shepherding them through a state machine represented by the file names. Note
- * that the second step is optional.
- *  1. foo.dmp is a minidump file, written to the directory by Breakpad.
- * (2) foo.dmpNNNNN is a minidump file, where NNNNN is the PID (process id) of the crashing
- *     process. This step is optional -- that is, a minidump could fail to have its PID included in
- *     the filename.
- *  3. foo.dmp.try0 or foo.dmpNNNNN.try0 is a minidump file with recent logcat output attached to
- *     it; or a file for which logcat output has been intentionally omitted. Notably,
- *     Webview-generated minidumps do not include logcat output.
- *  4. foo.dmpNNNNN.tryM for M > 0 is a minidump file that's been attempted to be uploaded to the
+ * minidump files and shepherding them through a state machine represented by the file names.
+ *  1. Minidumps are read from Crashpad's CrashReportDatabase and re-written as MIME files in the
+ *     "Crash Reports" directory as foo.dmpNNNNN where NNNNN is the PID (process id) of the
+ *     crashing process.
+ *  2. foo.dmpNNNNN.try0 is a minidump file with recent logcat output attached to it; or a file for
+ *     which logcat output has been intentionally omitted. Notably, Webview-generated minidumps do
+ *     not include logcat output.
+ *  3. foo.dmpNNNNN.tryM for M > 0 is a minidump file that's been attempted to be uploaded to the
  *     crash server, but for which M upload attempts have failed.
- *  5. foo.up.tryM and foo.upNNNNN.tryM are both valid possible names for a successfully uploaded
- *     file.
- *  6. foo.skipped.tryM and foo.skippedNNNNN.tryM are both valid possible names for a file whose
- *     upload was skipped. An upload may be skipped, for example, if the user has not consented to
- *     uploading crash reports. These files are marked as skipped rather than deleted immediately to
- *     allow the user to manually initiate an upload.
- *  7. foo.forced.tryM and foo.forcedNNNNN.tryM are both valid possible names for a file that the
- *     user has manually requested to upload.
- *  8. foo.tmp is a temporary file.
+ *  4. foo.upNNNNN.tryM names a successfully uploaded file.
+ *  5. foo.skippedNNNNN.tryM names for a file whose upload was skipped. An upload may be skipped,
+ *     for example, if the user has not consented to uploading crash reports. These files are marked
+ *     as skipped rather than deleted immediately to allow the user to manually initiate an upload.
+ *  6. foo.forcedNNNNN.tryM names a file that the user has manually requested to upload.
+ *  7. foo.tmp is a temporary file.
  */
 public class CrashFileManager {
     private static final String TAG = "CrashFileManager";
@@ -351,9 +346,11 @@
 
     /**
      * Returns the most recent minidump without a logcat for a given pid, or null if no such
-     * minidump exists.
+     * minidump exists. This method begins by reading all minidumps from Crashpad's database and
+     * rewriting them as MIME files in the Crash Reports directory.
      */
     public File getMinidumpSansLogcatForPid(int pid) {
+        importCrashpadMinidumps();
         File[] foundFiles = listCrashFiles(
             Pattern.compile("\\.dmp" + Integer.toString(pid) + "\\z"));
         return foundFiles.length > 0 ? foundFiles[0] : null;
@@ -361,11 +358,14 @@
 
     /**
      * Returns all minidump files that definitely do not have logcat output, sorted by modification
-     * time stamp. Note: This method does not provide an "if and only if" test: it may return omit
-     * some files that lack logcat output, if logcat output has been intentionally skipped for those
-     * minidumps. However, any files returned definitely lack logcat output.
+     * time stamp. This method begins by reading all minidumps from Crashpad's database and
+     * rewriting them as MIME files in the Crash Reports directory. Note: This method does not
+     * provide an "if and only if" test: it may return omit some files that lack logcat output, if
+     * logcat output has been intentionally skipped for those minidumps. However, any files returned
+     * definitely lack logcat output.
      */
     public File[] getMinidumpsSansLogcat() {
+        importCrashpadMinidumps();
         return listCrashFiles(MINIDUMP_SANS_LOGCAT_PATTERN);
     }
 
diff --git a/components/minidump_uploader/android/javatests/src/org/chromium/components/minidump_uploader/CrashTestRule.java b/components/minidump_uploader/android/javatests/src/org/chromium/components/minidump_uploader/CrashTestRule.java
index 071c9b9..e9ddcab 100644
--- a/components/minidump_uploader/android/javatests/src/org/chromium/components/minidump_uploader/CrashTestRule.java
+++ b/components/minidump_uploader/android/javatests/src/org/chromium/components/minidump_uploader/CrashTestRule.java
@@ -12,6 +12,8 @@
 
 import org.chromium.base.ContextUtils;
 import org.chromium.base.Log;
+import org.chromium.base.library_loader.LibraryLoader;
+import org.chromium.base.library_loader.LibraryProcessType;
 import org.chromium.components.minidump_uploader.util.CrashReportingPermissionManager;
 
 import java.io.File;
@@ -51,6 +53,7 @@
     private void setUp() throws Exception {
         ContextUtils.initApplicationContextForTests(
                 InstrumentationRegistry.getTargetContext().getApplicationContext());
+        LibraryLoader.getInstance().ensureInitialized(LibraryProcessType.PROCESS_BROWSER);
         if (mCacheDir == null) {
             mCacheDir = getExistingCacheDir();
         }
diff --git a/components/minidump_uploader/rewrite_minidumps_as_mimes.cc b/components/minidump_uploader/rewrite_minidumps_as_mimes.cc
index f75f515..b9869ba3 100644
--- a/components/minidump_uploader/rewrite_minidumps_as_mimes.cc
+++ b/components/minidump_uploader/rewrite_minidumps_as_mimes.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "components/minidump_uploader/rewrite_minidumps_as_mimes.h"
+
 #include <utility>
 
 #include "base/android/jni_string.h"
@@ -9,7 +11,6 @@
 #include "base/strings/stringprintf.h"
 #include "build/build_config.h"
 #include "jni/CrashReportMimeWriter_jni.h"
-#include "third_party/crashpad/crashpad/client/crash_report_database.h"
 #include "third_party/crashpad/crashpad/handler/minidump_to_upload_parameters.h"
 #include "third_party/crashpad/crashpad/snapshot/minidump/process_snapshot_minidump.h"
 #include "third_party/crashpad/crashpad/util/file/file_writer.h"
@@ -18,13 +19,6 @@
 
 namespace minidump_uploader {
 
-bool MimeifyReport(const crashpad::CrashReportDatabase::UploadReport& report,
-                   crashpad::HTTPMultipartBuilder* http_multipart_builder,
-                   pid_t* pid);
-
-bool WriteBodyToFile(crashpad::HTTPBodyStream* body,
-                     crashpad::FileWriterInterface* writer);
-
 namespace {
 
 #if defined(OS_ANDROID)
diff --git a/components/minidump_uploader/rewrite_minidumps_as_mimes.h b/components/minidump_uploader/rewrite_minidumps_as_mimes.h
new file mode 100644
index 0000000..3238d97
--- /dev/null
+++ b/components/minidump_uploader/rewrite_minidumps_as_mimes.h
@@ -0,0 +1,34 @@
+// Copyright 2018 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.
+
+#ifndef COMPONENTS_MINIDUMP_UPLOADER_REWRITE_MINIDUMPS_AS_MIMES_H_
+#define COMPONENTS_MINIDUMP_UPLOADER_REWRITE_MINIDUMPS_AS_MIMES_H_
+
+#include <sys/types.h>
+
+#include "third_party/crashpad/crashpad/client/crash_report_database.h"
+
+namespace crashpad {
+class HTTPMultipartBuilder;
+class HTTPBodyStream;
+class FileWriterInterface;
+}  // namespace crashpad
+
+namespace minidump_uploader {
+
+// Re-encodes report as a MIME and places the result in http_multipart_builder.
+// pid is set to the process ID extracted from the report. Returns `true` on
+// success.
+bool MimeifyReport(const crashpad::CrashReportDatabase::UploadReport& report,
+                   crashpad::HTTPMultipartBuilder* http_multipart_builder,
+                   pid_t* pid);
+
+// Consumes all bytes from body and writes them to writer. Returns `true` on
+// success.
+bool WriteBodyToFile(crashpad::HTTPBodyStream* body,
+                     crashpad::FileWriterInterface* writer);
+
+}  // namespace minidump_uploader
+
+#endif  // COMPONENTS_MINIDUMP_UPLOADER_REWRITE_MINIDUMPS_AS_MIMES_H_
diff --git a/content/shell/app/shell_main_delegate.cc b/content/shell/app/shell_main_delegate.cc
index 30468f1..537e1a40 100644
--- a/content/shell/app/shell_main_delegate.cc
+++ b/content/shell/app/shell_main_delegate.cc
@@ -68,7 +68,7 @@
 #include "content/shell/android/shell_descriptors.h"
 #endif
 
-#if defined(OS_MACOSX) || defined(OS_WIN)
+#if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_ANDROID)
 #include "components/crash/content/app/crashpad.h"  // nogncheck
 #endif
 
@@ -85,7 +85,7 @@
 #include "content/shell/common/v8_crashpad_support_win.h"
 #endif
 
-#if defined(OS_POSIX) && !defined(OS_MACOSX)
+#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
 #include "components/crash/content/app/breakpad_linux.h"
 #endif
 
@@ -328,18 +328,13 @@
         base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
             switches::kProcessType);
     crash_reporter::SetCrashReporterClient(g_shell_crash_client.Pointer());
-#if defined(OS_MACOSX) || defined(OS_WIN)
+#if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_ANDROID)
     crash_reporter::InitializeCrashpad(process_type.empty(), process_type);
 #elif defined(OS_LINUX)
     // Reporting for sub-processes will be initialized in ZygoteForked.
     if (process_type != service_manager::switches::kZygoteProcess)
       breakpad::InitCrashReporter(process_type);
-#elif defined(OS_ANDROID)
-    if (process_type.empty())
-      breakpad::InitCrashReporter(process_type);
-    else
-      breakpad::InitNonBrowserCrashReporterForAndroid(process_type);
-#endif  // defined(OS_ANDROID)
+#endif  // defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_ANDROID)
   }
 #endif  // !defined(OS_FUCHSIA)
 
diff --git a/content/shell/browser/shell_browser_main_parts.cc b/content/shell/browser/shell_browser_main_parts.cc
index 5dac9b3..10f1b0c 100644
--- a/content/shell/browser/shell_browser_main_parts.cc
+++ b/content/shell/browser/shell_browser_main_parts.cc
@@ -154,11 +154,8 @@
       base::CommandLine::ForCurrentProcess();
   crash_reporter::ChildExitObserver::Create();
   if (command_line->HasSwitch(switches::kEnableCrashReporter)) {
-    base::FilePath crash_dumps_dir =
-        command_line->GetSwitchValuePath(switches::kCrashDumpsDir);
     crash_reporter::ChildExitObserver::GetInstance()->RegisterClient(
-        std::make_unique<crash_reporter::ChildProcessCrashObserver>(
-            crash_dumps_dir, kAndroidMinidumpDescriptor));
+        std::make_unique<crash_reporter::ChildProcessCrashObserver>());
   }
 #endif
 
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc
index 02225da..9f4f1f1 100644
--- a/content/shell/browser/shell_content_browser_client.cc
+++ b/content/shell/browser/shell_content_browser_client.cc
@@ -56,7 +56,7 @@
 #if defined(OS_ANDROID)
 #include "base/android/apk_assets.h"
 #include "base/android/path_utils.h"
-#include "components/crash/content/browser/child_exit_observer_android.h"
+#include "components/crash/content/app/crashpad.h"
 #include "content/shell/android/shell_descriptors.h"
 #endif
 
@@ -68,9 +68,8 @@
 #include "services/ws/test_ws/test_ws.mojom.h"                // nogncheck
 #endif
 
-#if defined(OS_LINUX)
+#if defined(OS_LINUX) || defined(OS_ANDROID)
 #include "base/debug/leak_annotations.h"
-#include "components/crash/content/app/breakpad_linux.h"
 #include "components/crash/content/browser/crash_handler_host_linux.h"
 #include "content/public/common/content_descriptors.h"
 #endif
@@ -91,7 +90,11 @@
 
 ShellContentBrowserClient* g_browser_client;
 
-#if defined(OS_LINUX)
+#if defined(OS_ANDROID)
+int GetCrashSignalFD(const base::CommandLine& command_line) {
+  return crashpad::CrashHandlerHost::Get()->GetDeathSignalSocket();
+}
+#elif defined(OS_LINUX)
 breakpad::CrashHandlerHostLinux* CreateCrashHandlerHost(
     const std::string& process_type) {
   base::FilePath dumps_path =
@@ -137,7 +140,7 @@
 
   return -1;
 }
-#endif  // defined(OS_LINUX)
+#endif  // defined(OS_ANDROID)
 
 }  // namespace
 
@@ -423,15 +426,11 @@
       kShellPakDescriptor,
       base::GlobalDescriptors::GetInstance()->Get(kShellPakDescriptor),
       base::GlobalDescriptors::GetInstance()->GetRegion(kShellPakDescriptor));
-
-  crash_reporter::ChildExitObserver::GetInstance()->BrowserChildProcessStarted(
-      child_process_id, mappings);
-#else
+#endif
   int crash_signal_fd = GetCrashSignalFD(command_line);
   if (crash_signal_fd >= 0) {
     mappings->Share(service_manager::kCrashDumpSignal, crash_signal_fd);
   }
-#endif  // !defined(OS_ANDROID)
 }
 #endif  // defined(OS_LINUX) || defined(OS_ANDROID)