blob: 6b8a55291725c4ccec87e5b3583a3a447a3bc9ff [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
17#include "update_engine/binder_service_android.h"
18
Yifan Hongb45ec662020-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
Casey Dahlina93cd532016-01-14 16:55:11 -080027using android::binder::Status;
28using android::os::IUpdateEngineCallback;
Kyeongkab.Nam42132992019-10-03 18:04:02 +090029using android::os::ParcelFileDescriptor;
Kyeongkab.Nam500ca132019-06-26 13:48:07 +090030using std::string;
31using std::vector;
Aaron Wood7f92e2b2017-08-28 14:51:21 -070032using update_engine::UpdateEngineStatus;
Alex Deymof8bfcff2016-02-02 21:22:11 -080033
34namespace {
35Status ErrorPtrToStatus(const brillo::ErrorPtr& error) {
36 return Status::fromServiceSpecificError(
37 1, android::String8{error->GetMessage().c_str()});
38}
Yifan Hongeec29272019-12-13 15:02:37 -080039
40vector<string> ToVecString(const vector<android::String16>& inp) {
41 vector<string> out;
42 out.reserve(inp.size());
43 for (const auto& e : inp) {
44 out.emplace_back(android::String8{e}.string());
45 }
46 return out;
47}
48
Alex Deymof8bfcff2016-02-02 21:22:11 -080049} // namespace
Casey Dahlina93cd532016-01-14 16:55:11 -080050
51namespace chromeos_update_engine {
52
Alex Deymofa78f142016-01-26 21:36:16 -080053BinderUpdateEngineAndroidService::BinderUpdateEngineAndroidService(
Alex Deymof8bfcff2016-02-02 21:22:11 -080054 ServiceDelegateAndroidInterface* service_delegate)
Amin Hassani7cc8bb02019-01-14 16:29:47 -080055 : service_delegate_(service_delegate) {}
Alex Deymofa78f142016-01-26 21:36:16 -080056
57void BinderUpdateEngineAndroidService::SendStatusUpdate(
Aaron Wood7f92e2b2017-08-28 14:51:21 -070058 const UpdateEngineStatus& update_engine_status) {
59 last_status_ = static_cast<int>(update_engine_status.status);
60 last_progress_ = update_engine_status.progress;
Alex Deymof8bfcff2016-02-02 21:22:11 -080061 for (auto& callback : callbacks_) {
Alex Deymo0e061ae2016-02-09 17:49:03 -080062 callback->onStatusUpdate(last_status_, last_progress_);
Alex Deymof8bfcff2016-02-02 21:22:11 -080063 }
64}
65
66void BinderUpdateEngineAndroidService::SendPayloadApplicationComplete(
67 ErrorCode error_code) {
68 for (auto& callback : callbacks_) {
69 callback->onPayloadApplicationComplete(static_cast<int>(error_code));
70 }
Alex Deymofa78f142016-01-26 21:36:16 -080071}
72
Alex Deymoe97b39c2016-01-20 13:22:17 -080073Status BinderUpdateEngineAndroidService::bind(
Alex Deymof8bfcff2016-02-02 21:22:11 -080074 const android::sp<IUpdateEngineCallback>& callback, bool* return_value) {
Tianjie Xu60f3a232019-12-11 13:53:39 -080075 // Send an status update on connection (except when no update sent so far).
76 // Even though the status update is oneway, it still returns an erroneous
77 // status in case of a selinux denial. We should at least check this status
78 // and fails the binding.
79 if (last_status_ != -1) {
80 auto status = callback->onStatusUpdate(last_status_, last_progress_);
81 if (!status.isOk()) {
82 LOG(ERROR) << "Failed to call onStatusUpdate() from callback: "
83 << status.toString8();
84 *return_value = false;
85 return Status::ok();
86 }
87 }
88
Alex Deymof8bfcff2016-02-02 21:22:11 -080089 callbacks_.emplace_back(callback);
90
Sen Jiangb7f73802017-07-18 15:29:26 -070091 const android::sp<IBinder>& callback_binder =
92 IUpdateEngineCallback::asBinder(callback);
Alex Deymof8bfcff2016-02-02 21:22:11 -080093 auto binder_wrapper = android::BinderWrapper::Get();
94 binder_wrapper->RegisterForDeathNotifications(
Sen Jiangb7f73802017-07-18 15:29:26 -070095 callback_binder,
Sen Jiang5caab192017-07-07 17:22:29 -070096 base::Bind(
97 base::IgnoreResult(&BinderUpdateEngineAndroidService::UnbindCallback),
98 base::Unretained(this),
Sen Jiangb7f73802017-07-18 15:29:26 -070099 base::Unretained(callback_binder.get())));
Alex Deymof8bfcff2016-02-02 21:22:11 -0800100
Casey Dahlina93cd532016-01-14 16:55:11 -0800101 *return_value = true;
102 return Status::ok();
103}
104
Sen Jiang5caab192017-07-07 17:22:29 -0700105Status BinderUpdateEngineAndroidService::unbind(
106 const android::sp<IUpdateEngineCallback>& callback, bool* return_value) {
Sen Jiangb7f73802017-07-18 15:29:26 -0700107 const android::sp<IBinder>& callback_binder =
108 IUpdateEngineCallback::asBinder(callback);
Sen Jiang5caab192017-07-07 17:22:29 -0700109 auto binder_wrapper = android::BinderWrapper::Get();
Sen Jiangb7f73802017-07-18 15:29:26 -0700110 binder_wrapper->UnregisterForDeathNotifications(callback_binder);
Sen Jiang5caab192017-07-07 17:22:29 -0700111
Sen Jiangb7f73802017-07-18 15:29:26 -0700112 *return_value = UnbindCallback(callback_binder.get());
Sen Jiang5caab192017-07-07 17:22:29 -0700113 return Status::ok();
114}
115
Alex Deymoe97b39c2016-01-20 13:22:17 -0800116Status BinderUpdateEngineAndroidService::applyPayload(
Alex Deymof8bfcff2016-02-02 21:22:11 -0800117 const android::String16& url,
Alex Deymo95b8f242016-01-28 16:06:57 -0800118 int64_t payload_offset,
119 int64_t payload_size,
Kyeongkab.Nam500ca132019-06-26 13:48:07 +0900120 const vector<android::String16>& header_kv_pairs) {
121 const string payload_url{android::String8{url}.string()};
Yifan Hongeec29272019-12-13 15:02:37 -0800122 vector<string> str_headers = ToVecString(header_kv_pairs);
Alex Deymof8bfcff2016-02-02 21:22:11 -0800123
124 brillo::ErrorPtr error;
125 if (!service_delegate_->ApplyPayload(
126 payload_url, payload_offset, payload_size, str_headers, &error)) {
127 return ErrorPtrToStatus(error);
128 }
Casey Dahlina93cd532016-01-14 16:55:11 -0800129 return Status::ok();
130}
131
Kyeongkab.Nam500ca132019-06-26 13:48:07 +0900132Status BinderUpdateEngineAndroidService::applyPayloadFd(
Kyeongkab.Nam42132992019-10-03 18:04:02 +0900133 const ParcelFileDescriptor& pfd,
Kyeongkab.Nam500ca132019-06-26 13:48:07 +0900134 int64_t payload_offset,
135 int64_t payload_size,
136 const vector<android::String16>& header_kv_pairs) {
Yifan Hongeec29272019-12-13 15:02:37 -0800137 vector<string> str_headers = ToVecString(header_kv_pairs);
Kyeongkab.Nam500ca132019-06-26 13:48:07 +0900138
139 brillo::ErrorPtr error;
140 if (!service_delegate_->ApplyPayload(
Kyeongkab.Nam42132992019-10-03 18:04:02 +0900141 pfd.get(), payload_offset, payload_size, str_headers, &error)) {
Kyeongkab.Nam500ca132019-06-26 13:48:07 +0900142 return ErrorPtrToStatus(error);
143 }
144 return Status::ok();
145}
146
Alex Deymoe97b39c2016-01-20 13:22:17 -0800147Status BinderUpdateEngineAndroidService::suspend() {
Alex Deymof8bfcff2016-02-02 21:22:11 -0800148 brillo::ErrorPtr error;
149 if (!service_delegate_->SuspendUpdate(&error))
150 return ErrorPtrToStatus(error);
Casey Dahlina93cd532016-01-14 16:55:11 -0800151 return Status::ok();
152}
153
Alex Deymoe97b39c2016-01-20 13:22:17 -0800154Status BinderUpdateEngineAndroidService::resume() {
Alex Deymof8bfcff2016-02-02 21:22:11 -0800155 brillo::ErrorPtr error;
156 if (!service_delegate_->ResumeUpdate(&error))
157 return ErrorPtrToStatus(error);
Casey Dahlina93cd532016-01-14 16:55:11 -0800158 return Status::ok();
159}
160
Alex Deymoe97b39c2016-01-20 13:22:17 -0800161Status BinderUpdateEngineAndroidService::cancel() {
Alex Deymof8bfcff2016-02-02 21:22:11 -0800162 brillo::ErrorPtr error;
163 if (!service_delegate_->CancelUpdate(&error))
164 return ErrorPtrToStatus(error);
Casey Dahlina93cd532016-01-14 16:55:11 -0800165 return Status::ok();
166}
167
Alex Deymo3b678db2016-02-09 11:50:06 -0800168Status BinderUpdateEngineAndroidService::resetStatus() {
169 brillo::ErrorPtr error;
170 if (!service_delegate_->ResetStatus(&error))
171 return ErrorPtrToStatus(error);
172 return Status::ok();
173}
174
Tao Bao20c96722018-01-09 22:38:57 -0800175Status BinderUpdateEngineAndroidService::verifyPayloadApplicable(
176 const android::String16& metadata_filename, bool* return_value) {
177 const std::string payload_metadata{
178 android::String8{metadata_filename}.string()};
179 LOG(INFO) << "Received a request of verifying payload metadata in "
180 << payload_metadata << ".";
Sen Jiang28d8ed92018-02-01 13:46:39 -0800181 brillo::ErrorPtr error;
182 *return_value =
183 service_delegate_->VerifyPayloadApplicable(payload_metadata, &error);
184 if (error != nullptr)
185 return ErrorPtrToStatus(error);
Tao Bao20c96722018-01-09 22:38:57 -0800186 return Status::ok();
187}
188
Sen Jiangb7f73802017-07-18 15:29:26 -0700189bool BinderUpdateEngineAndroidService::UnbindCallback(const IBinder* callback) {
190 auto it = std::find_if(
191 callbacks_.begin(),
192 callbacks_.end(),
193 [&callback](const android::sp<IUpdateEngineCallback>& elem) {
194 return IUpdateEngineCallback::asBinder(elem).get() == callback;
195 });
Alex Deymof8bfcff2016-02-02 21:22:11 -0800196 if (it == callbacks_.end()) {
Sen Jiang5caab192017-07-07 17:22:29 -0700197 LOG(ERROR) << "Unable to unbind unknown callback.";
198 return false;
Alex Deymof8bfcff2016-02-02 21:22:11 -0800199 }
200 callbacks_.erase(it);
Sen Jiang5caab192017-07-07 17:22:29 -0700201 return true;
Alex Deymof8bfcff2016-02-02 21:22:11 -0800202}
203
Yifan Hong6f7e29f2019-12-13 14:41:06 -0800204Status BinderUpdateEngineAndroidService::allocateSpaceForPayload(
205 const android::String16& metadata_filename,
206 const vector<android::String16>& header_kv_pairs,
207 int64_t* return_value) {
208 const std::string payload_metadata{
209 android::String8{metadata_filename}.string()};
210 vector<string> str_headers = ToVecString(header_kv_pairs);
211 LOG(INFO) << "Received a request of allocating space for " << payload_metadata
212 << ".";
213 brillo::ErrorPtr error;
214 *return_value =
215 static_cast<int64_t>(service_delegate_->AllocateSpaceForPayload(
216 payload_metadata, str_headers, &error));
217 if (error != nullptr)
218 return ErrorPtrToStatus(error);
Yifan Hong2236ea02019-12-13 16:11:22 -0800219 return Status::ok();
220}
Yifan Hong6f7e29f2019-12-13 14:41:06 -0800221
Yifan Hongb45ec662020-02-24 17:33:14 -0800222class CleanupSuccessfulUpdateCallback
223 : public CleanupSuccessfulUpdateCallbackInterface {
224 public:
225 CleanupSuccessfulUpdateCallback(
226 const android::sp<IUpdateEngineCallback>& callback)
227 : callback_(callback) {}
228 void OnCleanupComplete(int32_t error_code) {
229 ignore_result(callback_->onPayloadApplicationComplete(error_code));
230 }
231 void OnCleanupProgressUpdate(double progress) {
232 ignore_result(callback_->onStatusUpdate(
233 static_cast<int32_t>(
234 update_engine::UpdateStatus::CLEANUP_PREVIOUS_UPDATE),
235 progress));
236 }
237 void RegisterForDeathNotifications(base::Closure unbind) {
238 const android::sp<android::IBinder>& callback_binder =
239 IUpdateEngineCallback::asBinder(callback_);
240 auto binder_wrapper = android::BinderWrapper::Get();
241 binder_wrapper->RegisterForDeathNotifications(callback_binder, unbind);
242 }
243
244 private:
245 android::sp<IUpdateEngineCallback> callback_;
246};
247
Yifan Hong2236ea02019-12-13 16:11:22 -0800248Status BinderUpdateEngineAndroidService::cleanupSuccessfulUpdate(
Yifan Hongb45ec662020-02-24 17:33:14 -0800249 const android::sp<IUpdateEngineCallback>& callback) {
Yifan Hong2236ea02019-12-13 16:11:22 -0800250 brillo::ErrorPtr error;
Yifan Hongb45ec662020-02-24 17:33:14 -0800251 service_delegate_->CleanupSuccessfulUpdate(
252 std::make_unique<CleanupSuccessfulUpdateCallback>(callback), &error);
Yifan Hong2236ea02019-12-13 16:11:22 -0800253 if (error != nullptr)
254 return ErrorPtrToStatus(error);
Yifan Hong6f7e29f2019-12-13 14:41:06 -0800255 return Status::ok();
256}
257
Casey Dahlina93cd532016-01-14 16:55:11 -0800258} // namespace chromeos_update_engine