xref: /aosp_15_r20/system/update_engine/aosp/binder_service_android.cc (revision 5a9231315b4521097b8dc3750bc806fcafe0c72f)
1*5a923131SAndroid Build Coastguard Worker //
2*5a923131SAndroid Build Coastguard Worker // Copyright (C) 2015 The Android Open Source Project
3*5a923131SAndroid Build Coastguard Worker //
4*5a923131SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
5*5a923131SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
6*5a923131SAndroid Build Coastguard Worker // You may obtain a copy of the License at
7*5a923131SAndroid Build Coastguard Worker //
8*5a923131SAndroid Build Coastguard Worker //      http://www.apache.org/licenses/LICENSE-2.0
9*5a923131SAndroid Build Coastguard Worker //
10*5a923131SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
11*5a923131SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
12*5a923131SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*5a923131SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
14*5a923131SAndroid Build Coastguard Worker // limitations under the License.
15*5a923131SAndroid Build Coastguard Worker //
16*5a923131SAndroid Build Coastguard Worker 
17*5a923131SAndroid Build Coastguard Worker #include "update_engine/aosp/binder_service_android.h"
18*5a923131SAndroid Build Coastguard Worker 
19*5a923131SAndroid Build Coastguard Worker #include <memory>
20*5a923131SAndroid Build Coastguard Worker 
21*5a923131SAndroid Build Coastguard Worker #include <base/bind.h>
22*5a923131SAndroid Build Coastguard Worker #include <base/logging.h>
23*5a923131SAndroid Build Coastguard Worker #include <binderwrapper/binder_wrapper.h>
24*5a923131SAndroid Build Coastguard Worker #include <utils/String8.h>
25*5a923131SAndroid Build Coastguard Worker 
26*5a923131SAndroid Build Coastguard Worker #include "update_engine/aosp/binder_service_android_common.h"
27*5a923131SAndroid Build Coastguard Worker #include "update_engine/common/error_code.h"
28*5a923131SAndroid Build Coastguard Worker 
29*5a923131SAndroid Build Coastguard Worker using android::binder::Status;
30*5a923131SAndroid Build Coastguard Worker using android::os::IUpdateEngineCallback;
31*5a923131SAndroid Build Coastguard Worker using android::os::ParcelFileDescriptor;
32*5a923131SAndroid Build Coastguard Worker using std::string;
33*5a923131SAndroid Build Coastguard Worker using std::vector;
34*5a923131SAndroid Build Coastguard Worker using update_engine::UpdateEngineStatus;
35*5a923131SAndroid Build Coastguard Worker 
36*5a923131SAndroid Build Coastguard Worker namespace chromeos_update_engine {
37*5a923131SAndroid Build Coastguard Worker 
BinderUpdateEngineAndroidService(ServiceDelegateAndroidInterface * service_delegate)38*5a923131SAndroid Build Coastguard Worker BinderUpdateEngineAndroidService::BinderUpdateEngineAndroidService(
39*5a923131SAndroid Build Coastguard Worker     ServiceDelegateAndroidInterface* service_delegate)
40*5a923131SAndroid Build Coastguard Worker     : service_delegate_(service_delegate) {}
41*5a923131SAndroid Build Coastguard Worker 
SendStatusUpdate(const UpdateEngineStatus & update_engine_status)42*5a923131SAndroid Build Coastguard Worker void BinderUpdateEngineAndroidService::SendStatusUpdate(
43*5a923131SAndroid Build Coastguard Worker     const UpdateEngineStatus& update_engine_status) {
44*5a923131SAndroid Build Coastguard Worker   last_status_ = static_cast<int>(update_engine_status.status);
45*5a923131SAndroid Build Coastguard Worker   last_progress_ = update_engine_status.progress;
46*5a923131SAndroid Build Coastguard Worker   for (auto& callback : callbacks_) {
47*5a923131SAndroid Build Coastguard Worker     callback->onStatusUpdate(last_status_, last_progress_);
48*5a923131SAndroid Build Coastguard Worker   }
49*5a923131SAndroid Build Coastguard Worker }
50*5a923131SAndroid Build Coastguard Worker 
SendPayloadApplicationComplete(ErrorCode error_code)51*5a923131SAndroid Build Coastguard Worker void BinderUpdateEngineAndroidService::SendPayloadApplicationComplete(
52*5a923131SAndroid Build Coastguard Worker     ErrorCode error_code) {
53*5a923131SAndroid Build Coastguard Worker   for (auto& callback : callbacks_) {
54*5a923131SAndroid Build Coastguard Worker     callback->onPayloadApplicationComplete(static_cast<int>(error_code));
55*5a923131SAndroid Build Coastguard Worker   }
56*5a923131SAndroid Build Coastguard Worker }
57*5a923131SAndroid Build Coastguard Worker 
bind(const android::sp<IUpdateEngineCallback> & callback,bool * return_value)58*5a923131SAndroid Build Coastguard Worker Status BinderUpdateEngineAndroidService::bind(
59*5a923131SAndroid Build Coastguard Worker     const android::sp<IUpdateEngineCallback>& callback, bool* return_value) {
60*5a923131SAndroid Build Coastguard Worker   // Send an status update on connection (except when no update sent so far).
61*5a923131SAndroid Build Coastguard Worker   // Even though the status update is oneway, it still returns an erroneous
62*5a923131SAndroid Build Coastguard Worker   // status in case of a selinux denial. We should at least check this status
63*5a923131SAndroid Build Coastguard Worker   // and fails the binding.
64*5a923131SAndroid Build Coastguard Worker   if (last_status_ != -1) {
65*5a923131SAndroid Build Coastguard Worker     auto status = callback->onStatusUpdate(last_status_, last_progress_);
66*5a923131SAndroid Build Coastguard Worker     if (!status.isOk()) {
67*5a923131SAndroid Build Coastguard Worker       LOG(ERROR) << "Failed to call onStatusUpdate() from callback: "
68*5a923131SAndroid Build Coastguard Worker                  << status.toString8();
69*5a923131SAndroid Build Coastguard Worker       *return_value = false;
70*5a923131SAndroid Build Coastguard Worker       return Status::ok();
71*5a923131SAndroid Build Coastguard Worker     }
72*5a923131SAndroid Build Coastguard Worker   }
73*5a923131SAndroid Build Coastguard Worker 
74*5a923131SAndroid Build Coastguard Worker   callbacks_.emplace_back(callback);
75*5a923131SAndroid Build Coastguard Worker 
76*5a923131SAndroid Build Coastguard Worker   const android::sp<IBinder>& callback_binder =
77*5a923131SAndroid Build Coastguard Worker       IUpdateEngineCallback::asBinder(callback);
78*5a923131SAndroid Build Coastguard Worker   auto binder_wrapper = android::BinderWrapper::Get();
79*5a923131SAndroid Build Coastguard Worker   binder_wrapper->RegisterForDeathNotifications(
80*5a923131SAndroid Build Coastguard Worker       callback_binder,
81*5a923131SAndroid Build Coastguard Worker       [this, callback = callback_binder.get()]() { UnbindCallback(callback); });
82*5a923131SAndroid Build Coastguard Worker 
83*5a923131SAndroid Build Coastguard Worker   *return_value = true;
84*5a923131SAndroid Build Coastguard Worker   return Status::ok();
85*5a923131SAndroid Build Coastguard Worker }
86*5a923131SAndroid Build Coastguard Worker 
unbind(const android::sp<IUpdateEngineCallback> & callback,bool * return_value)87*5a923131SAndroid Build Coastguard Worker Status BinderUpdateEngineAndroidService::unbind(
88*5a923131SAndroid Build Coastguard Worker     const android::sp<IUpdateEngineCallback>& callback, bool* return_value) {
89*5a923131SAndroid Build Coastguard Worker   const android::sp<IBinder>& callback_binder =
90*5a923131SAndroid Build Coastguard Worker       IUpdateEngineCallback::asBinder(callback);
91*5a923131SAndroid Build Coastguard Worker   auto binder_wrapper = android::BinderWrapper::Get();
92*5a923131SAndroid Build Coastguard Worker   binder_wrapper->UnregisterForDeathNotifications(callback_binder);
93*5a923131SAndroid Build Coastguard Worker 
94*5a923131SAndroid Build Coastguard Worker   *return_value = UnbindCallback(callback_binder.get());
95*5a923131SAndroid Build Coastguard Worker   return Status::ok();
96*5a923131SAndroid Build Coastguard Worker }
97*5a923131SAndroid Build Coastguard Worker 
applyPayload(const android::String16 & url,int64_t payload_offset,int64_t payload_size,const vector<android::String16> & header_kv_pairs)98*5a923131SAndroid Build Coastguard Worker Status BinderUpdateEngineAndroidService::applyPayload(
99*5a923131SAndroid Build Coastguard Worker     const android::String16& url,
100*5a923131SAndroid Build Coastguard Worker     int64_t payload_offset,
101*5a923131SAndroid Build Coastguard Worker     int64_t payload_size,
102*5a923131SAndroid Build Coastguard Worker     const vector<android::String16>& header_kv_pairs) {
103*5a923131SAndroid Build Coastguard Worker   const string payload_url{android::String8{url}.c_str()};
104*5a923131SAndroid Build Coastguard Worker   vector<string> str_headers = ToVecString(header_kv_pairs);
105*5a923131SAndroid Build Coastguard Worker 
106*5a923131SAndroid Build Coastguard Worker   Error error;
107*5a923131SAndroid Build Coastguard Worker   if (!service_delegate_->ApplyPayload(
108*5a923131SAndroid Build Coastguard Worker           payload_url, payload_offset, payload_size, str_headers, &error)) {
109*5a923131SAndroid Build Coastguard Worker     return ErrorPtrToStatus(error);
110*5a923131SAndroid Build Coastguard Worker   }
111*5a923131SAndroid Build Coastguard Worker   return Status::ok();
112*5a923131SAndroid Build Coastguard Worker }
113*5a923131SAndroid Build Coastguard Worker 
applyPayloadFd(const ParcelFileDescriptor & pfd,int64_t payload_offset,int64_t payload_size,const vector<android::String16> & header_kv_pairs)114*5a923131SAndroid Build Coastguard Worker Status BinderUpdateEngineAndroidService::applyPayloadFd(
115*5a923131SAndroid Build Coastguard Worker     const ParcelFileDescriptor& pfd,
116*5a923131SAndroid Build Coastguard Worker     int64_t payload_offset,
117*5a923131SAndroid Build Coastguard Worker     int64_t payload_size,
118*5a923131SAndroid Build Coastguard Worker     const vector<android::String16>& header_kv_pairs) {
119*5a923131SAndroid Build Coastguard Worker   vector<string> str_headers = ToVecString(header_kv_pairs);
120*5a923131SAndroid Build Coastguard Worker 
121*5a923131SAndroid Build Coastguard Worker   Error error;
122*5a923131SAndroid Build Coastguard Worker   if (!service_delegate_->ApplyPayload(
123*5a923131SAndroid Build Coastguard Worker           pfd.get(), payload_offset, payload_size, str_headers, &error)) {
124*5a923131SAndroid Build Coastguard Worker     return ErrorPtrToStatus(error);
125*5a923131SAndroid Build Coastguard Worker   }
126*5a923131SAndroid Build Coastguard Worker   return Status::ok();
127*5a923131SAndroid Build Coastguard Worker }
128*5a923131SAndroid Build Coastguard Worker 
suspend()129*5a923131SAndroid Build Coastguard Worker Status BinderUpdateEngineAndroidService::suspend() {
130*5a923131SAndroid Build Coastguard Worker   Error error;
131*5a923131SAndroid Build Coastguard Worker   if (!service_delegate_->SuspendUpdate(&error))
132*5a923131SAndroid Build Coastguard Worker     return ErrorPtrToStatus(error);
133*5a923131SAndroid Build Coastguard Worker   return Status::ok();
134*5a923131SAndroid Build Coastguard Worker }
135*5a923131SAndroid Build Coastguard Worker 
resume()136*5a923131SAndroid Build Coastguard Worker Status BinderUpdateEngineAndroidService::resume() {
137*5a923131SAndroid Build Coastguard Worker   Error error;
138*5a923131SAndroid Build Coastguard Worker   if (!service_delegate_->ResumeUpdate(&error))
139*5a923131SAndroid Build Coastguard Worker     return ErrorPtrToStatus(error);
140*5a923131SAndroid Build Coastguard Worker   return Status::ok();
141*5a923131SAndroid Build Coastguard Worker }
142*5a923131SAndroid Build Coastguard Worker 
cancel()143*5a923131SAndroid Build Coastguard Worker Status BinderUpdateEngineAndroidService::cancel() {
144*5a923131SAndroid Build Coastguard Worker   Error error;
145*5a923131SAndroid Build Coastguard Worker   if (!service_delegate_->CancelUpdate(&error))
146*5a923131SAndroid Build Coastguard Worker     return ErrorPtrToStatus(error);
147*5a923131SAndroid Build Coastguard Worker   return Status::ok();
148*5a923131SAndroid Build Coastguard Worker }
149*5a923131SAndroid Build Coastguard Worker 
resetStatus()150*5a923131SAndroid Build Coastguard Worker Status BinderUpdateEngineAndroidService::resetStatus() {
151*5a923131SAndroid Build Coastguard Worker   Error error;
152*5a923131SAndroid Build Coastguard Worker   if (!service_delegate_->ResetStatus(&error))
153*5a923131SAndroid Build Coastguard Worker     return ErrorPtrToStatus(error);
154*5a923131SAndroid Build Coastguard Worker   return Status::ok();
155*5a923131SAndroid Build Coastguard Worker }
156*5a923131SAndroid Build Coastguard Worker 
setShouldSwitchSlotOnReboot(const android::String16 & metadata_filename)157*5a923131SAndroid Build Coastguard Worker Status BinderUpdateEngineAndroidService::setShouldSwitchSlotOnReboot(
158*5a923131SAndroid Build Coastguard Worker     const android::String16& metadata_filename) {
159*5a923131SAndroid Build Coastguard Worker   Error error;
160*5a923131SAndroid Build Coastguard Worker   if (!service_delegate_->setShouldSwitchSlotOnReboot(
161*5a923131SAndroid Build Coastguard Worker           android::String8(metadata_filename).c_str(), &error)) {
162*5a923131SAndroid Build Coastguard Worker     return ErrorPtrToStatus(error);
163*5a923131SAndroid Build Coastguard Worker   }
164*5a923131SAndroid Build Coastguard Worker   return Status::ok();
165*5a923131SAndroid Build Coastguard Worker }
166*5a923131SAndroid Build Coastguard Worker 
resetShouldSwitchSlotOnReboot()167*5a923131SAndroid Build Coastguard Worker Status BinderUpdateEngineAndroidService::resetShouldSwitchSlotOnReboot() {
168*5a923131SAndroid Build Coastguard Worker   Error error;
169*5a923131SAndroid Build Coastguard Worker   if (!service_delegate_->resetShouldSwitchSlotOnReboot(&error)) {
170*5a923131SAndroid Build Coastguard Worker     return ErrorPtrToStatus(error);
171*5a923131SAndroid Build Coastguard Worker   }
172*5a923131SAndroid Build Coastguard Worker   return Status::ok();
173*5a923131SAndroid Build Coastguard Worker }
174*5a923131SAndroid Build Coastguard Worker 
verifyPayloadApplicable(const android::String16 & metadata_filename,bool * return_value)175*5a923131SAndroid Build Coastguard Worker Status BinderUpdateEngineAndroidService::verifyPayloadApplicable(
176*5a923131SAndroid Build Coastguard Worker     const android::String16& metadata_filename, bool* return_value) {
177*5a923131SAndroid Build Coastguard Worker   const std::string payload_metadata{
178*5a923131SAndroid Build Coastguard Worker       android::String8{metadata_filename}.c_str()};
179*5a923131SAndroid Build Coastguard Worker   LOG(INFO) << "Received a request of verifying payload metadata in "
180*5a923131SAndroid Build Coastguard Worker             << payload_metadata << ".";
181*5a923131SAndroid Build Coastguard Worker   Error error;
182*5a923131SAndroid Build Coastguard Worker   *return_value =
183*5a923131SAndroid Build Coastguard Worker       service_delegate_->VerifyPayloadApplicable(payload_metadata, &error);
184*5a923131SAndroid Build Coastguard Worker   if (error.error_code != ErrorCode::kSuccess)
185*5a923131SAndroid Build Coastguard Worker     return ErrorPtrToStatus(error);
186*5a923131SAndroid Build Coastguard Worker   return Status::ok();
187*5a923131SAndroid Build Coastguard Worker }
188*5a923131SAndroid Build Coastguard Worker 
UnbindCallback(const IBinder * callback)189*5a923131SAndroid Build Coastguard Worker bool BinderUpdateEngineAndroidService::UnbindCallback(const IBinder* callback) {
190*5a923131SAndroid Build Coastguard Worker   auto it = std::find_if(
191*5a923131SAndroid Build Coastguard Worker       callbacks_.begin(),
192*5a923131SAndroid Build Coastguard Worker       callbacks_.end(),
193*5a923131SAndroid Build Coastguard Worker       [&callback](const android::sp<IUpdateEngineCallback>& elem) {
194*5a923131SAndroid Build Coastguard Worker         return IUpdateEngineCallback::asBinder(elem).get() == callback;
195*5a923131SAndroid Build Coastguard Worker       });
196*5a923131SAndroid Build Coastguard Worker   if (it == callbacks_.end()) {
197*5a923131SAndroid Build Coastguard Worker     LOG(ERROR) << "Unable to unbind unknown callback.";
198*5a923131SAndroid Build Coastguard Worker     return false;
199*5a923131SAndroid Build Coastguard Worker   }
200*5a923131SAndroid Build Coastguard Worker   callbacks_.erase(it);
201*5a923131SAndroid Build Coastguard Worker   return true;
202*5a923131SAndroid Build Coastguard Worker }
203*5a923131SAndroid Build Coastguard Worker 
allocateSpaceForPayload(const android::String16 & metadata_filename,const vector<android::String16> & header_kv_pairs,int64_t * return_value)204*5a923131SAndroid Build Coastguard Worker Status BinderUpdateEngineAndroidService::allocateSpaceForPayload(
205*5a923131SAndroid Build Coastguard Worker     const android::String16& metadata_filename,
206*5a923131SAndroid Build Coastguard Worker     const vector<android::String16>& header_kv_pairs,
207*5a923131SAndroid Build Coastguard Worker     int64_t* return_value) {
208*5a923131SAndroid Build Coastguard Worker   const std::string payload_metadata{
209*5a923131SAndroid Build Coastguard Worker       android::String8{metadata_filename}.c_str()};
210*5a923131SAndroid Build Coastguard Worker   vector<string> str_headers = ToVecString(header_kv_pairs);
211*5a923131SAndroid Build Coastguard Worker   LOG(INFO) << "Received a request of allocating space for " << payload_metadata
212*5a923131SAndroid Build Coastguard Worker             << ".";
213*5a923131SAndroid Build Coastguard Worker   Error error;
214*5a923131SAndroid Build Coastguard Worker   *return_value =
215*5a923131SAndroid Build Coastguard Worker       static_cast<int64_t>(service_delegate_->AllocateSpaceForPayload(
216*5a923131SAndroid Build Coastguard Worker           payload_metadata, str_headers, &error));
217*5a923131SAndroid Build Coastguard Worker   if (error.error_code != ErrorCode::kSuccess)
218*5a923131SAndroid Build Coastguard Worker     return ErrorPtrToStatus(error);
219*5a923131SAndroid Build Coastguard Worker   return Status::ok();
220*5a923131SAndroid Build Coastguard Worker }
221*5a923131SAndroid Build Coastguard Worker 
222*5a923131SAndroid Build Coastguard Worker class CleanupSuccessfulUpdateCallback
223*5a923131SAndroid Build Coastguard Worker     : public CleanupSuccessfulUpdateCallbackInterface {
224*5a923131SAndroid Build Coastguard Worker  public:
CleanupSuccessfulUpdateCallback(const android::sp<IUpdateEngineCallback> & callback)225*5a923131SAndroid Build Coastguard Worker   CleanupSuccessfulUpdateCallback(
226*5a923131SAndroid Build Coastguard Worker       const android::sp<IUpdateEngineCallback>& callback)
227*5a923131SAndroid Build Coastguard Worker       : callback_(callback) {}
OnCleanupComplete(int32_t error_code)228*5a923131SAndroid Build Coastguard Worker   void OnCleanupComplete(int32_t error_code) {
229*5a923131SAndroid Build Coastguard Worker     ignore_result(callback_->onPayloadApplicationComplete(error_code));
230*5a923131SAndroid Build Coastguard Worker   }
OnCleanupProgressUpdate(double progress)231*5a923131SAndroid Build Coastguard Worker   void OnCleanupProgressUpdate(double progress) {
232*5a923131SAndroid Build Coastguard Worker     ignore_result(callback_->onStatusUpdate(
233*5a923131SAndroid Build Coastguard Worker         static_cast<int32_t>(
234*5a923131SAndroid Build Coastguard Worker             update_engine::UpdateStatus::CLEANUP_PREVIOUS_UPDATE),
235*5a923131SAndroid Build Coastguard Worker         progress));
236*5a923131SAndroid Build Coastguard Worker   }
RegisterForDeathNotifications(const std::function<void ()> & unbind)237*5a923131SAndroid Build Coastguard Worker   void RegisterForDeathNotifications(const std::function<void()>& unbind) {
238*5a923131SAndroid Build Coastguard Worker     const android::sp<android::IBinder>& callback_binder =
239*5a923131SAndroid Build Coastguard Worker         IUpdateEngineCallback::asBinder(callback_);
240*5a923131SAndroid Build Coastguard Worker     auto binder_wrapper = android::BinderWrapper::Get();
241*5a923131SAndroid Build Coastguard Worker     binder_wrapper->RegisterForDeathNotifications(callback_binder, unbind);
242*5a923131SAndroid Build Coastguard Worker   }
243*5a923131SAndroid Build Coastguard Worker 
244*5a923131SAndroid Build Coastguard Worker  private:
245*5a923131SAndroid Build Coastguard Worker   android::sp<IUpdateEngineCallback> callback_;
246*5a923131SAndroid Build Coastguard Worker };
247*5a923131SAndroid Build Coastguard Worker 
cleanupSuccessfulUpdate(const android::sp<IUpdateEngineCallback> & callback)248*5a923131SAndroid Build Coastguard Worker Status BinderUpdateEngineAndroidService::cleanupSuccessfulUpdate(
249*5a923131SAndroid Build Coastguard Worker     const android::sp<IUpdateEngineCallback>& callback) {
250*5a923131SAndroid Build Coastguard Worker   Error error;
251*5a923131SAndroid Build Coastguard Worker   service_delegate_->CleanupSuccessfulUpdate(
252*5a923131SAndroid Build Coastguard Worker       std::make_unique<CleanupSuccessfulUpdateCallback>(callback), &error);
253*5a923131SAndroid Build Coastguard Worker   if (error.error_code != ErrorCode::kSuccess)
254*5a923131SAndroid Build Coastguard Worker     return ErrorPtrToStatus(error);
255*5a923131SAndroid Build Coastguard Worker   return Status::ok();
256*5a923131SAndroid Build Coastguard Worker }
257*5a923131SAndroid Build Coastguard Worker 
triggerPostinstall(const::android::String16 & partition)258*5a923131SAndroid Build Coastguard Worker Status BinderUpdateEngineAndroidService::triggerPostinstall(
259*5a923131SAndroid Build Coastguard Worker     const ::android::String16& partition) {
260*5a923131SAndroid Build Coastguard Worker   Error error;
261*5a923131SAndroid Build Coastguard Worker   service_delegate_->TriggerPostinstall(android::String8(partition).c_str(),
262*5a923131SAndroid Build Coastguard Worker                                         &error);
263*5a923131SAndroid Build Coastguard Worker   if (error.error_code != ErrorCode::kSuccess)
264*5a923131SAndroid Build Coastguard Worker     return ErrorPtrToStatus(error);
265*5a923131SAndroid Build Coastguard Worker   return Status::ok();
266*5a923131SAndroid Build Coastguard Worker }
267*5a923131SAndroid Build Coastguard Worker 
268*5a923131SAndroid Build Coastguard Worker }  // namespace chromeos_update_engine
269