blob: caf7befe23cf01dd56ec8a5fc73a192e1027ea34 [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>
Qijiang Fan45061b62020-06-24 15:47:47 +090020#include <base/message_loop/message_loop_current.h>
Casey Dahlina93cd532016-01-14 16:55:11 -080021
Amin Hassanic80d2d82019-06-21 17:43:32 -070022#include <memory>
23
Casey Dahlina93cd532016-01-14 16:55:11 -080024#include <dbus/bus.h>
25#include <update_engine/dbus-constants.h>
26
27#include "update_engine/update_status_utils.h"
28
Casey Dahlina93cd532016-01-14 16:55:11 -080029using dbus::Bus;
30using org::chromium::UpdateEngineInterfaceProxy;
31using std::string;
Amin Hassanic80d2d82019-06-21 17:43:32 -070032using std::unique_ptr;
Xiaochu Liu88d90382018-08-29 16:09:11 -070033using std::vector;
Casey Dahlina93cd532016-01-14 16:55:11 -080034
35namespace update_engine {
Amin Hassanic80d2d82019-06-21 17:43:32 -070036
37unique_ptr<UpdateEngineClient> UpdateEngineClient::CreateInstance() {
38 auto ret = std::make_unique<internal::DBusUpdateEngineClient>();
39 if (!ret->Init()) {
40 ret.reset();
41 }
42 return ret;
43}
44
Casey Dahlina93cd532016-01-14 16:55:11 -080045namespace internal {
46
Amin Hassanieb463ee2019-06-20 19:23:03 -070047namespace {
48// This converts the status from Protobuf |StatusResult| to The internal
49// |UpdateEngineStatus| struct.
Amin Hassania4417432019-07-08 12:52:40 -070050void ConvertToUpdateEngineStatus(const StatusResult& status,
Amin Hassanieb463ee2019-06-20 19:23:03 -070051 UpdateEngineStatus* out_status) {
52 out_status->last_checked_time = status.last_checked_time();
53 out_status->progress = status.progress();
54 out_status->new_version = status.new_version();
55 out_status->new_size_bytes = status.new_size();
Amin Hassania4417432019-07-08 12:52:40 -070056 out_status->status = static_cast<UpdateStatus>(status.current_operation());
Amin Hassani9be122e2019-08-29 09:20:12 -070057 out_status->is_enterprise_rollback = status.is_enterprise_rollback();
Jae Hoon Kim2f78c1c2019-07-25 13:20:43 -070058 out_status->is_install = status.is_install();
Jae Hoon Kim051627a2019-09-03 12:56:32 -070059 out_status->eol_date = status.eol_date();
Miriam Polzer0cf1acb2020-04-29 17:39:51 +020060 out_status->will_powerwash_after_reboot =
61 status.will_powerwash_after_reboot();
Amin Hassanieb463ee2019-06-20 19:23:03 -070062}
63} // namespace
64
Casey Dahlina93cd532016-01-14 16:55:11 -080065bool DBusUpdateEngineClient::Init() {
66 Bus::Options options;
67 options.bus_type = Bus::SYSTEM;
68 scoped_refptr<Bus> bus{new Bus{options}};
69
70 if (!bus->Connect())
71 return false;
72
73 proxy_.reset(new UpdateEngineInterfaceProxy{bus});
74 return true;
75}
76
77bool DBusUpdateEngineClient::AttemptUpdate(const string& in_app_version,
78 const string& in_omaha_url,
79 bool at_user_request) {
80 return proxy_->AttemptUpdateWithFlags(
81 in_app_version,
82 in_omaha_url,
Amin Hassani6bb001f2018-02-26 14:33:02 -080083 (at_user_request)
84 ? 0
85 : update_engine::UpdateAttemptFlags::kFlagNonInteractive,
Casey Dahlina93cd532016-01-14 16:55:11 -080086 nullptr);
87}
88
Amin Hassani9b66aa62019-03-14 14:13:30 -070089bool DBusUpdateEngineClient::AttemptInstall(const string& omaha_url,
90 const vector<string>& dlc_ids) {
Amin Hassanifab175a2020-04-17 11:20:50 -070091 return proxy_->AttemptInstall(omaha_url, dlc_ids, nullptr);
Xiaochu Liu88d90382018-08-29 16:09:11 -070092}
93
Andrewa8d7df32020-03-15 20:10:01 -070094bool DBusUpdateEngineClient::SetDlcActiveValue(bool is_active,
95 const std::string& dlc_id) {
96 return proxy_->SetDlcActiveValue(is_active, dlc_id, /*error=*/nullptr);
97}
98
Amin Hassanieb463ee2019-06-20 19:23:03 -070099bool DBusUpdateEngineClient::GetStatus(UpdateEngineStatus* out_status) const {
100 StatusResult status;
101 if (!proxy_->GetStatusAdvanced(&status, nullptr)) {
102 return false;
103 }
104
Amin Hassania4417432019-07-08 12:52:40 -0700105 ConvertToUpdateEngineStatus(status, out_status);
106 return true;
Casey Dahlina93cd532016-01-14 16:55:11 -0800107}
108
Alex Deymo5b5fa8b2016-10-06 15:40:49 -0700109bool DBusUpdateEngineClient::SetCohortHint(const string& cohort_hint) {
110 return proxy_->SetCohortHint(cohort_hint, nullptr);
111}
112
113bool DBusUpdateEngineClient::GetCohortHint(string* cohort_hint) const {
114 return proxy_->GetCohortHint(cohort_hint, nullptr);
115}
116
Casey Dahlina93cd532016-01-14 16:55:11 -0800117bool DBusUpdateEngineClient::SetUpdateOverCellularPermission(bool allowed) {
118 return proxy_->SetUpdateOverCellularPermission(allowed, nullptr);
119}
120
121bool DBusUpdateEngineClient::GetUpdateOverCellularPermission(
122 bool* allowed) const {
123 return proxy_->GetUpdateOverCellularPermission(allowed, nullptr);
124}
125
126bool DBusUpdateEngineClient::SetP2PUpdatePermission(bool enabled) {
127 return proxy_->SetP2PUpdatePermission(enabled, nullptr);
128}
129
130bool DBusUpdateEngineClient::GetP2PUpdatePermission(bool* enabled) const {
131 return proxy_->GetP2PUpdatePermission(enabled, nullptr);
132}
133
134bool DBusUpdateEngineClient::Rollback(bool powerwash) {
135 return proxy_->AttemptRollback(powerwash, nullptr);
136}
137
138bool DBusUpdateEngineClient::GetRollbackPartition(
139 string* rollback_partition) const {
140 return proxy_->GetRollbackPartition(rollback_partition, nullptr);
141}
142
143bool DBusUpdateEngineClient::GetPrevVersion(string* prev_version) const {
144 return proxy_->GetPrevVersion(prev_version, nullptr);
145}
146
147void DBusUpdateEngineClient::RebootIfNeeded() {
148 bool ret = proxy_->RebootIfNeeded(nullptr);
149 if (!ret) {
150 // Reboot error code doesn't necessarily mean that a reboot
151 // failed. For example, D-Bus may be shutdown before we receive the
152 // result.
153 LOG(INFO) << "RebootIfNeeded() failure ignored.";
154 }
155}
156
157bool DBusUpdateEngineClient::ResetStatus() {
158 return proxy_->ResetStatus(nullptr);
159}
160
Alex Deymo492eaf52016-02-02 12:05:02 -0800161void DBusUpdateEngineClient::DBusStatusHandlersRegistered(
Amin Hassaniaefaab22019-01-14 16:20:16 -0800162 const string& interface, const string& signal_name, bool success) const {
Casey Dahlina93cd532016-01-14 16:55:11 -0800163 if (!success) {
Casey Dahlina715f7b2016-01-29 16:38:51 -0800164 for (auto handler : handlers_) {
Amin Hassaniaefaab22019-01-14 16:20:16 -0800165 handler->IPCError("Could not connect to" + signal_name + " on " +
166 interface);
Casey Dahlina715f7b2016-01-29 16:38:51 -0800167 }
168 } else {
169 StatusUpdateHandlersRegistered(nullptr);
Casey Dahlina93cd532016-01-14 16:55:11 -0800170 }
Casey Dahlina715f7b2016-01-29 16:38:51 -0800171}
Casey Dahlina93cd532016-01-14 16:55:11 -0800172
Casey Dahlina715f7b2016-01-29 16:38:51 -0800173void DBusUpdateEngineClient::StatusUpdateHandlersRegistered(
174 StatusUpdateHandler* handler) const {
Amin Hassanieb463ee2019-06-20 19:23:03 -0700175 UpdateEngineStatus status;
176 if (!GetStatus(&status)) {
Casey Dahlina715f7b2016-01-29 16:38:51 -0800177 handler->IPCError("Could not query current status");
Casey Dahlina93cd532016-01-14 16:55:11 -0800178 return;
179 }
180
Alex Deymo492eaf52016-02-02 12:05:02 -0800181 std::vector<update_engine::StatusUpdateHandler*> just_handler = {handler};
182 for (auto h : handler ? just_handler : handlers_) {
Amin Hassanieb463ee2019-06-20 19:23:03 -0700183 h->HandleStatusUpdate(status);
Casey Dahlina715f7b2016-01-29 16:38:51 -0800184 }
Casey Dahlina93cd532016-01-14 16:55:11 -0800185}
186
Casey Dahlina715f7b2016-01-29 16:38:51 -0800187void DBusUpdateEngineClient::RunStatusUpdateHandlers(
Amin Hassanieb463ee2019-06-20 19:23:03 -0700188 const StatusResult& status) {
189 UpdateEngineStatus ue_status;
190 ConvertToUpdateEngineStatus(status, &ue_status);
Casey Dahlina93cd532016-01-14 16:55:11 -0800191
Casey Dahlina715f7b2016-01-29 16:38:51 -0800192 for (auto handler : handlers_) {
Amin Hassanieb463ee2019-06-20 19:23:03 -0700193 handler->HandleStatusUpdate(ue_status);
Casey Dahlina715f7b2016-01-29 16:38:51 -0800194 }
195}
196
197bool DBusUpdateEngineClient::UnregisterStatusUpdateHandler(
198 StatusUpdateHandler* handler) {
Alex Deymob3fa53b2016-04-18 19:57:58 -0700199 auto it = std::find(handlers_.begin(), handlers_.end(), handler);
Casey Dahlina715f7b2016-01-29 16:38:51 -0800200 if (it != handlers_.end()) {
201 handlers_.erase(it);
202 return true;
203 }
204
205 return false;
Casey Dahlina93cd532016-01-14 16:55:11 -0800206}
207
Casey Dahlin40892492016-01-25 16:55:28 -0800208bool DBusUpdateEngineClient::RegisterStatusUpdateHandler(
Casey Dahlina93cd532016-01-14 16:55:11 -0800209 StatusUpdateHandler* handler) {
hscham00b6aa22020-02-20 12:32:06 +0900210 if (!base::MessageLoopCurrent::IsSet()) {
Casey Dahlina93cd532016-01-14 16:55:11 -0800211 LOG(FATAL) << "Cannot get UpdateEngineClient outside of message loop.";
Casey Dahlin40892492016-01-25 16:55:28 -0800212 return false;
Casey Dahlina93cd532016-01-14 16:55:11 -0800213 }
214
Casey Dahlina715f7b2016-01-29 16:38:51 -0800215 handlers_.push_back(handler);
216
217 if (dbus_handler_registered_) {
218 StatusUpdateHandlersRegistered(handler);
219 return true;
220 }
221
Amin Hassanieb463ee2019-06-20 19:23:03 -0700222 proxy_->RegisterStatusUpdateAdvancedSignalHandler(
Casey Dahlina715f7b2016-01-29 16:38:51 -0800223 base::Bind(&DBusUpdateEngineClient::RunStatusUpdateHandlers,
224 base::Unretained(this)),
Alex Deymo492eaf52016-02-02 12:05:02 -0800225 base::Bind(&DBusUpdateEngineClient::DBusStatusHandlersRegistered,
226 base::Unretained(this)));
Casey Dahlina715f7b2016-01-29 16:38:51 -0800227
228 dbus_handler_registered_ = true;
Casey Dahlin40892492016-01-25 16:55:28 -0800229
230 return true;
Casey Dahlina93cd532016-01-14 16:55:11 -0800231}
232
233bool DBusUpdateEngineClient::SetTargetChannel(const string& in_target_channel,
234 bool allow_powerwash) {
235 return proxy_->SetChannel(in_target_channel, allow_powerwash, nullptr);
236}
237
238bool DBusUpdateEngineClient::GetTargetChannel(string* out_channel) const {
239 return proxy_->GetChannel(false, // Get the target channel.
240 out_channel,
241 nullptr);
242}
243
244bool DBusUpdateEngineClient::GetChannel(string* out_channel) const {
245 return proxy_->GetChannel(true, // Get the current channel.
246 out_channel,
247 nullptr);
248}
249
Shuqian Zhao29971732016-02-05 11:29:32 -0800250bool DBusUpdateEngineClient::GetLastAttemptError(
251 int32_t* last_attempt_error) const {
252 return proxy_->GetLastAttemptError(last_attempt_error, nullptr);
253}
254
Casey Dahlina93cd532016-01-14 16:55:11 -0800255} // namespace internal
256} // namespace update_engine