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