Android: Implement the binder service.

This patch introduces the service delegate interface for non-Brillo
targets, which is the class in charge of implementing the API exposed
by the service. The binder service for non-Brillo targets is now
completed using this interface.

The other side of this interface will be implemented in a follow up CL,
while this CL includes only the interface and its usage.

To accomodate non-Brillo targets, the generic ServiceObserverInterface
is extended with the PayloadApplicationComplete message, which will be
implemented for all targets in the future.

Bug: 25631949
TEST=`mmma system/update_engine` on aosp_arm-eng and edison-eng

Change-Id: I9fa8e9565ae92515e81e07d2cef562fc4e11a7ba
diff --git a/binder_service_android.cc b/binder_service_android.cc
index 98943a2..3c679da 100644
--- a/binder_service_android.cc
+++ b/binder_service_android.cc
@@ -16,53 +16,116 @@
 
 #include "update_engine/binder_service_android.h"
 
-using android::String16;
+#include <base/bind.h>
+#include <base/logging.h>
+#include <binderwrapper/binder_wrapper.h>
+#include <brillo/errors/error.h>
+#include <utils/String8.h>
+
 using android::binder::Status;
 using android::os::IUpdateEngineCallback;
-using android::sp;
-using std::vector;
+
+namespace {
+Status ErrorPtrToStatus(const brillo::ErrorPtr& error) {
+  return Status::fromServiceSpecificError(
+      1, android::String8{error->GetMessage().c_str()});
+}
+}  // namespace
 
 namespace chromeos_update_engine {
 
 BinderUpdateEngineAndroidService::BinderUpdateEngineAndroidService(
-    DaemonStateAndroid* /* daemon_state */) {
-  // TODO(deymo): Hook this interface calls to the daemon_state.
+    ServiceDelegateAndroidInterface* service_delegate)
+    : service_delegate_(service_delegate) {
 }
 
 void BinderUpdateEngineAndroidService::SendStatusUpdate(
-    int64_t last_checked_time,
+    int64_t /* last_checked_time */,
     double progress,
     update_engine::UpdateStatus status,
-    const std::string& new_version,
-    int64_t new_size) {
-  // TODO(deymo): Notify registered callers.
+    const std::string& /* new_version  */,
+    int64_t /* new_size */) {
+  for (auto& callback : callbacks_) {
+    callback->onStatusUpdate(static_cast<int>(status), progress);
+  }
+}
+
+void BinderUpdateEngineAndroidService::SendPayloadApplicationComplete(
+    ErrorCode error_code) {
+  for (auto& callback : callbacks_) {
+    callback->onPayloadApplicationComplete(static_cast<int>(error_code));
+  }
 }
 
 Status BinderUpdateEngineAndroidService::bind(
-    const sp<IUpdateEngineCallback>& callback,
-    bool* return_value) {
+    const android::sp<IUpdateEngineCallback>& callback, bool* return_value) {
+  callbacks_.emplace_back(callback);
+
+  auto binder_wrapper = android::BinderWrapper::Get();
+  binder_wrapper->RegisterForDeathNotifications(
+      IUpdateEngineCallback::asBinder(callback),
+      base::Bind(&BinderUpdateEngineAndroidService::UnbindCallback,
+                 base::Unretained(this),
+                 base::Unretained(callback.get())));
+
   *return_value = true;
   return Status::ok();
 }
 
 Status BinderUpdateEngineAndroidService::applyPayload(
-    const String16& url,
+    const android::String16& url,
     int64_t payload_offset,
     int64_t payload_size,
-    const vector<String16>& header_kv_pairs) {
+    const std::vector<android::String16>& header_kv_pairs) {
+  const std::string payload_url{android::String8{url}.string()};
+  std::vector<std::string> str_headers;
+  str_headers.reserve(header_kv_pairs.size());
+  for (const auto& header : header_kv_pairs) {
+    str_headers.emplace_back(android::String8{header}.string());
+  }
+
+  brillo::ErrorPtr error;
+  if (!service_delegate_->ApplyPayload(
+          payload_url, payload_offset, payload_size, str_headers, &error)) {
+    return ErrorPtrToStatus(error);
+  }
   return Status::ok();
 }
 
 Status BinderUpdateEngineAndroidService::suspend() {
+  brillo::ErrorPtr error;
+  if (!service_delegate_->SuspendUpdate(&error))
+    return ErrorPtrToStatus(error);
   return Status::ok();
 }
 
 Status BinderUpdateEngineAndroidService::resume() {
+  brillo::ErrorPtr error;
+  if (!service_delegate_->ResumeUpdate(&error))
+    return ErrorPtrToStatus(error);
   return Status::ok();
 }
 
 Status BinderUpdateEngineAndroidService::cancel() {
+  brillo::ErrorPtr error;
+  if (!service_delegate_->CancelUpdate(&error))
+    return ErrorPtrToStatus(error);
   return Status::ok();
 }
 
+void BinderUpdateEngineAndroidService::UnbindCallback(
+    IUpdateEngineCallback* callback) {
+  auto it =
+      std::find_if(callbacks_.begin(),
+                   callbacks_.end(),
+                   [&callback](const android::sp<IUpdateEngineCallback>& elem) {
+                     return elem.get() == callback;
+                   });
+  if (it == callbacks_.end()) {
+    LOG(ERROR) << "Got death notification for unknown callback.";
+    return;
+  }
+  callbacks_.erase(it);
+}
+
 }  // namespace chromeos_update_engine
diff --git a/binder_service_android.h b/binder_service_android.h
index 4ab19b3..3e256e0 100644
--- a/binder_service_android.h
+++ b/binder_service_android.h
@@ -19,6 +19,7 @@
 
 #include <stdint.h>
 
+#include <string>
 #include <vector>
 
 #include <utils/Errors.h>
@@ -27,7 +28,7 @@
 
 #include "android/os/BnUpdateEngine.h"
 #include "android/os/IUpdateEngineCallback.h"
-#include "update_engine/daemon_state_android.h"
+#include "update_engine/service_delegate_android_interface.h"
 #include "update_engine/service_observer_interface.h"
 
 namespace chromeos_update_engine {
@@ -35,7 +36,8 @@
 class BinderUpdateEngineAndroidService : public android::os::BnUpdateEngine,
                                          public ServiceObserverInterface {
  public:
-  BinderUpdateEngineAndroidService(DaemonStateAndroid* daemon_state);
+  BinderUpdateEngineAndroidService(
+      ServiceDelegateAndroidInterface* service_delegate);
   ~BinderUpdateEngineAndroidService() override = default;
 
   const char* ServiceName() const {
@@ -48,6 +50,7 @@
                         update_engine::UpdateStatus status,
                         const std::string& new_version,
                         int64_t new_size) override;
+  void SendPayloadApplicationComplete(ErrorCode error_code) override;
 
   // Channel tracking changes are ignored.
   void SendChannelChangeUpdate(const std::string& tracking_channel) override {}
@@ -58,16 +61,22 @@
       int64_t payload_offset,
       int64_t payload_size,
       const std::vector<android::String16>& header_kv_pairs) override;
-
   android::binder::Status bind(
       const android::sp<android::os::IUpdateEngineCallback>& callback,
       bool* return_value) override;
-
   android::binder::Status suspend() override;
-
   android::binder::Status resume() override;
-
   android::binder::Status cancel() override;
+
+ private:
+  // Remove the passed |callback| from the list of registered callbacks. Called
+  // whenever the callback object is destroyed.
+  void UnbindCallback(android::os::IUpdateEngineCallback* callback);
+
+  // List of currently bound callbacks.
+  std::vector<android::sp<android::os::IUpdateEngineCallback>> callbacks_;
+
+  ServiceDelegateAndroidInterface* service_delegate_;
 };
 
 }  // namespace chromeos_update_engine
diff --git a/binder_service_brillo.h b/binder_service_brillo.h
index 99aa76b..178305b 100644
--- a/binder_service_brillo.h
+++ b/binder_service_brillo.h
@@ -19,6 +19,7 @@
 
 #include <utils/Errors.h>
 
+#include <string>
 #include <vector>
 
 #include <utils/RefBase.h>
@@ -35,7 +36,7 @@
 class BinderUpdateEngineBrilloService : public android::brillo::BnUpdateEngine,
                                         public ServiceObserverInterface {
  public:
-  BinderUpdateEngineBrilloService(SystemState* system_state)
+  explicit BinderUpdateEngineBrilloService(SystemState* system_state)
       : common_(new UpdateEngineService(system_state)) {}
   virtual ~BinderUpdateEngineBrilloService() = default;
 
@@ -49,6 +50,7 @@
                         update_engine::UpdateStatus status,
                         const std::string& new_version,
                         int64_t new_size) override;
+  void SendPayloadApplicationComplete(ErrorCode error_code) override {}
   // Channel tracking changes are ignored.
   void SendChannelChangeUpdate(const std::string& tracking_channel) override {}
 
diff --git a/daemon.cc b/daemon.cc
index 27000d5..4c0c52f 100644
--- a/daemon.cc
+++ b/daemon.cc
@@ -90,7 +90,8 @@
 #if defined(__BRILLO__) || defined(__CHROMEOS__)
   binder_service_ = new BinderUpdateEngineBrilloService{real_system_state};
 #else  // !(defined(__BRILLO__) || defined(__CHROMEOS__))
-  binder_service_ = new BinderUpdateEngineAndroidService{daemon_state_android};
+  binder_service_ = new BinderUpdateEngineAndroidService{
+      daemon_state_android->service_delegate()};
 #endif  // defined(__BRILLO__) || defined(__CHROMEOS__)
   auto binder_wrapper = android::BinderWrapper::Get();
   if (!binder_wrapper->RegisterService(binder_service_->ServiceName(),
diff --git a/daemon_state_android.cc b/daemon_state_android.cc
index 3e89ad0..c1d9fcc 100644
--- a/daemon_state_android.cc
+++ b/daemon_state_android.cc
@@ -35,4 +35,9 @@
   service_observers_.erase(observer);
 }
 
+ServiceDelegateAndroidInterface* DaemonStateAndroid::service_delegate() {
+  // TODO(deymo): Implement a service delegate and return it here.
+  return nullptr;
+}
+
 }  // namespace chromeos_update_engine
diff --git a/daemon_state_android.h b/daemon_state_android.h
index 2b8926c..e0fac00 100644
--- a/daemon_state_android.h
+++ b/daemon_state_android.h
@@ -20,6 +20,7 @@
 #include <set>
 
 #include "update_engine/daemon_state_interface.h"
+#include "update_engine/service_delegate_android_interface.h"
 #include "update_engine/service_observer_interface.h"
 
 namespace chromeos_update_engine {
@@ -27,6 +28,7 @@
 class DaemonStateAndroid : public DaemonStateInterface {
  public:
   DaemonStateAndroid() = default;
+  ~DaemonStateAndroid() override = default;
 
   bool Initialize();
 
@@ -35,6 +37,13 @@
   void AddObserver(ServiceObserverInterface* observer) override;
   void RemoveObserver(ServiceObserverInterface* observer) override;
 
+  const std::set<ServiceObserverInterface*>& service_observers() {
+    return service_observers_;
+  }
+
+  // Return a pointer to the service delegate.
+  ServiceDelegateAndroidInterface* service_delegate();
+
  protected:
   std::set<ServiceObserverInterface*> service_observers_;
 };
diff --git a/dbus_service.h b/dbus_service.h
index fe250c8..b0c68e5 100644
--- a/dbus_service.h
+++ b/dbus_service.h
@@ -159,6 +159,8 @@
                         const std::string& new_version,
                         int64_t new_size) override;
 
+  void SendPayloadApplicationComplete(ErrorCode error_code) override {}
+
   // Channel tracking changes are ignored.
   void SendChannelChangeUpdate(const std::string& tracking_channel) override {}
 
diff --git a/service_delegate_android_interface.h b/service_delegate_android_interface.h
new file mode 100644
index 0000000..62e6540
--- /dev/null
+++ b/service_delegate_android_interface.h
@@ -0,0 +1,73 @@
+//
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef UPDATE_ENGINE_SERVICE_DELEGATE_ANDROID_INTERFACE_H_
+#define UPDATE_ENGINE_SERVICE_DELEGATE_ANDROID_INTERFACE_H_
+
+#include <inttypes.h>
+
+#include <string>
+#include <vector>
+
+#include <brillo/errors/error.h>
+
+namespace chromeos_update_engine {
+
+// This class defines the interface exposed by the Android version of the
+// daemon service. This interface only includes the method calls that such
+// daemon exposes. For asynchronous events initiated by a class implementing
+// this interface see the ServiceObserverInterface class.
+class ServiceDelegateAndroidInterface {
+ public:
+  virtual ~ServiceDelegateAndroidInterface() = default;
+
+  // Start an update attempt to download an apply the provided |payload_url| if
+  // no other update is running. The extra |key_value_pair_headers| will be
+  // included when fetching the payload. Returns whether the update was started
+  // successfully, which means that no other update was running and the passed
+  // parameters were correct, but not necessarily that the update finished
+  // correctly.
+  virtual bool ApplyPayload(
+      const std::string& payload_url,
+      int64_t payload_offset,
+      int64_t payload_size,
+      const std::vector<std::string>& key_value_pair_headers,
+      brillo::ErrorPtr* error) = 0;
+
+  // Suspend an ongoing update. Returns true if there was an update ongoing and
+  // it was suspended. In case of failure, it returns false and sets |error|
+  // accordingly.
+  virtual bool SuspendUpdate(brillo::ErrorPtr* error) = 0;
+
+  // Resumes an update suspended with SuspendUpdate(). The update can't be
+  // suspended after it finished and this method will fail in that case.
+  // Returns whether the resume operation was successful, which only implies
+  // that there was a suspended update. In case of error, returns false and sets
+  // |error| accordingly.
+  virtual bool ResumeUpdate(brillo::ErrorPtr* error) = 0;
+
+  // Cancel the ongoing update. The update could be running or suspended, but it
+  // can't be canceled after it was done. In case of error, returns false and
+  // sets |error| accordingly.
+  virtual bool CancelUpdate(brillo::ErrorPtr* error) = 0;
+
+ protected:
+  ServiceDelegateAndroidInterface() = default;
+};
+
+}  // namespace chromeos_update_engine
+
+#endif  // UPDATE_ENGINE_SERVICE_DELEGATE_ANDROID_INTERFACE_H_
diff --git a/service_observer_interface.h b/service_observer_interface.h
index 73d8350..75a739f 100644
--- a/service_observer_interface.h
+++ b/service_observer_interface.h
@@ -21,6 +21,7 @@
 #include <string>
 
 #include "update_engine/client_library/include/update_engine/update_status.h"
+#include "update_engine/common/error_code.h"
 
 namespace chromeos_update_engine {
 
@@ -36,6 +37,9 @@
                                 const std::string& new_version,
                                 int64_t new_size) = 0;
 
+  // Called whenever an update attempt is completed.
+  virtual void SendPayloadApplicationComplete(ErrorCode error_code) = 0;
+
   // Called whenever the channel we are tracking changes.
   virtual void SendChannelChangeUpdate(const std::string& tracking_channel) = 0;
 
diff --git a/weave_service.h b/weave_service.h
index b1068e7..5a3aff3 100644
--- a/weave_service.h
+++ b/weave_service.h
@@ -42,6 +42,7 @@
                         const std::string& new_version,
                         int64_t new_size) override;
   void SendChannelChangeUpdate(const std::string& tracking_channel) override;
+  void SendPayloadApplicationComplete(ErrorCode error_code) override {}
 
  private:
   // Force a weave update.