blob: 1072836ab6d4c845f8e32b29a0044bc28aca6e79 [file] [log] [blame]
Casey Dahlina93cd532016-01-14 16:55:11 -08001//
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_dbus.h"
18
19#include <base/message_loop/message_loop.h>
20
21#include <dbus/bus.h>
22#include <update_engine/dbus-constants.h>
23
24#include "update_engine/update_status_utils.h"
25
26using chromeos_update_engine::StringToUpdateStatus;
27using dbus::Bus;
28using org::chromium::UpdateEngineInterfaceProxy;
29using std::string;
30
31namespace update_engine {
32namespace internal {
33
34bool DBusUpdateEngineClient::Init() {
35 Bus::Options options;
36 options.bus_type = Bus::SYSTEM;
37 scoped_refptr<Bus> bus{new Bus{options}};
38
39 if (!bus->Connect())
40 return false;
41
42 proxy_.reset(new UpdateEngineInterfaceProxy{bus});
43 return true;
44}
45
46bool DBusUpdateEngineClient::AttemptUpdate(const string& in_app_version,
47 const string& in_omaha_url,
48 bool at_user_request) {
49 return proxy_->AttemptUpdateWithFlags(
50 in_app_version,
51 in_omaha_url,
Amin Hassani6bb001f2018-02-26 14:33:02 -080052 (at_user_request)
53 ? 0
54 : update_engine::UpdateAttemptFlags::kFlagNonInteractive,
Casey Dahlina93cd532016-01-14 16:55:11 -080055 nullptr);
56}
57
58bool DBusUpdateEngineClient::GetStatus(int64_t* out_last_checked_time,
59 double* out_progress,
60 UpdateStatus* out_update_status,
61 string* out_new_version,
62 int64_t* out_new_size) const {
63 string status_as_string;
64 const bool success = proxy_->GetStatus(out_last_checked_time,
65 out_progress,
66 &status_as_string,
67 out_new_version,
68 out_new_size,
69 nullptr);
70 if (!success) {
71 return false;
72 }
73
74 return StringToUpdateStatus(status_as_string, out_update_status);
75}
76
Alex Deymo5b5fa8b2016-10-06 15:40:49 -070077bool DBusUpdateEngineClient::SetCohortHint(const string& cohort_hint) {
78 return proxy_->SetCohortHint(cohort_hint, nullptr);
79}
80
81bool DBusUpdateEngineClient::GetCohortHint(string* cohort_hint) const {
82 return proxy_->GetCohortHint(cohort_hint, nullptr);
83}
84
Casey Dahlina93cd532016-01-14 16:55:11 -080085bool DBusUpdateEngineClient::SetUpdateOverCellularPermission(bool allowed) {
86 return proxy_->SetUpdateOverCellularPermission(allowed, nullptr);
87}
88
89bool DBusUpdateEngineClient::GetUpdateOverCellularPermission(
90 bool* allowed) const {
91 return proxy_->GetUpdateOverCellularPermission(allowed, nullptr);
92}
93
94bool DBusUpdateEngineClient::SetP2PUpdatePermission(bool enabled) {
95 return proxy_->SetP2PUpdatePermission(enabled, nullptr);
96}
97
98bool DBusUpdateEngineClient::GetP2PUpdatePermission(bool* enabled) const {
99 return proxy_->GetP2PUpdatePermission(enabled, nullptr);
100}
101
102bool DBusUpdateEngineClient::Rollback(bool powerwash) {
103 return proxy_->AttemptRollback(powerwash, nullptr);
104}
105
106bool DBusUpdateEngineClient::GetRollbackPartition(
107 string* rollback_partition) const {
108 return proxy_->GetRollbackPartition(rollback_partition, nullptr);
109}
110
111bool DBusUpdateEngineClient::GetPrevVersion(string* prev_version) const {
112 return proxy_->GetPrevVersion(prev_version, nullptr);
113}
114
115void DBusUpdateEngineClient::RebootIfNeeded() {
116 bool ret = proxy_->RebootIfNeeded(nullptr);
117 if (!ret) {
118 // Reboot error code doesn't necessarily mean that a reboot
119 // failed. For example, D-Bus may be shutdown before we receive the
120 // result.
121 LOG(INFO) << "RebootIfNeeded() failure ignored.";
122 }
123}
124
125bool DBusUpdateEngineClient::ResetStatus() {
126 return proxy_->ResetStatus(nullptr);
127}
128
Alex Deymo492eaf52016-02-02 12:05:02 -0800129void DBusUpdateEngineClient::DBusStatusHandlersRegistered(
Casey Dahlina93cd532016-01-14 16:55:11 -0800130 const string& interface,
131 const string& signal_name,
132 bool success) const {
133 if (!success) {
Casey Dahlina715f7b2016-01-29 16:38:51 -0800134 for (auto handler : handlers_) {
135 handler->IPCError("Could not connect to" + signal_name +
136 " on " + interface);
137 }
138 } else {
139 StatusUpdateHandlersRegistered(nullptr);
Casey Dahlina93cd532016-01-14 16:55:11 -0800140 }
Casey Dahlina715f7b2016-01-29 16:38:51 -0800141}
Casey Dahlina93cd532016-01-14 16:55:11 -0800142
Casey Dahlina715f7b2016-01-29 16:38:51 -0800143void DBusUpdateEngineClient::StatusUpdateHandlersRegistered(
144 StatusUpdateHandler* handler) const {
Casey Dahlina93cd532016-01-14 16:55:11 -0800145 int64_t last_checked_time;
146 double progress;
147 UpdateStatus update_status;
148 string new_version;
149 int64_t new_size;
150
Casey Dahlina715f7b2016-01-29 16:38:51 -0800151 if (!GetStatus(&last_checked_time,
152 &progress,
153 &update_status,
154 &new_version,
155 &new_size)) {
156 handler->IPCError("Could not query current status");
Casey Dahlina93cd532016-01-14 16:55:11 -0800157 return;
158 }
159
Alex Deymo492eaf52016-02-02 12:05:02 -0800160 std::vector<update_engine::StatusUpdateHandler*> just_handler = {handler};
161 for (auto h : handler ? just_handler : handlers_) {
Casey Dahlina715f7b2016-01-29 16:38:51 -0800162 h->HandleStatusUpdate(
163 last_checked_time, progress, update_status, new_version, new_size);
164 }
Casey Dahlina93cd532016-01-14 16:55:11 -0800165}
166
Casey Dahlina715f7b2016-01-29 16:38:51 -0800167void DBusUpdateEngineClient::RunStatusUpdateHandlers(
Casey Dahlina93cd532016-01-14 16:55:11 -0800168 int64_t last_checked_time,
169 double progress,
170 const string& current_operation,
171 const string& new_version,
172 int64_t new_size) {
173 UpdateStatus status;
174 StringToUpdateStatus(current_operation, &status);
175
Casey Dahlina715f7b2016-01-29 16:38:51 -0800176 for (auto handler : handlers_) {
177 handler->HandleStatusUpdate(
178 last_checked_time, progress, status, new_version, new_size);
179 }
180}
181
182bool DBusUpdateEngineClient::UnregisterStatusUpdateHandler(
183 StatusUpdateHandler* handler) {
Alex Deymob3fa53b2016-04-18 19:57:58 -0700184 auto it = std::find(handlers_.begin(), handlers_.end(), handler);
Casey Dahlina715f7b2016-01-29 16:38:51 -0800185 if (it != handlers_.end()) {
186 handlers_.erase(it);
187 return true;
188 }
189
190 return false;
Casey Dahlina93cd532016-01-14 16:55:11 -0800191}
192
Casey Dahlin40892492016-01-25 16:55:28 -0800193bool DBusUpdateEngineClient::RegisterStatusUpdateHandler(
Casey Dahlina93cd532016-01-14 16:55:11 -0800194 StatusUpdateHandler* handler) {
195 if (!base::MessageLoopForIO::current()) {
196 LOG(FATAL) << "Cannot get UpdateEngineClient outside of message loop.";
Casey Dahlin40892492016-01-25 16:55:28 -0800197 return false;
Casey Dahlina93cd532016-01-14 16:55:11 -0800198 }
199
Casey Dahlina715f7b2016-01-29 16:38:51 -0800200 handlers_.push_back(handler);
201
202 if (dbus_handler_registered_) {
203 StatusUpdateHandlersRegistered(handler);
204 return true;
205 }
206
Casey Dahlina93cd532016-01-14 16:55:11 -0800207 proxy_->RegisterStatusUpdateSignalHandler(
Casey Dahlina715f7b2016-01-29 16:38:51 -0800208 base::Bind(&DBusUpdateEngineClient::RunStatusUpdateHandlers,
209 base::Unretained(this)),
Alex Deymo492eaf52016-02-02 12:05:02 -0800210 base::Bind(&DBusUpdateEngineClient::DBusStatusHandlersRegistered,
211 base::Unretained(this)));
Casey Dahlina715f7b2016-01-29 16:38:51 -0800212
213 dbus_handler_registered_ = true;
Casey Dahlin40892492016-01-25 16:55:28 -0800214
215 return true;
Casey Dahlina93cd532016-01-14 16:55:11 -0800216}
217
218bool DBusUpdateEngineClient::SetTargetChannel(const string& in_target_channel,
219 bool allow_powerwash) {
220 return proxy_->SetChannel(in_target_channel, allow_powerwash, nullptr);
221}
222
223bool DBusUpdateEngineClient::GetTargetChannel(string* out_channel) const {
224 return proxy_->GetChannel(false, // Get the target channel.
225 out_channel,
226 nullptr);
227}
228
229bool DBusUpdateEngineClient::GetChannel(string* out_channel) const {
230 return proxy_->GetChannel(true, // Get the current channel.
231 out_channel,
232 nullptr);
233}
234
Shuqian Zhao29971732016-02-05 11:29:32 -0800235bool DBusUpdateEngineClient::GetLastAttemptError(
236 int32_t* last_attempt_error) const {
237 return proxy_->GetLastAttemptError(last_attempt_error, nullptr);
238}
239
Alex Deymob3fa53b2016-04-18 19:57:58 -0700240bool DBusUpdateEngineClient::GetEolStatus(int32_t* eol_status) const {
241 return proxy_->GetEolStatus(eol_status, nullptr);
242}
243
Casey Dahlina93cd532016-01-14 16:55:11 -0800244} // namespace internal
245} // namespace update_engine