Remove watcher process and move exit code watcher to crashpad process

This change removes the watcher process.  The watcher process is
responsible for waiting for the browser process to exit and logs the exit
code to a known registry location. Subsequent launches read from the
registry location and log the value to a histogram.  The watcher process
was originally created prior to the creation of crashpad.  Since all the
watcher process is doing is waiting for the browser process to exit it
makes sense to move this functionality to the crashpad process and get
rid of the watcher process and code entirely.  Use of the registry is
now removed and the histogram is logged directly on shutdown.
This change removes the chrome_watcher.dll which gives back ~ 1MB of
disk space.

Bug: 1043844
Change-Id: I666819e64817197e8950a9c5749c921fcebdb964
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2035054
Commit-Queue: Chris Davis <[email protected]>
Reviewed-by: Scott Violet <[email protected]>
Reviewed-by: Sigurður Ásgeirsson <[email protected]>
Cr-Commit-Position: refs/heads/master@{#739109}
diff --git a/components/browser_watcher/exit_code_watcher_win.cc b/components/browser_watcher/exit_code_watcher_win.cc
index d5af475..3948243 100644
--- a/components/browser_watcher/exit_code_watcher_win.cc
+++ b/components/browser_watcher/exit_code_watcher_win.cc
@@ -7,27 +7,22 @@
 #include <utility>
 
 #include "base/logging.h"
+#include "base/metrics/sparse_histogram.h"
 #include "base/process/kill.h"
-#include "base/strings/stringprintf.h"
-#include "base/win/registry.h"
+#include "base/process/process.h"
+#include "base/process/process_handle.h"
+#include "base/sequenced_task_runner.h"
+#include "base/threading/thread.h"
+#include "base/threading/thread_task_runner_handle.h"
 
 #include <windows.h>
 
 namespace browser_watcher {
 
-namespace {
+const char kBrowserExitCodeHistogramName[] = "Stability.BrowserExitCodes";
 
-base::string16 GetValueName(const base::Time creation_time,
-                            base::ProcessId pid) {
-  // Convert the PID and creation time to a string value unique to this
-  // process instance.
-  return base::StringPrintf(L"%d-%lld", pid, creation_time.ToInternalValue());
-}
-
-}  // namespace
-
-ExitCodeWatcher::ExitCodeWatcher(base::StringPiece16 registry_path)
-    : registry_path_(registry_path.as_string()), exit_code_(STILL_ACTIVE) {}
+ExitCodeWatcher::ExitCodeWatcher()
+    : background_thread_("ExitCodeWatcherThread"), exit_code_(STILL_ACTIVE) {}
 
 ExitCodeWatcher::~ExitCodeWatcher() {
 }
@@ -54,12 +49,24 @@
 
   // Success, take ownership of the process.
   process_ = std::move(process);
-  process_creation_time_ = base::Time::FromFileTime(creation_time);
 
-  // Start by writing the value STILL_ACTIVE to registry, to allow detection
-  // of the case where the watcher itself is somehow terminated before it can
-  // write the process' actual exit code.
-  return WriteProcessExitCode(STILL_ACTIVE);
+  return true;
+}
+
+bool ExitCodeWatcher::StartWatching() {
+  if (!background_thread_.StartWithOptions(
+          base::Thread::Options(base::MessagePumpType::IO, 0))) {
+    return false;
+  }
+
+  if (!background_thread_.task_runner()->PostTask(
+          FROM_HERE, base::BindOnce(&ExitCodeWatcher::WaitForExit,
+                                    base::Unretained(this)))) {
+    background_thread_.Stop();
+    return false;
+  }
+
+  return true;
 }
 
 void ExitCodeWatcher::WaitForExit() {
@@ -72,19 +79,17 @@
 }
 
 bool ExitCodeWatcher::WriteProcessExitCode(int exit_code) {
-  base::win::RegKey key(HKEY_CURRENT_USER,
-                        registry_path_.c_str(),
-                        KEY_WRITE);
-  base::string16 value_name(
-      GetValueName(process_creation_time_, process_.Pid()));
-
-  ULONG result = key.WriteValue(value_name.c_str(), exit_code);
-  if (result != ERROR_SUCCESS) {
-    LOG(ERROR) << "Unable to write to registry, error " << result;
-    return false;
+  if (exit_code != STILL_ACTIVE) {
+    // Record the exit codes in a sparse stability histogram, as the range of
+    // values used to report failures is large.
+    base::HistogramBase* exit_code_histogram =
+        base::SparseHistogram::FactoryGet(
+            kBrowserExitCodeHistogramName,
+            base::HistogramBase::kUmaStabilityHistogramFlag);
+    exit_code_histogram->Add(exit_code);
+    return true;
   }
-
-  return true;
+  return false;
 }
 
 }  // namespace browser_watcher