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