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::sp; 29 using android::String16; 30 using android::String8; 31 using android::binder::Status; 32 using android::brillo::IUpdateEngineStatusCallback; 33 using android::brillo::ParcelableUpdateEngineStatus; 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::SetUpdateOverCellularTarget( 157 const String16& target_version, int64_t target_size) { 158 return CallCommonHandler(&UpdateEngineService::SetUpdateOverCellularTarget, 159 NormalString(target_version), 160 target_size); 161 } 162 163 Status BinderUpdateEngineBrilloService::GetUpdateOverCellularPermission( 164 bool* out_cellular_permission) { 165 return CallCommonHandler( 166 &UpdateEngineService::GetUpdateOverCellularPermission, 167 out_cellular_permission); 168 } 169 170 Status BinderUpdateEngineBrilloService::GetDurationSinceUpdate( 171 int64_t* out_duration) { 172 return CallCommonHandler(&UpdateEngineService::GetDurationSinceUpdate, 173 out_duration); 174 } 175 176 Status BinderUpdateEngineBrilloService::GetPrevVersion( 177 String16* out_prev_version) { 178 string version_string; 179 auto ret = 180 CallCommonHandler(&UpdateEngineService::GetPrevVersion, &version_string); 181 182 *out_prev_version = String16(version_string.c_str()); 183 return ret; 184 } 185 186 Status BinderUpdateEngineBrilloService::GetRollbackPartition( 187 String16* out_rollback_partition) { 188 string partition_string; 189 auto ret = CallCommonHandler(&UpdateEngineService::GetRollbackPartition, 190 &partition_string); 191 192 if (ret.isOk()) { 193 *out_rollback_partition = String16(partition_string.c_str()); 194 } 195 196 return ret; 197 } 198 199 Status BinderUpdateEngineBrilloService::RegisterStatusCallback( 200 const sp<IUpdateEngineStatusCallback>& callback) { 201 callbacks_.emplace_back(callback); 202 203 auto binder_wrapper = android::BinderWrapper::Get(); 204 205 binder_wrapper->RegisterForDeathNotifications( 206 IUpdateEngineStatusCallback::asBinder(callback), 207 base::Bind(&BinderUpdateEngineBrilloService::UnregisterStatusCallback, 208 base::Unretained(this), 209 base::Unretained(callback.get()))); 210 211 return Status::ok(); 212 } 213 214 Status BinderUpdateEngineBrilloService::GetLastAttemptError( 215 int* out_last_attempt_error) { 216 return CallCommonHandler(&UpdateEngineService::GetLastAttemptError, 217 out_last_attempt_error); 218 } 219 220 Status BinderUpdateEngineBrilloService::GetEolStatus(int* out_eol_status) { 221 return CallCommonHandler(&UpdateEngineService::GetEolStatus, out_eol_status); 222 } 223 224 void BinderUpdateEngineBrilloService::UnregisterStatusCallback( 225 IUpdateEngineStatusCallback* callback) { 226 auto it = callbacks_.begin(); 227 while (it != callbacks_.end() && it->get() != callback) 228 it++; 229 230 if (it == callbacks_.end()) { 231 LOG(ERROR) << "Got death notification for unknown callback."; 232 return; 233 } 234 235 LOG(INFO) << "Erasing orphan callback"; 236 callbacks_.erase(it); 237 } 238 239 void BinderUpdateEngineBrilloService::SendStatusUpdate( 240 const UpdateEngineStatus& update_engine_status) { 241 ParcelableUpdateEngineStatus parcelable_status(update_engine_status); 242 for (auto& callback : callbacks_) { 243 callback->HandleStatusUpdate(parcelable_status); 244 } 245 } 246 247 } // namespace chromeos_update_engine 248