blob: 84b5b7a90cbcb71c3274903a73161054fe8bf6ec [file] [log] [blame]
Casey Dahlina93cd532016-01-14 16:55:11 -08001//
2// Copyright (C) 2015 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
Amin Hassaniec7bc112020-10-29 16:47:58 -070017#include "update_engine/aosp/binder_service_android.h"
Casey Dahlina93cd532016-01-14 16:55:11 -080018
Yifan Hong40bb0d02020-02-24 17:33:14 -080019#include <memory>
20
Alex Deymof8bfcff2016-02-02 21:22:11 -080021#include <base/bind.h>
22#include <base/logging.h>
23#include <binderwrapper/binder_wrapper.h>
24#include <brillo/errors/error.h>
25#include <utils/String8.h>
26
Amin Hassaniec7bc112020-10-29 16:47:58 -070027#include "update_engine/aosp/binder_service_android_common.h"
Yifan Hong2562cf22020-07-21 19:28:44 -070028
Casey Dahlina93cd532016-01-14 16:55:11 -080029using android::binder::Status;
30using android::os::IUpdateEngineCallback;
Kyeongkab.Nam42132992019-10-03 18:04:02 +090031using android::os::ParcelFileDescriptor;
Kyeongkab.Nam500ca132019-06-26 13:48:07 +090032using std::string;
33using std::vector;
Aaron Wood7f92e2b2017-08-28 14:51:21 -070034using update_engine::UpdateEngineStatus;
Alex Deymof8bfcff2016-02-02 21:22:11 -080035
Casey Dahlina93cd532016-01-14 16:55:11 -080036namespace chromeos_update_engine {
37
Alex Deymofa78f142016-01-26 21:36:16 -080038BinderUpdateEngineAndroidService::BinderUpdateEngineAndroidService(
Alex Deymof8bfcff2016-02-02 21:22:11 -080039 ServiceDelegateAndroidInterface* service_delegate)
Amin Hassani7cc8bb02019-01-14 16:29:47 -080040 : service_delegate_(service_delegate) {}
Alex Deymofa78f142016-01-26 21:36:16 -080041
42void BinderUpdateEngineAndroidService::SendStatusUpdate(
Aaron Wood7f92e2b2017-08-28 14:51:21 -070043 const UpdateEngineStatus& update_engine_status) {
44 last_status_ = static_cast<int>(update_engine_status.status);
45 last_progress_ = update_engine_status.progress;
Alex Deymof8bfcff2016-02-02 21:22:11 -080046 for (auto& callback : callbacks_) {
Alex Deymo0e061ae2016-02-09 17:49:03 -080047 callback->onStatusUpdate(last_status_, last_progress_);
Alex Deymof8bfcff2016-02-02 21:22:11 -080048 }
49}
50
51void BinderUpdateEngineAndroidService::SendPayloadApplicationComplete(
52 ErrorCode error_code) {
53 for (auto& callback : callbacks_) {
54 callback->onPayloadApplicationComplete(static_cast<int>(error_code));
55 }
Alex Deymofa78f142016-01-26 21:36:16 -080056}
57
Alex Deymoe97b39c2016-01-20 13:22:17 -080058Status BinderUpdateEngineAndroidService::bind(
Alex Deymof8bfcff2016-02-02 21:22:11 -080059 const android::sp<IUpdateEngineCallback>& callback, bool* return_value) {
Tianjie Xu60f3a232019-12-11 13:53:39 -080060 // Send an status update on connection (except when no update sent so far).
61 // Even though the status update is oneway, it still returns an erroneous
62 // status in case of a selinux denial. We should at least check this status
63 // and fails the binding.
64 if (last_status_ != -1) {
65 auto status = callback->onStatusUpdate(last_status_, last_progress_);
66 if (!status.isOk()) {
67 LOG(ERROR) << "Failed to call onStatusUpdate() from callback: "
68 << status.toString8();
69 *return_value = false;
70 return Status::ok();
71 }
72 }
73
Alex Deymof8bfcff2016-02-02 21:22:11 -080074 callbacks_.emplace_back(callback);
75
Sen Jiangb7f73802017-07-18 15:29:26 -070076 const android::sp<IBinder>& callback_binder =
77 IUpdateEngineCallback::asBinder(callback);
Alex Deymof8bfcff2016-02-02 21:22:11 -080078 auto binder_wrapper = android::BinderWrapper::Get();
79 binder_wrapper->RegisterForDeathNotifications(
Sen Jiangb7f73802017-07-18 15:29:26 -070080 callback_binder,
Sen Jiang5caab192017-07-07 17:22:29 -070081 base::Bind(
82 base::IgnoreResult(&BinderUpdateEngineAndroidService::UnbindCallback),
83 base::Unretained(this),
Sen Jiangb7f73802017-07-18 15:29:26 -070084 base::Unretained(callback_binder.get())));
Alex Deymof8bfcff2016-02-02 21:22:11 -080085
Casey Dahlina93cd532016-01-14 16:55:11 -080086 *return_value = true;
87 return Status::ok();
88}
89
Sen Jiang5caab192017-07-07 17:22:29 -070090Status BinderUpdateEngineAndroidService::unbind(
91 const android::sp<IUpdateEngineCallback>& callback, bool* return_value) {
Sen Jiangb7f73802017-07-18 15:29:26 -070092 const android::sp<IBinder>& callback_binder =
93 IUpdateEngineCallback::asBinder(callback);
Sen Jiang5caab192017-07-07 17:22:29 -070094 auto binder_wrapper = android::BinderWrapper::Get();
Sen Jiangb7f73802017-07-18 15:29:26 -070095 binder_wrapper->UnregisterForDeathNotifications(callback_binder);
Sen Jiang5caab192017-07-07 17:22:29 -070096
Sen Jiangb7f73802017-07-18 15:29:26 -070097 *return_value = UnbindCallback(callback_binder.get());
Sen Jiang5caab192017-07-07 17:22:29 -070098 return Status::ok();
99}
100
Alex Deymoe97b39c2016-01-20 13:22:17 -0800101Status BinderUpdateEngineAndroidService::applyPayload(
Alex Deymof8bfcff2016-02-02 21:22:11 -0800102 const android::String16& url,
Alex Deymo95b8f242016-01-28 16:06:57 -0800103 int64_t payload_offset,
104 int64_t payload_size,
Kyeongkab.Nam500ca132019-06-26 13:48:07 +0900105 const vector<android::String16>& header_kv_pairs) {
106 const string payload_url{android::String8{url}.string()};
Yifan Hongeec29272019-12-13 15:02:37 -0800107 vector<string> str_headers = ToVecString(header_kv_pairs);
Alex Deymof8bfcff2016-02-02 21:22:11 -0800108
109 brillo::ErrorPtr error;
110 if (!service_delegate_->ApplyPayload(
111 payload_url, payload_offset, payload_size, str_headers, &error)) {
112 return ErrorPtrToStatus(error);
113 }
Casey Dahlina93cd532016-01-14 16:55:11 -0800114 return Status::ok();
115}
116
Kyeongkab.Nam500ca132019-06-26 13:48:07 +0900117Status BinderUpdateEngineAndroidService::applyPayloadFd(
Kyeongkab.Nam42132992019-10-03 18:04:02 +0900118 const ParcelFileDescriptor& pfd,
Kyeongkab.Nam500ca132019-06-26 13:48:07 +0900119 int64_t payload_offset,
120 int64_t payload_size,
121 const vector<android::String16>& header_kv_pairs) {
Yifan Hongeec29272019-12-13 15:02:37 -0800122 vector<string> str_headers = ToVecString(header_kv_pairs);
Kyeongkab.Nam500ca132019-06-26 13:48:07 +0900123
124 brillo::ErrorPtr error;
125 if (!service_delegate_->ApplyPayload(
Kyeongkab.Nam42132992019-10-03 18:04:02 +0900126 pfd.get(), payload_offset, payload_size, str_headers, &error)) {
Kyeongkab.Nam500ca132019-06-26 13:48:07 +0900127 return ErrorPtrToStatus(error);
128 }
129 return Status::ok();
130}
131
Alex Deymoe97b39c2016-01-20 13:22:17 -0800132Status BinderUpdateEngineAndroidService::suspend() {
Alex Deymof8bfcff2016-02-02 21:22:11 -0800133 brillo::ErrorPtr error;
134 if (!service_delegate_->SuspendUpdate(&error))
135 return ErrorPtrToStatus(error);
Casey Dahlina93cd532016-01-14 16:55:11 -0800136 return Status::ok();
137}
138
Alex Deymoe97b39c2016-01-20 13:22:17 -0800139Status BinderUpdateEngineAndroidService::resume() {
Alex Deymof8bfcff2016-02-02 21:22:11 -0800140 brillo::ErrorPtr error;
141 if (!service_delegate_->ResumeUpdate(&error))
142 return ErrorPtrToStatus(error);
Casey Dahlina93cd532016-01-14 16:55:11 -0800143 return Status::ok();
144}
145
Alex Deymoe97b39c2016-01-20 13:22:17 -0800146Status BinderUpdateEngineAndroidService::cancel() {
Alex Deymof8bfcff2016-02-02 21:22:11 -0800147 brillo::ErrorPtr error;
148 if (!service_delegate_->CancelUpdate(&error))
149 return ErrorPtrToStatus(error);
Casey Dahlina93cd532016-01-14 16:55:11 -0800150 return Status::ok();
151}
152
Alex Deymo3b678db2016-02-09 11:50:06 -0800153Status BinderUpdateEngineAndroidService::resetStatus() {
154 brillo::ErrorPtr error;
155 if (!service_delegate_->ResetStatus(&error))
156 return ErrorPtrToStatus(error);
157 return Status::ok();
158}
159
Tianjieda607a32021-05-05 17:38:06 -0700160Status BinderUpdateEngineAndroidService::setShouldSwitchSlotOnReboot(
161 const android::String16& metadata_filename) {
Tianjie7f8f2ab2021-07-23 17:08:50 -0700162 brillo::ErrorPtr error;
163 if (!service_delegate_->setShouldSwitchSlotOnReboot(
164 android::String8(metadata_filename).string(), &error)) {
165 return ErrorPtrToStatus(error);
166 }
Tianjieda607a32021-05-05 17:38:06 -0700167 return Status::ok();
168}
169
170Status BinderUpdateEngineAndroidService::resetShouldSwitchSlotOnReboot() {
Tianjie7f8f2ab2021-07-23 17:08:50 -0700171 brillo::ErrorPtr error;
172 if (!service_delegate_->resetShouldSwitchSlotOnReboot(&error)) {
173 return ErrorPtrToStatus(error);
174 }
Tianjieda607a32021-05-05 17:38:06 -0700175 return Status::ok();
176}
177
Tao Bao20c96722018-01-09 22:38:57 -0800178Status BinderUpdateEngineAndroidService::verifyPayloadApplicable(
179 const android::String16& metadata_filename, bool* return_value) {
180 const std::string payload_metadata{
181 android::String8{metadata_filename}.string()};
182 LOG(INFO) << "Received a request of verifying payload metadata in "
183 << payload_metadata << ".";
Sen Jiang28d8ed92018-02-01 13:46:39 -0800184 brillo::ErrorPtr error;
185 *return_value =
186 service_delegate_->VerifyPayloadApplicable(payload_metadata, &error);
187 if (error != nullptr)
188 return ErrorPtrToStatus(error);
Tao Bao20c96722018-01-09 22:38:57 -0800189 return Status::ok();
190}
191
Sen Jiangb7f73802017-07-18 15:29:26 -0700192bool BinderUpdateEngineAndroidService::UnbindCallback(const IBinder* callback) {
193 auto it = std::find_if(
194 callbacks_.begin(),
195 callbacks_.end(),
196 [&callback](const android::sp<IUpdateEngineCallback>& elem) {
197 return IUpdateEngineCallback::asBinder(elem).get() == callback;
198 });
Alex Deymof8bfcff2016-02-02 21:22:11 -0800199 if (it == callbacks_.end()) {
Sen Jiang5caab192017-07-07 17:22:29 -0700200 LOG(ERROR) << "Unable to unbind unknown callback.";
201 return false;
Alex Deymof8bfcff2016-02-02 21:22:11 -0800202 }
203 callbacks_.erase(it);
Sen Jiang5caab192017-07-07 17:22:29 -0700204 return true;
Alex Deymof8bfcff2016-02-02 21:22:11 -0800205}
206
Yifan Hong6f7e29f2019-12-13 14:41:06 -0800207Status BinderUpdateEngineAndroidService::allocateSpaceForPayload(
208 const android::String16& metadata_filename,
209 const vector<android::String16>& header_kv_pairs,
210 int64_t* return_value) {
211 const std::string payload_metadata{
212 android::String8{metadata_filename}.string()};
213 vector<string> str_headers = ToVecString(header_kv_pairs);
214 LOG(INFO) << "Received a request of allocating space for " << payload_metadata
215 << ".";
216 brillo::ErrorPtr error;
217 *return_value =
218 static_cast<int64_t>(service_delegate_->AllocateSpaceForPayload(
219 payload_metadata, str_headers, &error));
220 if (error != nullptr)
221 return ErrorPtrToStatus(error);
Yifan Hong2236ea02019-12-13 16:11:22 -0800222 return Status::ok();
223}
Yifan Hong6f7e29f2019-12-13 14:41:06 -0800224
Yifan Hong40bb0d02020-02-24 17:33:14 -0800225class CleanupSuccessfulUpdateCallback
226 : public CleanupSuccessfulUpdateCallbackInterface {
227 public:
228 CleanupSuccessfulUpdateCallback(
229 const android::sp<IUpdateEngineCallback>& callback)
230 : callback_(callback) {}
231 void OnCleanupComplete(int32_t error_code) {
232 ignore_result(callback_->onPayloadApplicationComplete(error_code));
233 }
234 void OnCleanupProgressUpdate(double progress) {
235 ignore_result(callback_->onStatusUpdate(
236 static_cast<int32_t>(
237 update_engine::UpdateStatus::CLEANUP_PREVIOUS_UPDATE),
238 progress));
239 }
240 void RegisterForDeathNotifications(base::Closure unbind) {
241 const android::sp<android::IBinder>& callback_binder =
242 IUpdateEngineCallback::asBinder(callback_);
243 auto binder_wrapper = android::BinderWrapper::Get();
244 binder_wrapper->RegisterForDeathNotifications(callback_binder, unbind);
245 }
246
247 private:
248 android::sp<IUpdateEngineCallback> callback_;
249};
250
Yifan Hong2236ea02019-12-13 16:11:22 -0800251Status BinderUpdateEngineAndroidService::cleanupSuccessfulUpdate(
Yifan Hong40bb0d02020-02-24 17:33:14 -0800252 const android::sp<IUpdateEngineCallback>& callback) {
Yifan Hong2236ea02019-12-13 16:11:22 -0800253 brillo::ErrorPtr error;
Yifan Hong40bb0d02020-02-24 17:33:14 -0800254 service_delegate_->CleanupSuccessfulUpdate(
255 std::make_unique<CleanupSuccessfulUpdateCallback>(callback), &error);
Yifan Hong2236ea02019-12-13 16:11:22 -0800256 if (error != nullptr)
257 return ErrorPtrToStatus(error);
Yifan Hong6f7e29f2019-12-13 14:41:06 -0800258 return Status::ok();
259}
260
Casey Dahlina93cd532016-01-14 16:55:11 -0800261} // namespace chromeos_update_engine