blob: 97ce2267c62991393c9d206b7a9a75f65e58cf52 [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 Deymo5fdf7762013-07-17 20:01:40 -070016#include "update_engine/p2p_manager.h"
Alex Deymof4867c42013-06-28 14:41:39 -070017#include "update_engine/update_attempter.h"
18#include "update_engine/prefs.h"
Darin Petkova07586b2010-10-20 13:41:15 -070019#include "update_engine/utils.h"
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070020
Alex Deymof4867c42013-06-28 14:41:39 -070021using std::set;
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070022using std::string;
23
Darin Petkov820a77b2011-04-27 16:48:58 -070024static const char kAUTestURLRequest[] = "autest";
Jay Srinivasane73acab2012-07-10 14:34:03 -070025// By default autest bypasses scattering. If we want to test scattering,
26// we should use autest-scheduled. The Url used is same in both cases, but
27// different params are passed to CheckForUpdate method.
28static const char kScheduledAUTestURLRequest[] = "autest-scheduled";
29
Darin Petkov820a77b2011-04-27 16:48:58 -070030static const char kAUTestURL[] =
Darin Petkov5445e162011-11-04 10:10:27 +010031 "https://omaha.sandbox.google.com/service/update2";
Darin Petkov820a77b2011-04-27 16:48:58 -070032
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070033G_DEFINE_TYPE(UpdateEngineService, update_engine_service, G_TYPE_OBJECT)
34
35static void update_engine_service_finalize(GObject* object) {
36 G_OBJECT_CLASS(update_engine_service_parent_class)->finalize(object);
37}
38
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070039static guint status_update_signal = 0;
40
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070041static void update_engine_service_class_init(UpdateEngineServiceClass* klass) {
42 GObjectClass *object_class;
43 object_class = G_OBJECT_CLASS(klass);
44 object_class->finalize = update_engine_service_finalize;
Darin Petkov5a7f5652010-07-22 21:40:09 -070045
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070046 status_update_signal = g_signal_new(
47 "status_update",
48 G_OBJECT_CLASS_TYPE(klass),
49 G_SIGNAL_RUN_LAST,
50 0, // 0 == no class method associated
51 NULL, // Accumulator
52 NULL, // Accumulator data
53 update_engine_VOID__INT64_DOUBLE_STRING_STRING_INT64,
54 G_TYPE_NONE, // Return type
55 5, // param count:
56 G_TYPE_INT64,
57 G_TYPE_DOUBLE,
58 G_TYPE_STRING,
59 G_TYPE_STRING,
60 G_TYPE_INT64);
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070061}
62
63static void update_engine_service_init(UpdateEngineService* object) {
64}
65
66UpdateEngineService* update_engine_service_new(void) {
67 return reinterpret_cast<UpdateEngineService*>(
68 g_object_new(UPDATE_ENGINE_TYPE_SERVICE, NULL));
69}
70
Darin Petkov296889c2010-07-23 16:20:54 -070071gboolean update_engine_service_attempt_update(UpdateEngineService* self,
72 gchar* app_version,
73 gchar* omaha_url,
74 GError **error) {
Darin Petkova07586b2010-10-20 13:41:15 -070075 string update_app_version;
76 string update_omaha_url;
Gilad Arnoldb92f0df2013-01-10 16:32:45 -080077 bool interactive = true;
Jay Srinivasane73acab2012-07-10 14:34:03 -070078
Darin Petkova07586b2010-10-20 13:41:15 -070079 // Only non-official (e.g., dev and test) builds can override the current
Darin Petkov820a77b2011-04-27 16:48:58 -070080 // version and update server URL over D-Bus. However, pointing to the
81 // hardcoded test update server URL is always allowed.
Darin Petkova07586b2010-10-20 13:41:15 -070082 if (!chromeos_update_engine::utils::IsOfficialBuild()) {
83 if (app_version) {
84 update_app_version = app_version;
85 }
86 if (omaha_url) {
87 update_omaha_url = omaha_url;
88 }
89 }
Jay Srinivasane73acab2012-07-10 14:34:03 -070090 if (omaha_url) {
91 if (strcmp(omaha_url, kScheduledAUTestURLRequest) == 0) {
92 update_omaha_url = kAUTestURL;
93 // pretend that it's not user-initiated even though it is,
94 // so as to test scattering logic, etc. which get kicked off
95 // only in scheduled update checks.
Gilad Arnoldb92f0df2013-01-10 16:32:45 -080096 interactive = false;
Jay Srinivasane73acab2012-07-10 14:34:03 -070097 } else if (strcmp(omaha_url, kAUTestURLRequest) == 0) {
98 update_omaha_url = kAUTestURL;
99 }
Darin Petkov820a77b2011-04-27 16:48:58 -0700100 }
Darin Petkov296889c2010-07-23 16:20:54 -0700101 LOG(INFO) << "Attempt update: app_version=\"" << update_app_version << "\" "
Jay Srinivasane73acab2012-07-10 14:34:03 -0700102 << "omaha_url=\"" << update_omaha_url << "\" "
Gilad Arnoldb92f0df2013-01-10 16:32:45 -0800103 << "interactive=" << (interactive? "yes" : "no");
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700104 self->system_state_->update_attempter()->CheckForUpdate(update_app_version,
105 update_omaha_url,
106 interactive);
Darin Petkov296889c2010-07-23 16:20:54 -0700107 return TRUE;
108}
109
Chris Sosad317e402013-06-12 13:47:09 -0700110gboolean update_engine_service_attempt_rollback(UpdateEngineService* self,
Alex Deymoad923732013-08-29 16:13:49 -0700111 gboolean powerwash,
Chris Sosad317e402013-06-12 13:47:09 -0700112 GError **error) {
113 LOG(INFO) << "Attempting rollback to non-active partitions.";
Chris Sosa76a29ae2013-07-11 17:59:24 -0700114 return self->system_state_->update_attempter()->Rollback(powerwash, NULL);
Chris Sosad317e402013-06-12 13:47:09 -0700115}
116
Jay Srinivasanc1ba09a2012-08-14 14:15:57 -0700117gboolean update_engine_service_reset_status(UpdateEngineService* self,
118 GError **error) {
119 *error = NULL;
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700120 return self->system_state_->update_attempter()->ResetStatus();
Jay Srinivasanc1ba09a2012-08-14 14:15:57 -0700121}
122
123
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700124gboolean update_engine_service_get_status(UpdateEngineService* self,
125 int64_t* last_checked_time,
126 double* progress,
127 gchar** current_operation,
128 gchar** new_version,
129 int64_t* new_size,
130 GError **error) {
131 string current_op;
132 string new_version_str;
Darin Petkov5a7f5652010-07-22 21:40:09 -0700133
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700134 CHECK(self->system_state_->update_attempter()->GetStatus(last_checked_time,
135 progress,
136 &current_op,
137 &new_version_str,
138 new_size));
Darin Petkov5a7f5652010-07-22 21:40:09 -0700139
Satoru Takabayashid6982312010-11-29 12:54:12 +0900140 *current_operation = g_strdup(current_op.c_str());
141 *new_version = g_strdup(new_version_str.c_str());
Chris Masonec6c57a52010-09-23 13:06:14 -0700142 if (!(*current_operation && *new_version)) {
143 *error = NULL;
144 return FALSE;
145 }
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700146 return TRUE;
147}
148
Darin Petkov296889c2010-07-23 16:20:54 -0700149gboolean update_engine_service_reboot_if_needed(UpdateEngineService* self,
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700150 GError **error) {
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700151 if (!self->system_state_->update_attempter()->RebootIfNeeded()) {
Darin Petkov296889c2010-07-23 16:20:54 -0700152 *error = NULL;
153 return FALSE;
154 }
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700155 return TRUE;
156}
157
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700158gboolean update_engine_service_set_channel(UpdateEngineService* self,
159 gchar* target_channel,
Alex Deymoad923732013-08-29 16:13:49 -0700160 gboolean is_powerwash_allowed,
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700161 GError **error) {
162 if (!target_channel)
163 return FALSE;
164
Jay Srinivasan1c0fe792013-03-28 16:45:25 -0700165 const policy::DevicePolicy* device_policy =
166 self->system_state_->device_policy();
Chris Sosacb7fa882013-07-25 17:02:59 -0700167
168 // The device_policy is loaded in a lazy way before an update check. Load it
169 // now from the libchromeos cache if it wasn't already loaded.
Jay Srinivasan1c0fe792013-03-28 16:45:25 -0700170 if (!device_policy) {
Chris Sosacb7fa882013-07-25 17:02:59 -0700171 chromeos_update_engine::UpdateAttempter* update_attempter =
172 self->system_state_->update_attempter();
173 if (update_attempter) {
174 update_attempter->RefreshDevicePolicy();
175 device_policy = self->system_state_->device_policy();
176 }
Darin Petkov8daa3242010-10-25 13:28:47 -0700177 }
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700178
179 bool delegated = false;
Chris Sosacb7fa882013-07-25 17:02:59 -0700180 if (device_policy &&
181 device_policy->GetReleaseChannelDelegated(&delegated) && !delegated) {
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700182 LOG(INFO) << "Cannot set target channel explicitly when channel "
183 "policy/settings is not delegated";
184 return FALSE;
185 }
186
187 LOG(INFO) << "Setting destination channel to: " << target_channel;
188 if (!self->system_state_->request_params()->SetTargetChannel(
189 target_channel, is_powerwash_allowed)) {
190 *error = NULL;
191 return FALSE;
192 }
193
194 return TRUE;
195}
196
197gboolean update_engine_service_get_channel(UpdateEngineService* self,
Alex Deymoad923732013-08-29 16:13:49 -0700198 gboolean get_current_channel,
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700199 gchar** channel,
200 GError **error) {
201 chromeos_update_engine::OmahaRequestParams* rp =
202 self->system_state_->request_params();
203
204 string channel_str = get_current_channel ?
205 rp->current_channel() : rp->target_channel();
206
207 *channel = g_strdup(channel_str.c_str());
Darin Petkov8daa3242010-10-25 13:28:47 -0700208 return TRUE;
209}
210
Alex Deymo5fdf7762013-07-17 20:01:40 -0700211gboolean update_engine_service_set_p2p_update_permission(
212 UpdateEngineService* self,
213 gboolean enabled,
214 GError **error) {
215 chromeos_update_engine::PrefsInterface* prefs = self->system_state_->prefs();
216 chromeos_update_engine::P2PManager* p2p_manager =
217 self->system_state_->p2p_manager();
218
219 bool p2p_was_enabled = p2p_manager && p2p_manager->IsP2PEnabled();
220
221 if (!prefs->SetBoolean(chromeos_update_engine::kPrefsP2PEnabled, enabled)) {
222 LOG(ERROR) << "Error setting the update over cellular to "
223 << (enabled ? "true" : "false");
224 *error = NULL;
225 return FALSE;
226 }
227
228 // If P2P is being effectively disabled (IsP2PEnabled() reports the change)
229 // then we need to shutdown the service.
230 if (p2p_was_enabled && !p2p_manager->IsP2PEnabled())
231 p2p_manager->EnsureP2PNotRunning();
232
233 return TRUE;
234}
235
236gboolean update_engine_service_get_p2p_update_permission(
237 UpdateEngineService* self,
238 gboolean* enabled,
239 GError **error) {
240 chromeos_update_engine::PrefsInterface* prefs = self->system_state_->prefs();
241
242 // The default for not present setting is false.
243 if (!prefs->Exists(chromeos_update_engine::kPrefsP2PEnabled)) {
244 *enabled = false;
245 return TRUE;
246 }
247
248 bool p2p_pref = false;
249 if (!prefs->GetBoolean(chromeos_update_engine::kPrefsP2PEnabled, &p2p_pref)) {
250 LOG(ERROR) << "Error getting the P2PEnabled setting.";
251 *error = NULL;
252 return FALSE;
253 }
254
255 *enabled = p2p_pref;
256 return TRUE;
257}
258
Alex Deymof4867c42013-06-28 14:41:39 -0700259gboolean update_engine_service_set_update_over_cellular_permission(
260 UpdateEngineService* self,
Alex Deymoad923732013-08-29 16:13:49 -0700261 gboolean allowed,
Alex Deymof4867c42013-06-28 14:41:39 -0700262 GError **error) {
263 set<string> allowed_types;
264 const policy::DevicePolicy* device_policy =
265 self->system_state_->device_policy();
266
267 // The device_policy is loaded in a lazy way before an update check. Load it
268 // now from the libchromeos cache if it wasn't already loaded.
269 if (!device_policy) {
270 chromeos_update_engine::UpdateAttempter* update_attempter =
271 self->system_state_->update_attempter();
272 if (update_attempter) {
273 update_attempter->RefreshDevicePolicy();
Chris Sosacb7fa882013-07-25 17:02:59 -0700274 device_policy = self->system_state_->device_policy();
Alex Deymof4867c42013-06-28 14:41:39 -0700275 }
276 }
277
278 // Check if this setting is allowed by the device policy.
279 if (device_policy &&
280 device_policy->GetAllowedConnectionTypesForUpdate(&allowed_types)) {
281 LOG(INFO) << "Ignoring the update over cellular setting since there's "
282 "a device policy enforcing this setting.";
283 *error = NULL;
284 return FALSE;
285 }
286
287 // If the policy wasn't loaded yet, then it is still OK to change the local
288 // setting because the policy will be checked again during the update check.
289
290 chromeos_update_engine::PrefsInterface* prefs = self->system_state_->prefs();
291
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700292 if (!prefs->SetBoolean(
Alex Deymof4867c42013-06-28 14:41:39 -0700293 chromeos_update_engine::kPrefsUpdateOverCellularPermission,
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700294 allowed)) {
Alex Deymof4867c42013-06-28 14:41:39 -0700295 LOG(ERROR) << "Error setting the update over cellular to "
Alex Deymoefb7c4c2013-07-09 14:34:00 -0700296 << (allowed ? "true" : "false");
Alex Deymof4867c42013-06-28 14:41:39 -0700297 *error = NULL;
298 return FALSE;
299 }
300
301 return TRUE;
302}
303
304gboolean update_engine_service_get_update_over_cellular_permission(
305 UpdateEngineService* self,
Alex Deymoad923732013-08-29 16:13:49 -0700306 gboolean* allowed,
Alex Deymof4867c42013-06-28 14:41:39 -0700307 GError **/*error*/) {
308 chromeos_update_engine::ConnectionManager* cm =
309 self->system_state_->connection_manager();
310
311 // The device_policy is loaded in a lazy way before an update check and is
312 // used to determine if an update is allowed over cellular. Load the device
313 // policy now from the libchromeos cache if it wasn't already loaded.
314 if (!self->system_state_->device_policy()) {
315 chromeos_update_engine::UpdateAttempter* update_attempter =
316 self->system_state_->update_attempter();
317 if (update_attempter)
318 update_attempter->RefreshDevicePolicy();
319 }
320
321 // Return the current setting based on the same logic used while checking for
322 // updates. A log message could be printed as the result of this test.
323 LOG(INFO) << "Checking if updates over cellular networks are allowed:";
324 *allowed = cm->IsUpdateAllowedOver(chromeos_update_engine::kNetCellular);
325
326 return TRUE;
327}
328
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700329gboolean update_engine_service_emit_status_update(
330 UpdateEngineService* self,
331 gint64 last_checked_time,
332 gdouble progress,
333 const gchar* current_operation,
334 const gchar* new_version,
335 gint64 new_size) {
336 g_signal_emit(self,
337 status_update_signal,
338 0,
339 last_checked_time,
340 progress,
341 current_operation,
342 new_version,
343 new_size);
344 return TRUE;
345}