blob: 956b73bb4dd8f1fafc45f7af7ece846a88d12812 [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>
Jay Srinivasan1c0fe792013-03-28 16:45:25 -070011#include <policy/device_policy.h>
Darin Petkova07586b2010-10-20 13:41:15 -070012
David Zeuthen3c55abd2013-10-14 12:48:03 -070013#include "update_engine/clock_interface.h"
Alex Deymof4867c42013-06-28 14:41:39 -070014#include "update_engine/connection_manager.h"
David Zeuthen75a4c3e2013-09-06 11:36:59 -070015#include "update_engine/dbus_constants.h"
J. Richard Barnette056b0ab2013-10-29 15:24:56 -070016#include "update_engine/hardware_interface.h"
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070017#include "update_engine/marshal.glibmarshal.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
Darin Petkov820a77b2011-04-27 16:48:58 -070029static const char kAUTestURLRequest[] = "autest";
Jay Srinivasane73acab2012-07-10 14:34:03 -070030// By default autest bypasses scattering. If we want to test scattering,
31// we should use autest-scheduled. The Url used is same in both cases, but
32// different params are passed to CheckForUpdate method.
33static const char kScheduledAUTestURLRequest[] = "autest-scheduled";
34
Darin Petkov820a77b2011-04-27 16:48:58 -070035static const char kAUTestURL[] =
Darin Petkov5445e162011-11-04 10:10:27 +010036 "https://omaha.sandbox.google.com/service/update2";
Darin Petkov820a77b2011-04-27 16:48:58 -070037
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070038G_DEFINE_TYPE(UpdateEngineService, update_engine_service, G_TYPE_OBJECT)
39
40static void update_engine_service_finalize(GObject* object) {
41 G_OBJECT_CLASS(update_engine_service_parent_class)->finalize(object);
42}
43
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070044static guint status_update_signal = 0;
45
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070046static void update_engine_service_class_init(UpdateEngineServiceClass* klass) {
47 GObjectClass *object_class;
48 object_class = G_OBJECT_CLASS(klass);
49 object_class->finalize = update_engine_service_finalize;
Darin Petkov5a7f5652010-07-22 21:40:09 -070050
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070051 status_update_signal = g_signal_new(
52 "status_update",
53 G_OBJECT_CLASS_TYPE(klass),
54 G_SIGNAL_RUN_LAST,
55 0, // 0 == no class method associated
56 NULL, // Accumulator
57 NULL, // Accumulator data
58 update_engine_VOID__INT64_DOUBLE_STRING_STRING_INT64,
59 G_TYPE_NONE, // Return type
60 5, // param count:
61 G_TYPE_INT64,
62 G_TYPE_DOUBLE,
63 G_TYPE_STRING,
64 G_TYPE_STRING,
65 G_TYPE_INT64);
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070066}
67
68static void update_engine_service_init(UpdateEngineService* object) {
69}
70
71UpdateEngineService* update_engine_service_new(void) {
72 return reinterpret_cast<UpdateEngineService*>(
73 g_object_new(UPDATE_ENGINE_TYPE_SERVICE, NULL));
74}
75
Darin Petkov296889c2010-07-23 16:20:54 -070076gboolean update_engine_service_attempt_update(UpdateEngineService* self,
77 gchar* app_version,
78 gchar* omaha_url,
79 GError **error) {
David Zeuthen75a4c3e2013-09-06 11:36:59 -070080 return update_engine_service_attempt_update_with_flags(self,
81 app_version,
82 omaha_url,
83 0, // No flags set.
84 error);
85}
86
87gboolean update_engine_service_attempt_update_with_flags(
88 UpdateEngineService* self,
89 gchar* app_version,
90 gchar* omaha_url,
91 gint flags_as_int,
92 GError **error) {
Darin Petkova07586b2010-10-20 13:41:15 -070093 string update_app_version;
94 string update_omaha_url;
David Zeuthen75a4c3e2013-09-06 11:36:59 -070095 AttemptUpdateFlags flags = static_cast<AttemptUpdateFlags>(flags_as_int);
Gilad Arnoldb92f0df2013-01-10 16:32:45 -080096 bool interactive = true;
Jay Srinivasane73acab2012-07-10 14:34:03 -070097
Darin Petkova07586b2010-10-20 13:41:15 -070098 // Only non-official (e.g., dev and test) builds can override the current
Darin Petkov820a77b2011-04-27 16:48:58 -070099 // version and update server URL over D-Bus. However, pointing to the
100 // hardcoded test update server URL is always allowed.
J. Richard Barnette056b0ab2013-10-29 15:24:56 -0700101 if (!self->system_state_->hardware()->IsOfficialBuild()) {
Darin Petkova07586b2010-10-20 13:41:15 -0700102 if (app_version) {
103 update_app_version = app_version;
104 }
105 if (omaha_url) {
106 update_omaha_url = omaha_url;
107 }
108 }
Jay Srinivasane73acab2012-07-10 14:34:03 -0700109 if (omaha_url) {
110 if (strcmp(omaha_url, kScheduledAUTestURLRequest) == 0) {
111 update_omaha_url = kAUTestURL;
112 // pretend that it's not user-initiated even though it is,
113 // so as to test scattering logic, etc. which get kicked off
114 // only in scheduled update checks.
Gilad Arnoldb92f0df2013-01-10 16:32:45 -0800115 interactive = false;
Jay Srinivasane73acab2012-07-10 14:34:03 -0700116 } else if (strcmp(omaha_url, kAUTestURLRequest) == 0) {
117 update_omaha_url = kAUTestURL;
118 }
Darin Petkov820a77b2011-04-27 16:48:58 -0700119 }
David Zeuthen75a4c3e2013-09-06 11:36:59 -0700120 if (flags & kAttemptUpdateFlagNonInteractive)
121 interactive = false;
Darin Petkov296889c2010-07-23 16:20:54 -0700122 LOG(INFO) << "Attempt update: app_version=\"" << update_app_version << "\" "
Jay Srinivasane73acab2012-07-10 14:34:03 -0700123 << "omaha_url=\"" << update_omaha_url << "\" "
David Zeuthen75a4c3e2013-09-06 11:36:59 -0700124 << "flags=0x" << std::hex << flags << " "
Gilad Arnoldb92f0df2013-01-10 16:32:45 -0800125 << "interactive=" << (interactive? "yes" : "no");
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700126 self->system_state_->update_attempter()->CheckForUpdate(update_app_version,
127 update_omaha_url,
128 interactive);
Darin Petkov296889c2010-07-23 16:20:54 -0700129 return TRUE;
130}
131
Chris Sosad317e402013-06-12 13:47:09 -0700132gboolean update_engine_service_attempt_rollback(UpdateEngineService* self,
Alex Deymoad923732013-08-29 16:13:49 -0700133 gboolean powerwash,
Chris Sosad317e402013-06-12 13:47:09 -0700134 GError **error) {
135 LOG(INFO) << "Attempting rollback to non-active partitions.";
Chris Sosa76a29ae2013-07-11 17:59:24 -0700136 return self->system_state_->update_attempter()->Rollback(powerwash, NULL);
Chris Sosad317e402013-06-12 13:47:09 -0700137}
138
Jay Srinivasanc1ba09a2012-08-14 14:15:57 -0700139gboolean update_engine_service_reset_status(UpdateEngineService* self,
140 GError **error) {
141 *error = NULL;
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700142 return self->system_state_->update_attempter()->ResetStatus();
Jay Srinivasanc1ba09a2012-08-14 14:15:57 -0700143}
144
145
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700146gboolean update_engine_service_get_status(UpdateEngineService* self,
147 int64_t* last_checked_time,
148 double* progress,
149 gchar** current_operation,
150 gchar** new_version,
151 int64_t* new_size,
152 GError **error) {
153 string current_op;
154 string new_version_str;
Darin Petkov5a7f5652010-07-22 21:40:09 -0700155
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700156 CHECK(self->system_state_->update_attempter()->GetStatus(last_checked_time,
157 progress,
158 &current_op,
159 &new_version_str,
160 new_size));
Darin Petkov5a7f5652010-07-22 21:40:09 -0700161
Satoru Takabayashid6982312010-11-29 12:54:12 +0900162 *current_operation = g_strdup(current_op.c_str());
163 *new_version = g_strdup(new_version_str.c_str());
Chris Masonec6c57a52010-09-23 13:06:14 -0700164 if (!(*current_operation && *new_version)) {
165 *error = NULL;
166 return FALSE;
167 }
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700168 return TRUE;
169}
170
Darin Petkov296889c2010-07-23 16:20:54 -0700171gboolean update_engine_service_reboot_if_needed(UpdateEngineService* self,
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700172 GError **error) {
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700173 if (!self->system_state_->update_attempter()->RebootIfNeeded()) {
Darin Petkov296889c2010-07-23 16:20:54 -0700174 *error = NULL;
175 return FALSE;
176 }
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700177 return TRUE;
178}
179
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700180gboolean update_engine_service_set_channel(UpdateEngineService* self,
181 gchar* target_channel,
Alex Deymoad923732013-08-29 16:13:49 -0700182 gboolean is_powerwash_allowed,
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700183 GError **error) {
184 if (!target_channel)
185 return FALSE;
186
Jay Srinivasan1c0fe792013-03-28 16:45:25 -0700187 const policy::DevicePolicy* device_policy =
188 self->system_state_->device_policy();
Chris Sosacb7fa882013-07-25 17:02:59 -0700189
190 // The device_policy is loaded in a lazy way before an update check. Load it
191 // now from the libchromeos cache if it wasn't already loaded.
Jay Srinivasan1c0fe792013-03-28 16:45:25 -0700192 if (!device_policy) {
Chris Sosacb7fa882013-07-25 17:02:59 -0700193 chromeos_update_engine::UpdateAttempter* update_attempter =
194 self->system_state_->update_attempter();
195 if (update_attempter) {
196 update_attempter->RefreshDevicePolicy();
197 device_policy = self->system_state_->device_policy();
198 }
Darin Petkov8daa3242010-10-25 13:28:47 -0700199 }
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700200
201 bool delegated = false;
Chris Sosacb7fa882013-07-25 17:02:59 -0700202 if (device_policy &&
203 device_policy->GetReleaseChannelDelegated(&delegated) && !delegated) {
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700204 LOG(INFO) << "Cannot set target channel explicitly when channel "
205 "policy/settings is not delegated";
206 return FALSE;
207 }
208
209 LOG(INFO) << "Setting destination channel to: " << target_channel;
210 if (!self->system_state_->request_params()->SetTargetChannel(
211 target_channel, is_powerwash_allowed)) {
212 *error = NULL;
213 return FALSE;
214 }
215
216 return TRUE;
217}
218
219gboolean update_engine_service_get_channel(UpdateEngineService* self,
Alex Deymoad923732013-08-29 16:13:49 -0700220 gboolean get_current_channel,
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700221 gchar** channel,
222 GError **error) {
223 chromeos_update_engine::OmahaRequestParams* rp =
224 self->system_state_->request_params();
225
226 string channel_str = get_current_channel ?
227 rp->current_channel() : rp->target_channel();
228
229 *channel = g_strdup(channel_str.c_str());
Darin Petkov8daa3242010-10-25 13:28:47 -0700230 return TRUE;
231}
232
Alex Deymo5fdf7762013-07-17 20:01:40 -0700233gboolean update_engine_service_set_p2p_update_permission(
234 UpdateEngineService* self,
235 gboolean enabled,
236 GError **error) {
237 chromeos_update_engine::PrefsInterface* prefs = self->system_state_->prefs();
238 chromeos_update_engine::P2PManager* p2p_manager =
239 self->system_state_->p2p_manager();
240
241 bool p2p_was_enabled = p2p_manager && p2p_manager->IsP2PEnabled();
242
243 if (!prefs->SetBoolean(chromeos_update_engine::kPrefsP2PEnabled, enabled)) {
244 LOG(ERROR) << "Error setting the update over cellular to "
245 << (enabled ? "true" : "false");
246 *error = NULL;
247 return FALSE;
248 }
249
250 // If P2P is being effectively disabled (IsP2PEnabled() reports the change)
251 // then we need to shutdown the service.
252 if (p2p_was_enabled && !p2p_manager->IsP2PEnabled())
253 p2p_manager->EnsureP2PNotRunning();
254
255 return TRUE;
256}
257
258gboolean update_engine_service_get_p2p_update_permission(
259 UpdateEngineService* self,
260 gboolean* enabled,
261 GError **error) {
262 chromeos_update_engine::PrefsInterface* prefs = self->system_state_->prefs();
263
264 // The default for not present setting is false.
265 if (!prefs->Exists(chromeos_update_engine::kPrefsP2PEnabled)) {
266 *enabled = false;
267 return TRUE;
268 }
269
270 bool p2p_pref = false;
271 if (!prefs->GetBoolean(chromeos_update_engine::kPrefsP2PEnabled, &p2p_pref)) {
272 LOG(ERROR) << "Error getting the P2PEnabled setting.";
273 *error = NULL;
274 return FALSE;
275 }
276
277 *enabled = p2p_pref;
278 return TRUE;
279}
280
Alex Deymof4867c42013-06-28 14:41:39 -0700281gboolean update_engine_service_set_update_over_cellular_permission(
282 UpdateEngineService* self,
Alex Deymoad923732013-08-29 16:13:49 -0700283 gboolean allowed,
Alex Deymof4867c42013-06-28 14:41:39 -0700284 GError **error) {
285 set<string> allowed_types;
286 const policy::DevicePolicy* device_policy =
287 self->system_state_->device_policy();
288
289 // The device_policy is loaded in a lazy way before an update check. Load it
290 // now from the libchromeos cache if it wasn't already loaded.
291 if (!device_policy) {
292 chromeos_update_engine::UpdateAttempter* update_attempter =
293 self->system_state_->update_attempter();
294 if (update_attempter) {
295 update_attempter->RefreshDevicePolicy();
Chris Sosacb7fa882013-07-25 17:02:59 -0700296 device_policy = self->system_state_->device_policy();
Alex Deymof4867c42013-06-28 14:41:39 -0700297 }
298 }
299
300 // Check if this setting is allowed by the device policy.
301 if (device_policy &&
302 device_policy->GetAllowedConnectionTypesForUpdate(&allowed_types)) {
303 LOG(INFO) << "Ignoring the update over cellular setting since there's "
304 "a device policy enforcing this setting.";
305 *error = NULL;
306 return FALSE;
307 }
308
309 // If the policy wasn't loaded yet, then it is still OK to change the local
310 // setting because the policy will be checked again during the update check.
311
312 chromeos_update_engine::PrefsInterface* prefs = self->system_state_->prefs();
313
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700314 if (!prefs->SetBoolean(
Alex Deymof4867c42013-06-28 14:41:39 -0700315 chromeos_update_engine::kPrefsUpdateOverCellularPermission,
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700316 allowed)) {
Alex Deymof4867c42013-06-28 14:41:39 -0700317 LOG(ERROR) << "Error setting the update over cellular to "
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700318 << (allowed ? "true" : "false");
Alex Deymof4867c42013-06-28 14:41:39 -0700319 *error = NULL;
320 return FALSE;
321 }
322
323 return TRUE;
324}
325
326gboolean update_engine_service_get_update_over_cellular_permission(
327 UpdateEngineService* self,
Alex Deymoad923732013-08-29 16:13:49 -0700328 gboolean* allowed,
Alex Deymof4867c42013-06-28 14:41:39 -0700329 GError **/*error*/) {
330 chromeos_update_engine::ConnectionManager* cm =
331 self->system_state_->connection_manager();
332
333 // The device_policy is loaded in a lazy way before an update check and is
334 // used to determine if an update is allowed over cellular. Load the device
335 // policy now from the libchromeos cache if it wasn't already loaded.
336 if (!self->system_state_->device_policy()) {
337 chromeos_update_engine::UpdateAttempter* update_attempter =
338 self->system_state_->update_attempter();
339 if (update_attempter)
340 update_attempter->RefreshDevicePolicy();
341 }
342
343 // Return the current setting based on the same logic used while checking for
344 // updates. A log message could be printed as the result of this test.
345 LOG(INFO) << "Checking if updates over cellular networks are allowed:";
346 *allowed = cm->IsUpdateAllowedOver(chromeos_update_engine::kNetCellular);
347
348 return TRUE;
349}
350
David Zeuthen3c55abd2013-10-14 12:48:03 -0700351gboolean update_engine_service_get_duration_since_update(
352 UpdateEngineService* self,
353 gint64* out_usec_wallclock,
354 GError **/*error*/) {
355
356 base::Time time;
357 if (!self->system_state_->update_attempter()->GetBootTimeAtUpdate(&time))
358 return FALSE;
359
360 chromeos_update_engine::ClockInterface *clock = self->system_state_->clock();
361 *out_usec_wallclock = (clock->GetBootTime() - time).InMicroseconds();
362 return TRUE;
363}
364
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700365gboolean update_engine_service_emit_status_update(
366 UpdateEngineService* self,
367 gint64 last_checked_time,
368 gdouble progress,
369 const gchar* current_operation,
370 const gchar* new_version,
371 gint64 new_size) {
372 g_signal_emit(self,
373 status_update_signal,
374 0,
375 last_checked_time,
376 progress,
377 current_operation,
378 new_version,
379 new_size);
380 return TRUE;
381}