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