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_brillo.h"
     18 
     19 #include <base/bind.h>
     20 
     21 #include <binderwrapper/binder_wrapper.h>
     22 
     23 #include <utils/String16.h>
     24 #include <utils/StrongPointer.h>
     25 
     26 #include "update_engine/update_status_utils.h"
     27 
     28 using android::String16;
     29 using android::String8;
     30 using android::binder::Status;
     31 using android::brillo::IUpdateEngineStatusCallback;
     32 using android::brillo::ParcelableUpdateEngineStatus;
     33 using android::sp;
     34 using brillo::ErrorPtr;
     35 using std::string;
     36 
     37 namespace chromeos_update_engine {
     38 
     39 namespace {
     40 string NormalString(const String16& in) {
     41   return string{String8{in}.string()};
     42 }
     43 
     44 Status ToStatus(ErrorPtr* error) {
     45   return Status::fromServiceSpecificError(
     46       1, String8{error->get()->GetMessage().c_str()});
     47 }
     48 }  // namespace
     49 
     50 template <typename... Parameters, typename... Arguments>
     51 Status BinderUpdateEngineBrilloService::CallCommonHandler(
     52     bool (UpdateEngineService::*Handler)(ErrorPtr*, Parameters...),
     53     Arguments... arguments) {
     54   ErrorPtr error;
     55   if (((common_.get())->*Handler)(&error, arguments...))
     56     return Status::ok();
     57   return ToStatus(&error);
     58 }
     59 
     60 Status BinderUpdateEngineBrilloService::AttemptUpdate(
     61     const String16& app_version, const String16& omaha_url, int flags) {
     62   return CallCommonHandler(&UpdateEngineService::AttemptUpdate,
     63                            NormalString(app_version),
     64                            NormalString(omaha_url),
     65                            flags);
     66 }
     67 
     68 Status BinderUpdateEngineBrilloService::AttemptRollback(bool powerwash) {
     69   return CallCommonHandler(&UpdateEngineService::AttemptRollback, powerwash);
     70 }
     71 
     72 Status BinderUpdateEngineBrilloService::CanRollback(bool* out_can_rollback) {
     73   return CallCommonHandler(&UpdateEngineService::CanRollback, out_can_rollback);
     74 }
     75 
     76 Status BinderUpdateEngineBrilloService::ResetStatus() {
     77   return CallCommonHandler(&UpdateEngineService::ResetStatus);
     78 }
     79 
     80 Status BinderUpdateEngineBrilloService::GetStatus(
     81     ParcelableUpdateEngineStatus* status) {
     82   string current_op;
     83   string new_version;
     84 
     85   auto ret = CallCommonHandler(&UpdateEngineService::GetStatus,
     86                                &status->last_checked_time_,
     87                                &status->progress_,
     88                                &current_op,
     89                                &new_version,
     90                                &status->new_size_);
     91 
     92   if (ret.isOk()) {
     93     status->current_operation_ = String16{current_op.c_str()};
     94     status->new_version_ = String16{new_version.c_str()};
     95   }
     96 
     97   return ret;
     98 }
     99 
    100 Status BinderUpdateEngineBrilloService::RebootIfNeeded() {
    101   return CallCommonHandler(&UpdateEngineService::RebootIfNeeded);
    102 }
    103 
    104 Status BinderUpdateEngineBrilloService::SetChannel(
    105     const String16& target_channel, bool powerwash) {
    106   return CallCommonHandler(&UpdateEngineService::SetChannel,
    107                            NormalString(target_channel),
    108                            powerwash);
    109 }
    110 
    111 Status BinderUpdateEngineBrilloService::GetChannel(bool get_current_channel,
    112                                                    String16* out_channel) {
    113   string channel_string;
    114   auto ret = CallCommonHandler(
    115       &UpdateEngineService::GetChannel, get_current_channel, &channel_string);
    116 
    117   *out_channel = String16(channel_string.c_str());
    118   return ret;
    119 }
    120 
    121 Status BinderUpdateEngineBrilloService::SetCohortHint(
    122     const String16& in_cohort_hint) {
    123   return CallCommonHandler(&UpdateEngineService::SetCohortHint,
    124                            NormalString(in_cohort_hint));
    125 }
    126 
    127 Status BinderUpdateEngineBrilloService::GetCohortHint(
    128     String16* out_cohort_hint) {
    129   string cohort_hint;
    130   auto ret =
    131       CallCommonHandler(&UpdateEngineService::GetCohortHint, &cohort_hint);
    132 
    133   *out_cohort_hint = String16(cohort_hint.c_str());
    134   return ret;
    135 }
    136 
    137 Status BinderUpdateEngineBrilloService::SetP2PUpdatePermission(bool enabled) {
    138   return CallCommonHandler(&UpdateEngineService::SetP2PUpdatePermission,
    139                            enabled);
    140 }
    141 
    142 Status BinderUpdateEngineBrilloService::GetP2PUpdatePermission(
    143     bool* out_p2p_permission) {
    144   return CallCommonHandler(&UpdateEngineService::GetP2PUpdatePermission,
    145                            out_p2p_permission);
    146 }
    147 
    148 Status BinderUpdateEngineBrilloService::SetUpdateOverCellularPermission(
    149     bool enabled) {
    150   return CallCommonHandler(
    151       &UpdateEngineService::SetUpdateOverCellularPermission, enabled);
    152 }
    153 
    154 Status BinderUpdateEngineBrilloService::GetUpdateOverCellularPermission(
    155     bool* out_cellular_permission) {
    156   return CallCommonHandler(
    157       &UpdateEngineService::GetUpdateOverCellularPermission,
    158       out_cellular_permission);
    159 }
    160 
    161 Status BinderUpdateEngineBrilloService::GetDurationSinceUpdate(
    162     int64_t* out_duration) {
    163   return CallCommonHandler(&UpdateEngineService::GetDurationSinceUpdate,
    164                            out_duration);
    165 }
    166 
    167 Status BinderUpdateEngineBrilloService::GetPrevVersion(
    168     String16* out_prev_version) {
    169   string version_string;
    170   auto ret =
    171       CallCommonHandler(&UpdateEngineService::GetPrevVersion, &version_string);
    172 
    173   *out_prev_version = String16(version_string.c_str());
    174   return ret;
    175 }
    176 
    177 Status BinderUpdateEngineBrilloService::GetRollbackPartition(
    178     String16* out_rollback_partition) {
    179   string partition_string;
    180   auto ret = CallCommonHandler(&UpdateEngineService::GetRollbackPartition,
    181                                &partition_string);
    182 
    183   if (ret.isOk()) {
    184     *out_rollback_partition = String16(partition_string.c_str());
    185   }
    186 
    187   return ret;
    188 }
    189 
    190 Status BinderUpdateEngineBrilloService::RegisterStatusCallback(
    191     const sp<IUpdateEngineStatusCallback>& callback) {
    192   callbacks_.emplace_back(callback);
    193 
    194   auto binder_wrapper = android::BinderWrapper::Get();
    195 
    196   binder_wrapper->RegisterForDeathNotifications(
    197       IUpdateEngineStatusCallback::asBinder(callback),
    198       base::Bind(&BinderUpdateEngineBrilloService::UnregisterStatusCallback,
    199                  base::Unretained(this),
    200                  base::Unretained(callback.get())));
    201 
    202   return Status::ok();
    203 }
    204 
    205 Status BinderUpdateEngineBrilloService::GetLastAttemptError(
    206     int* out_last_attempt_error) {
    207   return CallCommonHandler(&UpdateEngineService::GetLastAttemptError,
    208                            out_last_attempt_error);
    209 }
    210 
    211 Status BinderUpdateEngineBrilloService::GetEolStatus(int* out_eol_status) {
    212   return CallCommonHandler(&UpdateEngineService::GetEolStatus, out_eol_status);
    213 }
    214 
    215 void BinderUpdateEngineBrilloService::UnregisterStatusCallback(
    216     IUpdateEngineStatusCallback* callback) {
    217   auto it = callbacks_.begin();
    218   while (it != callbacks_.end() && it->get() != callback)
    219     it++;
    220 
    221   if (it == callbacks_.end()) {
    222     LOG(ERROR) << "Got death notification for unknown callback.";
    223     return;
    224   }
    225 
    226   LOG(INFO) << "Erasing orphan callback";
    227   callbacks_.erase(it);
    228 }
    229 
    230 void BinderUpdateEngineBrilloService::SendStatusUpdate(
    231     int64_t last_checked_time,
    232     double progress,
    233     update_engine::UpdateStatus status,
    234     const string& new_version,
    235     int64_t new_size) {
    236   const string str_status = UpdateStatusToString(status);
    237   for (auto& callback : callbacks_) {
    238     callback->HandleStatusUpdate(last_checked_time,
    239                                  progress,
    240                                  String16{str_status.c_str()},
    241                                  String16{new_version.c_str()},
    242                                  new_size);
    243   }
    244 }
    245 
    246 }  // namespace chromeos_update_engine
    247