1 //
2 // Copyright (C) 2020 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include "update_engine/aosp/binder_service_stable_android.h"
18
19 #include <memory>
20
21 #include <base/bind.h>
22 #include <base/logging.h>
23 #include <binderwrapper/binder_wrapper.h>
24 #include <utils/String8.h>
25
26 #include "update_engine/aosp/binder_service_android_common.h"
27
28 using android::binder::Status;
29 using android::os::IUpdateEngineStableCallback;
30 using android::os::ParcelFileDescriptor;
31 using std::string;
32 using std::vector;
33 using update_engine::UpdateEngineStatus;
34
35 namespace chromeos_update_engine {
36
BinderUpdateEngineAndroidStableService(ServiceDelegateAndroidInterface * service_delegate)37 BinderUpdateEngineAndroidStableService::BinderUpdateEngineAndroidStableService(
38 ServiceDelegateAndroidInterface* service_delegate)
39 : service_delegate_(service_delegate) {}
40
SendStatusUpdate(const UpdateEngineStatus & update_engine_status)41 void BinderUpdateEngineAndroidStableService::SendStatusUpdate(
42 const UpdateEngineStatus& update_engine_status) {
43 last_status_ = static_cast<int>(update_engine_status.status);
44 last_progress_ = update_engine_status.progress;
45 if (callback_) {
46 callback_->onStatusUpdate(last_status_, last_progress_);
47 }
48 }
49
SendPayloadApplicationComplete(ErrorCode error_code)50 void BinderUpdateEngineAndroidStableService::SendPayloadApplicationComplete(
51 ErrorCode error_code) {
52 if (callback_) {
53 callback_->onPayloadApplicationComplete(static_cast<int>(error_code));
54 }
55 }
56
bind(const android::sp<IUpdateEngineStableCallback> & callback,bool * return_value)57 Status BinderUpdateEngineAndroidStableService::bind(
58 const android::sp<IUpdateEngineStableCallback>& callback,
59 bool* return_value) {
60 // Reject binding if another callback is already bound.
61 if (callback_ != nullptr) {
62 LOG(ERROR) << "Another callback is already bound. Can't bind new callback.";
63 *return_value = false;
64 return Status::ok();
65 }
66
67 // See BinderUpdateEngineAndroidService::bind.
68 if (last_status_ != -1) {
69 auto status = callback->onStatusUpdate(last_status_, last_progress_);
70 if (!status.isOk()) {
71 LOG(ERROR) << "Failed to call onStatusUpdate() from callback: "
72 << status.toString8();
73 *return_value = false;
74 return Status::ok();
75 }
76 }
77
78 callback_ = callback;
79
80 const android::sp<IBinder>& callback_binder =
81 IUpdateEngineStableCallback::asBinder(callback);
82 auto binder_wrapper = android::BinderWrapper::Get();
83 binder_wrapper->RegisterForDeathNotifications(
84 callback_binder,
85 [this, callback = callback_binder.get()]() { UnbindCallback(callback); });
86
87 *return_value = true;
88 return Status::ok();
89 }
90
unbind(const android::sp<IUpdateEngineStableCallback> & callback,bool * return_value)91 Status BinderUpdateEngineAndroidStableService::unbind(
92 const android::sp<IUpdateEngineStableCallback>& callback,
93 bool* return_value) {
94 const android::sp<IBinder>& callback_binder =
95 IUpdateEngineStableCallback::asBinder(callback);
96 auto binder_wrapper = android::BinderWrapper::Get();
97 binder_wrapper->UnregisterForDeathNotifications(callback_binder);
98
99 *return_value = UnbindCallback(callback_binder.get());
100 return Status::ok();
101 }
102
applyPayloadFd(const ParcelFileDescriptor & pfd,int64_t payload_offset,int64_t payload_size,const vector<android::String16> & header_kv_pairs)103 Status BinderUpdateEngineAndroidStableService::applyPayloadFd(
104 const ParcelFileDescriptor& pfd,
105 int64_t payload_offset,
106 int64_t payload_size,
107 const vector<android::String16>& header_kv_pairs) {
108 vector<string> str_headers = ToVecString(header_kv_pairs);
109
110 Error error;
111 if (!service_delegate_->ApplyPayload(
112 pfd.get(), payload_offset, payload_size, str_headers, &error)) {
113 return ErrorPtrToStatus(error);
114 }
115 return Status::ok();
116 }
117
UnbindCallback(const IBinder * callback)118 bool BinderUpdateEngineAndroidStableService::UnbindCallback(
119 const IBinder* callback) {
120 if (IUpdateEngineStableCallback::asBinder(callback_).get() != callback) {
121 LOG(ERROR) << "Unable to unbind unknown callback.";
122 return false;
123 }
124 callback_ = nullptr;
125 return true;
126 }
127
128 } // namespace chromeos_update_engine
129