Add binder_service_stable_android am: 2562cf2960
Original change: https://android-review.googlesource.com/c/platform/system/update_engine/+/1371070
Change-Id: Ie1ad27b60e8cfc5044a421a56cbdb0b0606a95fb
diff --git a/Android.bp b/Android.bp
index 4e3e248..b8cff0a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -272,6 +272,7 @@
"libbrillo-binder",
"libcurl",
"libcutils",
+ "libupdate_engine_stable-cpp",
"liblog",
"libssl",
"libstatslog",
@@ -298,6 +299,7 @@
srcs: [
":libupdate_engine_aidl",
"binder_service_android.cc",
+ "binder_service_stable_android.cc",
"certificate_checker.cc",
"daemon_android.cc",
"daemon_state_android.cc",
diff --git a/binder_service_android.cc b/binder_service_android.cc
index 6b8a552..0c8bc2f 100644
--- a/binder_service_android.cc
+++ b/binder_service_android.cc
@@ -24,6 +24,8 @@
#include <brillo/errors/error.h>
#include <utils/String8.h>
+#include "update_engine/binder_service_android_common.h"
+
using android::binder::Status;
using android::os::IUpdateEngineCallback;
using android::os::ParcelFileDescriptor;
@@ -31,23 +33,6 @@
using std::vector;
using update_engine::UpdateEngineStatus;
-namespace {
-Status ErrorPtrToStatus(const brillo::ErrorPtr& error) {
- return Status::fromServiceSpecificError(
- 1, android::String8{error->GetMessage().c_str()});
-}
-
-vector<string> ToVecString(const vector<android::String16>& inp) {
- vector<string> out;
- out.reserve(inp.size());
- for (const auto& e : inp) {
- out.emplace_back(android::String8{e}.string());
- }
- return out;
-}
-
-} // namespace
-
namespace chromeos_update_engine {
BinderUpdateEngineAndroidService::BinderUpdateEngineAndroidService(
diff --git a/binder_service_android_common.h b/binder_service_android_common.h
new file mode 100644
index 0000000..fc621d9
--- /dev/null
+++ b/binder_service_android_common.h
@@ -0,0 +1,45 @@
+//
+// Copyright (C) 2020 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_BINDER_SERVICE_ANDROID_COMMON_H_
+#define UPDATE_ENGINE_BINDER_SERVICE_ANDROID_COMMON_H_
+
+#include <string>
+#include <vector>
+
+#include <binder/Status.h>
+
+namespace chromeos_update_engine {
+
+static inline android::binder::Status ErrorPtrToStatus(
+ const brillo::ErrorPtr& error) {
+ return android::binder::Status::fromServiceSpecificError(
+ 1, android::String8{error->GetMessage().c_str()});
+}
+
+static inline std::vector<std::string> ToVecString(
+ const std::vector<android::String16>& inp) {
+ std::vector<std::string> out;
+ out.reserve(inp.size());
+ for (const auto& e : inp) {
+ out.emplace_back(android::String8{e}.string());
+ }
+ return out;
+}
+
+} // namespace chromeos_update_engine
+
+#endif // UPDATE_ENGINE_BINDER_SERVICE_ANDROID_COMMON_H_
diff --git a/binder_service_stable_android.cc b/binder_service_stable_android.cc
new file mode 100644
index 0000000..a12b349
--- /dev/null
+++ b/binder_service_stable_android.cc
@@ -0,0 +1,132 @@
+//
+// Copyright (C) 2020 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.
+//
+
+#include "update_engine/binder_service_stable_android.h"
+
+#include <memory>
+
+#include <base/bind.h>
+#include <base/logging.h>
+#include <binderwrapper/binder_wrapper.h>
+#include <brillo/errors/error.h>
+#include <utils/String8.h>
+
+#include "update_engine/binder_service_android_common.h"
+
+using android::binder::Status;
+using android::os::IUpdateEngineStableCallback;
+using android::os::ParcelFileDescriptor;
+using std::string;
+using std::vector;
+using update_engine::UpdateEngineStatus;
+
+namespace chromeos_update_engine {
+
+BinderUpdateEngineAndroidStableService::BinderUpdateEngineAndroidStableService(
+ ServiceDelegateAndroidInterface* service_delegate)
+ : service_delegate_(service_delegate) {}
+
+void BinderUpdateEngineAndroidStableService::SendStatusUpdate(
+ const UpdateEngineStatus& update_engine_status) {
+ last_status_ = static_cast<int>(update_engine_status.status);
+ last_progress_ = update_engine_status.progress;
+ if (callback_) {
+ callback_->onStatusUpdate(last_status_, last_progress_);
+ }
+}
+
+void BinderUpdateEngineAndroidStableService::SendPayloadApplicationComplete(
+ ErrorCode error_code) {
+ if (callback_) {
+ callback_->onPayloadApplicationComplete(static_cast<int>(error_code));
+ }
+}
+
+Status BinderUpdateEngineAndroidStableService::bind(
+ const android::sp<IUpdateEngineStableCallback>& callback,
+ bool* return_value) {
+ // Reject binding if another callback is already bound.
+ if (callback_ != nullptr) {
+ LOG(ERROR) << "Another callback is already bound. Can't bind new callback.";
+ *return_value = false;
+ return Status::ok();
+ }
+
+ // See BinderUpdateEngineAndroidService::bind.
+ if (last_status_ != -1) {
+ auto status = callback->onStatusUpdate(last_status_, last_progress_);
+ if (!status.isOk()) {
+ LOG(ERROR) << "Failed to call onStatusUpdate() from callback: "
+ << status.toString8();
+ *return_value = false;
+ return Status::ok();
+ }
+ }
+
+ callback_ = callback;
+
+ const android::sp<IBinder>& callback_binder =
+ IUpdateEngineStableCallback::asBinder(callback);
+ auto binder_wrapper = android::BinderWrapper::Get();
+ binder_wrapper->RegisterForDeathNotifications(
+ callback_binder,
+ base::Bind(base::IgnoreResult(
+ &BinderUpdateEngineAndroidStableService::UnbindCallback),
+ base::Unretained(this),
+ base::Unretained(callback_binder.get())));
+
+ *return_value = true;
+ return Status::ok();
+}
+
+Status BinderUpdateEngineAndroidStableService::unbind(
+ const android::sp<IUpdateEngineStableCallback>& callback,
+ bool* return_value) {
+ const android::sp<IBinder>& callback_binder =
+ IUpdateEngineStableCallback::asBinder(callback);
+ auto binder_wrapper = android::BinderWrapper::Get();
+ binder_wrapper->UnregisterForDeathNotifications(callback_binder);
+
+ *return_value = UnbindCallback(callback_binder.get());
+ return Status::ok();
+}
+
+Status BinderUpdateEngineAndroidStableService::applyPayloadFd(
+ const ParcelFileDescriptor& pfd,
+ int64_t payload_offset,
+ int64_t payload_size,
+ const vector<android::String16>& header_kv_pairs) {
+ vector<string> str_headers = ToVecString(header_kv_pairs);
+
+ brillo::ErrorPtr error;
+ if (!service_delegate_->ApplyPayload(
+ pfd.get(), payload_offset, payload_size, str_headers, &error)) {
+ return ErrorPtrToStatus(error);
+ }
+ return Status::ok();
+}
+
+bool BinderUpdateEngineAndroidStableService::UnbindCallback(
+ const IBinder* callback) {
+ if (IUpdateEngineStableCallback::asBinder(callback_).get() != callback) {
+ LOG(ERROR) << "Unable to unbind unknown callback.";
+ return false;
+ }
+ callback_ = nullptr;
+ return true;
+}
+
+} // namespace chromeos_update_engine
diff --git a/binder_service_stable_android.h b/binder_service_stable_android.h
new file mode 100644
index 0000000..1667798
--- /dev/null
+++ b/binder_service_stable_android.h
@@ -0,0 +1,85 @@
+//
+// Copyright (C) 2020 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_BINDER_SERVICE_STABLE_ANDROID_H_
+#define UPDATE_ENGINE_BINDER_SERVICE_STABLE_ANDROID_H_
+
+#include <stdint.h>
+
+#include <string>
+#include <vector>
+
+#include <utils/Errors.h>
+#include <utils/String16.h>
+#include <utils/StrongPointer.h>
+
+#include "android/os/BnUpdateEngineStable.h"
+#include "android/os/IUpdateEngineStableCallback.h"
+#include "update_engine/service_delegate_android_interface.h"
+#include "update_engine/service_observer_interface.h"
+
+namespace chromeos_update_engine {
+
+class BinderUpdateEngineAndroidStableService
+ : public android::os::BnUpdateEngineStable,
+ public ServiceObserverInterface {
+ public:
+ explicit BinderUpdateEngineAndroidStableService(
+ ServiceDelegateAndroidInterface* service_delegate);
+ ~BinderUpdateEngineAndroidStableService() override = default;
+
+ const char* ServiceName() const {
+ return "android.os.UpdateEngineStableService";
+ }
+
+ // ServiceObserverInterface overrides.
+ void SendStatusUpdate(
+ const update_engine::UpdateEngineStatus& update_engine_status) override;
+ void SendPayloadApplicationComplete(ErrorCode error_code) override;
+
+ // android::os::BnUpdateEngineStable overrides.
+ android::binder::Status applyPayloadFd(
+ const ::android::os::ParcelFileDescriptor& pfd,
+ 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::IUpdateEngineStableCallback>& callback,
+ bool* return_value) override;
+ android::binder::Status unbind(
+ const android::sp<android::os::IUpdateEngineStableCallback>& callback,
+ bool* return_value) override;
+
+ private:
+ // Remove the passed |callback| from the list of registered callbacks. Called
+ // on unbind() or whenever the callback object is destroyed.
+ // Returns true on success.
+ bool UnbindCallback(const IBinder* callback);
+
+ // Bound callback. The stable interface only supports one callback at a time.
+ android::sp<android::os::IUpdateEngineStableCallback> callback_;
+
+ // Cached copy of the last status update sent. Used to send an initial
+ // notification when bind() is called from the client.
+ int last_status_{-1};
+ double last_progress_{0.0};
+
+ ServiceDelegateAndroidInterface* service_delegate_;
+};
+
+} // namespace chromeos_update_engine
+
+#endif // UPDATE_ENGINE_BINDER_SERVICE_STABLE_ANDROID_H_
diff --git a/daemon_android.cc b/daemon_android.cc
index 1aa921f..313d7dd 100644
--- a/daemon_android.cc
+++ b/daemon_android.cc
@@ -47,16 +47,26 @@
LOG_IF(ERROR, !daemon_state_android->Initialize())
<< "Failed to initialize system state.";
+ auto binder_wrapper = android::BinderWrapper::Get();
+
// Create the Binder Service.
binder_service_ = new BinderUpdateEngineAndroidService{
daemon_state_android->service_delegate()};
- auto binder_wrapper = android::BinderWrapper::Get();
if (!binder_wrapper->RegisterService(binder_service_->ServiceName(),
binder_service_)) {
LOG(ERROR) << "Failed to register binder service.";
}
-
daemon_state_->AddObserver(binder_service_.get());
+
+ // Create the stable binder service.
+ stable_binder_service_ = new BinderUpdateEngineAndroidStableService{
+ daemon_state_android->service_delegate()};
+ if (!binder_wrapper->RegisterService(stable_binder_service_->ServiceName(),
+ stable_binder_service_)) {
+ LOG(ERROR) << "Failed to register stable binder service.";
+ }
+ daemon_state_->AddObserver(stable_binder_service_.get());
+
daemon_state_->StartUpdater();
return EX_OK;
}
diff --git a/daemon_android.h b/daemon_android.h
index baead37..f0c028e 100644
--- a/daemon_android.h
+++ b/daemon_android.h
@@ -22,6 +22,7 @@
#include <brillo/binder_watcher.h>
#include "update_engine/binder_service_android.h"
+#include "update_engine/binder_service_stable_android.h"
#include "update_engine/common/subprocess.h"
#include "update_engine/daemon_base.h"
#include "update_engine/daemon_state_interface.h"
@@ -43,6 +44,7 @@
brillo::BinderWatcher binder_watcher_;
android::sp<BinderUpdateEngineAndroidService> binder_service_;
+ android::sp<BinderUpdateEngineAndroidStableService> stable_binder_service_;
// The daemon state with all the required daemon classes for the configured
// platform.