diff options
author | Yifan Hong <elsk@google.com> | 2020-08-04 19:15:49 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-08-04 19:15:49 +0000 |
commit | 29b8115b51ead2445a9ab747afcc40e3e84b8f3a (patch) | |
tree | 7c45b7d14abd6710b55aa01240f51c7fa04f1bdf | |
parent | e7e72fae64996db0614798ea9615f51758fd7ad1 (diff) | |
parent | 2562cf2960c97acdaac2dee7e306cd3c88cd9c68 (diff) |
Add binder_service_stable_android am: 2562cf2960
Original change: https://android-review.googlesource.com/c/platform/system/update_engine/+/1371070
Change-Id: Ie1ad27b60e8cfc5044a421a56cbdb0b0606a95fb
-rw-r--r-- | Android.bp | 2 | ||||
-rw-r--r-- | binder_service_android.cc | 19 | ||||
-rw-r--r-- | binder_service_android_common.h | 45 | ||||
-rw-r--r-- | binder_service_stable_android.cc | 132 | ||||
-rw-r--r-- | binder_service_stable_android.h | 85 | ||||
-rw-r--r-- | daemon_android.cc | 14 | ||||
-rw-r--r-- | daemon_android.h | 2 |
7 files changed, 280 insertions, 19 deletions
@@ -272,6 +272,7 @@ cc_defaults { "libbrillo-binder", "libcurl", "libcutils", + "libupdate_engine_stable-cpp", "liblog", "libssl", "libstatslog", @@ -298,6 +299,7 @@ cc_library_static { 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 6b8a5529..0c8bc2f4 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::string; 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 00000000..fc621d97 --- /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 00000000..a12b349b --- /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 00000000..16677980 --- /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 1aa921f8..313d7ddc 100644 --- a/daemon_android.cc +++ b/daemon_android.cc @@ -47,16 +47,26 @@ int DaemonAndroid::OnInit() { 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 baead373..f0c028ec 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 @@ class DaemonAndroid : public DaemonBase { 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. |