1 // 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 19 #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 25 using android::binder::Status; 26 using android::os::IUpdateEngineCallback; 27 using update_engine::UpdateEngineStatus; 28 29 namespace { 30 Status ErrorPtrToStatus(const brillo::ErrorPtr& error) { 31 return Status::fromServiceSpecificError( 32 1, android::String8{error->GetMessage().c_str()}); 33 } 34 } // namespace 35 36 namespace chromeos_update_engine { 37 38 BinderUpdateEngineAndroidService::BinderUpdateEngineAndroidService( 39 ServiceDelegateAndroidInterface* service_delegate) 40 : service_delegate_(service_delegate) { 41 } 42 43 void BinderUpdateEngineAndroidService::SendStatusUpdate( 44 const UpdateEngineStatus& update_engine_status) { 45 last_status_ = static_cast<int>(update_engine_status.status); 46 last_progress_ = update_engine_status.progress; 47 for (auto& callback : callbacks_) { 48 callback->onStatusUpdate(last_status_, last_progress_); 49 } 50 } 51 52 void BinderUpdateEngineAndroidService::SendPayloadApplicationComplete( 53 ErrorCode error_code) { 54 for (auto& callback : callbacks_) { 55 callback->onPayloadApplicationComplete(static_cast<int>(error_code)); 56 } 57 } 58 59 Status BinderUpdateEngineAndroidService::bind( 60 const android::sp<IUpdateEngineCallback>& callback, bool* return_value) { 61 callbacks_.emplace_back(callback); 62 63 const android::sp<IBinder>& callback_binder = 64 IUpdateEngineCallback::asBinder(callback); 65 auto binder_wrapper = android::BinderWrapper::Get(); 66 binder_wrapper->RegisterForDeathNotifications( 67 callback_binder, 68 base::Bind( 69 base::IgnoreResult(&BinderUpdateEngineAndroidService::UnbindCallback), 70 base::Unretained(this), 71 base::Unretained(callback_binder.get()))); 72 73 // Send an status update on connection (except when no update sent so far), 74 // since the status update is oneway and we don't need to wait for the 75 // response. 76 if (last_status_ != -1) 77 callback->onStatusUpdate(last_status_, last_progress_); 78 79 *return_value = true; 80 return Status::ok(); 81 } 82 83 Status BinderUpdateEngineAndroidService::unbind( 84 const android::sp<IUpdateEngineCallback>& callback, bool* return_value) { 85 const android::sp<IBinder>& callback_binder = 86 IUpdateEngineCallback::asBinder(callback); 87 auto binder_wrapper = android::BinderWrapper::Get(); 88 binder_wrapper->UnregisterForDeathNotifications(callback_binder); 89 90 *return_value = UnbindCallback(callback_binder.get()); 91 return Status::ok(); 92 } 93 94 Status BinderUpdateEngineAndroidService::applyPayload( 95 const android::String16& url, 96 int64_t payload_offset, 97 int64_t payload_size, 98 const std::vector<android::String16>& header_kv_pairs) { 99 const std::string payload_url{android::String8{url}.string()}; 100 std::vector<std::string> str_headers; 101 str_headers.reserve(header_kv_pairs.size()); 102 for (const auto& header : header_kv_pairs) { 103 str_headers.emplace_back(android::String8{header}.string()); 104 } 105 106 brillo::ErrorPtr error; 107 if (!service_delegate_->ApplyPayload( 108 payload_url, payload_offset, payload_size, str_headers, &error)) { 109 return ErrorPtrToStatus(error); 110 } 111 return Status::ok(); 112 } 113 114 Status BinderUpdateEngineAndroidService::suspend() { 115 brillo::ErrorPtr error; 116 if (!service_delegate_->SuspendUpdate(&error)) 117 return ErrorPtrToStatus(error); 118 return Status::ok(); 119 } 120 121 Status BinderUpdateEngineAndroidService::resume() { 122 brillo::ErrorPtr error; 123 if (!service_delegate_->ResumeUpdate(&error)) 124 return ErrorPtrToStatus(error); 125 return Status::ok(); 126 } 127 128 Status BinderUpdateEngineAndroidService::cancel() { 129 brillo::ErrorPtr error; 130 if (!service_delegate_->CancelUpdate(&error)) 131 return ErrorPtrToStatus(error); 132 return Status::ok(); 133 } 134 135 Status BinderUpdateEngineAndroidService::resetStatus() { 136 brillo::ErrorPtr error; 137 if (!service_delegate_->ResetStatus(&error)) 138 return ErrorPtrToStatus(error); 139 return Status::ok(); 140 } 141 142 Status BinderUpdateEngineAndroidService::verifyPayloadApplicable( 143 const android::String16& metadata_filename, bool* return_value) { 144 const std::string payload_metadata{ 145 android::String8{metadata_filename}.string()}; 146 LOG(INFO) << "Received a request of verifying payload metadata in " 147 << payload_metadata << "."; 148 brillo::ErrorPtr error; 149 *return_value = 150 service_delegate_->VerifyPayloadApplicable(payload_metadata, &error); 151 if (error != nullptr) 152 return ErrorPtrToStatus(error); 153 return Status::ok(); 154 } 155 156 bool BinderUpdateEngineAndroidService::UnbindCallback(const IBinder* callback) { 157 auto it = std::find_if( 158 callbacks_.begin(), 159 callbacks_.end(), 160 [&callback](const android::sp<IUpdateEngineCallback>& elem) { 161 return IUpdateEngineCallback::asBinder(elem).get() == callback; 162 }); 163 if (it == callbacks_.end()) { 164 LOG(ERROR) << "Unable to unbind unknown callback."; 165 return false; 166 } 167 callbacks_.erase(it); 168 return true; 169 } 170 171 } // namespace chromeos_update_engine 172