blob: e75b2b2a56cf087a58fe129dc654c67b6fe3a2e6 [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
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -07007#include <string>
Darin Petkova07586b2010-10-20 13:41:15 -07008
9#include <base/logging.h>
Jay Srinivasan1c0fe792013-03-28 16:45:25 -070010#include <policy/device_policy.h>
Darin Petkova07586b2010-10-20 13:41:15 -070011
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070012#include "update_engine/marshal.glibmarshal.h"
Darin Petkov49d91322010-10-25 16:34:58 -070013#include "update_engine/omaha_request_params.h"
Darin Petkova07586b2010-10-20 13:41:15 -070014#include "update_engine/utils.h"
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070015
16using std::string;
17
Darin Petkov820a77b2011-04-27 16:48:58 -070018static const char kAUTestURLRequest[] = "autest";
Jay Srinivasane73acab2012-07-10 14:34:03 -070019// By default autest bypasses scattering. If we want to test scattering,
20// we should use autest-scheduled. The Url used is same in both cases, but
21// different params are passed to CheckForUpdate method.
22static const char kScheduledAUTestURLRequest[] = "autest-scheduled";
23
Darin Petkov820a77b2011-04-27 16:48:58 -070024static const char kAUTestURL[] =
Darin Petkov5445e162011-11-04 10:10:27 +010025 "https://omaha.sandbox.google.com/service/update2";
Darin Petkov820a77b2011-04-27 16:48:58 -070026
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070027G_DEFINE_TYPE(UpdateEngineService, update_engine_service, G_TYPE_OBJECT)
28
29static void update_engine_service_finalize(GObject* object) {
30 G_OBJECT_CLASS(update_engine_service_parent_class)->finalize(object);
31}
32
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070033static guint status_update_signal = 0;
34
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070035static void update_engine_service_class_init(UpdateEngineServiceClass* klass) {
36 GObjectClass *object_class;
37 object_class = G_OBJECT_CLASS(klass);
38 object_class->finalize = update_engine_service_finalize;
Darin Petkov5a7f5652010-07-22 21:40:09 -070039
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070040 status_update_signal = g_signal_new(
41 "status_update",
42 G_OBJECT_CLASS_TYPE(klass),
43 G_SIGNAL_RUN_LAST,
44 0, // 0 == no class method associated
45 NULL, // Accumulator
46 NULL, // Accumulator data
47 update_engine_VOID__INT64_DOUBLE_STRING_STRING_INT64,
48 G_TYPE_NONE, // Return type
49 5, // param count:
50 G_TYPE_INT64,
51 G_TYPE_DOUBLE,
52 G_TYPE_STRING,
53 G_TYPE_STRING,
54 G_TYPE_INT64);
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070055}
56
57static void update_engine_service_init(UpdateEngineService* object) {
58}
59
60UpdateEngineService* update_engine_service_new(void) {
61 return reinterpret_cast<UpdateEngineService*>(
62 g_object_new(UPDATE_ENGINE_TYPE_SERVICE, NULL));
63}
64
Darin Petkov296889c2010-07-23 16:20:54 -070065gboolean update_engine_service_attempt_update(UpdateEngineService* self,
66 gchar* app_version,
67 gchar* omaha_url,
68 GError **error) {
Darin Petkova07586b2010-10-20 13:41:15 -070069 string update_app_version;
70 string update_omaha_url;
Gilad Arnoldb92f0df2013-01-10 16:32:45 -080071 bool interactive = true;
Jay Srinivasane73acab2012-07-10 14:34:03 -070072
Darin Petkova07586b2010-10-20 13:41:15 -070073 // Only non-official (e.g., dev and test) builds can override the current
Darin Petkov820a77b2011-04-27 16:48:58 -070074 // version and update server URL over D-Bus. However, pointing to the
75 // hardcoded test update server URL is always allowed.
Darin Petkova07586b2010-10-20 13:41:15 -070076 if (!chromeos_update_engine::utils::IsOfficialBuild()) {
77 if (app_version) {
78 update_app_version = app_version;
79 }
80 if (omaha_url) {
81 update_omaha_url = omaha_url;
82 }
83 }
Jay Srinivasane73acab2012-07-10 14:34:03 -070084 if (omaha_url) {
85 if (strcmp(omaha_url, kScheduledAUTestURLRequest) == 0) {
86 update_omaha_url = kAUTestURL;
87 // pretend that it's not user-initiated even though it is,
88 // so as to test scattering logic, etc. which get kicked off
89 // only in scheduled update checks.
Gilad Arnoldb92f0df2013-01-10 16:32:45 -080090 interactive = false;
Jay Srinivasane73acab2012-07-10 14:34:03 -070091 } else if (strcmp(omaha_url, kAUTestURLRequest) == 0) {
92 update_omaha_url = kAUTestURL;
93 }
Darin Petkov820a77b2011-04-27 16:48:58 -070094 }
Darin Petkov296889c2010-07-23 16:20:54 -070095 LOG(INFO) << "Attempt update: app_version=\"" << update_app_version << "\" "
Jay Srinivasane73acab2012-07-10 14:34:03 -070096 << "omaha_url=\"" << update_omaha_url << "\" "
Gilad Arnoldb92f0df2013-01-10 16:32:45 -080097 << "interactive=" << (interactive? "yes" : "no");
Jay Srinivasanae4697c2013-03-18 17:08:08 -070098 self->system_state_->update_attempter()->CheckForUpdate(update_app_version,
99 update_omaha_url,
100 interactive);
Darin Petkov296889c2010-07-23 16:20:54 -0700101 return TRUE;
102}
103
Chris Sosad317e402013-06-12 13:47:09 -0700104gboolean update_engine_service_attempt_rollback(UpdateEngineService* self,
105 bool powerwash,
106 GError **error) {
107 LOG(INFO) << "Attempting rollback to non-active partitions.";
Chris Sosaaa18e162013-06-20 13:20:30 -0700108 return self->system_state_->update_attempter()->Rollback(powerwash);
Chris Sosad317e402013-06-12 13:47:09 -0700109}
110
Jay Srinivasanc1ba09a2012-08-14 14:15:57 -0700111gboolean update_engine_service_reset_status(UpdateEngineService* self,
112 GError **error) {
113 *error = NULL;
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700114 return self->system_state_->update_attempter()->ResetStatus();
Jay Srinivasanc1ba09a2012-08-14 14:15:57 -0700115}
116
117
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700118gboolean update_engine_service_get_status(UpdateEngineService* self,
119 int64_t* last_checked_time,
120 double* progress,
121 gchar** current_operation,
122 gchar** new_version,
123 int64_t* new_size,
124 GError **error) {
125 string current_op;
126 string new_version_str;
Darin Petkov5a7f5652010-07-22 21:40:09 -0700127
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700128 CHECK(self->system_state_->update_attempter()->GetStatus(last_checked_time,
129 progress,
130 &current_op,
131 &new_version_str,
132 new_size));
Darin Petkov5a7f5652010-07-22 21:40:09 -0700133
Satoru Takabayashid6982312010-11-29 12:54:12 +0900134 *current_operation = g_strdup(current_op.c_str());
135 *new_version = g_strdup(new_version_str.c_str());
Chris Masonec6c57a52010-09-23 13:06:14 -0700136 if (!(*current_operation && *new_version)) {
137 *error = NULL;
138 return FALSE;
139 }
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700140 return TRUE;
141}
142
Darin Petkov296889c2010-07-23 16:20:54 -0700143gboolean update_engine_service_reboot_if_needed(UpdateEngineService* self,
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700144 GError **error) {
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700145 if (!self->system_state_->update_attempter()->RebootIfNeeded()) {
Darin Petkov296889c2010-07-23 16:20:54 -0700146 *error = NULL;
147 return FALSE;
148 }
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700149 return TRUE;
150}
151
Darin Petkov8daa3242010-10-25 13:28:47 -0700152gboolean update_engine_service_set_track(UpdateEngineService* self,
153 gchar* track,
154 GError **error) {
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700155 // track == target channel.
Jay Srinivasan1c0fe792013-03-28 16:45:25 -0700156 // TODO(jaysri): Remove this method once chromium:219292 is fixed.
157 // Since UI won't be ready for now, preserve the existing
158 // behavior for set_track by calling SetTargetChannel directly without the
159 // policy checks instead of calling update_engine_service_set_channel.
160 LOG(INFO) << "Setting destination track to: " << track;
161 if (!self->system_state_->request_params()->SetTargetChannel(track, false)) {
162 *error = NULL;
163 return FALSE;
164 }
165
166 return TRUE;
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700167}
168
169gboolean update_engine_service_get_track(UpdateEngineService* self,
170 gchar** track,
171 GError **error) {
172 // track == target channel.
173 return update_engine_service_get_channel(self, false, track, error);
174}
175
176gboolean update_engine_service_set_channel(UpdateEngineService* self,
177 gchar* target_channel,
178 bool is_powerwash_allowed,
179 GError **error) {
180 if (!target_channel)
181 return FALSE;
182
Jay Srinivasan1c0fe792013-03-28 16:45:25 -0700183 const policy::DevicePolicy* device_policy =
184 self->system_state_->device_policy();
185 if (!device_policy) {
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700186 LOG(INFO) << "Cannot set target channel until device policy/settings are "
187 "known";
188 return FALSE;
Darin Petkov8daa3242010-10-25 13:28:47 -0700189 }
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700190
191 bool delegated = false;
Chris Sosa1ed60782013-06-18 17:05:33 -0700192 if (device_policy->GetReleaseChannelDelegated(&delegated) && !delegated) {
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700193 LOG(INFO) << "Cannot set target channel explicitly when channel "
194 "policy/settings is not delegated";
195 return FALSE;
196 }
197
198 LOG(INFO) << "Setting destination channel to: " << target_channel;
199 if (!self->system_state_->request_params()->SetTargetChannel(
200 target_channel, is_powerwash_allowed)) {
201 *error = NULL;
202 return FALSE;
203 }
204
205 return TRUE;
206}
207
208gboolean update_engine_service_get_channel(UpdateEngineService* self,
209 bool get_current_channel,
210 gchar** channel,
211 GError **error) {
212 chromeos_update_engine::OmahaRequestParams* rp =
213 self->system_state_->request_params();
214
215 string channel_str = get_current_channel ?
216 rp->current_channel() : rp->target_channel();
217
218 *channel = g_strdup(channel_str.c_str());
Darin Petkov8daa3242010-10-25 13:28:47 -0700219 return TRUE;
220}
221
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700222gboolean update_engine_service_emit_status_update(
223 UpdateEngineService* self,
224 gint64 last_checked_time,
225 gdouble progress,
226 const gchar* current_operation,
227 const gchar* new_version,
228 gint64 new_size) {
229 g_signal_emit(self,
230 status_update_signal,
231 0,
232 last_checked_time,
233 progress,
234 current_operation,
235 new_version,
236 new_size);
237 return TRUE;
238}