• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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