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 ¤t_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