Make client use binder interface on brillo
TEST=Verified status and update commands
Bug: 25908638
Change-Id: I7994de41001b4e116bffa539f23f1344ab1deae9
diff --git a/Android.mk b/Android.mk
index aa3b9ee..892de7b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -426,9 +426,7 @@
LOCAL_STATIC_LIBRARIES := update_engine_client-dbus-proxies
LOCAL_SHARED_LIBRARIES := \
$(ue_common_shared_libraries) \
- libdbus \
- libbrillo-dbus \
- libchrome-dbus \
+ libutils \
libupdate_engine_client
LOCAL_SRC_FILES := \
update_engine_client.cc
@@ -605,6 +603,7 @@
LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/binder_bindings
LOCAL_SHARED_LIBRARIES += \
libbinder \
+ libbrillo-binder \
libutils
LOCAL_SRC_FILES += \
binder_bindings/android/brillo/IUpdateEngine.aidl \
diff --git a/binder_service.cc b/binder_service.cc
index 19acf6e..07ff22d 100644
--- a/binder_service.cc
+++ b/binder_service.cc
@@ -16,6 +16,10 @@
#include "update_engine/binder_service.h"
+#include <base/bind.h>
+
+#include <binderwrapper/binder_wrapper.h>
+
#include <utils/String16.h>
#include <utils/StrongPointer.h>
@@ -166,7 +170,43 @@
Status BinderUpdateEngineService::RegisterStatusCallback(
const sp<IUpdateEngineStatusCallback>& callback) {
+ callbacks_.emplace_back(callback);
+
+ auto binder_wrapper = android::BinderWrapper::Get();
+
+ binder_wrapper->RegisterForDeathNotifications(
+ IUpdateEngineStatusCallback::asBinder(callback),
+ base::Bind(&BinderUpdateEngineService::UnregisterStatusCallback,
+ base::Unretained(this), base::Unretained(callback.get())));
+
return Status::ok();
}
+void BinderUpdateEngineService::UnregisterStatusCallback(
+ IUpdateEngineStatusCallback* callback) {
+ auto it = callbacks_.begin();
+
+ for (; it != callbacks_.end() && it->get() != callback; it++)
+ ;
+
+ if (it == callbacks_.end()) {
+ LOG(ERROR) << "Got death notification for unknown callback.";
+ return;
+ }
+
+ LOG(INFO) << "Erasing orphan callback";
+ callbacks_.erase(it);
+}
+
+void BinderUpdateEngineService::SendStatusUpdate(
+ int64_t in_last_checked_time, double in_progress,
+ const std::string& in_current_operation, const std::string& in_new_version,
+ int64_t in_new_size) {
+ for (auto& callback : callbacks_) {
+ callback->HandleStatusUpdate(in_last_checked_time, in_progress,
+ String16{in_current_operation.c_str()},
+ String16{in_new_version.c_str()}, in_new_size);
+ }
+}
+
} // namespace chromeos_update_engine
diff --git a/binder_service.h b/binder_service.h
index ddbd147..b9b2ea5 100644
--- a/binder_service.h
+++ b/binder_service.h
@@ -19,6 +19,10 @@
#include <utils/Errors.h>
+#include <vector>
+
+#include <utils/RefBase.h>
+
#include "update_engine/common_service.h"
#include "update_engine/parcelable_update_engine_status.h"
@@ -33,6 +37,10 @@
: common_(new UpdateEngineService(system_state)) {}
virtual ~BinderUpdateEngineService() = default;
+ void SendStatusUpdate(int64_t in_last_checked_time, double in_progress,
+ const std::string& in_current_operation,
+ const std::string& in_new_version, int64_t in_new_size);
+
// android::brillo::BnUpdateEngine overrides.
android::binder::Status AttemptUpdate(const android::String16& app_version,
const android::String16& omaha_url,
@@ -65,12 +73,20 @@
override;
private:
+ // Generic function for dispatching to the common service.
template<typename... Parameters, typename... Arguments>
android::binder::Status CallCommonHandler(
bool (UpdateEngineService::*Handler)(brillo::ErrorPtr*, Parameters...),
Arguments... arguments);
+ // To be used as a death notification handler only.
+ void UnregisterStatusCallback(
+ android::brillo::IUpdateEngineStatusCallback* callback);
+
std::unique_ptr<UpdateEngineService> common_;
+
+ std::vector<android::sp<android::brillo::IUpdateEngineStatusCallback>>
+ callbacks_;
}; // class BinderService
} // namespace chromeos_update_engine
diff --git a/client_library/client_binder.cc b/client_library/client_binder.cc
index b3bd3e7..969c5e9 100644
--- a/client_library/client_binder.cc
+++ b/client_library/client_binder.cc
@@ -19,7 +19,6 @@
#include <binder/IServiceManager.h>
#include <base/message_loop/message_loop.h>
-#include <utils/String16.h>
#include <utils/String8.h>
#include "update_engine/parcelable_update_engine_status.h"
@@ -29,6 +28,7 @@
using android::String16;
using android::String8;
using android::brillo::ParcelableUpdateEngineStatus;
+using android::binder::Status;
using android::getService;
using chromeos_update_engine::StringToUpdateStatus;
using std::string;
@@ -37,6 +37,8 @@
namespace internal {
bool BinderUpdateEngineClient::Init() {
+ if (!binder_watcher_.Init()) return false;
+
return getService(String16{"android.brillo.UpdateEngineService"},
&service_) == OK;
}
@@ -123,8 +125,36 @@
return service_->ResetStatus().isOk();
}
-void BinderUpdateEngineClient::RegisterStatusUpdateHandler(
+Status BinderUpdateEngineClient::StatusUpdateCallback::HandleStatusUpdate(
+ int64_t last_checked_time,
+ double progress,
+ const String16& current_operation,
+ const String16& new_version,
+ int64_t new_size) {
+ UpdateStatus update_status;
+
+ StringToUpdateStatus(String8{current_operation}.string(), &update_status);
+
+ for (auto& handler : client_->handlers_) {
+ handler->HandleStatusUpdate(last_checked_time, progress, update_status,
+ String8{new_version}.string(), new_size);
+ }
+
+ return Status::ok();
+}
+
+bool BinderUpdateEngineClient::RegisterStatusUpdateHandler(
StatusUpdateHandler* handler) {
+ if (!status_callback_.get()) {
+ status_callback_ =
+ new BinderUpdateEngineClient::StatusUpdateCallback(this);
+ if (!service_->RegisterStatusCallback(status_callback_).isOk()) {
+ return false;
+ }
+ }
+
+ handlers_.push_back(handler);
+ return true;
}
bool BinderUpdateEngineClient::SetTargetChannel(const string& in_target_channel,
diff --git a/client_library/client_binder.h b/client_library/client_binder.h
index 22d1cf0..744b238 100644
--- a/client_library/client_binder.h
+++ b/client_library/client_binder.h
@@ -20,11 +20,17 @@
#include <cstdint>
#include <memory>
#include <string>
+#include <vector>
#include <base/macros.h>
#include <utils/StrongPointer.h>
+#include <utils/String16.h>
+
+#include <brillo/binder_watcher.h>
#include "android/brillo/IUpdateEngine.h"
+#include "android/brillo/BnUpdateEngineStatusCallback.h"
+
#include "update_engine/client_library/include/update_engine/client.h"
@@ -71,10 +77,29 @@
bool GetChannel(std::string* out_channel) const override;
- void RegisterStatusUpdateHandler(StatusUpdateHandler* handler) override;
+ bool RegisterStatusUpdateHandler(StatusUpdateHandler* handler) override;
private:
+ class StatusUpdateCallback :
+ public android::brillo::BnUpdateEngineStatusCallback {
+ public:
+ StatusUpdateCallback(BinderUpdateEngineClient* client) : client_(client) {}
+
+ android::binder::Status HandleStatusUpdate(
+ int64_t last_checked_time,
+ double progress,
+ const android::String16& current_operation,
+ const android::String16& new_version,
+ int64_t new_size) override;
+
+ private:
+ BinderUpdateEngineClient* client_;
+ };
+
android::sp<android::brillo::IUpdateEngine> service_;
+ android::sp<android::brillo::IUpdateEngineStatusCallback> status_callback_;
+ std::vector<update_engine::StatusUpdateHandler*> handlers_;
+ brillo::BinderWatcher binder_watcher_;
DISALLOW_COPY_AND_ASSIGN(BinderUpdateEngineClient);
}; // class BinderUpdateEngineClient
diff --git a/client_library/client_dbus.cc b/client_library/client_dbus.cc
index 0d02936..d9b4a05 100644
--- a/client_library/client_dbus.cc
+++ b/client_library/client_dbus.cc
@@ -159,20 +159,20 @@
last_checked_time, progress, status, new_version, new_size);
}
-void DBusUpdateEngineClient::RegisterStatusUpdateHandler(
+bool DBusUpdateEngineClient::RegisterStatusUpdateHandler(
StatusUpdateHandler* handler) {
if (!base::MessageLoopForIO::current()) {
LOG(FATAL) << "Cannot get UpdateEngineClient outside of message loop.";
- return;
+ return false;
}
proxy_->RegisterStatusUpdateSignalHandler(
base::Bind(&DBusUpdateEngineClient::RunStatusUpdateHandler,
- base::Unretained(this),
- base::Unretained(handler)),
+ base::Unretained(this), base::Unretained(handler)),
base::Bind(&DBusUpdateEngineClient::StatusUpdateHandlerRegistered,
- base::Unretained(this),
- base::Unretained(handler)));
+ base::Unretained(this), base::Unretained(handler)));
+
+ return true;
}
bool DBusUpdateEngineClient::SetTargetChannel(const string& in_target_channel,
diff --git a/client_library/client_dbus.h b/client_library/client_dbus.h
index 3590a21..e6bbe36 100644
--- a/client_library/client_dbus.h
+++ b/client_library/client_dbus.h
@@ -69,7 +69,7 @@
bool GetChannel(std::string* out_channel) const override;
- void RegisterStatusUpdateHandler(StatusUpdateHandler* handler) override;
+ bool RegisterStatusUpdateHandler(StatusUpdateHandler* handler) override;
private:
std::unique_ptr<org::chromium::UpdateEngineInterfaceProxy> proxy_;
diff --git a/client_library/include/update_engine/client.h b/client_library/include/update_engine/client.h
index 8bfb631..f2af453 100644
--- a/client_library/include/update_engine/client.h
+++ b/client_library/include/update_engine/client.h
@@ -106,7 +106,7 @@
// not be registered. Otherwise its HandleStatusUpdate method will be called
// every time update_engine's status changes. Will always report the status
// on registration to prevent race conditions.
- virtual void RegisterStatusUpdateHandler(StatusUpdateHandler* handler) = 0;
+ virtual bool RegisterStatusUpdateHandler(StatusUpdateHandler* handler) = 0;
protected:
// Use CreateInstance().
diff --git a/daemon.cc b/daemon.cc
index 3f88a84..ece151c 100644
--- a/daemon.cc
+++ b/daemon.cc
@@ -90,6 +90,10 @@
service_)) {
LOG(ERROR) << "Failed to register binder service.";
}
+
+#if defined(__BRILLO__) || defined(__CHROMEOS__)
+ update_attempter->set_binder_service(service_.get());
+#endif // defined(__BRILLO__) || defined(__CHROMEOS__)
#endif // USE_BINDER
#if USE_DBUS
diff --git a/update_attempter.cc b/update_attempter.cc
index 9b68c44..d0c20d0 100644
--- a/update_attempter.cc
+++ b/update_attempter.cc
@@ -1217,6 +1217,13 @@
if (system_state_->weave_service())
system_state_->weave_service()->UpdateWeaveState();
+#if USE_BINDER
+ if (binder_service_)
+ binder_service_->SendStatusUpdate(last_checked_time_, download_progress_,
+ UpdateStatusToString(status_),
+ new_version_.c_str(), new_payload_size_);
+#endif // USE_BINDER
+
if (!dbus_adaptor_)
return;
last_notify_time_ = TimeTicks::Now();
diff --git a/update_attempter.h b/update_attempter.h
index 3a2c30d..2401d60 100644
--- a/update_attempter.h
+++ b/update_attempter.h
@@ -28,6 +28,10 @@
#include <base/time/time.h>
#include <gtest/gtest_prod.h> // for FRIEND_TEST
+#if USE_BINDER
+#include "update_engine/binder_service.h"
+#endif // USE_BINDER
+
#include "debugd/dbus-proxies.h"
#include "update_engine/chrome_browser_proxy_resolver.h"
#include "update_engine/client_library/include/update_engine/update_status.h"
@@ -138,6 +142,12 @@
dbus_adaptor_ = dbus_adaptor;
}
+#if USE_BINDER
+ void set_binder_service(BinderUpdateEngineService* service) {
+ binder_service_ = service;
+ }
+#endif
+
// This is the internal entry point for going through an
// update. If the current status is idle invokes Update.
// This is called by the DBus implementation.
@@ -415,6 +425,12 @@
// dbus service.
UpdateEngineAdaptor* dbus_adaptor_ = nullptr;
+#if USE_BINDER
+ // If non-null, this UpdateAttempter will send status updates over this
+ // binder interface.
+ BinderUpdateEngineService* binder_service_ = nullptr;
+#endif // USE_BINDER
+
// Pointer to the OmahaResponseHandlerAction in the actions_ vector.
std::shared_ptr<OmahaResponseHandlerAction> response_handler_action_;