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::binder::Status;
32 using android::brillo::ParcelableUpdateEngineStatus;
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
Init()41 bool BinderUpdateEngineClient::Init() {
42 if (!binder_watcher_.Init()) return false;
43
44 return getService(String16{"android.brillo.UpdateEngineService"},
45 &service_) == OK;
46 }
47
AttemptUpdate(const string & in_app_version,const string & in_omaha_url,bool at_user_request)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
GetStatus(int64_t * out_last_checked_time,double * out_progress,UpdateStatus * out_update_status,string * out_new_version,int64_t * out_new_size) const57 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
SetCohortHint(const string & in_cohort_hint)76 bool BinderUpdateEngineClient::SetCohortHint(const string& in_cohort_hint) {
77 return service_->SetCohortHint(String16{in_cohort_hint.c_str()}).isOk();
78 }
79
GetCohortHint(string * out_cohort_hint) const80 bool 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
SetUpdateOverCellularPermission(bool allowed)90 bool BinderUpdateEngineClient::SetUpdateOverCellularPermission(bool allowed) {
91 return service_->SetUpdateOverCellularPermission(allowed).isOk();
92 }
93
GetUpdateOverCellularPermission(bool * allowed) const94 bool BinderUpdateEngineClient::GetUpdateOverCellularPermission(
95 bool* allowed) const {
96 return service_->GetUpdateOverCellularPermission(allowed).isOk();
97 }
98
SetP2PUpdatePermission(bool enabled)99 bool BinderUpdateEngineClient::SetP2PUpdatePermission(bool enabled) {
100 return service_->SetP2PUpdatePermission(enabled).isOk();
101 }
102
GetP2PUpdatePermission(bool * enabled) const103 bool BinderUpdateEngineClient::GetP2PUpdatePermission(bool* enabled) const {
104 return service_->GetP2PUpdatePermission(enabled).isOk();
105 }
106
Rollback(bool powerwash)107 bool BinderUpdateEngineClient::Rollback(bool powerwash) {
108 return service_->AttemptRollback(powerwash).isOk();
109 }
110
GetRollbackPartition(string * rollback_partition) const111 bool 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
GetPrevVersion(string * prev_version) const122 bool 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
RebootIfNeeded()132 void 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
ResetStatus()141 bool BinderUpdateEngineClient::ResetStatus() {
142 return service_->ResetStatus().isOk();
143 }
144
HandleStatusUpdate(int64_t last_checked_time,double progress,const String16 & current_operation,const String16 & new_version,int64_t new_size)145 Status 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
RegisterStatusUpdateHandler(StatusUpdateHandler * handler)163 bool 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
UnregisterStatusUpdateHandler(StatusUpdateHandler * handler)192 bool 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
SetTargetChannel(const string & in_target_channel,bool allow_powerwash)203 bool 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
GetTargetChannel(string * out_channel) const209 bool 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
GetChannel(string * out_channel) const219 bool 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
GetLastAttemptError(int32_t * last_attempt_error) const229 bool 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
GetEolStatus(int32_t * eol_status) const240 bool 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