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/client_library/client_binder.h" 18 19 #include <binder/IServiceManager.h> 20 21 #include <base/message_loop/message_loop.h> 22 #include <utils/String8.h> 23 24 #include "update_engine/common_service.h" 25 #include "update_engine/parcelable_update_engine_status.h" 26 #include "update_engine/update_status_utils.h" 27 28 using android::getService; 29 using android::OK; 30 using android::String16; 31 using android::String8; 32 using android::binder::Status; 33 using android::brillo::ParcelableUpdateEngineStatus; 34 using chromeos_update_engine::StringToUpdateStatus; 35 using std::string; 36 using update_engine::UpdateAttemptFlags; 37 38 namespace update_engine { 39 namespace internal { 40 41 bool BinderUpdateEngineClient::Init() { 42 if (!binder_watcher_.Init()) 43 return false; 44 45 return getService(String16{"android.brillo.UpdateEngineService"}, 46 &service_) == OK; 47 } 48 49 bool BinderUpdateEngineClient::AttemptUpdate(const string& in_app_version, 50 const string& in_omaha_url, 51 bool at_user_request) { 52 bool started; 53 return service_ 54 ->AttemptUpdate( 55 String16{in_app_version.c_str()}, 56 String16{in_omaha_url.c_str()}, 57 at_user_request ? 0 : UpdateAttemptFlags::kFlagNonInteractive, 58 &started) 59 .isOk(); 60 } 61 62 bool BinderUpdateEngineClient::AttemptInstall( 63 const string& omaha_url, const std::vector<string>& dlc_module_ids) { 64 return false; 65 } 66 67 bool BinderUpdateEngineClient::GetStatus(int64_t* out_last_checked_time, 68 double* out_progress, 69 UpdateStatus* out_update_status, 70 string* out_new_version, 71 int64_t* out_new_size) const { 72 ParcelableUpdateEngineStatus status; 73 74 if (!service_->GetStatus(&status).isOk()) 75 return false; 76 77 *out_last_checked_time = status.last_checked_time_; 78 *out_progress = status.progress_; 79 StringToUpdateStatus(String8{status.current_operation_}.string(), 80 out_update_status); 81 *out_new_version = String8{status.new_version_}.string(); 82 *out_new_size = status.new_size_; 83 return true; 84 } 85 86 bool BinderUpdateEngineClient::SetCohortHint(const string& in_cohort_hint) { 87 return service_->SetCohortHint(String16{in_cohort_hint.c_str()}).isOk(); 88 } 89 90 bool BinderUpdateEngineClient::GetCohortHint(string* out_cohort_hint) const { 91 String16 out_as_string16; 92 93 if (!service_->GetCohortHint(&out_as_string16).isOk()) 94 return false; 95 96 *out_cohort_hint = String8{out_as_string16}.string(); 97 return true; 98 } 99 100 bool BinderUpdateEngineClient::SetUpdateOverCellularPermission(bool allowed) { 101 return service_->SetUpdateOverCellularPermission(allowed).isOk(); 102 } 103 104 bool BinderUpdateEngineClient::GetUpdateOverCellularPermission( 105 bool* allowed) const { 106 return service_->GetUpdateOverCellularPermission(allowed).isOk(); 107 } 108 109 bool BinderUpdateEngineClient::SetP2PUpdatePermission(bool enabled) { 110 return service_->SetP2PUpdatePermission(enabled).isOk(); 111 } 112 113 bool BinderUpdateEngineClient::GetP2PUpdatePermission(bool* enabled) const { 114 return service_->GetP2PUpdatePermission(enabled).isOk(); 115 } 116 117 bool BinderUpdateEngineClient::Rollback(bool powerwash) { 118 return service_->AttemptRollback(powerwash).isOk(); 119 } 120 121 bool BinderUpdateEngineClient::GetRollbackPartition( 122 string* rollback_partition) const { 123 String16 out_as_string16; 124 125 if (!service_->GetRollbackPartition(&out_as_string16).isOk()) 126 return false; 127 128 *rollback_partition = String8{out_as_string16}.string(); 129 return true; 130 } 131 132 bool BinderUpdateEngineClient::GetPrevVersion(string* prev_version) const { 133 String16 out_as_string16; 134 135 if (!service_->GetPrevVersion(&out_as_string16).isOk()) 136 return false; 137 138 *prev_version = String8{out_as_string16}.string(); 139 return true; 140 } 141 142 void BinderUpdateEngineClient::RebootIfNeeded() { 143 if (!service_->RebootIfNeeded().isOk()) { 144 // Reboot error code doesn't necessarily mean that a reboot 145 // failed. For example, D-Bus may be shutdown before we receive the 146 // result. 147 LOG(INFO) << "RebootIfNeeded() failure ignored."; 148 } 149 } 150 151 bool BinderUpdateEngineClient::ResetStatus() { 152 return service_->ResetStatus().isOk(); 153 } 154 155 Status BinderUpdateEngineClient::StatusUpdateCallback::HandleStatusUpdate( 156 const ParcelableUpdateEngineStatus& status) { 157 UpdateStatus update_status; 158 159 StringToUpdateStatus(String8{status.current_operation_}.string(), 160 &update_status); 161 162 for (auto& handler : client_->handlers_) { 163 handler->HandleStatusUpdate(status.last_checked_time_, 164 status.progress_, 165 update_status, 166 String8{status.new_version_}.string(), 167 status.new_size_); 168 } 169 170 return Status::ok(); 171 } 172 173 bool BinderUpdateEngineClient::RegisterStatusUpdateHandler( 174 StatusUpdateHandler* handler) { 175 if (!status_callback_.get()) { 176 status_callback_ = new BinderUpdateEngineClient::StatusUpdateCallback(this); 177 if (!service_->RegisterStatusCallback(status_callback_).isOk()) { 178 return false; 179 } 180 } 181 182 handlers_.push_back(handler); 183 184 int64_t last_checked_time; 185 double progress; 186 UpdateStatus update_status; 187 string new_version; 188 int64_t new_size; 189 190 if (!GetStatus(&last_checked_time, 191 &progress, 192 &update_status, 193 &new_version, 194 &new_size)) { 195 handler->IPCError("Could not get status from binder service"); 196 } 197 198 handler->HandleStatusUpdate( 199 last_checked_time, progress, update_status, new_version, new_size); 200 201 return true; 202 } 203 204 bool BinderUpdateEngineClient::UnregisterStatusUpdateHandler( 205 StatusUpdateHandler* handler) { 206 auto it = std::find(handlers_.begin(), handlers_.end(), handler); 207 if (it != handlers_.end()) { 208 handlers_.erase(it); 209 return true; 210 } 211 212 return false; 213 } 214 215 bool BinderUpdateEngineClient::SetTargetChannel(const string& in_target_channel, 216 bool allow_powerwash) { 217 return service_ 218 ->SetChannel(String16{in_target_channel.c_str()}, allow_powerwash) 219 .isOk(); 220 } 221 222 bool BinderUpdateEngineClient::GetTargetChannel(string* out_channel) const { 223 String16 out_as_string16; 224 225 if (!service_->GetChannel(false, &out_as_string16).isOk()) 226 return false; 227 228 *out_channel = String8{out_as_string16}.string(); 229 return true; 230 } 231 232 bool BinderUpdateEngineClient::GetChannel(string* out_channel) const { 233 String16 out_as_string16; 234 235 if (!service_->GetChannel(true, &out_as_string16).isOk()) 236 return false; 237 238 *out_channel = String8{out_as_string16}.string(); 239 return true; 240 } 241 242 bool BinderUpdateEngineClient::GetLastAttemptError( 243 int32_t* last_attempt_error) const { 244 int out_as_int; 245 246 if (!service_->GetLastAttemptError(&out_as_int).isOk()) 247 return false; 248 249 *last_attempt_error = out_as_int; 250 return true; 251 } 252 253 bool BinderUpdateEngineClient::GetEolStatus(int32_t* eol_status) const { 254 int out_as_int; 255 256 if (!service_->GetEolStatus(&out_as_int).isOk()) 257 return false; 258 259 *eol_status = out_as_int; 260 return true; 261 } 262 263 } // namespace internal 264 } // namespace update_engine 265