xref: /aosp_15_r20/system/update_engine/aosp/binder_service_stable_android.cc (revision 5a9231315b4521097b8dc3750bc806fcafe0c72f)
1 //
2 // Copyright (C) 2020 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/aosp/binder_service_stable_android.h"
18 
19 #include <base/bind.h>
20 #include <base/logging.h>
21 #include <binderwrapper/binder_wrapper.h>
22 #include <utils/String8.h>
23 
24 #include "update_engine/aosp/binder_service_android_common.h"
25 
26 using android::binder::Status;
27 using android::os::IUpdateEngineStableCallback;
28 using android::os::ParcelFileDescriptor;
29 using std::string;
30 using std::vector;
31 using update_engine::UpdateEngineStatus;
32 
33 namespace chromeos_update_engine {
34 
BinderUpdateEngineAndroidStableService(ServiceDelegateAndroidInterface * service_delegate)35 BinderUpdateEngineAndroidStableService::BinderUpdateEngineAndroidStableService(
36     ServiceDelegateAndroidInterface* service_delegate)
37     : service_delegate_(service_delegate) {}
38 
SendStatusUpdate(const UpdateEngineStatus & update_engine_status)39 void BinderUpdateEngineAndroidStableService::SendStatusUpdate(
40     const UpdateEngineStatus& update_engine_status) {
41   last_status_ = static_cast<int>(update_engine_status.status);
42   last_progress_ = update_engine_status.progress;
43   if (callback_) {
44     callback_->onStatusUpdate(last_status_, last_progress_);
45   }
46 }
47 
SendPayloadApplicationComplete(ErrorCode error_code)48 void BinderUpdateEngineAndroidStableService::SendPayloadApplicationComplete(
49     ErrorCode error_code) {
50   if (callback_) {
51     callback_->onPayloadApplicationComplete(static_cast<int>(error_code));
52   }
53 }
54 
bind(const android::sp<IUpdateEngineStableCallback> & callback,bool * return_value)55 Status BinderUpdateEngineAndroidStableService::bind(
56     const android::sp<IUpdateEngineStableCallback>& callback,
57     bool* return_value) {
58   // Reject binding if another callback is already bound.
59   if (callback_ != nullptr) {
60     LOG(ERROR) << "Another callback is already bound. Can't bind new callback.";
61     *return_value = false;
62     return Status::ok();
63   }
64 
65   // See BinderUpdateEngineAndroidService::bind.
66   if (last_status_ != -1) {
67     auto status = callback->onStatusUpdate(last_status_, last_progress_);
68     if (!status.isOk()) {
69       LOG(ERROR) << "Failed to call onStatusUpdate() from callback: "
70                  << status.toString8();
71       *return_value = false;
72       return Status::ok();
73     }
74   }
75 
76   callback_ = callback;
77 
78   const android::sp<IBinder>& callback_binder =
79       IUpdateEngineStableCallback::asBinder(callback);
80   auto binder_wrapper = android::BinderWrapper::Get();
81   binder_wrapper->RegisterForDeathNotifications(
82       callback_binder,
83       [this, callback = callback_binder.get()]() { UnbindCallback(callback); });
84 
85   *return_value = true;
86   return Status::ok();
87 }
88 
unbind(const android::sp<IUpdateEngineStableCallback> & callback,bool * return_value)89 Status BinderUpdateEngineAndroidStableService::unbind(
90     const android::sp<IUpdateEngineStableCallback>& callback,
91     bool* return_value) {
92   const android::sp<IBinder>& callback_binder =
93       IUpdateEngineStableCallback::asBinder(callback);
94   auto binder_wrapper = android::BinderWrapper::Get();
95   binder_wrapper->UnregisterForDeathNotifications(callback_binder);
96 
97   *return_value = UnbindCallback(callback_binder.get());
98   return Status::ok();
99 }
100 
applyPayloadFd(const ParcelFileDescriptor & pfd,int64_t payload_offset,int64_t payload_size,const vector<android::String16> & header_kv_pairs)101 Status BinderUpdateEngineAndroidStableService::applyPayloadFd(
102     const ParcelFileDescriptor& pfd,
103     int64_t payload_offset,
104     int64_t payload_size,
105     const vector<android::String16>& header_kv_pairs) {
106   vector<string> str_headers = ToVecString(header_kv_pairs);
107 
108   Error error;
109   if (!service_delegate_->ApplyPayload(
110           pfd.get(), payload_offset, payload_size, str_headers, &error)) {
111     return ErrorPtrToStatus(error);
112   }
113   return Status::ok();
114 }
115 
UnbindCallback(const IBinder * callback)116 bool BinderUpdateEngineAndroidStableService::UnbindCallback(
117     const IBinder* callback) {
118   if (IUpdateEngineStableCallback::asBinder(callback_).get() != callback) {
119     LOG(ERROR) << "Unable to unbind unknown callback.";
120     return false;
121   }
122   callback_ = nullptr;
123   return true;
124 }
125 
126 android::binder::Status
triggerPostinstall(const::android::String16 & partition)127 BinderUpdateEngineAndroidStableService::triggerPostinstall(
128     const ::android::String16& partition) {
129   Error error;
130   if (!service_delegate_->TriggerPostinstall(
131           android::String8{partition}.c_str(), &error)) {
132     return ErrorPtrToStatus(error);
133   }
134   return Status::ok();
135 }
136 
137 }  // namespace chromeos_update_engine
138