binder_service_android.cc revision 07fbb1b7dff86d8b26bf976b72f2722fde66b603
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 25using android::binder::Status; 26using android::os::IUpdateEngineCallback; 27using update_engine::UpdateEngineStatus; 28 29namespace { 30Status ErrorPtrToStatus(const brillo::ErrorPtr& error) { 31 return Status::fromServiceSpecificError( 32 1, android::String8{error->GetMessage().c_str()}); 33} 34} // namespace 35 36namespace chromeos_update_engine { 37 38BinderUpdateEngineAndroidService::BinderUpdateEngineAndroidService( 39 ServiceDelegateAndroidInterface* service_delegate) 40 : service_delegate_(service_delegate) { 41} 42 43void 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 52void BinderUpdateEngineAndroidService::SendPayloadApplicationComplete( 53 ErrorCode error_code) { 54 for (auto& callback : callbacks_) { 55 callback->onPayloadApplicationComplete(static_cast<int>(error_code)); 56 } 57} 58 59Status 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 83Status 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 94Status 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 114Status BinderUpdateEngineAndroidService::suspend() { 115 brillo::ErrorPtr error; 116 if (!service_delegate_->SuspendUpdate(&error)) 117 return ErrorPtrToStatus(error); 118 return Status::ok(); 119} 120 121Status BinderUpdateEngineAndroidService::resume() { 122 brillo::ErrorPtr error; 123 if (!service_delegate_->ResumeUpdate(&error)) 124 return ErrorPtrToStatus(error); 125 return Status::ok(); 126} 127 128Status BinderUpdateEngineAndroidService::cancel() { 129 brillo::ErrorPtr error; 130 if (!service_delegate_->CancelUpdate(&error)) 131 return ErrorPtrToStatus(error); 132 return Status::ok(); 133} 134 135Status BinderUpdateEngineAndroidService::resetStatus() { 136 brillo::ErrorPtr error; 137 if (!service_delegate_->ResetStatus(&error)) 138 return ErrorPtrToStatus(error); 139 return Status::ok(); 140} 141 142Status 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 149 // FIXME: Do the actual verification work. 150 *return_value = true; 151 return Status::ok(); 152} 153 154bool BinderUpdateEngineAndroidService::UnbindCallback(const IBinder* callback) { 155 auto it = std::find_if( 156 callbacks_.begin(), 157 callbacks_.end(), 158 [&callback](const android::sp<IUpdateEngineCallback>& elem) { 159 return IUpdateEngineCallback::asBinder(elem).get() == callback; 160 }); 161 if (it == callbacks_.end()) { 162 LOG(ERROR) << "Unable to unbind unknown callback."; 163 return false; 164 } 165 callbacks_.erase(it); 166 return true; 167} 168 169} // namespace chromeos_update_engine 170