blob: e7b877d0a18d74c07655219e9fc4c489f097d942 [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>
Jay Srinivasan1c0fe792013-03-28 16:45:25 -070012#include <policy/device_policy.h>
Darin Petkova07586b2010-10-20 13:41:15 -070013
David Zeuthen3c55abd2013-10-14 12:48:03 -070014#include "update_engine/clock_interface.h"
Alex Deymof4867c42013-06-28 14:41:39 -070015#include "update_engine/connection_manager.h"
David Zeuthen75a4c3e2013-09-06 11:36:59 -070016#include "update_engine/dbus_constants.h"
J. Richard Barnette056b0ab2013-10-29 15:24:56 -070017#include "update_engine/hardware_interface.h"
Darin Petkov49d91322010-10-25 16:34:58 -070018#include "update_engine/omaha_request_params.h"
Alex Deymo5fdf7762013-07-17 20:01:40 -070019#include "update_engine/p2p_manager.h"
Alex Deymof4867c42013-06-28 14:41:39 -070020#include "update_engine/prefs.h"
J. Richard Barnette056b0ab2013-10-29 15:24:56 -070021#include "update_engine/update_attempter.h"
Darin Petkova07586b2010-10-20 13:41:15 -070022#include "update_engine/utils.h"
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070023
Alex Deymof4867c42013-06-28 14:41:39 -070024using std::set;
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070025using std::string;
David Zeuthen75a4c3e2013-09-06 11:36:59 -070026using chromeos_update_engine::AttemptUpdateFlags;
27using chromeos_update_engine::kAttemptUpdateFlagNonInteractive;
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070028
Don Garrettbb26fc82013-11-15 10:40:17 -080029#define UPDATE_ENGINE_SERVICE_ERROR update_engine_service_error_quark ()
30#define UPDATE_ENGINE_SERVICE_TYPE_ERROR \
31 (update_engine_service_error_get_type())
32
Alex Vakulenkod2779df2014-06-16 13:19:00 -070033enum UpdateEngineServiceError {
Don Garrettbb26fc82013-11-15 10:40:17 -080034 UPDATE_ENGINE_SERVICE_ERROR_FAILED,
35 UPDATE_ENGINE_SERVICE_NUM_ERRORS
Alex Vakulenkod2779df2014-06-16 13:19:00 -070036};
Don Garrettbb26fc82013-11-15 10:40:17 -080037
38static GQuark update_engine_service_error_quark(void) {
39 static GQuark ret = 0;
40
41 if (ret == 0)
42 ret = g_quark_from_static_string("update_engine_service_error");
43
44 return ret;
45}
46
47#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
48
49static GType update_engine_service_error_get_type(void) {
50 static GType etype = 0;
51
52 if (etype == 0) {
53 static const GEnumValue values[] = {
54 ENUM_ENTRY(UPDATE_ENGINE_SERVICE_ERROR_FAILED, "Failed"),
55 { 0, 0, 0 }
56 };
57 G_STATIC_ASSERT(UPDATE_ENGINE_SERVICE_NUM_ERRORS ==
Alex Vakulenkod2779df2014-06-16 13:19:00 -070058 G_N_ELEMENTS(values) - 1);
Don Garrettbb26fc82013-11-15 10:40:17 -080059 etype = g_enum_register_static("UpdateEngineServiceError", values);
60 }
61
62 return etype;
63}
64
Darin Petkov820a77b2011-04-27 16:48:58 -070065static const char kAUTestURLRequest[] = "autest";
Jay Srinivasane73acab2012-07-10 14:34:03 -070066// By default autest bypasses scattering. If we want to test scattering,
67// we should use autest-scheduled. The Url used is same in both cases, but
68// different params are passed to CheckForUpdate method.
69static const char kScheduledAUTestURLRequest[] = "autest-scheduled";
70
Darin Petkov820a77b2011-04-27 16:48:58 -070071static const char kAUTestURL[] =
Darin Petkov5445e162011-11-04 10:10:27 +010072 "https://omaha.sandbox.google.com/service/update2";
Darin Petkov820a77b2011-04-27 16:48:58 -070073
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070074G_DEFINE_TYPE(UpdateEngineService, update_engine_service, G_TYPE_OBJECT)
75
76static void update_engine_service_finalize(GObject* object) {
77 G_OBJECT_CLASS(update_engine_service_parent_class)->finalize(object);
78}
79
Don Garrettbb26fc82013-11-15 10:40:17 -080080static void log_and_set_response_error(GError** error,
81 UpdateEngineServiceError error_code,
82 const string& reason) {
83 LOG(ERROR) << "Sending DBus Failure: " << reason;
84 g_set_error_literal(error, UPDATE_ENGINE_SERVICE_ERROR,
85 error_code, reason.c_str());
86}
87
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070088static guint status_update_signal = 0;
89
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070090static void update_engine_service_class_init(UpdateEngineServiceClass* klass) {
91 GObjectClass *object_class;
92 object_class = G_OBJECT_CLASS(klass);
93 object_class->finalize = update_engine_service_finalize;
Darin Petkov5a7f5652010-07-22 21:40:09 -070094
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070095 status_update_signal = g_signal_new(
96 "status_update",
97 G_OBJECT_CLASS_TYPE(klass),
98 G_SIGNAL_RUN_LAST,
99 0, // 0 == no class method associated
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700100 nullptr, // Accumulator
101 nullptr, // Accumulator data
102 nullptr, // Marshaller
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700103 G_TYPE_NONE, // Return type
104 5, // param count:
105 G_TYPE_INT64,
106 G_TYPE_DOUBLE,
107 G_TYPE_STRING,
108 G_TYPE_STRING,
109 G_TYPE_INT64);
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700110}
111
112static void update_engine_service_init(UpdateEngineService* object) {
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700113 dbus_g_error_domain_register(UPDATE_ENGINE_SERVICE_ERROR,
114 "org.chromium.UpdateEngine.Error",
115 UPDATE_ENGINE_SERVICE_TYPE_ERROR);
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700116}
117
118UpdateEngineService* update_engine_service_new(void) {
119 return reinterpret_cast<UpdateEngineService*>(
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700120 g_object_new(UPDATE_ENGINE_TYPE_SERVICE, nullptr));
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700121}
122
Darin Petkov296889c2010-07-23 16:20:54 -0700123gboolean update_engine_service_attempt_update(UpdateEngineService* self,
124 gchar* app_version,
125 gchar* omaha_url,
126 GError **error) {
David Zeuthen75a4c3e2013-09-06 11:36:59 -0700127 return update_engine_service_attempt_update_with_flags(self,
128 app_version,
129 omaha_url,
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700130 0, // No flags set.
David Zeuthen75a4c3e2013-09-06 11:36:59 -0700131 error);
132}
133
134gboolean update_engine_service_attempt_update_with_flags(
135 UpdateEngineService* self,
136 gchar* app_version,
137 gchar* omaha_url,
138 gint flags_as_int,
139 GError **error) {
Darin Petkova07586b2010-10-20 13:41:15 -0700140 string update_app_version;
141 string update_omaha_url;
David Zeuthen75a4c3e2013-09-06 11:36:59 -0700142 AttemptUpdateFlags flags = static_cast<AttemptUpdateFlags>(flags_as_int);
Gilad Arnoldb92f0df2013-01-10 16:32:45 -0800143 bool interactive = true;
Jay Srinivasane73acab2012-07-10 14:34:03 -0700144
Darin Petkova07586b2010-10-20 13:41:15 -0700145 // Only non-official (e.g., dev and test) builds can override the current
Darin Petkov820a77b2011-04-27 16:48:58 -0700146 // version and update server URL over D-Bus. However, pointing to the
147 // hardcoded test update server URL is always allowed.
J. Richard Barnette056b0ab2013-10-29 15:24:56 -0700148 if (!self->system_state_->hardware()->IsOfficialBuild()) {
Darin Petkova07586b2010-10-20 13:41:15 -0700149 if (app_version) {
150 update_app_version = app_version;
151 }
152 if (omaha_url) {
153 update_omaha_url = omaha_url;
154 }
155 }
Jay Srinivasane73acab2012-07-10 14:34:03 -0700156 if (omaha_url) {
157 if (strcmp(omaha_url, kScheduledAUTestURLRequest) == 0) {
158 update_omaha_url = kAUTestURL;
159 // pretend that it's not user-initiated even though it is,
160 // so as to test scattering logic, etc. which get kicked off
161 // only in scheduled update checks.
Gilad Arnoldb92f0df2013-01-10 16:32:45 -0800162 interactive = false;
Jay Srinivasane73acab2012-07-10 14:34:03 -0700163 } else if (strcmp(omaha_url, kAUTestURLRequest) == 0) {
164 update_omaha_url = kAUTestURL;
165 }
Darin Petkov820a77b2011-04-27 16:48:58 -0700166 }
David Zeuthen75a4c3e2013-09-06 11:36:59 -0700167 if (flags & kAttemptUpdateFlagNonInteractive)
168 interactive = false;
Darin Petkov296889c2010-07-23 16:20:54 -0700169 LOG(INFO) << "Attempt update: app_version=\"" << update_app_version << "\" "
Jay Srinivasane73acab2012-07-10 14:34:03 -0700170 << "omaha_url=\"" << update_omaha_url << "\" "
David Zeuthen75a4c3e2013-09-06 11:36:59 -0700171 << "flags=0x" << std::hex << flags << " "
Gilad Arnoldb92f0df2013-01-10 16:32:45 -0800172 << "interactive=" << (interactive? "yes" : "no");
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700173 self->system_state_->update_attempter()->CheckForUpdate(update_app_version,
174 update_omaha_url,
175 interactive);
Darin Petkov296889c2010-07-23 16:20:54 -0700176 return TRUE;
177}
178
Chris Sosad317e402013-06-12 13:47:09 -0700179gboolean update_engine_service_attempt_rollback(UpdateEngineService* self,
Alex Deymoad923732013-08-29 16:13:49 -0700180 gboolean powerwash,
Chris Sosad317e402013-06-12 13:47:09 -0700181 GError **error) {
182 LOG(INFO) << "Attempting rollback to non-active partitions.";
Don Garrettbb26fc82013-11-15 10:40:17 -0800183
Chris Sosa44b9b7e2014-04-02 13:53:46 -0700184 if (!self->system_state_->update_attempter()->Rollback(powerwash)) {
Don Garrettbb26fc82013-11-15 10:40:17 -0800185 // TODO(dgarrett): Give a more specific error code/reason.
186 log_and_set_response_error(error,
187 UPDATE_ENGINE_SERVICE_ERROR_FAILED,
188 "Rollback attempt failed.");
189 return FALSE;
190 }
191
192 return TRUE;
Chris Sosad317e402013-06-12 13:47:09 -0700193}
194
Alex Vakulenko59e253e2014-02-24 10:40:21 -0800195gboolean update_engine_service_can_rollback(UpdateEngineService* self,
196 gboolean* out_can_rollback,
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700197 GError **error) {
Alex Vakulenko2bddadd2014-03-27 13:23:46 -0700198 bool can_rollback = self->system_state_->update_attempter()->CanRollback();
Chris Sosa44b9b7e2014-04-02 13:53:46 -0700199 LOG(INFO) << "Checking to see if we can rollback . Result: " << can_rollback;
Alex Vakulenko2bddadd2014-03-27 13:23:46 -0700200 *out_can_rollback = can_rollback;
201 return TRUE;
202}
203
204gboolean update_engine_service_get_rollback_partition(
205 UpdateEngineService* self,
206 gchar** out_rollback_partition_name,
207 GError **error) {
208 auto name = self->system_state_->update_attempter()->GetRollbackPartition();
209 LOG(INFO) << "Getting rollback partition name. Result: " << name;
210 *out_rollback_partition_name = g_strdup(name.c_str());
211 return TRUE;
212}
213
214gboolean update_engine_service_get_kernel_devices(UpdateEngineService* self,
215 gchar** out_kernel_devices,
216 GError **error) {
217 auto devices = self->system_state_->update_attempter()->GetKernelDevices();
218 std::string info;
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700219 for (const auto& device : devices) {
Alex Vakulenko2bddadd2014-03-27 13:23:46 -0700220 base::StringAppendF(&info, "%d:%s\n",
221 device.second ? 1 : 0, device.first.c_str());
222 }
223 LOG(INFO) << "Available kernel devices: " << info;
224 *out_kernel_devices = g_strdup(info.c_str());
Alex Vakulenko59e253e2014-02-24 10:40:21 -0800225 return TRUE;
226}
227
228
Jay Srinivasanc1ba09a2012-08-14 14:15:57 -0700229gboolean update_engine_service_reset_status(UpdateEngineService* self,
230 GError **error) {
Don Garrettbb26fc82013-11-15 10:40:17 -0800231 if (!self->system_state_->update_attempter()->ResetStatus()) {
232 // TODO(dgarrett): Give a more specific error code/reason.
233 log_and_set_response_error(error,
234 UPDATE_ENGINE_SERVICE_ERROR_FAILED,
235 "ResetStatus failed.");
236 return FALSE;
237 }
Jay Srinivasanc1ba09a2012-08-14 14:15:57 -0700238
Don Garrettbb26fc82013-11-15 10:40:17 -0800239 return TRUE;
240}
Jay Srinivasanc1ba09a2012-08-14 14:15:57 -0700241
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700242gboolean update_engine_service_get_status(UpdateEngineService* self,
243 int64_t* last_checked_time,
244 double* progress,
245 gchar** current_operation,
246 gchar** new_version,
247 int64_t* new_size,
248 GError **error) {
249 string current_op;
250 string new_version_str;
Darin Petkov5a7f5652010-07-22 21:40:09 -0700251
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700252 CHECK(self->system_state_->update_attempter()->GetStatus(last_checked_time,
253 progress,
254 &current_op,
255 &new_version_str,
256 new_size));
Satoru Takabayashid6982312010-11-29 12:54:12 +0900257 *current_operation = g_strdup(current_op.c_str());
258 *new_version = g_strdup(new_version_str.c_str());
Don Garrettbb26fc82013-11-15 10:40:17 -0800259
260 if (!*current_operation) {
261 log_and_set_response_error(error,
262 UPDATE_ENGINE_SERVICE_ERROR_FAILED,
263 "Unable to find current_operation.");
Chris Masonec6c57a52010-09-23 13:06:14 -0700264 return FALSE;
265 }
Don Garrettbb26fc82013-11-15 10:40:17 -0800266
267 if (!*new_version) {
268 log_and_set_response_error(error,
269 UPDATE_ENGINE_SERVICE_ERROR_FAILED,
270 "Unable to find vew_version.");
271 return FALSE;
272 }
273
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700274 return TRUE;
275}
276
Darin Petkov296889c2010-07-23 16:20:54 -0700277gboolean update_engine_service_reboot_if_needed(UpdateEngineService* self,
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700278 GError **error) {
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700279 if (!self->system_state_->update_attempter()->RebootIfNeeded()) {
Don Garrettbb26fc82013-11-15 10:40:17 -0800280 // TODO(dgarrett): Give a more specific error code/reason.
281 log_and_set_response_error(error,
282 UPDATE_ENGINE_SERVICE_ERROR_FAILED,
283 "Reboot not needed, or attempt failed.");
Darin Petkov296889c2010-07-23 16:20:54 -0700284 return FALSE;
285 }
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700286 return TRUE;
287}
288
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700289gboolean update_engine_service_set_channel(UpdateEngineService* self,
290 gchar* target_channel,
Alex Deymoad923732013-08-29 16:13:49 -0700291 gboolean is_powerwash_allowed,
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700292 GError **error) {
Don Garrettbb26fc82013-11-15 10:40:17 -0800293 if (!target_channel) {
294 log_and_set_response_error(error,
295 UPDATE_ENGINE_SERVICE_ERROR_FAILED,
296 "Target channel to set not specified.");
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700297 return FALSE;
Don Garrettbb26fc82013-11-15 10:40:17 -0800298 }
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700299
Jay Srinivasan1c0fe792013-03-28 16:45:25 -0700300 const policy::DevicePolicy* device_policy =
301 self->system_state_->device_policy();
Chris Sosacb7fa882013-07-25 17:02:59 -0700302
303 // The device_policy is loaded in a lazy way before an update check. Load it
304 // now from the libchromeos cache if it wasn't already loaded.
Jay Srinivasan1c0fe792013-03-28 16:45:25 -0700305 if (!device_policy) {
Chris Sosacb7fa882013-07-25 17:02:59 -0700306 chromeos_update_engine::UpdateAttempter* update_attempter =
307 self->system_state_->update_attempter();
308 if (update_attempter) {
309 update_attempter->RefreshDevicePolicy();
310 device_policy = self->system_state_->device_policy();
311 }
Darin Petkov8daa3242010-10-25 13:28:47 -0700312 }
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700313
314 bool delegated = false;
Chris Sosacb7fa882013-07-25 17:02:59 -0700315 if (device_policy &&
316 device_policy->GetReleaseChannelDelegated(&delegated) && !delegated) {
Don Garrettbb26fc82013-11-15 10:40:17 -0800317 log_and_set_response_error(
318 error, UPDATE_ENGINE_SERVICE_ERROR_FAILED,
319 "Cannot set target channel explicitly when channel "
320 "policy/settings is not delegated");
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700321 return FALSE;
322 }
323
324 LOG(INFO) << "Setting destination channel to: " << target_channel;
325 if (!self->system_state_->request_params()->SetTargetChannel(
326 target_channel, is_powerwash_allowed)) {
Don Garrettbb26fc82013-11-15 10:40:17 -0800327 // TODO(dgarrett): Give a more specific error code/reason.
328 log_and_set_response_error(error,
329 UPDATE_ENGINE_SERVICE_ERROR_FAILED,
330 "Setting channel failed.");
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700331 return FALSE;
332 }
333
334 return TRUE;
335}
336
337gboolean update_engine_service_get_channel(UpdateEngineService* self,
Alex Deymoad923732013-08-29 16:13:49 -0700338 gboolean get_current_channel,
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700339 gchar** channel,
340 GError **error) {
341 chromeos_update_engine::OmahaRequestParams* rp =
342 self->system_state_->request_params();
343
344 string channel_str = get_current_channel ?
345 rp->current_channel() : rp->target_channel();
346
347 *channel = g_strdup(channel_str.c_str());
Darin Petkov8daa3242010-10-25 13:28:47 -0700348 return TRUE;
349}
350
Alex Deymo5fdf7762013-07-17 20:01:40 -0700351gboolean update_engine_service_set_p2p_update_permission(
352 UpdateEngineService* self,
353 gboolean enabled,
354 GError **error) {
355 chromeos_update_engine::PrefsInterface* prefs = self->system_state_->prefs();
356 chromeos_update_engine::P2PManager* p2p_manager =
357 self->system_state_->p2p_manager();
358
359 bool p2p_was_enabled = p2p_manager && p2p_manager->IsP2PEnabled();
360
361 if (!prefs->SetBoolean(chromeos_update_engine::kPrefsP2PEnabled, enabled)) {
Don Garrettbb26fc82013-11-15 10:40:17 -0800362 log_and_set_response_error(
363 error, UPDATE_ENGINE_SERVICE_ERROR_FAILED,
364 string("Error setting the update over cellular to ") +
365 (enabled ? "true." : "false."));
Alex Deymo5fdf7762013-07-17 20:01:40 -0700366 return FALSE;
367 }
368
369 // If P2P is being effectively disabled (IsP2PEnabled() reports the change)
370 // then we need to shutdown the service.
371 if (p2p_was_enabled && !p2p_manager->IsP2PEnabled())
372 p2p_manager->EnsureP2PNotRunning();
373
374 return TRUE;
375}
376
377gboolean update_engine_service_get_p2p_update_permission(
378 UpdateEngineService* self,
379 gboolean* enabled,
380 GError **error) {
381 chromeos_update_engine::PrefsInterface* prefs = self->system_state_->prefs();
382
Gilad Arnold367a3ad2014-10-23 16:00:17 -0700383 bool p2p_pref = false; // Default if no setting is present.
384 if (prefs->Exists(chromeos_update_engine::kPrefsP2PEnabled) &&
385 !prefs->GetBoolean(chromeos_update_engine::kPrefsP2PEnabled, &p2p_pref)) {
Don Garrettbb26fc82013-11-15 10:40:17 -0800386 log_and_set_response_error(error, UPDATE_ENGINE_SERVICE_ERROR_FAILED,
387 "Error getting the P2PEnabled setting.");
Alex Deymo5fdf7762013-07-17 20:01:40 -0700388 return FALSE;
389 }
390
391 *enabled = p2p_pref;
392 return TRUE;
393}
394
Alex Deymof4867c42013-06-28 14:41:39 -0700395gboolean update_engine_service_set_update_over_cellular_permission(
396 UpdateEngineService* self,
Alex Deymoad923732013-08-29 16:13:49 -0700397 gboolean allowed,
Alex Deymof4867c42013-06-28 14:41:39 -0700398 GError **error) {
399 set<string> allowed_types;
400 const policy::DevicePolicy* device_policy =
401 self->system_state_->device_policy();
402
403 // The device_policy is loaded in a lazy way before an update check. Load it
404 // now from the libchromeos cache if it wasn't already loaded.
405 if (!device_policy) {
406 chromeos_update_engine::UpdateAttempter* update_attempter =
407 self->system_state_->update_attempter();
408 if (update_attempter) {
409 update_attempter->RefreshDevicePolicy();
Chris Sosacb7fa882013-07-25 17:02:59 -0700410 device_policy = self->system_state_->device_policy();
Alex Deymof4867c42013-06-28 14:41:39 -0700411 }
412 }
413
414 // Check if this setting is allowed by the device policy.
415 if (device_policy &&
416 device_policy->GetAllowedConnectionTypesForUpdate(&allowed_types)) {
Don Garrettbb26fc82013-11-15 10:40:17 -0800417 log_and_set_response_error(
418 error, UPDATE_ENGINE_SERVICE_ERROR_FAILED,
419 "Ignoring the update over cellular setting since there's "
420 "a device policy enforcing this setting.");
Alex Deymof4867c42013-06-28 14:41:39 -0700421 return FALSE;
422 }
423
424 // If the policy wasn't loaded yet, then it is still OK to change the local
425 // setting because the policy will be checked again during the update check.
426
427 chromeos_update_engine::PrefsInterface* prefs = self->system_state_->prefs();
428
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700429 if (!prefs->SetBoolean(
Alex Deymof4867c42013-06-28 14:41:39 -0700430 chromeos_update_engine::kPrefsUpdateOverCellularPermission,
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700431 allowed)) {
Don Garrettbb26fc82013-11-15 10:40:17 -0800432 log_and_set_response_error(
433 error, UPDATE_ENGINE_SERVICE_ERROR_FAILED,
434 string("Error setting the update over cellular to ") +
435 (allowed ? "true" : "false"));
Alex Deymof4867c42013-06-28 14:41:39 -0700436 return FALSE;
437 }
438
439 return TRUE;
440}
441
442gboolean update_engine_service_get_update_over_cellular_permission(
443 UpdateEngineService* self,
Alex Deymoad923732013-08-29 16:13:49 -0700444 gboolean* allowed,
Don Garrettbb26fc82013-11-15 10:40:17 -0800445 GError **error) {
Alex Deymof4867c42013-06-28 14:41:39 -0700446 chromeos_update_engine::ConnectionManager* cm =
447 self->system_state_->connection_manager();
448
449 // The device_policy is loaded in a lazy way before an update check and is
450 // used to determine if an update is allowed over cellular. Load the device
451 // policy now from the libchromeos cache if it wasn't already loaded.
452 if (!self->system_state_->device_policy()) {
453 chromeos_update_engine::UpdateAttempter* update_attempter =
454 self->system_state_->update_attempter();
455 if (update_attempter)
456 update_attempter->RefreshDevicePolicy();
457 }
458
459 // Return the current setting based on the same logic used while checking for
460 // updates. A log message could be printed as the result of this test.
461 LOG(INFO) << "Checking if updates over cellular networks are allowed:";
Alex Deymo6ae91202014-03-10 19:21:25 -0700462 *allowed = cm->IsUpdateAllowedOver(
463 chromeos_update_engine::kNetCellular,
464 chromeos_update_engine::NetworkTethering::kUnknown);
Alex Deymof4867c42013-06-28 14:41:39 -0700465
466 return TRUE;
467}
468
David Zeuthen3c55abd2013-10-14 12:48:03 -0700469gboolean update_engine_service_get_duration_since_update(
470 UpdateEngineService* self,
471 gint64* out_usec_wallclock,
Don Garrettbb26fc82013-11-15 10:40:17 -0800472 GError **error) {
David Zeuthen3c55abd2013-10-14 12:48:03 -0700473
474 base::Time time;
Don Garrettbb26fc82013-11-15 10:40:17 -0800475 if (!self->system_state_->update_attempter()->GetBootTimeAtUpdate(&time)) {
476 log_and_set_response_error(error, UPDATE_ENGINE_SERVICE_ERROR_FAILED,
477 "No pending update.");
David Zeuthen3c55abd2013-10-14 12:48:03 -0700478 return FALSE;
Don Garrettbb26fc82013-11-15 10:40:17 -0800479 }
David Zeuthen3c55abd2013-10-14 12:48:03 -0700480
481 chromeos_update_engine::ClockInterface *clock = self->system_state_->clock();
482 *out_usec_wallclock = (clock->GetBootTime() - time).InMicroseconds();
483 return TRUE;
484}
485
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700486gboolean update_engine_service_emit_status_update(
487 UpdateEngineService* self,
488 gint64 last_checked_time,
489 gdouble progress,
490 const gchar* current_operation,
491 const gchar* new_version,
492 gint64 new_size) {
493 g_signal_emit(self,
494 status_update_signal,
495 0,
496 last_checked_time,
497 progress,
498 current_operation,
499 new_version,
500 new_size);
501 return TRUE;
502}
Alex Vakulenkodea2eac2014-03-14 15:56:59 -0700503
504gboolean update_engine_service_get_prev_version(
505 UpdateEngineService* self,
506 gchar** prev_version,
507 GError **error) {
508 std::string ver = self->system_state_->update_attempter()->GetPrevVersion();
509 *prev_version = g_strdup(ver.c_str());
510 return TRUE;
511}