blob: a89655f1c4c0f788dc5f8e4582b0e9fa6c112b08 [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>
Kelvin Zhang596969b2023-10-05 10:21:13 -070025#include <android-base/stringprintf.h>
Alex Deymof8bfcff2016-02-02 21:22:11 -080026
Amin Hassaniec7bc112020-10-29 16:47:58 -070027#include "update_engine/aosp/binder_service_android_common.h"
Kelvin Zhang596969b2023-10-05 10:21:13 -070028#include "update_engine/aosp/permission.h"
Yifan Hong2562cf22020-07-21 19:28:44 -070029
Casey Dahlina93cd532016-01-14 16:55:11 -080030using android::binder::Status;
31using android::os::IUpdateEngineCallback;
Kyeongkab.Nam42132992019-10-03 18:04:02 +090032using android::os::ParcelFileDescriptor;
Kyeongkab.Nam500ca132019-06-26 13:48:07 +090033using std::string;
34using std::vector;
Aaron Wood7f92e2b2017-08-28 14:51:21 -070035using update_engine::UpdateEngineStatus;
Alex Deymof8bfcff2016-02-02 21:22:11 -080036
Casey Dahlina93cd532016-01-14 16:55:11 -080037namespace chromeos_update_engine {
38
Kelvin Zhang596969b2023-10-05 10:21:13 -070039
Alex Deymofa78f142016-01-26 21:36:16 -080040BinderUpdateEngineAndroidService::BinderUpdateEngineAndroidService(
Alex Deymof8bfcff2016-02-02 21:22:11 -080041 ServiceDelegateAndroidInterface* service_delegate)
Amin Hassani7cc8bb02019-01-14 16:29:47 -080042 : service_delegate_(service_delegate) {}
Alex Deymofa78f142016-01-26 21:36:16 -080043
44void BinderUpdateEngineAndroidService::SendStatusUpdate(
Aaron Wood7f92e2b2017-08-28 14:51:21 -070045 const UpdateEngineStatus& update_engine_status) {
46 last_status_ = static_cast<int>(update_engine_status.status);
47 last_progress_ = update_engine_status.progress;
Alex Deymof8bfcff2016-02-02 21:22:11 -080048 for (auto& callback : callbacks_) {
Alex Deymo0e061ae2016-02-09 17:49:03 -080049 callback->onStatusUpdate(last_status_, last_progress_);
Alex Deymof8bfcff2016-02-02 21:22:11 -080050 }
51}
52
53void BinderUpdateEngineAndroidService::SendPayloadApplicationComplete(
54 ErrorCode error_code) {
55 for (auto& callback : callbacks_) {
56 callback->onPayloadApplicationComplete(static_cast<int>(error_code));
57 }
Alex Deymofa78f142016-01-26 21:36:16 -080058}
59
Alex Deymoe97b39c2016-01-20 13:22:17 -080060Status BinderUpdateEngineAndroidService::bind(
Alex Deymof8bfcff2016-02-02 21:22:11 -080061 const android::sp<IUpdateEngineCallback>& callback, bool* return_value) {
Kelvin Zhang596969b2023-10-05 10:21:13 -070062 if (const auto status = CheckCallingUid(); !status.isOk()) {
63 return status;
64 }
Tianjie Xu60f3a232019-12-11 13:53:39 -080065 // Send an status update on connection (except when no update sent so far).
66 // Even though the status update is oneway, it still returns an erroneous
67 // status in case of a selinux denial. We should at least check this status
68 // and fails the binding.
69 if (last_status_ != -1) {
70 auto status = callback->onStatusUpdate(last_status_, last_progress_);
71 if (!status.isOk()) {
72 LOG(ERROR) << "Failed to call onStatusUpdate() from callback: "
73 << status.toString8();
74 *return_value = false;
75 return Status::ok();
76 }
77 }
78
Alex Deymof8bfcff2016-02-02 21:22:11 -080079 callbacks_.emplace_back(callback);
80
Sen Jiangb7f73802017-07-18 15:29:26 -070081 const android::sp<IBinder>& callback_binder =
82 IUpdateEngineCallback::asBinder(callback);
Alex Deymof8bfcff2016-02-02 21:22:11 -080083 auto binder_wrapper = android::BinderWrapper::Get();
84 binder_wrapper->RegisterForDeathNotifications(
Sen Jiangb7f73802017-07-18 15:29:26 -070085 callback_binder,
Kelvin Zhang2f6c25a2023-07-05 12:49:34 -070086 [this, callback = callback_binder.get()]() { UnbindCallback(callback); });
Alex Deymof8bfcff2016-02-02 21:22:11 -080087
Casey Dahlina93cd532016-01-14 16:55:11 -080088 *return_value = true;
89 return Status::ok();
90}
91
Sen Jiang5caab192017-07-07 17:22:29 -070092Status BinderUpdateEngineAndroidService::unbind(
93 const android::sp<IUpdateEngineCallback>& callback, bool* return_value) {
Kelvin Zhang596969b2023-10-05 10:21:13 -070094 if (const auto status = CheckCallingUid(); !status.isOk()) {
95 return status;
96 }
Sen Jiangb7f73802017-07-18 15:29:26 -070097 const android::sp<IBinder>& callback_binder =
98 IUpdateEngineCallback::asBinder(callback);
Sen Jiang5caab192017-07-07 17:22:29 -070099 auto binder_wrapper = android::BinderWrapper::Get();
Sen Jiangb7f73802017-07-18 15:29:26 -0700100 binder_wrapper->UnregisterForDeathNotifications(callback_binder);
Sen Jiang5caab192017-07-07 17:22:29 -0700101
Sen Jiangb7f73802017-07-18 15:29:26 -0700102 *return_value = UnbindCallback(callback_binder.get());
Sen Jiang5caab192017-07-07 17:22:29 -0700103 return Status::ok();
104}
105
Alex Deymoe97b39c2016-01-20 13:22:17 -0800106Status BinderUpdateEngineAndroidService::applyPayload(
Alex Deymof8bfcff2016-02-02 21:22:11 -0800107 const android::String16& url,
Alex Deymo95b8f242016-01-28 16:06:57 -0800108 int64_t payload_offset,
109 int64_t payload_size,
Kyeongkab.Nam500ca132019-06-26 13:48:07 +0900110 const vector<android::String16>& header_kv_pairs) {
Kelvin Zhang596969b2023-10-05 10:21:13 -0700111 if (const auto status = CheckCallingUid(); !status.isOk()) {
112 return status;
113 }
Tomasz Wasilczyk0e78ec22023-08-11 16:11:15 +0000114 const string payload_url{android::String8{url}.c_str()};
Yifan Hongeec29272019-12-13 15:02:37 -0800115 vector<string> str_headers = ToVecString(header_kv_pairs);
Alex Deymof8bfcff2016-02-02 21:22:11 -0800116
Daniel Zheng92f7d172023-06-22 14:31:37 -0700117 Error error;
Alex Deymof8bfcff2016-02-02 21:22:11 -0800118 if (!service_delegate_->ApplyPayload(
119 payload_url, payload_offset, payload_size, str_headers, &error)) {
120 return ErrorPtrToStatus(error);
121 }
Casey Dahlina93cd532016-01-14 16:55:11 -0800122 return Status::ok();
123}
124
Kyeongkab.Nam500ca132019-06-26 13:48:07 +0900125Status BinderUpdateEngineAndroidService::applyPayloadFd(
Kyeongkab.Nam42132992019-10-03 18:04:02 +0900126 const ParcelFileDescriptor& pfd,
Kyeongkab.Nam500ca132019-06-26 13:48:07 +0900127 int64_t payload_offset,
128 int64_t payload_size,
129 const vector<android::String16>& header_kv_pairs) {
Kelvin Zhang596969b2023-10-05 10:21:13 -0700130 if (const auto status = CheckCallingUid(); !status.isOk()) {
131 return status;
132 }
Yifan Hongeec29272019-12-13 15:02:37 -0800133 vector<string> str_headers = ToVecString(header_kv_pairs);
Kyeongkab.Nam500ca132019-06-26 13:48:07 +0900134
Daniel Zheng92f7d172023-06-22 14:31:37 -0700135 Error error;
Kyeongkab.Nam500ca132019-06-26 13:48:07 +0900136 if (!service_delegate_->ApplyPayload(
Kyeongkab.Nam42132992019-10-03 18:04:02 +0900137 pfd.get(), payload_offset, payload_size, str_headers, &error)) {
Kyeongkab.Nam500ca132019-06-26 13:48:07 +0900138 return ErrorPtrToStatus(error);
139 }
140 return Status::ok();
141}
142
Alex Deymoe97b39c2016-01-20 13:22:17 -0800143Status BinderUpdateEngineAndroidService::suspend() {
Kelvin Zhang596969b2023-10-05 10:21:13 -0700144 if (const auto status = CheckCallingUid(); !status.isOk()) {
145 return status;
146 }
Daniel Zheng92f7d172023-06-22 14:31:37 -0700147 Error error;
Alex Deymof8bfcff2016-02-02 21:22:11 -0800148 if (!service_delegate_->SuspendUpdate(&error))
149 return ErrorPtrToStatus(error);
Casey Dahlina93cd532016-01-14 16:55:11 -0800150 return Status::ok();
151}
152
Alex Deymoe97b39c2016-01-20 13:22:17 -0800153Status BinderUpdateEngineAndroidService::resume() {
Kelvin Zhang596969b2023-10-05 10:21:13 -0700154 if (const auto status = CheckCallingUid(); !status.isOk()) {
155 return status;
156 }
Daniel Zheng92f7d172023-06-22 14:31:37 -0700157 Error error;
Alex Deymof8bfcff2016-02-02 21:22:11 -0800158 if (!service_delegate_->ResumeUpdate(&error))
159 return ErrorPtrToStatus(error);
Casey Dahlina93cd532016-01-14 16:55:11 -0800160 return Status::ok();
161}
162
Alex Deymoe97b39c2016-01-20 13:22:17 -0800163Status BinderUpdateEngineAndroidService::cancel() {
Kelvin Zhang596969b2023-10-05 10:21:13 -0700164 if (const auto status = CheckCallingUid(); !status.isOk()) {
165 return status;
166 }
Daniel Zheng92f7d172023-06-22 14:31:37 -0700167 Error error;
Alex Deymof8bfcff2016-02-02 21:22:11 -0800168 if (!service_delegate_->CancelUpdate(&error))
169 return ErrorPtrToStatus(error);
Casey Dahlina93cd532016-01-14 16:55:11 -0800170 return Status::ok();
171}
172
Alex Deymo3b678db2016-02-09 11:50:06 -0800173Status BinderUpdateEngineAndroidService::resetStatus() {
Kelvin Zhang596969b2023-10-05 10:21:13 -0700174 if (const auto status = CheckCallingUid(); !status.isOk()) {
175 return status;
176 }
Daniel Zheng92f7d172023-06-22 14:31:37 -0700177 Error error;
Alex Deymo3b678db2016-02-09 11:50:06 -0800178 if (!service_delegate_->ResetStatus(&error))
179 return ErrorPtrToStatus(error);
180 return Status::ok();
181}
182
Tianjieda607a32021-05-05 17:38:06 -0700183Status BinderUpdateEngineAndroidService::setShouldSwitchSlotOnReboot(
184 const android::String16& metadata_filename) {
Kelvin Zhang596969b2023-10-05 10:21:13 -0700185 if (const auto status = CheckCallingUid(); !status.isOk()) {
186 return status;
187 }
Daniel Zheng92f7d172023-06-22 14:31:37 -0700188 Error error;
Tianjie7f8f2ab2021-07-23 17:08:50 -0700189 if (!service_delegate_->setShouldSwitchSlotOnReboot(
Tomasz Wasilczyk0e78ec22023-08-11 16:11:15 +0000190 android::String8(metadata_filename).c_str(), &error)) {
Tianjie7f8f2ab2021-07-23 17:08:50 -0700191 return ErrorPtrToStatus(error);
192 }
Tianjieda607a32021-05-05 17:38:06 -0700193 return Status::ok();
194}
195
196Status BinderUpdateEngineAndroidService::resetShouldSwitchSlotOnReboot() {
Kelvin Zhang596969b2023-10-05 10:21:13 -0700197 if (const auto status = CheckCallingUid(); !status.isOk()) {
198 return status;
199 }
Daniel Zheng92f7d172023-06-22 14:31:37 -0700200 Error error;
Tianjie7f8f2ab2021-07-23 17:08:50 -0700201 if (!service_delegate_->resetShouldSwitchSlotOnReboot(&error)) {
202 return ErrorPtrToStatus(error);
203 }
Tianjieda607a32021-05-05 17:38:06 -0700204 return Status::ok();
205}
206
Tao Bao20c96722018-01-09 22:38:57 -0800207Status BinderUpdateEngineAndroidService::verifyPayloadApplicable(
208 const android::String16& metadata_filename, bool* return_value) {
Kelvin Zhang596969b2023-10-05 10:21:13 -0700209 if (const auto status = CheckCallingUid(); !status.isOk()) {
210 return status;
211 }
Tao Bao20c96722018-01-09 22:38:57 -0800212 const std::string payload_metadata{
Tomasz Wasilczyk0e78ec22023-08-11 16:11:15 +0000213 android::String8{metadata_filename}.c_str()};
Tao Bao20c96722018-01-09 22:38:57 -0800214 LOG(INFO) << "Received a request of verifying payload metadata in "
215 << payload_metadata << ".";
Daniel Zheng92f7d172023-06-22 14:31:37 -0700216 Error error;
Sen Jiang28d8ed92018-02-01 13:46:39 -0800217 *return_value =
218 service_delegate_->VerifyPayloadApplicable(payload_metadata, &error);
Daniel Zheng92f7d172023-06-22 14:31:37 -0700219 if (error.error_code != ErrorCode::kSuccess)
Sen Jiang28d8ed92018-02-01 13:46:39 -0800220 return ErrorPtrToStatus(error);
Tao Bao20c96722018-01-09 22:38:57 -0800221 return Status::ok();
222}
223
Sen Jiangb7f73802017-07-18 15:29:26 -0700224bool BinderUpdateEngineAndroidService::UnbindCallback(const IBinder* callback) {
225 auto it = std::find_if(
226 callbacks_.begin(),
227 callbacks_.end(),
228 [&callback](const android::sp<IUpdateEngineCallback>& elem) {
229 return IUpdateEngineCallback::asBinder(elem).get() == callback;
230 });
Alex Deymof8bfcff2016-02-02 21:22:11 -0800231 if (it == callbacks_.end()) {
Sen Jiang5caab192017-07-07 17:22:29 -0700232 LOG(ERROR) << "Unable to unbind unknown callback.";
233 return false;
Alex Deymof8bfcff2016-02-02 21:22:11 -0800234 }
235 callbacks_.erase(it);
Sen Jiang5caab192017-07-07 17:22:29 -0700236 return true;
Alex Deymof8bfcff2016-02-02 21:22:11 -0800237}
238
Yifan Hong6f7e29f2019-12-13 14:41:06 -0800239Status BinderUpdateEngineAndroidService::allocateSpaceForPayload(
240 const android::String16& metadata_filename,
241 const vector<android::String16>& header_kv_pairs,
242 int64_t* return_value) {
Kelvin Zhang596969b2023-10-05 10:21:13 -0700243 if (const auto status = CheckCallingUid(); !status.isOk()) {
244 return status;
245 }
Yifan Hong6f7e29f2019-12-13 14:41:06 -0800246 const std::string payload_metadata{
Tomasz Wasilczyk0e78ec22023-08-11 16:11:15 +0000247 android::String8{metadata_filename}.c_str()};
Yifan Hong6f7e29f2019-12-13 14:41:06 -0800248 vector<string> str_headers = ToVecString(header_kv_pairs);
249 LOG(INFO) << "Received a request of allocating space for " << payload_metadata
250 << ".";
Daniel Zheng92f7d172023-06-22 14:31:37 -0700251 Error error;
Yifan Hong6f7e29f2019-12-13 14:41:06 -0800252 *return_value =
253 static_cast<int64_t>(service_delegate_->AllocateSpaceForPayload(
254 payload_metadata, str_headers, &error));
Daniel Zheng92f7d172023-06-22 14:31:37 -0700255 if (error.error_code != ErrorCode::kSuccess)
Yifan Hong6f7e29f2019-12-13 14:41:06 -0800256 return ErrorPtrToStatus(error);
Yifan Hong2236ea02019-12-13 16:11:22 -0800257 return Status::ok();
258}
Yifan Hong6f7e29f2019-12-13 14:41:06 -0800259
Yifan Hong40bb0d02020-02-24 17:33:14 -0800260class CleanupSuccessfulUpdateCallback
261 : public CleanupSuccessfulUpdateCallbackInterface {
262 public:
263 CleanupSuccessfulUpdateCallback(
264 const android::sp<IUpdateEngineCallback>& callback)
265 : callback_(callback) {}
266 void OnCleanupComplete(int32_t error_code) {
267 ignore_result(callback_->onPayloadApplicationComplete(error_code));
268 }
269 void OnCleanupProgressUpdate(double progress) {
270 ignore_result(callback_->onStatusUpdate(
271 static_cast<int32_t>(
272 update_engine::UpdateStatus::CLEANUP_PREVIOUS_UPDATE),
273 progress));
274 }
Kelvin Zhang2f6c25a2023-07-05 12:49:34 -0700275 void RegisterForDeathNotifications(const std::function<void()>& unbind) {
Yifan Hong40bb0d02020-02-24 17:33:14 -0800276 const android::sp<android::IBinder>& callback_binder =
277 IUpdateEngineCallback::asBinder(callback_);
278 auto binder_wrapper = android::BinderWrapper::Get();
279 binder_wrapper->RegisterForDeathNotifications(callback_binder, unbind);
280 }
281
282 private:
283 android::sp<IUpdateEngineCallback> callback_;
284};
285
Yifan Hong2236ea02019-12-13 16:11:22 -0800286Status BinderUpdateEngineAndroidService::cleanupSuccessfulUpdate(
Yifan Hong40bb0d02020-02-24 17:33:14 -0800287 const android::sp<IUpdateEngineCallback>& callback) {
Kelvin Zhang596969b2023-10-05 10:21:13 -0700288 if (const auto status = CheckCallingUid(); !status.isOk()) {
289 return status;
290 }
Daniel Zheng92f7d172023-06-22 14:31:37 -0700291 Error error;
Yifan Hong40bb0d02020-02-24 17:33:14 -0800292 service_delegate_->CleanupSuccessfulUpdate(
293 std::make_unique<CleanupSuccessfulUpdateCallback>(callback), &error);
Daniel Zheng92f7d172023-06-22 14:31:37 -0700294 if (error.error_code != ErrorCode::kSuccess)
Yifan Hong2236ea02019-12-13 16:11:22 -0800295 return ErrorPtrToStatus(error);
Yifan Hong6f7e29f2019-12-13 14:41:06 -0800296 return Status::ok();
297}
298
Casey Dahlina93cd532016-01-14 16:55:11 -0800299} // namespace chromeos_update_engine