blob: e7c20c51c7552a1999b01c5b4c1307678b4e57c1 [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>
Alex Deymof8bfcff2016-02-02 21:22:11 -080024#include <utils/String8.h>
25
Amin Hassaniec7bc112020-10-29 16:47:58 -070026#include "update_engine/aosp/binder_service_android_common.h"
Yifan Hong2562cf22020-07-21 19:28:44 -070027
Casey Dahlina93cd532016-01-14 16:55:11 -080028using android::binder::Status;
29using android::os::IUpdateEngineCallback;
Kyeongkab.Nam42132992019-10-03 18:04:02 +090030using android::os::ParcelFileDescriptor;
Kyeongkab.Nam500ca132019-06-26 13:48:07 +090031using std::string;
32using std::vector;
Aaron Wood7f92e2b2017-08-28 14:51:21 -070033using update_engine::UpdateEngineStatus;
Alex Deymof8bfcff2016-02-02 21:22:11 -080034
Casey Dahlina93cd532016-01-14 16:55:11 -080035namespace chromeos_update_engine {
36
Alex Deymofa78f142016-01-26 21:36:16 -080037BinderUpdateEngineAndroidService::BinderUpdateEngineAndroidService(
Alex Deymof8bfcff2016-02-02 21:22:11 -080038 ServiceDelegateAndroidInterface* service_delegate)
Amin Hassani7cc8bb02019-01-14 16:29:47 -080039 : service_delegate_(service_delegate) {}
Alex Deymofa78f142016-01-26 21:36:16 -080040
41void BinderUpdateEngineAndroidService::SendStatusUpdate(
Aaron Wood7f92e2b2017-08-28 14:51:21 -070042 const UpdateEngineStatus& update_engine_status) {
43 last_status_ = static_cast<int>(update_engine_status.status);
44 last_progress_ = update_engine_status.progress;
Alex Deymof8bfcff2016-02-02 21:22:11 -080045 for (auto& callback : callbacks_) {
Alex Deymo0e061ae2016-02-09 17:49:03 -080046 callback->onStatusUpdate(last_status_, last_progress_);
Alex Deymof8bfcff2016-02-02 21:22:11 -080047 }
48}
49
50void BinderUpdateEngineAndroidService::SendPayloadApplicationComplete(
51 ErrorCode error_code) {
52 for (auto& callback : callbacks_) {
53 callback->onPayloadApplicationComplete(static_cast<int>(error_code));
54 }
Alex Deymofa78f142016-01-26 21:36:16 -080055}
56
Alex Deymoe97b39c2016-01-20 13:22:17 -080057Status BinderUpdateEngineAndroidService::bind(
Alex Deymof8bfcff2016-02-02 21:22:11 -080058 const android::sp<IUpdateEngineCallback>& callback, bool* return_value) {
Tianjie Xu60f3a232019-12-11 13:53:39 -080059 // Send an status update on connection (except when no update sent so far).
60 // Even though the status update is oneway, it still returns an erroneous
61 // status in case of a selinux denial. We should at least check this status
62 // and fails the binding.
63 if (last_status_ != -1) {
64 auto status = callback->onStatusUpdate(last_status_, last_progress_);
65 if (!status.isOk()) {
66 LOG(ERROR) << "Failed to call onStatusUpdate() from callback: "
67 << status.toString8();
68 *return_value = false;
69 return Status::ok();
70 }
71 }
72
Alex Deymof8bfcff2016-02-02 21:22:11 -080073 callbacks_.emplace_back(callback);
74
Sen Jiangb7f73802017-07-18 15:29:26 -070075 const android::sp<IBinder>& callback_binder =
76 IUpdateEngineCallback::asBinder(callback);
Alex Deymof8bfcff2016-02-02 21:22:11 -080077 auto binder_wrapper = android::BinderWrapper::Get();
78 binder_wrapper->RegisterForDeathNotifications(
Sen Jiangb7f73802017-07-18 15:29:26 -070079 callback_binder,
Sen Jiang5caab192017-07-07 17:22:29 -070080 base::Bind(
81 base::IgnoreResult(&BinderUpdateEngineAndroidService::UnbindCallback),
82 base::Unretained(this),
Sen Jiangb7f73802017-07-18 15:29:26 -070083 base::Unretained(callback_binder.get())));
Alex Deymof8bfcff2016-02-02 21:22:11 -080084
Casey Dahlina93cd532016-01-14 16:55:11 -080085 *return_value = true;
86 return Status::ok();
87}
88
Sen Jiang5caab192017-07-07 17:22:29 -070089Status BinderUpdateEngineAndroidService::unbind(
90 const android::sp<IUpdateEngineCallback>& callback, bool* return_value) {
Sen Jiangb7f73802017-07-18 15:29:26 -070091 const android::sp<IBinder>& callback_binder =
92 IUpdateEngineCallback::asBinder(callback);
Sen Jiang5caab192017-07-07 17:22:29 -070093 auto binder_wrapper = android::BinderWrapper::Get();
Sen Jiangb7f73802017-07-18 15:29:26 -070094 binder_wrapper->UnregisterForDeathNotifications(callback_binder);
Sen Jiang5caab192017-07-07 17:22:29 -070095
Sen Jiangb7f73802017-07-18 15:29:26 -070096 *return_value = UnbindCallback(callback_binder.get());
Sen Jiang5caab192017-07-07 17:22:29 -070097 return Status::ok();
98}
99
Alex Deymoe97b39c2016-01-20 13:22:17 -0800100Status BinderUpdateEngineAndroidService::applyPayload(
Alex Deymof8bfcff2016-02-02 21:22:11 -0800101 const android::String16& url,
Alex Deymo95b8f242016-01-28 16:06:57 -0800102 int64_t payload_offset,
103 int64_t payload_size,
Kyeongkab.Nam500ca132019-06-26 13:48:07 +0900104 const vector<android::String16>& header_kv_pairs) {
105 const string payload_url{android::String8{url}.string()};
Yifan Hongeec29272019-12-13 15:02:37 -0800106 vector<string> str_headers = ToVecString(header_kv_pairs);
Alex Deymof8bfcff2016-02-02 21:22:11 -0800107
Daniel Zheng92f7d172023-06-22 14:31:37 -0700108 Error error;
Alex Deymof8bfcff2016-02-02 21:22:11 -0800109 if (!service_delegate_->ApplyPayload(
110 payload_url, payload_offset, payload_size, str_headers, &error)) {
111 return ErrorPtrToStatus(error);
112 }
Casey Dahlina93cd532016-01-14 16:55:11 -0800113 return Status::ok();
114}
115
Kyeongkab.Nam500ca132019-06-26 13:48:07 +0900116Status BinderUpdateEngineAndroidService::applyPayloadFd(
Kyeongkab.Nam42132992019-10-03 18:04:02 +0900117 const ParcelFileDescriptor& pfd,
Kyeongkab.Nam500ca132019-06-26 13:48:07 +0900118 int64_t payload_offset,
119 int64_t payload_size,
120 const vector<android::String16>& header_kv_pairs) {
Yifan Hongeec29272019-12-13 15:02:37 -0800121 vector<string> str_headers = ToVecString(header_kv_pairs);
Kyeongkab.Nam500ca132019-06-26 13:48:07 +0900122
Daniel Zheng92f7d172023-06-22 14:31:37 -0700123 Error error;
Kyeongkab.Nam500ca132019-06-26 13:48:07 +0900124 if (!service_delegate_->ApplyPayload(
Kyeongkab.Nam42132992019-10-03 18:04:02 +0900125 pfd.get(), payload_offset, payload_size, str_headers, &error)) {
Kyeongkab.Nam500ca132019-06-26 13:48:07 +0900126 return ErrorPtrToStatus(error);
127 }
128 return Status::ok();
129}
130
Alex Deymoe97b39c2016-01-20 13:22:17 -0800131Status BinderUpdateEngineAndroidService::suspend() {
Daniel Zheng92f7d172023-06-22 14:31:37 -0700132 Error error;
Alex Deymof8bfcff2016-02-02 21:22:11 -0800133 if (!service_delegate_->SuspendUpdate(&error))
134 return ErrorPtrToStatus(error);
Casey Dahlina93cd532016-01-14 16:55:11 -0800135 return Status::ok();
136}
137
Alex Deymoe97b39c2016-01-20 13:22:17 -0800138Status BinderUpdateEngineAndroidService::resume() {
Daniel Zheng92f7d172023-06-22 14:31:37 -0700139 Error error;
Alex Deymof8bfcff2016-02-02 21:22:11 -0800140 if (!service_delegate_->ResumeUpdate(&error))
141 return ErrorPtrToStatus(error);
Casey Dahlina93cd532016-01-14 16:55:11 -0800142 return Status::ok();
143}
144
Alex Deymoe97b39c2016-01-20 13:22:17 -0800145Status BinderUpdateEngineAndroidService::cancel() {
Daniel Zheng92f7d172023-06-22 14:31:37 -0700146 Error error;
Alex Deymof8bfcff2016-02-02 21:22:11 -0800147 if (!service_delegate_->CancelUpdate(&error))
148 return ErrorPtrToStatus(error);
Casey Dahlina93cd532016-01-14 16:55:11 -0800149 return Status::ok();
150}
151
Alex Deymo3b678db2016-02-09 11:50:06 -0800152Status BinderUpdateEngineAndroidService::resetStatus() {
Daniel Zheng92f7d172023-06-22 14:31:37 -0700153 Error error;
Alex Deymo3b678db2016-02-09 11:50:06 -0800154 if (!service_delegate_->ResetStatus(&error))
155 return ErrorPtrToStatus(error);
156 return Status::ok();
157}
158
Tianjieda607a32021-05-05 17:38:06 -0700159Status BinderUpdateEngineAndroidService::setShouldSwitchSlotOnReboot(
160 const android::String16& metadata_filename) {
Daniel Zheng92f7d172023-06-22 14:31:37 -0700161 Error error;
Tianjie7f8f2ab2021-07-23 17:08:50 -0700162 if (!service_delegate_->setShouldSwitchSlotOnReboot(
163 android::String8(metadata_filename).string(), &error)) {
164 return ErrorPtrToStatus(error);
165 }
Tianjieda607a32021-05-05 17:38:06 -0700166 return Status::ok();
167}
168
169Status BinderUpdateEngineAndroidService::resetShouldSwitchSlotOnReboot() {
Daniel Zheng92f7d172023-06-22 14:31:37 -0700170 Error error;
Tianjie7f8f2ab2021-07-23 17:08:50 -0700171 if (!service_delegate_->resetShouldSwitchSlotOnReboot(&error)) {
172 return ErrorPtrToStatus(error);
173 }
Tianjieda607a32021-05-05 17:38:06 -0700174 return Status::ok();
175}
176
Tao Bao20c96722018-01-09 22:38:57 -0800177Status BinderUpdateEngineAndroidService::verifyPayloadApplicable(
178 const android::String16& metadata_filename, bool* return_value) {
179 const std::string payload_metadata{
180 android::String8{metadata_filename}.string()};
181 LOG(INFO) << "Received a request of verifying payload metadata in "
182 << payload_metadata << ".";
Daniel Zheng92f7d172023-06-22 14:31:37 -0700183 Error error;
Sen Jiang28d8ed92018-02-01 13:46:39 -0800184 *return_value =
185 service_delegate_->VerifyPayloadApplicable(payload_metadata, &error);
Daniel Zheng92f7d172023-06-22 14:31:37 -0700186 if (error.error_code != ErrorCode::kSuccess)
Sen Jiang28d8ed92018-02-01 13:46:39 -0800187 return ErrorPtrToStatus(error);
Tao Bao20c96722018-01-09 22:38:57 -0800188 return Status::ok();
189}
190
Sen Jiangb7f73802017-07-18 15:29:26 -0700191bool BinderUpdateEngineAndroidService::UnbindCallback(const IBinder* callback) {
192 auto it = std::find_if(
193 callbacks_.begin(),
194 callbacks_.end(),
195 [&callback](const android::sp<IUpdateEngineCallback>& elem) {
196 return IUpdateEngineCallback::asBinder(elem).get() == callback;
197 });
Alex Deymof8bfcff2016-02-02 21:22:11 -0800198 if (it == callbacks_.end()) {
Sen Jiang5caab192017-07-07 17:22:29 -0700199 LOG(ERROR) << "Unable to unbind unknown callback.";
200 return false;
Alex Deymof8bfcff2016-02-02 21:22:11 -0800201 }
202 callbacks_.erase(it);
Sen Jiang5caab192017-07-07 17:22:29 -0700203 return true;
Alex Deymof8bfcff2016-02-02 21:22:11 -0800204}
205
Yifan Hong6f7e29f2019-12-13 14:41:06 -0800206Status BinderUpdateEngineAndroidService::allocateSpaceForPayload(
207 const android::String16& metadata_filename,
208 const vector<android::String16>& header_kv_pairs,
209 int64_t* return_value) {
210 const std::string payload_metadata{
211 android::String8{metadata_filename}.string()};
212 vector<string> str_headers = ToVecString(header_kv_pairs);
213 LOG(INFO) << "Received a request of allocating space for " << payload_metadata
214 << ".";
Daniel Zheng92f7d172023-06-22 14:31:37 -0700215 Error error;
Yifan Hong6f7e29f2019-12-13 14:41:06 -0800216 *return_value =
217 static_cast<int64_t>(service_delegate_->AllocateSpaceForPayload(
218 payload_metadata, str_headers, &error));
Daniel Zheng92f7d172023-06-22 14:31:37 -0700219 if (error.error_code != ErrorCode::kSuccess)
Yifan Hong6f7e29f2019-12-13 14:41:06 -0800220 return ErrorPtrToStatus(error);
Yifan Hong2236ea02019-12-13 16:11:22 -0800221 return Status::ok();
222}
Yifan Hong6f7e29f2019-12-13 14:41:06 -0800223
Yifan Hong40bb0d02020-02-24 17:33:14 -0800224class CleanupSuccessfulUpdateCallback
225 : public CleanupSuccessfulUpdateCallbackInterface {
226 public:
227 CleanupSuccessfulUpdateCallback(
228 const android::sp<IUpdateEngineCallback>& callback)
229 : callback_(callback) {}
230 void OnCleanupComplete(int32_t error_code) {
231 ignore_result(callback_->onPayloadApplicationComplete(error_code));
232 }
233 void OnCleanupProgressUpdate(double progress) {
234 ignore_result(callback_->onStatusUpdate(
235 static_cast<int32_t>(
236 update_engine::UpdateStatus::CLEANUP_PREVIOUS_UPDATE),
237 progress));
238 }
239 void RegisterForDeathNotifications(base::Closure unbind) {
240 const android::sp<android::IBinder>& callback_binder =
241 IUpdateEngineCallback::asBinder(callback_);
242 auto binder_wrapper = android::BinderWrapper::Get();
243 binder_wrapper->RegisterForDeathNotifications(callback_binder, unbind);
244 }
245
246 private:
247 android::sp<IUpdateEngineCallback> callback_;
248};
249
Yifan Hong2236ea02019-12-13 16:11:22 -0800250Status BinderUpdateEngineAndroidService::cleanupSuccessfulUpdate(
Yifan Hong40bb0d02020-02-24 17:33:14 -0800251 const android::sp<IUpdateEngineCallback>& callback) {
Daniel Zheng92f7d172023-06-22 14:31:37 -0700252 Error error;
Yifan Hong40bb0d02020-02-24 17:33:14 -0800253 service_delegate_->CleanupSuccessfulUpdate(
254 std::make_unique<CleanupSuccessfulUpdateCallback>(callback), &error);
Daniel Zheng92f7d172023-06-22 14:31:37 -0700255 if (error.error_code != ErrorCode::kSuccess)
Yifan Hong2236ea02019-12-13 16:11:22 -0800256 return ErrorPtrToStatus(error);
Yifan Hong6f7e29f2019-12-13 14:41:06 -0800257 return Status::ok();
258}
259
Casey Dahlina93cd532016-01-14 16:55:11 -0800260} // namespace chromeos_update_engine