Introduce status handlers and use them in client

We introduce a StatusUpdateHandler class which can be overridden to
provide a method with which to react to status updates. This replaces
manual dbus logic in several places in update_engine_client with a
consistent interface for asynchronously handling status updates.

Change-Id: Idca4229de82074fb7a87a315b45dd0292c1b1f16
Test: Confirmed --update blocks and resumes correctly
Bug: 26233663
diff --git a/client_library/client_impl.cc b/client_library/client_impl.cc
index 7b80025..247f8f0 100644
--- a/client_library/client_impl.cc
+++ b/client_library/client_impl.cc
@@ -40,10 +40,8 @@
                                            const string& in_omaha_url,
                                            bool at_user_request) {
   return proxy_->AttemptUpdateWithFlags(
-      in_app_version,
-      in_omaha_url,
-      (at_user_request) ? 0 : kAttemptUpdateFlagNonInteractive,
-      nullptr);
+      in_app_version, in_omaha_url,
+      (at_user_request) ? 0 : kAttemptUpdateFlagNonInteractive, nullptr);
 }
 
 bool UpdateEngineClientImpl::GetStatus(int64_t* out_last_checked_time,
@@ -52,13 +50,9 @@
                                        string* out_new_version,
                                        int64_t* out_new_size) {
   string status_as_string;
-  const bool success = proxy_->GetStatus(
-      out_last_checked_time,
-      out_progress,
-      &status_as_string,
-      out_new_version,
-      out_new_size,
-      nullptr);
+  const bool success =
+      proxy_->GetStatus(out_last_checked_time, out_progress, &status_as_string,
+                        out_new_version, out_new_size, nullptr);
   if (!success) {
     return false;
   }
@@ -70,7 +64,7 @@
   return proxy_->SetUpdateOverCellularPermission(allowed, nullptr);
 }
 
-bool UpdateEngineClientImpl::GetUpdateOverCellularPermission(bool *allowed) {
+bool UpdateEngineClientImpl::GetUpdateOverCellularPermission(bool* allowed) {
   return proxy_->GetUpdateOverCellularPermission(allowed, nullptr);
 }
 
@@ -108,26 +102,63 @@
   return proxy_->ResetStatus(nullptr);
 }
 
+void UpdateEngineClientImpl::StatusUpdateHandlerRegistered(
+    StatusUpdateHandler* handler, const std::string& interface,
+    const std::string& signal_name, bool success) {
+  if (!success) {
+    handler->IPCError("Could not connect to" + signal_name);
+    return;
+  }
+
+  int64_t last_checked_time;
+  double progress;
+  UpdateStatus update_status;
+  string new_version;
+  int64_t new_size;
+
+  if (GetStatus(&last_checked_time, &progress, &update_status, &new_version,
+                &new_size)) {
+    handler->HandleStatusUpdate(last_checked_time, progress, update_status,
+                                new_version, new_size);
+    return;
+  }
+
+  handler->IPCError("Could not query current status");
+}
+
+void UpdateEngineClientImpl::RunStatusUpdateHandler(
+    StatusUpdateHandler* h, int64_t last_checked_time, double progress,
+    const std::string& current_operation, const std::string& new_version,
+    int64_t new_size) {
+  UpdateStatus status;
+  StringToUpdateStatus(current_operation, &status);
+
+  h->HandleStatusUpdate(last_checked_time, progress, status, new_version,
+                        new_size);
+}
+
+void UpdateEngineClientImpl::RegisterStatusUpdateHandler(
+    StatusUpdateHandler* handler) {
+  proxy_->RegisterStatusUpdateSignalHandler(
+      base::Bind(&UpdateEngineClientImpl::RunStatusUpdateHandler,
+                 base::Unretained(this), base::Unretained(handler)),
+      base::Bind(&UpdateEngineClientImpl::StatusUpdateHandlerRegistered,
+                 base::Unretained(this), base::Unretained(handler)));
+}
+
 bool UpdateEngineClientImpl::SetTargetChannel(const string& in_target_channel,
                                               bool allow_powerwash) {
-  return proxy_->SetChannel(
-      in_target_channel,
-      allow_powerwash,
-      nullptr);
+  return proxy_->SetChannel(in_target_channel, allow_powerwash, nullptr);
 }
 
 bool UpdateEngineClientImpl::GetTargetChannel(string* out_channel) {
-  return proxy_->GetChannel(
-      false,  // Get the target channel.
-      out_channel,
-      nullptr);
+  return proxy_->GetChannel(false,  // Get the target channel.
+                            out_channel, nullptr);
 }
 
 bool UpdateEngineClientImpl::GetChannel(string* out_channel) {
-  return proxy_->GetChannel(
-      true,  // Get the current channel.
-      out_channel,
-      nullptr);
+  return proxy_->GetChannel(true,  // Get the current channel.
+                            out_channel, nullptr);
 }
 
 }  // namespace internal