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