blob: cf6bbaed607a89b4ad6740f32f195090c09ec6b6 [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
Alex Deymof4867c42013-06-28 14:41:39 -070013#include "update_engine/connection_manager.h"
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070014#include "update_engine/marshal.glibmarshal.h"
Darin Petkov49d91322010-10-25 16:34:58 -070015#include "update_engine/omaha_request_params.h"
Alex Deymof4867c42013-06-28 14:41:39 -070016#include "update_engine/update_attempter.h"
17#include "update_engine/prefs.h"
Darin Petkova07586b2010-10-20 13:41:15 -070018#include "update_engine/utils.h"
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070019
Alex Deymof4867c42013-06-28 14:41:39 -070020using std::set;
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070021using std::string;
22
Darin Petkov820a77b2011-04-27 16:48:58 -070023static const char kAUTestURLRequest[] = "autest";
Jay Srinivasane73acab2012-07-10 14:34:03 -070024// By default autest bypasses scattering. If we want to test scattering,
25// we should use autest-scheduled. The Url used is same in both cases, but
26// different params are passed to CheckForUpdate method.
27static const char kScheduledAUTestURLRequest[] = "autest-scheduled";
28
Darin Petkov820a77b2011-04-27 16:48:58 -070029static const char kAUTestURL[] =
Darin Petkov5445e162011-11-04 10:10:27 +010030 "https://omaha.sandbox.google.com/service/update2";
Darin Petkov820a77b2011-04-27 16:48:58 -070031
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070032G_DEFINE_TYPE(UpdateEngineService, update_engine_service, G_TYPE_OBJECT)
33
34static void update_engine_service_finalize(GObject* object) {
35 G_OBJECT_CLASS(update_engine_service_parent_class)->finalize(object);
36}
37
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070038static guint status_update_signal = 0;
39
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070040static void update_engine_service_class_init(UpdateEngineServiceClass* klass) {
41 GObjectClass *object_class;
42 object_class = G_OBJECT_CLASS(klass);
43 object_class->finalize = update_engine_service_finalize;
Darin Petkov5a7f5652010-07-22 21:40:09 -070044
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070045 status_update_signal = g_signal_new(
46 "status_update",
47 G_OBJECT_CLASS_TYPE(klass),
48 G_SIGNAL_RUN_LAST,
49 0, // 0 == no class method associated
50 NULL, // Accumulator
51 NULL, // Accumulator data
52 update_engine_VOID__INT64_DOUBLE_STRING_STRING_INT64,
53 G_TYPE_NONE, // Return type
54 5, // param count:
55 G_TYPE_INT64,
56 G_TYPE_DOUBLE,
57 G_TYPE_STRING,
58 G_TYPE_STRING,
59 G_TYPE_INT64);
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070060}
61
62static void update_engine_service_init(UpdateEngineService* object) {
63}
64
65UpdateEngineService* update_engine_service_new(void) {
66 return reinterpret_cast<UpdateEngineService*>(
67 g_object_new(UPDATE_ENGINE_TYPE_SERVICE, NULL));
68}
69
Darin Petkov296889c2010-07-23 16:20:54 -070070gboolean update_engine_service_attempt_update(UpdateEngineService* self,
71 gchar* app_version,
72 gchar* omaha_url,
73 GError **error) {
Darin Petkova07586b2010-10-20 13:41:15 -070074 string update_app_version;
75 string update_omaha_url;
Gilad Arnoldb92f0df2013-01-10 16:32:45 -080076 bool interactive = true;
Jay Srinivasane73acab2012-07-10 14:34:03 -070077
Darin Petkova07586b2010-10-20 13:41:15 -070078 // Only non-official (e.g., dev and test) builds can override the current
Darin Petkov820a77b2011-04-27 16:48:58 -070079 // version and update server URL over D-Bus. However, pointing to the
80 // hardcoded test update server URL is always allowed.
Darin Petkova07586b2010-10-20 13:41:15 -070081 if (!chromeos_update_engine::utils::IsOfficialBuild()) {
82 if (app_version) {
83 update_app_version = app_version;
84 }
85 if (omaha_url) {
86 update_omaha_url = omaha_url;
87 }
88 }
Jay Srinivasane73acab2012-07-10 14:34:03 -070089 if (omaha_url) {
90 if (strcmp(omaha_url, kScheduledAUTestURLRequest) == 0) {
91 update_omaha_url = kAUTestURL;
92 // pretend that it's not user-initiated even though it is,
93 // so as to test scattering logic, etc. which get kicked off
94 // only in scheduled update checks.
Gilad Arnoldb92f0df2013-01-10 16:32:45 -080095 interactive = false;
Jay Srinivasane73acab2012-07-10 14:34:03 -070096 } else if (strcmp(omaha_url, kAUTestURLRequest) == 0) {
97 update_omaha_url = kAUTestURL;
98 }
Darin Petkov820a77b2011-04-27 16:48:58 -070099 }
Darin Petkov296889c2010-07-23 16:20:54 -0700100 LOG(INFO) << "Attempt update: app_version=\"" << update_app_version << "\" "
Jay Srinivasane73acab2012-07-10 14:34:03 -0700101 << "omaha_url=\"" << update_omaha_url << "\" "
Gilad Arnoldb92f0df2013-01-10 16:32:45 -0800102 << "interactive=" << (interactive? "yes" : "no");
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700103 self->system_state_->update_attempter()->CheckForUpdate(update_app_version,
104 update_omaha_url,
105 interactive);
Darin Petkov296889c2010-07-23 16:20:54 -0700106 return TRUE;
107}
108
Chris Sosad317e402013-06-12 13:47:09 -0700109gboolean update_engine_service_attempt_rollback(UpdateEngineService* self,
110 bool powerwash,
111 GError **error) {
112 LOG(INFO) << "Attempting rollback to non-active partitions.";
Chris Sosa76a29ae2013-07-11 17:59:24 -0700113 return self->system_state_->update_attempter()->Rollback(powerwash, NULL);
Chris Sosad317e402013-06-12 13:47:09 -0700114}
115
Jay Srinivasanc1ba09a2012-08-14 14:15:57 -0700116gboolean update_engine_service_reset_status(UpdateEngineService* self,
117 GError **error) {
118 *error = NULL;
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700119 return self->system_state_->update_attempter()->ResetStatus();
Jay Srinivasanc1ba09a2012-08-14 14:15:57 -0700120}
121
122
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700123gboolean update_engine_service_get_status(UpdateEngineService* self,
124 int64_t* last_checked_time,
125 double* progress,
126 gchar** current_operation,
127 gchar** new_version,
128 int64_t* new_size,
129 GError **error) {
130 string current_op;
131 string new_version_str;
Darin Petkov5a7f5652010-07-22 21:40:09 -0700132
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700133 CHECK(self->system_state_->update_attempter()->GetStatus(last_checked_time,
134 progress,
135 &current_op,
136 &new_version_str,
137 new_size));
Darin Petkov5a7f5652010-07-22 21:40:09 -0700138
Satoru Takabayashid6982312010-11-29 12:54:12 +0900139 *current_operation = g_strdup(current_op.c_str());
140 *new_version = g_strdup(new_version_str.c_str());
Chris Masonec6c57a52010-09-23 13:06:14 -0700141 if (!(*current_operation && *new_version)) {
142 *error = NULL;
143 return FALSE;
144 }
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700145 return TRUE;
146}
147
Darin Petkov296889c2010-07-23 16:20:54 -0700148gboolean update_engine_service_reboot_if_needed(UpdateEngineService* self,
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700149 GError **error) {
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700150 if (!self->system_state_->update_attempter()->RebootIfNeeded()) {
Darin Petkov296889c2010-07-23 16:20:54 -0700151 *error = NULL;
152 return FALSE;
153 }
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700154 return TRUE;
155}
156
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700157gboolean update_engine_service_set_channel(UpdateEngineService* self,
158 gchar* target_channel,
159 bool is_powerwash_allowed,
160 GError **error) {
161 if (!target_channel)
162 return FALSE;
163
Jay Srinivasan1c0fe792013-03-28 16:45:25 -0700164 const policy::DevicePolicy* device_policy =
165 self->system_state_->device_policy();
Chris Sosacb7fa882013-07-25 17:02:59 -0700166
167 // The device_policy is loaded in a lazy way before an update check. Load it
168 // now from the libchromeos cache if it wasn't already loaded.
Jay Srinivasan1c0fe792013-03-28 16:45:25 -0700169 if (!device_policy) {
Chris Sosacb7fa882013-07-25 17:02:59 -0700170 chromeos_update_engine::UpdateAttempter* update_attempter =
171 self->system_state_->update_attempter();
172 if (update_attempter) {
173 update_attempter->RefreshDevicePolicy();
174 device_policy = self->system_state_->device_policy();
175 }
Darin Petkov8daa3242010-10-25 13:28:47 -0700176 }
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700177
178 bool delegated = false;
Chris Sosacb7fa882013-07-25 17:02:59 -0700179 if (device_policy &&
180 device_policy->GetReleaseChannelDelegated(&delegated) && !delegated) {
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700181 LOG(INFO) << "Cannot set target channel explicitly when channel "
182 "policy/settings is not delegated";
183 return FALSE;
184 }
185
186 LOG(INFO) << "Setting destination channel to: " << target_channel;
187 if (!self->system_state_->request_params()->SetTargetChannel(
188 target_channel, is_powerwash_allowed)) {
189 *error = NULL;
190 return FALSE;
191 }
192
193 return TRUE;
194}
195
196gboolean update_engine_service_get_channel(UpdateEngineService* self,
197 bool get_current_channel,
198 gchar** channel,
199 GError **error) {
200 chromeos_update_engine::OmahaRequestParams* rp =
201 self->system_state_->request_params();
202
203 string channel_str = get_current_channel ?
204 rp->current_channel() : rp->target_channel();
205
206 *channel = g_strdup(channel_str.c_str());
Darin Petkov8daa3242010-10-25 13:28:47 -0700207 return TRUE;
208}
209
Alex Deymof4867c42013-06-28 14:41:39 -0700210gboolean update_engine_service_set_update_over_cellular_permission(
211 UpdateEngineService* self,
212 bool allowed,
213 GError **error) {
214 set<string> allowed_types;
215 const policy::DevicePolicy* device_policy =
216 self->system_state_->device_policy();
217
218 // The device_policy is loaded in a lazy way before an update check. Load it
219 // now from the libchromeos cache if it wasn't already loaded.
220 if (!device_policy) {
221 chromeos_update_engine::UpdateAttempter* update_attempter =
222 self->system_state_->update_attempter();
223 if (update_attempter) {
224 update_attempter->RefreshDevicePolicy();
Chris Sosacb7fa882013-07-25 17:02:59 -0700225 device_policy = self->system_state_->device_policy();
Alex Deymof4867c42013-06-28 14:41:39 -0700226 }
227 }
228
229 // Check if this setting is allowed by the device policy.
230 if (device_policy &&
231 device_policy->GetAllowedConnectionTypesForUpdate(&allowed_types)) {
232 LOG(INFO) << "Ignoring the update over cellular setting since there's "
233 "a device policy enforcing this setting.";
234 *error = NULL;
235 return FALSE;
236 }
237
238 // If the policy wasn't loaded yet, then it is still OK to change the local
239 // setting because the policy will be checked again during the update check.
240
241 chromeos_update_engine::PrefsInterface* prefs = self->system_state_->prefs();
242
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700243 if (!prefs->SetBoolean(
Alex Deymof4867c42013-06-28 14:41:39 -0700244 chromeos_update_engine::kPrefsUpdateOverCellularPermission,
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700245 allowed)) {
Alex Deymof4867c42013-06-28 14:41:39 -0700246 LOG(ERROR) << "Error setting the update over cellular to "
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700247 << (allowed ? "true" : "false");
Alex Deymof4867c42013-06-28 14:41:39 -0700248 *error = NULL;
249 return FALSE;
250 }
251
252 return TRUE;
253}
254
255gboolean update_engine_service_get_update_over_cellular_permission(
256 UpdateEngineService* self,
257 bool* allowed,
258 GError **/*error*/) {
259 chromeos_update_engine::ConnectionManager* cm =
260 self->system_state_->connection_manager();
261
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
264 // policy now from the libchromeos cache if it wasn't already loaded.
265 if (!self->system_state_->device_policy()) {
266 chromeos_update_engine::UpdateAttempter* update_attempter =
267 self->system_state_->update_attempter();
268 if (update_attempter)
269 update_attempter->RefreshDevicePolicy();
270 }
271
272 // Return the current setting based on the same logic used while checking for
273 // updates. A log message could be printed as the result of this test.
274 LOG(INFO) << "Checking if updates over cellular networks are allowed:";
275 *allowed = cm->IsUpdateAllowedOver(chromeos_update_engine::kNetCellular);
276
277 return TRUE;
278}
279
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700280gboolean update_engine_service_emit_status_update(
281 UpdateEngineService* self,
282 gint64 last_checked_time,
283 gdouble progress,
284 const gchar* current_operation,
285 const gchar* new_version,
286 gint64 new_size) {
287 g_signal_emit(self,
288 status_update_signal,
289 0,
290 last_checked_time,
291 progress,
292 current_operation,
293 new_version,
294 new_size);
295 return TRUE;
296}