blob: c376f4ea3176c1410b8f25b62532026829a4ffd0 [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
Alex Deymof8bfcff2016-02-02 21:22:11 -080019#include <base/bind.h>
20#include <base/logging.h>
21#include <binderwrapper/binder_wrapper.h>
22#include <brillo/errors/error.h>
23#include <utils/String8.h>
24
Casey Dahlina93cd532016-01-14 16:55:11 -080025using android::binder::Status;
26using android::os::IUpdateEngineCallback;
Kyeongkab.Nam42132992019-10-03 18:04:02 +090027using android::os::ParcelFileDescriptor;
Kyeongkab.Nam500ca132019-06-26 13:48:07 +090028using std::string;
29using std::vector;
Aaron Wood7f92e2b2017-08-28 14:51:21 -070030using update_engine::UpdateEngineStatus;
Alex Deymof8bfcff2016-02-02 21:22:11 -080031
32namespace {
33Status ErrorPtrToStatus(const brillo::ErrorPtr& error) {
34 return Status::fromServiceSpecificError(
35 1, android::String8{error->GetMessage().c_str()});
36}
Yifan Hongeec29272019-12-13 15:02:37 -080037
38vector<string> ToVecString(const vector<android::String16>& inp) {
39 vector<string> out;
40 out.reserve(inp.size());
41 for (const auto& e : inp) {
42 out.emplace_back(android::String8{e}.string());
43 }
44 return out;
45}
46
Alex Deymof8bfcff2016-02-02 21:22:11 -080047} // namespace
Casey Dahlina93cd532016-01-14 16:55:11 -080048
49namespace chromeos_update_engine {
50
Alex Deymofa78f142016-01-26 21:36:16 -080051BinderUpdateEngineAndroidService::BinderUpdateEngineAndroidService(
Alex Deymof8bfcff2016-02-02 21:22:11 -080052 ServiceDelegateAndroidInterface* service_delegate)
Amin Hassani7cc8bb02019-01-14 16:29:47 -080053 : service_delegate_(service_delegate) {}
Alex Deymofa78f142016-01-26 21:36:16 -080054
55void BinderUpdateEngineAndroidService::SendStatusUpdate(
Aaron Wood7f92e2b2017-08-28 14:51:21 -070056 const UpdateEngineStatus& update_engine_status) {
57 last_status_ = static_cast<int>(update_engine_status.status);
58 last_progress_ = update_engine_status.progress;
Alex Deymof8bfcff2016-02-02 21:22:11 -080059 for (auto& callback : callbacks_) {
Alex Deymo0e061ae2016-02-09 17:49:03 -080060 callback->onStatusUpdate(last_status_, last_progress_);
Alex Deymof8bfcff2016-02-02 21:22:11 -080061 }
62}
63
64void BinderUpdateEngineAndroidService::SendPayloadApplicationComplete(
65 ErrorCode error_code) {
66 for (auto& callback : callbacks_) {
67 callback->onPayloadApplicationComplete(static_cast<int>(error_code));
68 }
Alex Deymofa78f142016-01-26 21:36:16 -080069}
70
Alex Deymoe97b39c2016-01-20 13:22:17 -080071Status BinderUpdateEngineAndroidService::bind(
Alex Deymof8bfcff2016-02-02 21:22:11 -080072 const android::sp<IUpdateEngineCallback>& callback, bool* return_value) {
Tianjie Xu60f3a232019-12-11 13:53:39 -080073 // Send an status update on connection (except when no update sent so far).
74 // Even though the status update is oneway, it still returns an erroneous
75 // status in case of a selinux denial. We should at least check this status
76 // and fails the binding.
77 if (last_status_ != -1) {
78 auto status = callback->onStatusUpdate(last_status_, last_progress_);
79 if (!status.isOk()) {
80 LOG(ERROR) << "Failed to call onStatusUpdate() from callback: "
81 << status.toString8();
82 *return_value = false;
83 return Status::ok();
84 }
85 }
86
Alex Deymof8bfcff2016-02-02 21:22:11 -080087 callbacks_.emplace_back(callback);
88
Sen Jiangb7f73802017-07-18 15:29:26 -070089 const android::sp<IBinder>& callback_binder =
90 IUpdateEngineCallback::asBinder(callback);
Alex Deymof8bfcff2016-02-02 21:22:11 -080091 auto binder_wrapper = android::BinderWrapper::Get();
92 binder_wrapper->RegisterForDeathNotifications(
Sen Jiangb7f73802017-07-18 15:29:26 -070093 callback_binder,
Sen Jiang5caab192017-07-07 17:22:29 -070094 base::Bind(
95 base::IgnoreResult(&BinderUpdateEngineAndroidService::UnbindCallback),
96 base::Unretained(this),
Sen Jiangb7f73802017-07-18 15:29:26 -070097 base::Unretained(callback_binder.get())));
Alex Deymof8bfcff2016-02-02 21:22:11 -080098
Casey Dahlina93cd532016-01-14 16:55:11 -080099 *return_value = true;
100 return Status::ok();
101}
102
Sen Jiang5caab192017-07-07 17:22:29 -0700103Status BinderUpdateEngineAndroidService::unbind(
104 const android::sp<IUpdateEngineCallback>& callback, bool* return_value) {
Sen Jiangb7f73802017-07-18 15:29:26 -0700105 const android::sp<IBinder>& callback_binder =
106 IUpdateEngineCallback::asBinder(callback);
Sen Jiang5caab192017-07-07 17:22:29 -0700107 auto binder_wrapper = android::BinderWrapper::Get();
Sen Jiangb7f73802017-07-18 15:29:26 -0700108 binder_wrapper->UnregisterForDeathNotifications(callback_binder);
Sen Jiang5caab192017-07-07 17:22:29 -0700109
Sen Jiangb7f73802017-07-18 15:29:26 -0700110 *return_value = UnbindCallback(callback_binder.get());
Sen Jiang5caab192017-07-07 17:22:29 -0700111 return Status::ok();
112}
113
Alex Deymoe97b39c2016-01-20 13:22:17 -0800114Status BinderUpdateEngineAndroidService::applyPayload(
Alex Deymof8bfcff2016-02-02 21:22:11 -0800115 const android::String16& url,
Alex Deymo95b8f242016-01-28 16:06:57 -0800116 int64_t payload_offset,
117 int64_t payload_size,
Kyeongkab.Nam500ca132019-06-26 13:48:07 +0900118 const vector<android::String16>& header_kv_pairs) {
119 const string payload_url{android::String8{url}.string()};
Yifan Hongeec29272019-12-13 15:02:37 -0800120 vector<string> str_headers = ToVecString(header_kv_pairs);
Alex Deymof8bfcff2016-02-02 21:22:11 -0800121
122 brillo::ErrorPtr error;
123 if (!service_delegate_->ApplyPayload(
124 payload_url, payload_offset, payload_size, str_headers, &error)) {
125 return ErrorPtrToStatus(error);
126 }
Casey Dahlina93cd532016-01-14 16:55:11 -0800127 return Status::ok();
128}
129
Kyeongkab.Nam500ca132019-06-26 13:48:07 +0900130Status BinderUpdateEngineAndroidService::applyPayloadFd(
Kyeongkab.Nam42132992019-10-03 18:04:02 +0900131 const ParcelFileDescriptor& pfd,
Kyeongkab.Nam500ca132019-06-26 13:48:07 +0900132 int64_t payload_offset,
133 int64_t payload_size,
134 const vector<android::String16>& header_kv_pairs) {
Yifan Hongeec29272019-12-13 15:02:37 -0800135 vector<string> str_headers = ToVecString(header_kv_pairs);
Kyeongkab.Nam500ca132019-06-26 13:48:07 +0900136
137 brillo::ErrorPtr error;
138 if (!service_delegate_->ApplyPayload(
Kyeongkab.Nam42132992019-10-03 18:04:02 +0900139 pfd.get(), payload_offset, payload_size, str_headers, &error)) {
Kyeongkab.Nam500ca132019-06-26 13:48:07 +0900140 return ErrorPtrToStatus(error);
141 }
142 return Status::ok();
143}
144
Alex Deymoe97b39c2016-01-20 13:22:17 -0800145Status BinderUpdateEngineAndroidService::suspend() {
Alex Deymof8bfcff2016-02-02 21:22:11 -0800146 brillo::ErrorPtr error;
147 if (!service_delegate_->SuspendUpdate(&error))
148 return ErrorPtrToStatus(error);
Casey Dahlina93cd532016-01-14 16:55:11 -0800149 return Status::ok();
150}
151
Alex Deymoe97b39c2016-01-20 13:22:17 -0800152Status BinderUpdateEngineAndroidService::resume() {
Alex Deymof8bfcff2016-02-02 21:22:11 -0800153 brillo::ErrorPtr error;
154 if (!service_delegate_->ResumeUpdate(&error))
155 return ErrorPtrToStatus(error);
Casey Dahlina93cd532016-01-14 16:55:11 -0800156 return Status::ok();
157}
158
Alex Deymoe97b39c2016-01-20 13:22:17 -0800159Status BinderUpdateEngineAndroidService::cancel() {
Alex Deymof8bfcff2016-02-02 21:22:11 -0800160 brillo::ErrorPtr error;
161 if (!service_delegate_->CancelUpdate(&error))
162 return ErrorPtrToStatus(error);
Casey Dahlina93cd532016-01-14 16:55:11 -0800163 return Status::ok();
164}
165
Alex Deymo3b678db2016-02-09 11:50:06 -0800166Status BinderUpdateEngineAndroidService::resetStatus() {
167 brillo::ErrorPtr error;
168 if (!service_delegate_->ResetStatus(&error))
169 return ErrorPtrToStatus(error);
170 return Status::ok();
171}
172
Tao Bao20c96722018-01-09 22:38:57 -0800173Status BinderUpdateEngineAndroidService::verifyPayloadApplicable(
174 const android::String16& metadata_filename, bool* return_value) {
175 const std::string payload_metadata{
176 android::String8{metadata_filename}.string()};
177 LOG(INFO) << "Received a request of verifying payload metadata in "
178 << payload_metadata << ".";
Sen Jiang28d8ed92018-02-01 13:46:39 -0800179 brillo::ErrorPtr error;
180 *return_value =
181 service_delegate_->VerifyPayloadApplicable(payload_metadata, &error);
182 if (error != nullptr)
183 return ErrorPtrToStatus(error);
Tao Bao20c96722018-01-09 22:38:57 -0800184 return Status::ok();
185}
186
Sen Jiangb7f73802017-07-18 15:29:26 -0700187bool BinderUpdateEngineAndroidService::UnbindCallback(const IBinder* callback) {
188 auto it = std::find_if(
189 callbacks_.begin(),
190 callbacks_.end(),
191 [&callback](const android::sp<IUpdateEngineCallback>& elem) {
192 return IUpdateEngineCallback::asBinder(elem).get() == callback;
193 });
Alex Deymof8bfcff2016-02-02 21:22:11 -0800194 if (it == callbacks_.end()) {
Sen Jiang5caab192017-07-07 17:22:29 -0700195 LOG(ERROR) << "Unable to unbind unknown callback.";
196 return false;
Alex Deymof8bfcff2016-02-02 21:22:11 -0800197 }
198 callbacks_.erase(it);
Sen Jiang5caab192017-07-07 17:22:29 -0700199 return true;
Alex Deymof8bfcff2016-02-02 21:22:11 -0800200}
201
Yifan Hong6f7e29f2019-12-13 14:41:06 -0800202Status BinderUpdateEngineAndroidService::allocateSpaceForPayload(
203 const android::String16& metadata_filename,
204 const vector<android::String16>& header_kv_pairs,
205 int64_t* return_value) {
206 const std::string payload_metadata{
207 android::String8{metadata_filename}.string()};
208 vector<string> str_headers = ToVecString(header_kv_pairs);
209 LOG(INFO) << "Received a request of allocating space for " << payload_metadata
210 << ".";
211 brillo::ErrorPtr error;
212 *return_value =
213 static_cast<int64_t>(service_delegate_->AllocateSpaceForPayload(
214 payload_metadata, str_headers, &error));
215 if (error != nullptr)
216 return ErrorPtrToStatus(error);
Yifan Hong2236ea02019-12-13 16:11:22 -0800217 return Status::ok();
218}
Yifan Hong6f7e29f2019-12-13 14:41:06 -0800219
Yifan Hong2236ea02019-12-13 16:11:22 -0800220Status BinderUpdateEngineAndroidService::cleanupSuccessfulUpdate(
221 int32_t* return_value) {
222 brillo::ErrorPtr error;
223 *return_value = service_delegate_->CleanupSuccessfulUpdate(&error);
224 if (error != nullptr)
225 return ErrorPtrToStatus(error);
Yifan Hong6f7e29f2019-12-13 14:41:06 -0800226 return Status::ok();
227}
228
Casey Dahlina93cd532016-01-14 16:55:11 -0800229} // namespace chromeos_update_engine