blob: ba9958689edaa78e5ef426da3c48e7a48cbeb7d3 [file] [log] [blame]
Jay Srinivasane73acab2012-07-10 14:34:03 -07001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "update_engine/dbus_service.h"
Darin Petkova07586b2010-10-20 13:41:15 -07006
Alex Deymof4867c42013-06-28 14:41:39 -07007#include <set>
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -07008#include <string>
Darin Petkova07586b2010-10-20 13:41:15 -07009
10#include <base/logging.h>
Alex Vakulenko2bddadd2014-03-27 13:23:46 -070011#include <base/strings/stringprintf.h>
Gilad Arnoldccd09572014-10-27 13:37:50 -070012#include <chromeos/strings/string_utils.h>
Jay Srinivasan1c0fe792013-03-28 16:45:25 -070013#include <policy/device_policy.h>
Darin Petkova07586b2010-10-20 13:41:15 -070014
David Zeuthen3c55abd2013-10-14 12:48:03 -070015#include "update_engine/clock_interface.h"
Alex Deymof4867c42013-06-28 14:41:39 -070016#include "update_engine/connection_manager.h"
David Zeuthen75a4c3e2013-09-06 11:36:59 -070017#include "update_engine/dbus_constants.h"
J. Richard Barnette056b0ab2013-10-29 15:24:56 -070018#include "update_engine/hardware_interface.h"
Darin Petkov49d91322010-10-25 16:34:58 -070019#include "update_engine/omaha_request_params.h"
Alex Deymo5fdf7762013-07-17 20:01:40 -070020#include "update_engine/p2p_manager.h"
Alex Deymof4867c42013-06-28 14:41:39 -070021#include "update_engine/prefs.h"
J. Richard Barnette056b0ab2013-10-29 15:24:56 -070022#include "update_engine/update_attempter.h"
Darin Petkova07586b2010-10-20 13:41:15 -070023#include "update_engine/utils.h"
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070024
Gilad Arnoldccd09572014-10-27 13:37:50 -070025using base::StringPrintf;
26using chromeos::string_utils::ToString;
David Zeuthen75a4c3e2013-09-06 11:36:59 -070027using chromeos_update_engine::AttemptUpdateFlags;
28using chromeos_update_engine::kAttemptUpdateFlagNonInteractive;
Alex Deymof329b932014-10-30 01:37:48 -070029using std::set;
30using std::string;
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070031
Don Garrettbb26fc82013-11-15 10:40:17 -080032#define UPDATE_ENGINE_SERVICE_ERROR update_engine_service_error_quark ()
33#define UPDATE_ENGINE_SERVICE_TYPE_ERROR \
34 (update_engine_service_error_get_type())
35
Alex Vakulenkod2779df2014-06-16 13:19:00 -070036enum UpdateEngineServiceError {
Don Garrettbb26fc82013-11-15 10:40:17 -080037 UPDATE_ENGINE_SERVICE_ERROR_FAILED,
38 UPDATE_ENGINE_SERVICE_NUM_ERRORS
Alex Vakulenkod2779df2014-06-16 13:19:00 -070039};
Don Garrettbb26fc82013-11-15 10:40:17 -080040
41static GQuark update_engine_service_error_quark(void) {
42 static GQuark ret = 0;
43
44 if (ret == 0)
45 ret = g_quark_from_static_string("update_engine_service_error");
46
47 return ret;
48}
49
50#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
51
52static GType update_engine_service_error_get_type(void) {
53 static GType etype = 0;
54
55 if (etype == 0) {
56 static const GEnumValue values[] = {
57 ENUM_ENTRY(UPDATE_ENGINE_SERVICE_ERROR_FAILED, "Failed"),
58 { 0, 0, 0 }
59 };
60 G_STATIC_ASSERT(UPDATE_ENGINE_SERVICE_NUM_ERRORS ==
Alex Vakulenkod2779df2014-06-16 13:19:00 -070061 G_N_ELEMENTS(values) - 1);
Don Garrettbb26fc82013-11-15 10:40:17 -080062 etype = g_enum_register_static("UpdateEngineServiceError", values);
63 }
64
65 return etype;
66}
67
Darin Petkov820a77b2011-04-27 16:48:58 -070068static const char kAUTestURLRequest[] = "autest";
Jay Srinivasane73acab2012-07-10 14:34:03 -070069// By default autest bypasses scattering. If we want to test scattering,
70// we should use autest-scheduled. The Url used is same in both cases, but
71// different params are passed to CheckForUpdate method.
72static const char kScheduledAUTestURLRequest[] = "autest-scheduled";
73
Darin Petkov820a77b2011-04-27 16:48:58 -070074static const char kAUTestURL[] =
Darin Petkov5445e162011-11-04 10:10:27 +010075 "https://omaha.sandbox.google.com/service/update2";
Darin Petkov820a77b2011-04-27 16:48:58 -070076
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070077G_DEFINE_TYPE(UpdateEngineService, update_engine_service, G_TYPE_OBJECT)
78
79static void update_engine_service_finalize(GObject* object) {
80 G_OBJECT_CLASS(update_engine_service_parent_class)->finalize(object);
81}
82
Don Garrettbb26fc82013-11-15 10:40:17 -080083static void log_and_set_response_error(GError** error,
84 UpdateEngineServiceError error_code,
85 const string& reason) {
86 LOG(ERROR) << "Sending DBus Failure: " << reason;
87 g_set_error_literal(error, UPDATE_ENGINE_SERVICE_ERROR,
88 error_code, reason.c_str());
89}
90
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070091static guint status_update_signal = 0;
92
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070093static void update_engine_service_class_init(UpdateEngineServiceClass* klass) {
94 GObjectClass *object_class;
95 object_class = G_OBJECT_CLASS(klass);
96 object_class->finalize = update_engine_service_finalize;
Darin Petkov5a7f5652010-07-22 21:40:09 -070097
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070098 status_update_signal = g_signal_new(
99 "status_update",
100 G_OBJECT_CLASS_TYPE(klass),
101 G_SIGNAL_RUN_LAST,
102 0, // 0 == no class method associated
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700103 nullptr, // Accumulator
104 nullptr, // Accumulator data
105 nullptr, // Marshaller
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700106 G_TYPE_NONE, // Return type
107 5, // param count:
108 G_TYPE_INT64,
109 G_TYPE_DOUBLE,
110 G_TYPE_STRING,
111 G_TYPE_STRING,
112 G_TYPE_INT64);
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700113}
114
115static void update_engine_service_init(UpdateEngineService* object) {
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700116 dbus_g_error_domain_register(UPDATE_ENGINE_SERVICE_ERROR,
117 "org.chromium.UpdateEngine.Error",
118 UPDATE_ENGINE_SERVICE_TYPE_ERROR);
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700119}
120
121UpdateEngineService* update_engine_service_new(void) {
122 return reinterpret_cast<UpdateEngineService*>(
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700123 g_object_new(UPDATE_ENGINE_TYPE_SERVICE, nullptr));
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700124}
125
Darin Petkov296889c2010-07-23 16:20:54 -0700126gboolean update_engine_service_attempt_update(UpdateEngineService* self,
127 gchar* app_version,
128 gchar* omaha_url,
129 GError **error) {
David Zeuthen75a4c3e2013-09-06 11:36:59 -0700130 return update_engine_service_attempt_update_with_flags(self,
131 app_version,
132 omaha_url,
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700133 0, // No flags set.
David Zeuthen75a4c3e2013-09-06 11:36:59 -0700134 error);
135}
136
137gboolean update_engine_service_attempt_update_with_flags(
138 UpdateEngineService* self,
139 gchar* app_version,
140 gchar* omaha_url,
141 gint flags_as_int,
142 GError **error) {
Darin Petkova07586b2010-10-20 13:41:15 -0700143 string update_app_version;
144 string update_omaha_url;
David Zeuthen75a4c3e2013-09-06 11:36:59 -0700145 AttemptUpdateFlags flags = static_cast<AttemptUpdateFlags>(flags_as_int);
Gilad Arnoldb92f0df2013-01-10 16:32:45 -0800146 bool interactive = true;
Jay Srinivasane73acab2012-07-10 14:34:03 -0700147
Darin Petkova07586b2010-10-20 13:41:15 -0700148 // Only non-official (e.g., dev and test) builds can override the current
Darin Petkov820a77b2011-04-27 16:48:58 -0700149 // version and update server URL over D-Bus. However, pointing to the
150 // hardcoded test update server URL is always allowed.
J. Richard Barnette056b0ab2013-10-29 15:24:56 -0700151 if (!self->system_state_->hardware()->IsOfficialBuild()) {
Darin Petkova07586b2010-10-20 13:41:15 -0700152 if (app_version) {
153 update_app_version = app_version;
154 }
155 if (omaha_url) {
156 update_omaha_url = omaha_url;
157 }
158 }
Jay Srinivasane73acab2012-07-10 14:34:03 -0700159 if (omaha_url) {
160 if (strcmp(omaha_url, kScheduledAUTestURLRequest) == 0) {
161 update_omaha_url = kAUTestURL;
162 // pretend that it's not user-initiated even though it is,
163 // so as to test scattering logic, etc. which get kicked off
164 // only in scheduled update checks.
Gilad Arnoldb92f0df2013-01-10 16:32:45 -0800165 interactive = false;
Jay Srinivasane73acab2012-07-10 14:34:03 -0700166 } else if (strcmp(omaha_url, kAUTestURLRequest) == 0) {
167 update_omaha_url = kAUTestURL;
168 }
Darin Petkov820a77b2011-04-27 16:48:58 -0700169 }
David Zeuthen75a4c3e2013-09-06 11:36:59 -0700170 if (flags & kAttemptUpdateFlagNonInteractive)
171 interactive = false;
Darin Petkov296889c2010-07-23 16:20:54 -0700172 LOG(INFO) << "Attempt update: app_version=\"" << update_app_version << "\" "
Jay Srinivasane73acab2012-07-10 14:34:03 -0700173 << "omaha_url=\"" << update_omaha_url << "\" "
David Zeuthen75a4c3e2013-09-06 11:36:59 -0700174 << "flags=0x" << std::hex << flags << " "
Gilad Arnoldb92f0df2013-01-10 16:32:45 -0800175 << "interactive=" << (interactive? "yes" : "no");
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700176 self->system_state_->update_attempter()->CheckForUpdate(update_app_version,
177 update_omaha_url,
178 interactive);
Darin Petkov296889c2010-07-23 16:20:54 -0700179 return TRUE;
180}
181
Chris Sosad317e402013-06-12 13:47:09 -0700182gboolean update_engine_service_attempt_rollback(UpdateEngineService* self,
Alex Deymoad923732013-08-29 16:13:49 -0700183 gboolean powerwash,
Chris Sosad317e402013-06-12 13:47:09 -0700184 GError **error) {
185 LOG(INFO) << "Attempting rollback to non-active partitions.";
Don Garrettbb26fc82013-11-15 10:40:17 -0800186
Chris Sosa44b9b7e2014-04-02 13:53:46 -0700187 if (!self->system_state_->update_attempter()->Rollback(powerwash)) {
Don Garrettbb26fc82013-11-15 10:40:17 -0800188 // TODO(dgarrett): Give a more specific error code/reason.
189 log_and_set_response_error(error,
190 UPDATE_ENGINE_SERVICE_ERROR_FAILED,
191 "Rollback attempt failed.");
192 return FALSE;
193 }
194
195 return TRUE;
Chris Sosad317e402013-06-12 13:47:09 -0700196}
197
Alex Vakulenko59e253e2014-02-24 10:40:21 -0800198gboolean update_engine_service_can_rollback(UpdateEngineService* self,
199 gboolean* out_can_rollback,
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700200 GError **error) {
Alex Vakulenko2bddadd2014-03-27 13:23:46 -0700201 bool can_rollback = self->system_state_->update_attempter()->CanRollback();
Chris Sosa44b9b7e2014-04-02 13:53:46 -0700202 LOG(INFO) << "Checking to see if we can rollback . Result: " << can_rollback;
Alex Vakulenko2bddadd2014-03-27 13:23:46 -0700203 *out_can_rollback = can_rollback;
204 return TRUE;
205}
206
207gboolean update_engine_service_get_rollback_partition(
208 UpdateEngineService* self,
209 gchar** out_rollback_partition_name,
210 GError **error) {
211 auto name = self->system_state_->update_attempter()->GetRollbackPartition();
212 LOG(INFO) << "Getting rollback partition name. Result: " << name;
213 *out_rollback_partition_name = g_strdup(name.c_str());
214 return TRUE;
215}
216
217gboolean update_engine_service_get_kernel_devices(UpdateEngineService* self,
218 gchar** out_kernel_devices,
219 GError **error) {
220 auto devices = self->system_state_->update_attempter()->GetKernelDevices();
Alex Deymof329b932014-10-30 01:37:48 -0700221 string info;
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700222 for (const auto& device : devices) {
Alex Vakulenko2bddadd2014-03-27 13:23:46 -0700223 base::StringAppendF(&info, "%d:%s\n",
224 device.second ? 1 : 0, device.first.c_str());
225 }
226 LOG(INFO) << "Available kernel devices: " << info;
227 *out_kernel_devices = g_strdup(info.c_str());
Alex Vakulenko59e253e2014-02-24 10:40:21 -0800228 return TRUE;
229}
230
231
Jay Srinivasanc1ba09a2012-08-14 14:15:57 -0700232gboolean update_engine_service_reset_status(UpdateEngineService* self,
233 GError **error) {
Don Garrettbb26fc82013-11-15 10:40:17 -0800234 if (!self->system_state_->update_attempter()->ResetStatus()) {
235 // TODO(dgarrett): Give a more specific error code/reason.
236 log_and_set_response_error(error,
237 UPDATE_ENGINE_SERVICE_ERROR_FAILED,
238 "ResetStatus failed.");
239 return FALSE;
240 }
Jay Srinivasanc1ba09a2012-08-14 14:15:57 -0700241
Don Garrettbb26fc82013-11-15 10:40:17 -0800242 return TRUE;
243}
Jay Srinivasanc1ba09a2012-08-14 14:15:57 -0700244
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700245gboolean update_engine_service_get_status(UpdateEngineService* self,
246 int64_t* last_checked_time,
247 double* progress,
248 gchar** current_operation,
249 gchar** new_version,
250 int64_t* new_size,
251 GError **error) {
252 string current_op;
253 string new_version_str;
Darin Petkov5a7f5652010-07-22 21:40:09 -0700254
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700255 CHECK(self->system_state_->update_attempter()->GetStatus(last_checked_time,
256 progress,
257 &current_op,
258 &new_version_str,
259 new_size));
Satoru Takabayashid6982312010-11-29 12:54:12 +0900260 *current_operation = g_strdup(current_op.c_str());
261 *new_version = g_strdup(new_version_str.c_str());
Don Garrettbb26fc82013-11-15 10:40:17 -0800262
263 if (!*current_operation) {
264 log_and_set_response_error(error,
265 UPDATE_ENGINE_SERVICE_ERROR_FAILED,
266 "Unable to find current_operation.");
Chris Masonec6c57a52010-09-23 13:06:14 -0700267 return FALSE;
268 }
Don Garrettbb26fc82013-11-15 10:40:17 -0800269
270 if (!*new_version) {
271 log_and_set_response_error(error,
272 UPDATE_ENGINE_SERVICE_ERROR_FAILED,
273 "Unable to find vew_version.");
274 return FALSE;
275 }
276
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700277 return TRUE;
278}
279
Darin Petkov296889c2010-07-23 16:20:54 -0700280gboolean update_engine_service_reboot_if_needed(UpdateEngineService* self,
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700281 GError **error) {
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700282 if (!self->system_state_->update_attempter()->RebootIfNeeded()) {
Don Garrettbb26fc82013-11-15 10:40:17 -0800283 // TODO(dgarrett): Give a more specific error code/reason.
284 log_and_set_response_error(error,
285 UPDATE_ENGINE_SERVICE_ERROR_FAILED,
286 "Reboot not needed, or attempt failed.");
Darin Petkov296889c2010-07-23 16:20:54 -0700287 return FALSE;
288 }
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700289 return TRUE;
290}
291
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700292gboolean update_engine_service_set_channel(UpdateEngineService* self,
293 gchar* target_channel,
Alex Deymoad923732013-08-29 16:13:49 -0700294 gboolean is_powerwash_allowed,
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700295 GError **error) {
Don Garrettbb26fc82013-11-15 10:40:17 -0800296 if (!target_channel) {
297 log_and_set_response_error(error,
298 UPDATE_ENGINE_SERVICE_ERROR_FAILED,
299 "Target channel to set not specified.");
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700300 return FALSE;
Don Garrettbb26fc82013-11-15 10:40:17 -0800301 }
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700302
Jay Srinivasan1c0fe792013-03-28 16:45:25 -0700303 const policy::DevicePolicy* device_policy =
304 self->system_state_->device_policy();
Chris Sosacb7fa882013-07-25 17:02:59 -0700305
306 // The device_policy is loaded in a lazy way before an update check. Load it
307 // now from the libchromeos cache if it wasn't already loaded.
Jay Srinivasan1c0fe792013-03-28 16:45:25 -0700308 if (!device_policy) {
Chris Sosacb7fa882013-07-25 17:02:59 -0700309 chromeos_update_engine::UpdateAttempter* update_attempter =
310 self->system_state_->update_attempter();
311 if (update_attempter) {
312 update_attempter->RefreshDevicePolicy();
313 device_policy = self->system_state_->device_policy();
314 }
Darin Petkov8daa3242010-10-25 13:28:47 -0700315 }
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700316
317 bool delegated = false;
Chris Sosacb7fa882013-07-25 17:02:59 -0700318 if (device_policy &&
319 device_policy->GetReleaseChannelDelegated(&delegated) && !delegated) {
Don Garrettbb26fc82013-11-15 10:40:17 -0800320 log_and_set_response_error(
321 error, UPDATE_ENGINE_SERVICE_ERROR_FAILED,
322 "Cannot set target channel explicitly when channel "
323 "policy/settings is not delegated");
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700324 return FALSE;
325 }
326
327 LOG(INFO) << "Setting destination channel to: " << target_channel;
328 if (!self->system_state_->request_params()->SetTargetChannel(
329 target_channel, is_powerwash_allowed)) {
Don Garrettbb26fc82013-11-15 10:40:17 -0800330 // TODO(dgarrett): Give a more specific error code/reason.
331 log_and_set_response_error(error,
332 UPDATE_ENGINE_SERVICE_ERROR_FAILED,
333 "Setting channel failed.");
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700334 return FALSE;
335 }
336
337 return TRUE;
338}
339
340gboolean update_engine_service_get_channel(UpdateEngineService* self,
Alex Deymoad923732013-08-29 16:13:49 -0700341 gboolean get_current_channel,
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700342 gchar** channel,
343 GError **error) {
344 chromeos_update_engine::OmahaRequestParams* rp =
345 self->system_state_->request_params();
346
347 string channel_str = get_current_channel ?
348 rp->current_channel() : rp->target_channel();
349
350 *channel = g_strdup(channel_str.c_str());
Darin Petkov8daa3242010-10-25 13:28:47 -0700351 return TRUE;
352}
353
Alex Deymo5fdf7762013-07-17 20:01:40 -0700354gboolean update_engine_service_set_p2p_update_permission(
355 UpdateEngineService* self,
356 gboolean enabled,
357 GError **error) {
Gilad Arnold4a0321b2014-10-28 15:57:30 -0700358 chromeos_update_engine::PrefsInterface* prefs = self->system_state_->prefs();
Alex Deymo5fdf7762013-07-17 20:01:40 -0700359
Gilad Arnold4a0321b2014-10-28 15:57:30 -0700360 if (!prefs->SetBoolean(chromeos_update_engine::kPrefsP2PEnabled, enabled)) {
Don Garrettbb26fc82013-11-15 10:40:17 -0800361 log_and_set_response_error(
362 error, UPDATE_ENGINE_SERVICE_ERROR_FAILED,
Gilad Arnoldccd09572014-10-27 13:37:50 -0700363 StringPrintf("Error setting the update via p2p permission to %s.",
364 ToString(enabled).c_str()));
Alex Deymo5fdf7762013-07-17 20:01:40 -0700365 return FALSE;
366 }
367
Alex Deymo5fdf7762013-07-17 20:01:40 -0700368 return TRUE;
369}
370
371gboolean update_engine_service_get_p2p_update_permission(
372 UpdateEngineService* self,
373 gboolean* enabled,
374 GError **error) {
375 chromeos_update_engine::PrefsInterface* prefs = self->system_state_->prefs();
376
Gilad Arnold367a3ad2014-10-23 16:00:17 -0700377 bool p2p_pref = false; // Default if no setting is present.
378 if (prefs->Exists(chromeos_update_engine::kPrefsP2PEnabled) &&
379 !prefs->GetBoolean(chromeos_update_engine::kPrefsP2PEnabled, &p2p_pref)) {
Don Garrettbb26fc82013-11-15 10:40:17 -0800380 log_and_set_response_error(error, UPDATE_ENGINE_SERVICE_ERROR_FAILED,
381 "Error getting the P2PEnabled setting.");
Alex Deymo5fdf7762013-07-17 20:01:40 -0700382 return FALSE;
383 }
384
385 *enabled = p2p_pref;
386 return TRUE;
387}
388
Alex Deymof4867c42013-06-28 14:41:39 -0700389gboolean update_engine_service_set_update_over_cellular_permission(
390 UpdateEngineService* self,
Alex Deymoad923732013-08-29 16:13:49 -0700391 gboolean allowed,
Alex Deymof4867c42013-06-28 14:41:39 -0700392 GError **error) {
393 set<string> allowed_types;
394 const policy::DevicePolicy* device_policy =
395 self->system_state_->device_policy();
396
397 // The device_policy is loaded in a lazy way before an update check. Load it
398 // now from the libchromeos cache if it wasn't already loaded.
399 if (!device_policy) {
400 chromeos_update_engine::UpdateAttempter* update_attempter =
401 self->system_state_->update_attempter();
402 if (update_attempter) {
403 update_attempter->RefreshDevicePolicy();
Chris Sosacb7fa882013-07-25 17:02:59 -0700404 device_policy = self->system_state_->device_policy();
Alex Deymof4867c42013-06-28 14:41:39 -0700405 }
406 }
407
408 // Check if this setting is allowed by the device policy.
409 if (device_policy &&
410 device_policy->GetAllowedConnectionTypesForUpdate(&allowed_types)) {
Don Garrettbb26fc82013-11-15 10:40:17 -0800411 log_and_set_response_error(
412 error, UPDATE_ENGINE_SERVICE_ERROR_FAILED,
413 "Ignoring the update over cellular setting since there's "
414 "a device policy enforcing this setting.");
Alex Deymof4867c42013-06-28 14:41:39 -0700415 return FALSE;
416 }
417
418 // If the policy wasn't loaded yet, then it is still OK to change the local
419 // setting because the policy will be checked again during the update check.
420
421 chromeos_update_engine::PrefsInterface* prefs = self->system_state_->prefs();
422
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700423 if (!prefs->SetBoolean(
Alex Deymof4867c42013-06-28 14:41:39 -0700424 chromeos_update_engine::kPrefsUpdateOverCellularPermission,
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700425 allowed)) {
Don Garrettbb26fc82013-11-15 10:40:17 -0800426 log_and_set_response_error(
427 error, UPDATE_ENGINE_SERVICE_ERROR_FAILED,
428 string("Error setting the update over cellular to ") +
429 (allowed ? "true" : "false"));
Alex Deymof4867c42013-06-28 14:41:39 -0700430 return FALSE;
431 }
432
433 return TRUE;
434}
435
436gboolean update_engine_service_get_update_over_cellular_permission(
437 UpdateEngineService* self,
Alex Deymoad923732013-08-29 16:13:49 -0700438 gboolean* allowed,
Don Garrettbb26fc82013-11-15 10:40:17 -0800439 GError **error) {
Alex Deymof4867c42013-06-28 14:41:39 -0700440 chromeos_update_engine::ConnectionManager* cm =
441 self->system_state_->connection_manager();
442
443 // The device_policy is loaded in a lazy way before an update check and is
444 // used to determine if an update is allowed over cellular. Load the device
445 // policy now from the libchromeos cache if it wasn't already loaded.
446 if (!self->system_state_->device_policy()) {
447 chromeos_update_engine::UpdateAttempter* update_attempter =
448 self->system_state_->update_attempter();
449 if (update_attempter)
450 update_attempter->RefreshDevicePolicy();
451 }
452
453 // Return the current setting based on the same logic used while checking for
454 // updates. A log message could be printed as the result of this test.
455 LOG(INFO) << "Checking if updates over cellular networks are allowed:";
Alex Deymo6ae91202014-03-10 19:21:25 -0700456 *allowed = cm->IsUpdateAllowedOver(
457 chromeos_update_engine::kNetCellular,
458 chromeos_update_engine::NetworkTethering::kUnknown);
Alex Deymof4867c42013-06-28 14:41:39 -0700459
460 return TRUE;
461}
462
David Zeuthen3c55abd2013-10-14 12:48:03 -0700463gboolean update_engine_service_get_duration_since_update(
464 UpdateEngineService* self,
465 gint64* out_usec_wallclock,
Don Garrettbb26fc82013-11-15 10:40:17 -0800466 GError **error) {
David Zeuthen3c55abd2013-10-14 12:48:03 -0700467
468 base::Time time;
Don Garrettbb26fc82013-11-15 10:40:17 -0800469 if (!self->system_state_->update_attempter()->GetBootTimeAtUpdate(&time)) {
470 log_and_set_response_error(error, UPDATE_ENGINE_SERVICE_ERROR_FAILED,
471 "No pending update.");
David Zeuthen3c55abd2013-10-14 12:48:03 -0700472 return FALSE;
Don Garrettbb26fc82013-11-15 10:40:17 -0800473 }
David Zeuthen3c55abd2013-10-14 12:48:03 -0700474
475 chromeos_update_engine::ClockInterface *clock = self->system_state_->clock();
476 *out_usec_wallclock = (clock->GetBootTime() - time).InMicroseconds();
477 return TRUE;
478}
479
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700480gboolean update_engine_service_emit_status_update(
481 UpdateEngineService* self,
482 gint64 last_checked_time,
483 gdouble progress,
484 const gchar* current_operation,
485 const gchar* new_version,
486 gint64 new_size) {
487 g_signal_emit(self,
488 status_update_signal,
489 0,
490 last_checked_time,
491 progress,
492 current_operation,
493 new_version,
494 new_size);
495 return TRUE;
496}
Alex Vakulenkodea2eac2014-03-14 15:56:59 -0700497
498gboolean update_engine_service_get_prev_version(
499 UpdateEngineService* self,
500 gchar** prev_version,
501 GError **error) {
Alex Deymof329b932014-10-30 01:37:48 -0700502 string ver = self->system_state_->update_attempter()->GetPrevVersion();
Alex Vakulenkodea2eac2014-03-14 15:56:59 -0700503 *prev_version = g_strdup(ver.c_str());
504 return TRUE;
505}