Home | History | Annotate | Download | only in client_library
      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/client_library/client_binder.h"
     18 
     19 #include <binder/IServiceManager.h>
     20 
     21 #include <base/message_loop/message_loop.h>
     22 #include <utils/String8.h>
     23 
     24 #include "update_engine/common_service.h"
     25 #include "update_engine/parcelable_update_engine_status.h"
     26 #include "update_engine/update_status_utils.h"
     27 
     28 using android::OK;
     29 using android::String16;
     30 using android::String8;
     31 using android::brillo::ParcelableUpdateEngineStatus;
     32 using android::binder::Status;
     33 using android::getService;
     34 using chromeos_update_engine::StringToUpdateStatus;
     35 using chromeos_update_engine::UpdateEngineService;
     36 using std::string;
     37 
     38 namespace update_engine {
     39 namespace internal {
     40 
     41 bool BinderUpdateEngineClient::Init() {
     42   if (!binder_watcher_.Init()) return false;
     43 
     44   return getService(String16{"android.brillo.UpdateEngineService"},
     45       &service_) == OK;
     46 }
     47 
     48 bool BinderUpdateEngineClient::AttemptUpdate(const string& in_app_version,
     49                                              const string& in_omaha_url,
     50                                              bool at_user_request) {
     51   return service_->AttemptUpdate(String16{in_app_version.c_str()},
     52       String16{in_omaha_url.c_str()},
     53       at_user_request ? 0 :
     54           UpdateEngineService::kAttemptUpdateFlagNonInteractive).isOk();
     55 }
     56 
     57 bool BinderUpdateEngineClient::GetStatus(int64_t* out_last_checked_time,
     58                                          double* out_progress,
     59                                          UpdateStatus* out_update_status,
     60                                          string* out_new_version,
     61                                          int64_t* out_new_size) const {
     62   ParcelableUpdateEngineStatus status;
     63 
     64   if (!service_->GetStatus(&status).isOk())
     65     return false;
     66 
     67   *out_last_checked_time = status.last_checked_time_;
     68   *out_progress = status.progress_;
     69   StringToUpdateStatus(String8{status.current_operation_}.string(),
     70                        out_update_status);
     71   *out_new_version = String8{status.new_version_}.string();
     72   *out_new_size = status.new_size_;
     73   return true;
     74 }
     75 
     76 bool BinderUpdateEngineClient::SetUpdateOverCellularPermission(bool allowed) {
     77   return service_->SetUpdateOverCellularPermission(allowed).isOk();
     78 }
     79 
     80 bool BinderUpdateEngineClient::GetUpdateOverCellularPermission(
     81     bool* allowed) const {
     82   return service_->GetUpdateOverCellularPermission(allowed).isOk();
     83 }
     84 
     85 bool BinderUpdateEngineClient::SetP2PUpdatePermission(bool enabled) {
     86   return service_->SetP2PUpdatePermission(enabled).isOk();
     87 }
     88 
     89 bool BinderUpdateEngineClient::GetP2PUpdatePermission(bool* enabled) const {
     90   return service_->GetP2PUpdatePermission(enabled).isOk();
     91 }
     92 
     93 bool BinderUpdateEngineClient::Rollback(bool powerwash) {
     94   return service_->AttemptRollback(powerwash).isOk();
     95 }
     96 
     97 bool BinderUpdateEngineClient::GetRollbackPartition(
     98     string* rollback_partition) const {
     99   String16 out_as_string16;
    100 
    101   if (!service_->GetRollbackPartition(&out_as_string16).isOk())
    102     return false;
    103 
    104   *rollback_partition = String8{out_as_string16}.string();
    105   return true;
    106 }
    107 
    108 bool BinderUpdateEngineClient::GetPrevVersion(string* prev_version) const {
    109   String16 out_as_string16;
    110 
    111   if (!service_->GetPrevVersion(&out_as_string16).isOk())
    112     return false;
    113 
    114   *prev_version = String8{out_as_string16}.string();
    115   return true;
    116 }
    117 
    118 void BinderUpdateEngineClient::RebootIfNeeded() {
    119   if (!service_->RebootIfNeeded().isOk()) {
    120     // Reboot error code doesn't necessarily mean that a reboot
    121     // failed. For example, D-Bus may be shutdown before we receive the
    122     // result.
    123     LOG(INFO) << "RebootIfNeeded() failure ignored.";
    124   }
    125 }
    126 
    127 bool BinderUpdateEngineClient::ResetStatus() {
    128   return service_->ResetStatus().isOk();
    129 }
    130 
    131 Status BinderUpdateEngineClient::StatusUpdateCallback::HandleStatusUpdate(
    132     int64_t last_checked_time,
    133     double progress,
    134     const String16& current_operation,
    135     const String16& new_version,
    136     int64_t new_size) {
    137   UpdateStatus update_status;
    138 
    139   StringToUpdateStatus(String8{current_operation}.string(), &update_status);
    140 
    141   for (auto& handler : client_->handlers_) {
    142     handler->HandleStatusUpdate(last_checked_time, progress, update_status,
    143                                 String8{new_version}.string(), new_size);
    144   }
    145 
    146   return Status::ok();
    147 }
    148 
    149 bool BinderUpdateEngineClient::RegisterStatusUpdateHandler(
    150     StatusUpdateHandler* handler) {
    151   if (!status_callback_.get()) {
    152     status_callback_ =
    153         new BinderUpdateEngineClient::StatusUpdateCallback(this);
    154     if (!service_->RegisterStatusCallback(status_callback_).isOk()) {
    155       return false;
    156     }
    157   }
    158 
    159   handlers_.push_back(handler);
    160 
    161   int64_t last_checked_time;
    162   double progress;
    163   UpdateStatus update_status;
    164   string new_version;
    165   int64_t new_size;
    166 
    167   if (!GetStatus(&last_checked_time, &progress, &update_status,
    168                  &new_version, &new_size)) {
    169     handler->IPCError("Could not get status from binder service");
    170   }
    171 
    172   handler->HandleStatusUpdate(last_checked_time, progress, update_status,
    173                               new_version, new_size);
    174 
    175   return true;
    176 }
    177 
    178 bool BinderUpdateEngineClient::UnregisterStatusUpdateHandler(
    179     StatusUpdateHandler* handler) {
    180   auto it = handlers_.begin();
    181 
    182   for (; *it != handler && it != handlers_.end(); it++);
    183 
    184   if (it != handlers_.end()) {
    185     handlers_.erase(it);
    186     return true;
    187   }
    188 
    189   return false;
    190 }
    191 
    192 bool BinderUpdateEngineClient::SetTargetChannel(const string& in_target_channel,
    193                                                 bool allow_powerwash) {
    194   return service_->SetChannel(String16{in_target_channel.c_str()},
    195                               allow_powerwash).isOk();
    196 }
    197 
    198 bool BinderUpdateEngineClient::GetTargetChannel(string* out_channel) const {
    199   String16 out_as_string16;
    200 
    201   if (!service_->GetChannel(false, &out_as_string16).isOk())
    202     return false;
    203 
    204   *out_channel = String8{out_as_string16}.string();
    205   return true;
    206 }
    207 
    208 bool BinderUpdateEngineClient::GetChannel(string* out_channel) const {
    209   String16 out_as_string16;
    210 
    211   if (!service_->GetChannel(true, &out_as_string16).isOk())
    212     return false;
    213 
    214   *out_channel = String8{out_as_string16}.string();
    215   return true;
    216 }
    217 
    218 bool BinderUpdateEngineClient::GetLastAttemptError(
    219     int32_t* last_attempt_error) const {
    220   int out_as_int;
    221 
    222   if (!service_->GetLastAttemptError(&out_as_int).isOk())
    223     return false;
    224 
    225   *last_attempt_error = out_as_int;
    226   return true;
    227 }
    228 
    229 }  // namespace internal
    230 }  // namespace update_engine
    231