Home | History | Annotate | Download | only in update_engine
      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