blob: 6ed31d45b4447778b74028338961ee6bc9c21574 [file] [log] [blame]
Alex Deymoaea4c1c2015-08-19 20:24:43 -07001//
2// Copyright (C) 2012 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//
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070016
17#include "update_engine/dbus_service.h"
Darin Petkova07586b2010-10-20 13:41:15 -070018
Alex Deymof4867c42013-06-28 14:41:39 -070019#include <set>
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070020#include <string>
Darin Petkova07586b2010-10-20 13:41:15 -070021
Alex Deymob7ca0962014-10-01 17:58:07 -070022#include <base/location.h>
Darin Petkova07586b2010-10-20 13:41:15 -070023#include <base/logging.h>
Alex Vakulenko2bddadd2014-03-27 13:23:46 -070024#include <base/strings/stringprintf.h>
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070025#include <brillo/bind_lambda.h>
26#include <brillo/message_loops/message_loop.h>
27#include <brillo/strings/string_utils.h>
Jay Srinivasan1c0fe792013-03-28 16:45:25 -070028#include <policy/device_policy.h>
Alex Deymod6deb1d2015-08-28 15:54:37 -070029#include <update_engine/dbus-constants.h>
Darin Petkova07586b2010-10-20 13:41:15 -070030
Alex Deymo39910dc2015-11-09 17:04:30 -080031#include "update_engine/common/clock_interface.h"
32#include "update_engine/common/hardware_interface.h"
33#include "update_engine/common/prefs.h"
34#include "update_engine/common/utils.h"
Alex Deymof6ee0162015-07-31 12:35:22 -070035#include "update_engine/connection_manager_interface.h"
Darin Petkov49d91322010-10-25 16:34:58 -070036#include "update_engine/omaha_request_params.h"
Alex Deymo5fdf7762013-07-17 20:01:40 -070037#include "update_engine/p2p_manager.h"
J. Richard Barnette056b0ab2013-10-29 15:24:56 -070038#include "update_engine/update_attempter.h"
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070039
Gilad Arnoldccd09572014-10-27 13:37:50 -070040using base::StringPrintf;
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070041using brillo::ErrorPtr;
42using brillo::string_utils::ToString;
Alex Deymof329b932014-10-30 01:37:48 -070043using std::set;
44using std::string;
Alex Deymod6deb1d2015-08-28 15:54:37 -070045using update_engine::AttemptUpdateFlags;
46using update_engine::kAttemptUpdateFlagNonInteractive;
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070047
Alex Deymob7ca0962014-10-01 17:58:07 -070048namespace {
49// Log and set the error on the passed ErrorPtr.
50void LogAndSetError(ErrorPtr *error,
51 const tracked_objects::Location& location,
52 const string& reason) {
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070053 brillo::Error::AddTo(
Alex Deymob7ca0962014-10-01 17:58:07 -070054 error, location,
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070055 brillo::errors::dbus::kDomain,
Alex Deymod6deb1d2015-08-28 15:54:37 -070056 update_engine::kUpdateEngineServiceErrorFailed, reason);
Alex Deymob7ca0962014-10-01 17:58:07 -070057 LOG(ERROR) << "Sending DBus Failure: " << location.ToString() << ": "
58 << reason;
59}
60} // namespace
Don Garrettbb26fc82013-11-15 10:40:17 -080061
Alex Deymob7ca0962014-10-01 17:58:07 -070062namespace chromeos_update_engine {
Don Garrettbb26fc82013-11-15 10:40:17 -080063
Alex Deymob7ca0962014-10-01 17:58:07 -070064UpdateEngineService::UpdateEngineService(SystemState* system_state)
65 : system_state_(system_state) {}
Don Garrettbb26fc82013-11-15 10:40:17 -080066
Alex Deymob7ca0962014-10-01 17:58:07 -070067// org::chromium::UpdateEngineInterfaceInterface methods implementation.
Don Garrettbb26fc82013-11-15 10:40:17 -080068
Alex Deymob7ca0962014-10-01 17:58:07 -070069bool UpdateEngineService::AttemptUpdate(ErrorPtr* error,
70 const string& in_app_version,
71 const string& in_omaha_url) {
72 return AttemptUpdateWithFlags(
73 error, in_app_version, in_omaha_url, 0 /* no flags */);
Don Garrettbb26fc82013-11-15 10:40:17 -080074}
75
Alex Deymob7ca0962014-10-01 17:58:07 -070076bool UpdateEngineService::AttemptUpdateWithFlags(ErrorPtr* /* error */,
77 const string& in_app_version,
78 const string& in_omaha_url,
79 int32_t in_flags_as_int) {
80 AttemptUpdateFlags flags = static_cast<AttemptUpdateFlags>(in_flags_as_int);
David Pursell02c18642014-11-06 11:26:11 -080081 bool interactive = !(flags & kAttemptUpdateFlagNonInteractive);
Jay Srinivasane73acab2012-07-10 14:34:03 -070082
Alex Deymob7ca0962014-10-01 17:58:07 -070083 LOG(INFO) << "Attempt update: app_version=\"" << in_app_version << "\" "
84 << "omaha_url=\"" << in_omaha_url << "\" "
David Zeuthen75a4c3e2013-09-06 11:36:59 -070085 << "flags=0x" << std::hex << flags << " "
Gilad Arnoldb92f0df2013-01-10 16:32:45 -080086 << "interactive=" << (interactive? "yes" : "no");
Alex Deymob7ca0962014-10-01 17:58:07 -070087 system_state_->update_attempter()->CheckForUpdate(
88 in_app_version, in_omaha_url, interactive);
89 return true;
Darin Petkov296889c2010-07-23 16:20:54 -070090}
91
Alex Deymob7ca0962014-10-01 17:58:07 -070092bool UpdateEngineService::AttemptRollback(ErrorPtr* error,
93 bool in_powerwash) {
Chris Sosad317e402013-06-12 13:47:09 -070094 LOG(INFO) << "Attempting rollback to non-active partitions.";
Don Garrettbb26fc82013-11-15 10:40:17 -080095
Alex Deymob7ca0962014-10-01 17:58:07 -070096 if (!system_state_->update_attempter()->Rollback(in_powerwash)) {
Don Garrettbb26fc82013-11-15 10:40:17 -080097 // TODO(dgarrett): Give a more specific error code/reason.
Alex Deymob7ca0962014-10-01 17:58:07 -070098 LogAndSetError(error, FROM_HERE, "Rollback attempt failed.");
99 return false;
Don Garrettbb26fc82013-11-15 10:40:17 -0800100 }
Alex Deymob7ca0962014-10-01 17:58:07 -0700101 return true;
Chris Sosad317e402013-06-12 13:47:09 -0700102}
103
Alex Deymob7ca0962014-10-01 17:58:07 -0700104bool UpdateEngineService::CanRollback(ErrorPtr* /* error */,
105 bool* out_can_rollback) {
106 bool can_rollback = system_state_->update_attempter()->CanRollback();
Chris Sosa44b9b7e2014-04-02 13:53:46 -0700107 LOG(INFO) << "Checking to see if we can rollback . Result: " << can_rollback;
Alex Vakulenko2bddadd2014-03-27 13:23:46 -0700108 *out_can_rollback = can_rollback;
Alex Deymob7ca0962014-10-01 17:58:07 -0700109 return true;
Alex Vakulenko2bddadd2014-03-27 13:23:46 -0700110}
111
Alex Deymob7ca0962014-10-01 17:58:07 -0700112bool UpdateEngineService::ResetStatus(ErrorPtr* error) {
113 if (!system_state_->update_attempter()->ResetStatus()) {
Don Garrettbb26fc82013-11-15 10:40:17 -0800114 // TODO(dgarrett): Give a more specific error code/reason.
Alex Deymob7ca0962014-10-01 17:58:07 -0700115 LogAndSetError(error, FROM_HERE, "ResetStatus failed.");
116 return false;
Don Garrettbb26fc82013-11-15 10:40:17 -0800117 }
Alex Deymob7ca0962014-10-01 17:58:07 -0700118 return true;
Don Garrettbb26fc82013-11-15 10:40:17 -0800119}
Jay Srinivasanc1ba09a2012-08-14 14:15:57 -0700120
Alex Deymob7ca0962014-10-01 17:58:07 -0700121bool UpdateEngineService::GetStatus(ErrorPtr* error,
122 int64_t* out_last_checked_time,
123 double* out_progress,
124 string* out_current_operation,
125 string* out_new_version,
126 int64_t* out_new_size) {
127 if (!system_state_->update_attempter()->GetStatus(out_last_checked_time,
128 out_progress,
129 out_current_operation,
130 out_new_version,
131 out_new_size)) {
132 LogAndSetError(error, FROM_HERE, "GetStatus failed.");
133 return false;
Chris Masonec6c57a52010-09-23 13:06:14 -0700134 }
Alex Deymob7ca0962014-10-01 17:58:07 -0700135 return true;
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700136}
137
Alex Deymob7ca0962014-10-01 17:58:07 -0700138bool UpdateEngineService::RebootIfNeeded(ErrorPtr* error) {
139 if (!system_state_->update_attempter()->RebootIfNeeded()) {
Don Garrettbb26fc82013-11-15 10:40:17 -0800140 // TODO(dgarrett): Give a more specific error code/reason.
Alex Deymob7ca0962014-10-01 17:58:07 -0700141 LogAndSetError(error, FROM_HERE, "Reboot not needed, or attempt failed.");
142 return false;
Darin Petkov296889c2010-07-23 16:20:54 -0700143 }
Alex Deymob7ca0962014-10-01 17:58:07 -0700144 return true;
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700145}
146
Alex Deymob7ca0962014-10-01 17:58:07 -0700147bool UpdateEngineService::SetChannel(ErrorPtr* error,
148 const string& in_target_channel,
149 bool in_is_powerwash_allowed) {
150 const policy::DevicePolicy* device_policy = system_state_->device_policy();
Chris Sosacb7fa882013-07-25 17:02:59 -0700151
152 // The device_policy is loaded in a lazy way before an update check. Load it
Alex Vakulenko1bab5a82015-10-27 11:47:28 -0700153 // now from the libbrillo cache if it wasn't already loaded.
Jay Srinivasan1c0fe792013-03-28 16:45:25 -0700154 if (!device_policy) {
Alex Deymob7ca0962014-10-01 17:58:07 -0700155 UpdateAttempter* update_attempter = system_state_->update_attempter();
Chris Sosacb7fa882013-07-25 17:02:59 -0700156 if (update_attempter) {
157 update_attempter->RefreshDevicePolicy();
Alex Deymob7ca0962014-10-01 17:58:07 -0700158 device_policy = system_state_->device_policy();
Chris Sosacb7fa882013-07-25 17:02:59 -0700159 }
Darin Petkov8daa3242010-10-25 13:28:47 -0700160 }
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700161
162 bool delegated = false;
Chris Sosacb7fa882013-07-25 17:02:59 -0700163 if (device_policy &&
164 device_policy->GetReleaseChannelDelegated(&delegated) && !delegated) {
Alex Deymob7ca0962014-10-01 17:58:07 -0700165 LogAndSetError(
166 error, FROM_HERE,
Don Garrettbb26fc82013-11-15 10:40:17 -0800167 "Cannot set target channel explicitly when channel "
168 "policy/settings is not delegated");
Alex Deymob7ca0962014-10-01 17:58:07 -0700169 return false;
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700170 }
171
Alex Deymob7ca0962014-10-01 17:58:07 -0700172 LOG(INFO) << "Setting destination channel to: " << in_target_channel;
Alex Deymod942f9d2015-11-06 16:11:50 -0800173 string error_message;
Alex Deymob7ca0962014-10-01 17:58:07 -0700174 if (!system_state_->request_params()->SetTargetChannel(
Alex Deymod942f9d2015-11-06 16:11:50 -0800175 in_target_channel, in_is_powerwash_allowed, &error_message)) {
176 LogAndSetError(error, FROM_HERE, error_message);
Alex Deymob7ca0962014-10-01 17:58:07 -0700177 return false;
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700178 }
Alex Deymob7ca0962014-10-01 17:58:07 -0700179 return true;
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700180}
181
Alex Deymob7ca0962014-10-01 17:58:07 -0700182bool UpdateEngineService::GetChannel(ErrorPtr* /* error */,
183 bool in_get_current_channel,
184 string* out_channel) {
185 OmahaRequestParams* rp = system_state_->request_params();
186 *out_channel = (in_get_current_channel ?
187 rp->current_channel() : rp->target_channel());
188 return true;
Darin Petkov8daa3242010-10-25 13:28:47 -0700189}
190
Alex Deymob7ca0962014-10-01 17:58:07 -0700191bool UpdateEngineService::SetP2PUpdatePermission(ErrorPtr* error,
192 bool in_enabled) {
193 PrefsInterface* prefs = system_state_->prefs();
Alex Deymo5fdf7762013-07-17 20:01:40 -0700194
Alex Deymob7ca0962014-10-01 17:58:07 -0700195 if (!prefs->SetBoolean(kPrefsP2PEnabled, in_enabled)) {
196 LogAndSetError(
197 error, FROM_HERE,
Gilad Arnoldccd09572014-10-27 13:37:50 -0700198 StringPrintf("Error setting the update via p2p permission to %s.",
Alex Deymob7ca0962014-10-01 17:58:07 -0700199 ToString(in_enabled).c_str()));
200 return false;
Alex Deymo5fdf7762013-07-17 20:01:40 -0700201 }
Alex Deymob7ca0962014-10-01 17:58:07 -0700202 return true;
Alex Deymo5fdf7762013-07-17 20:01:40 -0700203}
204
Alex Deymob7ca0962014-10-01 17:58:07 -0700205bool UpdateEngineService::GetP2PUpdatePermission(ErrorPtr* error,
206 bool* out_enabled) {
207 PrefsInterface* prefs = system_state_->prefs();
Alex Deymo5fdf7762013-07-17 20:01:40 -0700208
Gilad Arnold367a3ad2014-10-23 16:00:17 -0700209 bool p2p_pref = false; // Default if no setting is present.
Alex Deymob7ca0962014-10-01 17:58:07 -0700210 if (prefs->Exists(kPrefsP2PEnabled) &&
211 !prefs->GetBoolean(kPrefsP2PEnabled, &p2p_pref)) {
212 LogAndSetError(error, FROM_HERE, "Error getting the P2PEnabled setting.");
213 return false;
Alex Deymo5fdf7762013-07-17 20:01:40 -0700214 }
215
Alex Deymob7ca0962014-10-01 17:58:07 -0700216 *out_enabled = p2p_pref;
217 return true;
Alex Deymo5fdf7762013-07-17 20:01:40 -0700218}
219
Alex Deymob7ca0962014-10-01 17:58:07 -0700220bool UpdateEngineService::SetUpdateOverCellularPermission(ErrorPtr* error,
221 bool in_allowed) {
Alex Deymof4867c42013-06-28 14:41:39 -0700222 set<string> allowed_types;
Alex Deymob7ca0962014-10-01 17:58:07 -0700223 const policy::DevicePolicy* device_policy = system_state_->device_policy();
Alex Deymof4867c42013-06-28 14:41:39 -0700224
225 // The device_policy is loaded in a lazy way before an update check. Load it
Alex Vakulenko1bab5a82015-10-27 11:47:28 -0700226 // now from the libbrillo cache if it wasn't already loaded.
Alex Deymof4867c42013-06-28 14:41:39 -0700227 if (!device_policy) {
Alex Deymob7ca0962014-10-01 17:58:07 -0700228 UpdateAttempter* update_attempter = system_state_->update_attempter();
Alex Deymof4867c42013-06-28 14:41:39 -0700229 if (update_attempter) {
230 update_attempter->RefreshDevicePolicy();
Alex Deymob7ca0962014-10-01 17:58:07 -0700231 device_policy = system_state_->device_policy();
Alex Deymof4867c42013-06-28 14:41:39 -0700232 }
233 }
234
235 // Check if this setting is allowed by the device policy.
236 if (device_policy &&
237 device_policy->GetAllowedConnectionTypesForUpdate(&allowed_types)) {
Alex Deymob7ca0962014-10-01 17:58:07 -0700238 LogAndSetError(error, FROM_HERE,
239 "Ignoring the update over cellular setting since there's "
240 "a device policy enforcing this setting.");
241 return false;
Alex Deymof4867c42013-06-28 14:41:39 -0700242 }
243
244 // If the policy wasn't loaded yet, then it is still OK to change the local
245 // setting because the policy will be checked again during the update check.
246
Alex Deymob7ca0962014-10-01 17:58:07 -0700247 PrefsInterface* prefs = system_state_->prefs();
Alex Deymof4867c42013-06-28 14:41:39 -0700248
Alex Deymob7ca0962014-10-01 17:58:07 -0700249 if (!prefs->SetBoolean(kPrefsUpdateOverCellularPermission, in_allowed)) {
250 LogAndSetError(error, FROM_HERE,
251 string("Error setting the update over cellular to ") +
252 (in_allowed ? "true" : "false"));
253 return false;
Alex Deymof4867c42013-06-28 14:41:39 -0700254 }
Alex Deymob7ca0962014-10-01 17:58:07 -0700255 return true;
Alex Deymof4867c42013-06-28 14:41:39 -0700256}
257
Alex Deymob7ca0962014-10-01 17:58:07 -0700258bool UpdateEngineService::GetUpdateOverCellularPermission(ErrorPtr* /* error */,
259 bool* out_allowed) {
260 ConnectionManagerInterface* cm = system_state_->connection_manager();
Alex Deymof4867c42013-06-28 14:41:39 -0700261
262 // The device_policy is loaded in a lazy way before an update check and is
263 // used to determine if an update is allowed over cellular. Load the device
Alex Vakulenko1bab5a82015-10-27 11:47:28 -0700264 // policy now from the libbrillo cache if it wasn't already loaded.
Alex Deymob7ca0962014-10-01 17:58:07 -0700265 if (!system_state_->device_policy()) {
266 UpdateAttempter* update_attempter = system_state_->update_attempter();
Alex Deymof4867c42013-06-28 14:41:39 -0700267 if (update_attempter)
268 update_attempter->RefreshDevicePolicy();
269 }
270
271 // Return the current setting based on the same logic used while checking for
272 // updates. A log message could be printed as the result of this test.
273 LOG(INFO) << "Checking if updates over cellular networks are allowed:";
Alex Deymob7ca0962014-10-01 17:58:07 -0700274 *out_allowed = cm->IsUpdateAllowedOver(
Alex Deymo75eac7e2015-07-29 13:39:14 -0700275 chromeos_update_engine::NetworkConnectionType::kCellular,
Alex Deymo6ae91202014-03-10 19:21:25 -0700276 chromeos_update_engine::NetworkTethering::kUnknown);
Alex Deymob7ca0962014-10-01 17:58:07 -0700277 return true;
Alex Deymof4867c42013-06-28 14:41:39 -0700278}
279
Alex Deymob7ca0962014-10-01 17:58:07 -0700280bool UpdateEngineService::GetDurationSinceUpdate(ErrorPtr* error,
281 int64_t* out_usec_wallclock) {
David Zeuthen3c55abd2013-10-14 12:48:03 -0700282 base::Time time;
Alex Deymob7ca0962014-10-01 17:58:07 -0700283 if (!system_state_->update_attempter()->GetBootTimeAtUpdate(&time)) {
284 LogAndSetError(error, FROM_HERE, "No pending update.");
285 return false;
Don Garrettbb26fc82013-11-15 10:40:17 -0800286 }
David Zeuthen3c55abd2013-10-14 12:48:03 -0700287
Alex Deymob7ca0962014-10-01 17:58:07 -0700288 ClockInterface* clock = system_state_->clock();
David Zeuthen3c55abd2013-10-14 12:48:03 -0700289 *out_usec_wallclock = (clock->GetBootTime() - time).InMicroseconds();
Alex Deymob7ca0962014-10-01 17:58:07 -0700290 return true;
David Zeuthen3c55abd2013-10-14 12:48:03 -0700291}
292
Alex Deymob7ca0962014-10-01 17:58:07 -0700293bool UpdateEngineService::GetPrevVersion(ErrorPtr* /* error */,
294 string* out_prev_version) {
295 *out_prev_version = system_state_->update_attempter()->GetPrevVersion();
296 return true;
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700297}
Alex Vakulenkodea2eac2014-03-14 15:56:59 -0700298
Alex Deymob7ca0962014-10-01 17:58:07 -0700299bool UpdateEngineService::GetRollbackPartition(
300 ErrorPtr* /* error */,
301 string* out_rollback_partition_name) {
Alex Deymo763e7db2015-08-27 21:08:08 -0700302 BootControlInterface::Slot rollback_slot =
303 system_state_->update_attempter()->GetRollbackSlot();
304
305 if (rollback_slot == BootControlInterface::kInvalidSlot) {
306 out_rollback_partition_name->clear();
307 return true;
308 }
309
310 string name;
311 if (!system_state_->boot_control()->GetPartitionDevice(
312 "KERNEL", rollback_slot, &name)) {
313 LOG(ERROR) << "Invalid rollback device";
314 return false;
315 }
316
Alex Deymob7ca0962014-10-01 17:58:07 -0700317 LOG(INFO) << "Getting rollback partition name. Result: " << name;
318 *out_rollback_partition_name = name;
319 return true;
320}
321
Alex Deymob7ca0962014-10-01 17:58:07 -0700322UpdateEngineAdaptor::UpdateEngineAdaptor(SystemState* system_state,
323 const scoped_refptr<dbus::Bus>& bus)
324 : org::chromium::UpdateEngineInterfaceAdaptor(&dbus_service_),
325 bus_(bus),
326 dbus_service_(system_state),
Alex Deymod6deb1d2015-08-28 15:54:37 -0700327 dbus_object_(nullptr,
328 bus,
329 dbus::ObjectPath(update_engine::kUpdateEngineServicePath)) {}
Alex Deymob7ca0962014-10-01 17:58:07 -0700330
331void UpdateEngineAdaptor::RegisterAsync(
332 const base::Callback<void(bool)>& completion_callback) {
333 RegisterWithDBusObject(&dbus_object_);
334 dbus_object_.RegisterAsync(completion_callback);
335}
336
337bool UpdateEngineAdaptor::RequestOwnership() {
Alex Deymod6deb1d2015-08-28 15:54:37 -0700338 return bus_->RequestOwnershipAndBlock(update_engine::kUpdateEngineServiceName,
Alex Deymob7ca0962014-10-01 17:58:07 -0700339 dbus::Bus::REQUIRE_PRIMARY);
340}
341
342} // namespace chromeos_update_engine