blob: 8e3209130e3863623a8bcd86d75e3d3b0ed72302 [file] [log] [blame]
Alex Deymoaea4c1c2015-08-19 20:24:43 -07001//
2// Copyright (C) 2012 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070016
17#include "update_engine/update_attempter.h"
Andrew de los Reyes63b96d72010-05-10 13:08:54 -070018
Ben Chan9abb7632014-08-07 00:10:53 -070019#include <stdint.h>
20
Alex Vakulenko59e253e2014-02-24 10:40:21 -080021#include <algorithm>
Andrewe045aef2020-01-08 16:29:22 -080022#include <map>
Alex Deymobc91a272014-05-20 16:45:33 -070023#include <memory>
24#include <string>
Alex Vakulenkod2779df2014-06-16 13:19:00 -070025#include <utility>
Alex Deymo44666f92014-07-22 20:29:24 -070026#include <vector>
Darin Petkov9d65b7b2010-07-20 09:13:01 -070027
Gilad Arnoldec7f9162014-07-15 13:24:46 -070028#include <base/bind.h>
Denis Nikitin8f2fa742019-05-29 10:36:52 -070029#include <base/compiler_specific.h>
Ben Chan06c76a42014-09-05 08:21:06 -070030#include <base/files/file_util.h>
David Zeuthen3c55abd2013-10-14 12:48:03 -070031#include <base/logging.h>
Andrew de los Reyes45168102010-11-22 11:13:50 -080032#include <base/rand_util.h>
Andrewe045aef2020-01-08 16:29:22 -080033#include <base/strings/string_number_conversions.h>
Daniel Erat65f1da02014-06-27 22:05:38 -070034#include <base/strings/string_util.h>
Alex Vakulenko75039d72014-03-25 12:36:28 -070035#include <base/strings/stringprintf.h>
May Lippert60aa3ca2018-08-15 16:55:29 -070036#include <base/time/time.h>
Sen Jiang2703ef42017-03-16 13:36:21 -070037#include <brillo/data_encoding.h>
Sen Jiange67bb5b2016-06-20 15:53:56 -070038#include <brillo/errors/error_codes.h>
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070039#include <brillo/message_loops/message_loop.h>
Patrick Dubroy7fbbe8a2011-08-01 17:28:22 +020040#include <policy/device_policy.h>
Alex Deymobc91a272014-05-20 16:45:33 -070041#include <policy/libpolicy.h>
Alex Deymod6deb1d2015-08-28 15:54:37 -070042#include <update_engine/dbus-constants.h>
Darin Petkov9d65b7b2010-07-20 09:13:01 -070043
Alex Deymo14c0da82016-07-20 16:45:45 -070044#include "update_engine/certificate_checker.h"
Alex Deymo39910dc2015-11-09 17:04:30 -080045#include "update_engine/common/boot_control_interface.h"
Alex Deymo39910dc2015-11-09 17:04:30 -080046#include "update_engine/common/clock_interface.h"
47#include "update_engine/common/constants.h"
Xiaochu Liu8ba486f2018-11-06 11:14:10 -080048#include "update_engine/common/dlcservice_interface.h"
Alex Deymo39910dc2015-11-09 17:04:30 -080049#include "update_engine/common/hardware_interface.h"
Alex Deymo39910dc2015-11-09 17:04:30 -080050#include "update_engine/common/platform_constants.h"
Andrewe045aef2020-01-08 16:29:22 -080051#include "update_engine/common/prefs.h"
Alex Deymo39910dc2015-11-09 17:04:30 -080052#include "update_engine/common/prefs_interface.h"
53#include "update_engine/common/subprocess.h"
54#include "update_engine/common/utils.h"
Alex Deymo14c0da82016-07-20 16:45:45 -070055#include "update_engine/libcurl_http_fetcher.h"
Tianjie Xu282aa1f2017-09-05 13:42:45 -070056#include "update_engine/metrics_reporter_interface.h"
Darin Petkov6a5b3222010-07-13 14:55:28 -070057#include "update_engine/omaha_request_action.h"
Darin Petkova4a8a8c2010-07-15 22:21:12 -070058#include "update_engine/omaha_request_params.h"
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070059#include "update_engine/omaha_response_handler_action.h"
Jae Hoon Kim051627a2019-09-03 12:56:32 -070060#include "update_engine/omaha_utils.h"
David Zeuthen8f191b22013-08-06 12:27:50 -070061#include "update_engine/p2p_manager.h"
Alex Deymo39910dc2015-11-09 17:04:30 -080062#include "update_engine/payload_consumer/download_action.h"
63#include "update_engine/payload_consumer/filesystem_verifier_action.h"
64#include "update_engine/payload_consumer/postinstall_runner_action.h"
Jay Srinivasan55f50c22013-01-10 19:24:35 -080065#include "update_engine/payload_state_interface.h"
Sen Jiangb8c6a8f2016-06-07 17:33:17 -070066#include "update_engine/power_manager_interface.h"
Jay Srinivasan43488792012-06-19 00:25:31 -070067#include "update_engine/system_state.h"
Amin Hassani0882a512018-04-05 16:25:44 -070068#include "update_engine/update_boot_flags_action.h"
Gilad Arnoldec7f9162014-07-15 13:24:46 -070069#include "update_engine/update_manager/policy.h"
Marton Hunyadye58bddb2018-04-10 20:27:26 +020070#include "update_engine/update_manager/policy_utils.h"
Gilad Arnoldec7f9162014-07-15 13:24:46 -070071#include "update_engine/update_manager/update_manager.h"
Christopher Wileycc8ce0e2015-10-01 16:48:47 -070072#include "update_engine/update_status_utils.h"
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070073
Gilad Arnoldec7f9162014-07-15 13:24:46 -070074using base::Bind;
75using base::Callback;
Andrewe045aef2020-01-08 16:29:22 -080076using base::FilePath;
David Zeuthen3c55abd2013-10-14 12:48:03 -070077using base::Time;
Darin Petkovaf183052010-08-23 12:07:13 -070078using base::TimeDelta;
79using base::TimeTicks;
Alex Vakulenko3f39d5c2015-10-13 09:27:13 -070080using brillo::MessageLoop;
Amin Hassani7cc8bb02019-01-14 16:29:47 -080081using chromeos_update_manager::CalculateStagingCase;
Gilad Arnoldec7f9162014-07-15 13:24:46 -070082using chromeos_update_manager::EvalStatus;
83using chromeos_update_manager::Policy;
Adolfo Victoria497044c2018-07-18 07:51:42 -070084using chromeos_update_manager::StagingCase;
Amin Hassani7cc8bb02019-01-14 16:29:47 -080085using chromeos_update_manager::UpdateCheckParams;
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070086using std::string;
87using std::vector;
Aaron Woodbf5a2522017-10-04 10:58:36 -070088using update_engine::UpdateAttemptFlags;
Aaron Wood7f92e2b2017-08-28 14:51:21 -070089using update_engine::UpdateEngineStatus;
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -070090
91namespace chromeos_update_engine {
92
Darin Petkov36275772010-10-01 11:40:57 -070093const int UpdateAttempter::kMaxDeltaUpdateFailures = 3;
94
Andrew de los Reyes45168102010-11-22 11:13:50 -080095namespace {
96const int kMaxConsecutiveObeyProxyRequests = 20;
Gilad Arnold70e476e2013-07-30 16:01:13 -070097
Alex Deymo0d298542016-03-30 18:31:49 -070098// Minimum threshold to broadcast an status update in progress and time.
99const double kBroadcastThresholdProgress = 0.01; // 1%
100const int kBroadcastThresholdSeconds = 10;
101
David Pursell02c18642014-11-06 11:26:11 -0800102// By default autest bypasses scattering. If we want to test scattering,
103// use kScheduledAUTestURLRequest. The URL used is same in both cases, but
104// different params are passed to CheckForUpdate().
105const char kAUTestURLRequest[] = "autest";
106const char kScheduledAUTestURLRequest[] = "autest-scheduled";
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700107} // namespace
Andrew de los Reyes45168102010-11-22 11:13:50 -0800108
Sen Jiangdaeaa432018-10-09 18:18:45 -0700109ErrorCode GetErrorCodeForAction(AbstractAction* action, ErrorCode code) {
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700110 if (code != ErrorCode::kError)
Darin Petkov777dbfa2010-07-20 15:03:37 -0700111 return code;
112
113 const string type = action->Type();
114 if (type == OmahaRequestAction::StaticType())
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700115 return ErrorCode::kOmahaRequestError;
Darin Petkov777dbfa2010-07-20 15:03:37 -0700116 if (type == OmahaResponseHandlerAction::StaticType())
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700117 return ErrorCode::kOmahaResponseHandlerError;
Allie Woodeb9e6d82015-04-17 13:55:30 -0700118 if (type == FilesystemVerifierAction::StaticType())
119 return ErrorCode::kFilesystemVerifierError;
Darin Petkov777dbfa2010-07-20 15:03:37 -0700120 if (type == PostinstallRunnerAction::StaticType())
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -0700121 return ErrorCode::kPostinstallRunnerError;
Darin Petkov777dbfa2010-07-20 15:03:37 -0700122
123 return code;
124}
125
Sen Jiang18414082018-01-11 14:50:36 -0800126UpdateAttempter::UpdateAttempter(SystemState* system_state,
127 CertificateChecker* cert_checker)
Gilad Arnold1f847232014-04-07 12:07:49 -0700128 : processor_(new ActionProcessor()),
129 system_state_(system_state),
Colin Howes978c1082018-12-03 11:46:12 -0800130 cert_checker_(cert_checker),
131 is_install_(false) {}
Darin Petkovc6c135c2010-08-11 13:36:18 -0700132
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700133UpdateAttempter::~UpdateAttempter() {
Alex Deymo33e91e72015-12-01 18:26:08 -0300134 // CertificateChecker might not be initialized in unittests.
135 if (cert_checker_)
136 cert_checker_->SetObserver(nullptr);
Alex Deymo2b4268c2015-12-04 13:56:25 -0800137 // Release ourselves as the ActionProcessor's delegate to prevent
138 // re-scheduling the updates due to the processing stopped.
139 processor_->set_delegate(nullptr);
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700140}
141
Gilad Arnold1f847232014-04-07 12:07:49 -0700142void UpdateAttempter::Init() {
143 // Pulling from the SystemState can only be done after construction, since
144 // this is an aggregate of various objects (such as the UpdateAttempter),
145 // which requires them all to be constructed prior to it being used.
146 prefs_ = system_state_->prefs();
147 omaha_request_params_ = system_state_->request_params();
Alex Deymo906191f2015-10-12 12:22:44 -0700148
Alex Deymo33e91e72015-12-01 18:26:08 -0300149 if (cert_checker_)
150 cert_checker_->SetObserver(this);
151
Alex Deymo906191f2015-10-12 12:22:44 -0700152 // In case of update_engine restart without a reboot we need to restore the
153 // reboot needed state.
154 if (GetBootTimeAtUpdate(nullptr))
155 status_ = UpdateStatus::UPDATED_NEED_REBOOT;
156 else
157 status_ = UpdateStatus::IDLE;
Gilad Arnold1f847232014-04-07 12:07:49 -0700158}
159
Xiaochu Liu88d90382018-08-29 16:09:11 -0700160bool UpdateAttempter::ScheduleUpdates() {
Jae Hoon Kimba2fdce2019-07-11 13:18:58 -0700161 if (IsBusyOrUpdateScheduled())
Xiaochu Liu88d90382018-08-29 16:09:11 -0700162 return false;
Gilad Arnold54fa66d2014-09-29 13:14:29 -0700163
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700164 chromeos_update_manager::UpdateManager* const update_manager =
165 system_state_->update_manager();
166 CHECK(update_manager);
Amin Hassani7cc8bb02019-01-14 16:29:47 -0800167 Callback<void(EvalStatus, const UpdateCheckParams&)> callback =
168 Bind(&UpdateAttempter::OnUpdateScheduled, base::Unretained(this));
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700169 // We limit the async policy request to a reasonably short time, to avoid a
170 // starvation due to a transient bug.
Jae Hoon Kim504c3cb2019-07-02 11:17:24 -0700171 update_manager->AsyncPolicyRequestUpdateCheckAllowed(
172 callback, &Policy::UpdateCheckAllowed);
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700173 waiting_for_scheduled_check_ = true;
Xiaochu Liu88d90382018-08-29 16:09:11 -0700174 return true;
Darin Petkovc6c135c2010-08-11 13:36:18 -0700175}
176
Alex Deymoc1c17b42015-11-23 03:53:15 -0300177void UpdateAttempter::CertificateChecked(ServerToCheck server_to_check,
178 CertificateCheckResult result) {
Tianjie Xu282aa1f2017-09-05 13:42:45 -0700179 system_state_->metrics_reporter()->ReportCertificateCheckMetrics(
180 server_to_check, result);
Alex Deymoc1c17b42015-11-23 03:53:15 -0300181}
182
David Zeuthen985b1122013-10-09 12:13:15 -0700183bool UpdateAttempter::CheckAndReportDailyMetrics() {
184 int64_t stored_value;
Alex Deymof329b932014-10-30 01:37:48 -0700185 Time now = system_state_->clock()->GetWallclockTime();
David Zeuthen985b1122013-10-09 12:13:15 -0700186 if (system_state_->prefs()->Exists(kPrefsDailyMetricsLastReportedAt) &&
187 system_state_->prefs()->GetInt64(kPrefsDailyMetricsLastReportedAt,
188 &stored_value)) {
Alex Deymof329b932014-10-30 01:37:48 -0700189 Time last_reported_at = Time::FromInternalValue(stored_value);
190 TimeDelta time_reported_since = now - last_reported_at;
David Zeuthen985b1122013-10-09 12:13:15 -0700191 if (time_reported_since.InSeconds() < 0) {
192 LOG(WARNING) << "Last reported daily metrics "
193 << utils::FormatTimeDelta(time_reported_since) << " ago "
194 << "which is negative. Either the system clock is wrong or "
195 << "the kPrefsDailyMetricsLastReportedAt state variable "
196 << "is wrong.";
197 // In this case, report daily metrics to reset.
198 } else {
Amin Hassani7cc8bb02019-01-14 16:29:47 -0800199 if (time_reported_since.InSeconds() < 24 * 60 * 60) {
David Zeuthen985b1122013-10-09 12:13:15 -0700200 LOG(INFO) << "Last reported daily metrics "
201 << utils::FormatTimeDelta(time_reported_since) << " ago.";
202 return false;
203 }
204 LOG(INFO) << "Last reported daily metrics "
205 << utils::FormatTimeDelta(time_reported_since) << " ago, "
206 << "which is more than 24 hours ago.";
207 }
208 }
209
210 LOG(INFO) << "Reporting daily metrics.";
211 system_state_->prefs()->SetInt64(kPrefsDailyMetricsLastReportedAt,
212 now.ToInternalValue());
213
214 ReportOSAge();
215
216 return true;
217}
218
219void UpdateAttempter::ReportOSAge() {
220 struct stat sb;
221
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700222 if (system_state_ == nullptr)
David Zeuthen985b1122013-10-09 12:13:15 -0700223 return;
224
225 if (stat("/etc/lsb-release", &sb) != 0) {
David Zeuthend9aca3b2014-08-21 13:11:21 -0400226 PLOG(ERROR) << "Error getting file status for /etc/lsb-release "
227 << "(Note: this may happen in some unit tests)";
David Zeuthen985b1122013-10-09 12:13:15 -0700228 return;
229 }
230
Sen Jiang1c3db7d2019-01-10 15:48:55 -0800231 Time lsb_release_timestamp = Time::FromTimeSpec(sb.st_ctim);
Alex Deymof329b932014-10-30 01:37:48 -0700232 Time now = system_state_->clock()->GetWallclockTime();
233 TimeDelta age = now - lsb_release_timestamp;
David Zeuthen985b1122013-10-09 12:13:15 -0700234 if (age.InSeconds() < 0) {
235 LOG(ERROR) << "The OS age (" << utils::FormatTimeDelta(age)
David Zeuthend9aca3b2014-08-21 13:11:21 -0400236 << ") is negative. Maybe the clock is wrong? "
237 << "(Note: this may happen in some unit tests.)";
David Zeuthen985b1122013-10-09 12:13:15 -0700238 return;
239 }
240
Tianjie Xu282aa1f2017-09-05 13:42:45 -0700241 system_state_->metrics_reporter()->ReportDailyMetrics(age);
David Zeuthen985b1122013-10-09 12:13:15 -0700242}
243
Gilad Arnold28e2f392012-02-09 14:36:46 -0800244void UpdateAttempter::Update(const string& app_version,
245 const string& omaha_url,
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700246 const string& target_channel,
247 const string& target_version_prefix,
Marton Hunyadyba51c3f2018-04-25 15:18:10 +0200248 bool rollback_allowed,
Zentaro Kavanagh28def4f2019-01-15 17:15:01 -0800249 bool rollback_data_save_requested,
Zentaro Kavanagh0ef9a2f2018-07-02 12:05:07 -0700250 int rollback_allowed_milestones,
Andrew de los Reyesfb2f4612011-06-09 18:21:49 -0700251 bool obey_proxies,
Nam T. Nguyen7d623eb2014-05-13 16:06:28 -0700252 bool interactive) {
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700253 // This is normally called frequently enough so it's appropriate to use as a
254 // hook for reporting daily metrics.
255 // TODO(garnold) This should be hooked to a separate (reliable and consistent)
256 // timeout event.
David Zeuthen985b1122013-10-09 12:13:15 -0700257 CheckAndReportDailyMetrics();
258
Andrew de los Reyesc1d5c932011-04-20 17:15:47 -0700259 fake_update_success_ = false;
Christopher Wileycc8ce0e2015-10-01 16:48:47 -0700260 if (status_ == UpdateStatus::UPDATED_NEED_REBOOT) {
Thieu Le116fda32011-04-19 11:01:54 -0700261 // Although we have applied an update, we still want to ping Omaha
262 // to ensure the number of active statistics is accurate.
David Zeuthen33bae492014-02-25 16:16:18 -0800263 //
264 // Also convey to the UpdateEngine.Check.Result metric that we're
265 // not performing an update check because of this.
Andrew de los Reyes6b78e292010-05-10 15:54:39 -0700266 LOG(INFO) << "Not updating b/c we already updated and we're waiting for "
Thieu Le116fda32011-04-19 11:01:54 -0700267 << "reboot, we'll ping Omaha instead";
Tianjie Xu282aa1f2017-09-05 13:42:45 -0700268 system_state_->metrics_reporter()->ReportUpdateCheckMetrics(
269 system_state_,
270 metrics::CheckResult::kRebootPending,
271 metrics::CheckReaction::kUnset,
272 metrics::DownloadErrorCode::kUnset);
Thieu Le116fda32011-04-19 11:01:54 -0700273 PingOmaha();
Andrew de los Reyes6b78e292010-05-10 15:54:39 -0700274 return;
275 }
Christopher Wileycc8ce0e2015-10-01 16:48:47 -0700276 if (status_ != UpdateStatus::IDLE) {
Andrew de los Reyes6b78e292010-05-10 15:54:39 -0700277 // Update in progress. Do nothing
278 return;
279 }
Jay Srinivasan480ddfa2012-06-01 19:15:26 -0700280
281 if (!CalculateUpdateParams(app_version,
282 omaha_url,
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700283 target_channel,
284 target_version_prefix,
Marton Hunyadyba51c3f2018-04-25 15:18:10 +0200285 rollback_allowed,
Zentaro Kavanagh28def4f2019-01-15 17:15:01 -0800286 rollback_data_save_requested,
Zentaro Kavanagh0ef9a2f2018-07-02 12:05:07 -0700287 rollback_allowed_milestones,
Jay Srinivasan480ddfa2012-06-01 19:15:26 -0700288 obey_proxies,
Nam T. Nguyen7d623eb2014-05-13 16:06:28 -0700289 interactive)) {
Jay Srinivasan480ddfa2012-06-01 19:15:26 -0700290 return;
291 }
292
293 BuildUpdateActions(interactive);
294
Christopher Wileycc8ce0e2015-10-01 16:48:47 -0700295 SetStatusAndNotify(UpdateStatus::CHECKING_FOR_UPDATE);
Jay Srinivasan480ddfa2012-06-01 19:15:26 -0700296
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700297 // Update the last check time here; it may be re-updated when an Omaha
298 // response is received, but this will prevent us from repeatedly scheduling
299 // checks in the case where a response is not received.
300 UpdateLastCheckedTime();
301
Amin Hassani0882a512018-04-05 16:25:44 -0700302 ScheduleProcessingStart();
Jay Srinivasan480ddfa2012-06-01 19:15:26 -0700303}
304
Jay Srinivasan1c0fe792013-03-28 16:45:25 -0700305void UpdateAttempter::RefreshDevicePolicy() {
306 // Lazy initialize the policy provider, or reload the latest policy data.
307 if (!policy_provider_.get())
308 policy_provider_.reset(new policy::PolicyProvider());
309 policy_provider_->Reload();
310
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700311 const policy::DevicePolicy* device_policy = nullptr;
Jay Srinivasan1c0fe792013-03-28 16:45:25 -0700312 if (policy_provider_->device_policy_is_loaded())
313 device_policy = &policy_provider_->GetDevicePolicy();
314
315 if (device_policy)
316 LOG(INFO) << "Device policies/settings present";
317 else
318 LOG(INFO) << "No device policies/settings present.";
319
320 system_state_->set_device_policy(device_policy);
David Zeuthen92d9c8b2013-09-11 10:58:11 -0700321 system_state_->p2p_manager()->SetDevicePolicy(device_policy);
Jay Srinivasan1c0fe792013-03-28 16:45:25 -0700322}
323
David Zeuthen8f191b22013-08-06 12:27:50 -0700324void UpdateAttempter::CalculateP2PParams(bool interactive) {
325 bool use_p2p_for_downloading = false;
326 bool use_p2p_for_sharing = false;
327
Thiemo Nagel27d9d532017-05-26 16:35:20 +0200328 // Never use p2p for downloading in interactive checks unless the developer
329 // has opted in for it via a marker file.
David Zeuthen8f191b22013-08-06 12:27:50 -0700330 //
Thiemo Nagel27d9d532017-05-26 16:35:20 +0200331 // (Why would a developer want to opt in? If they are working on the
332 // update_engine or p2p codebases so they can actually test their code.)
David Zeuthen8f191b22013-08-06 12:27:50 -0700333
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700334 if (system_state_ != nullptr) {
David Zeuthen8f191b22013-08-06 12:27:50 -0700335 if (!system_state_->p2p_manager()->IsP2PEnabled()) {
336 LOG(INFO) << "p2p is not enabled - disallowing p2p for both"
337 << " downloading and sharing.";
338 } else {
339 // Allow p2p for sharing, even in interactive checks.
340 use_p2p_for_sharing = true;
341 if (!interactive) {
342 LOG(INFO) << "Non-interactive check - allowing p2p for downloading";
343 use_p2p_for_downloading = true;
344 } else {
David Zeuthen052d2902013-09-06 11:41:30 -0700345 LOG(INFO) << "Forcibly disabling use of p2p for downloading "
346 << "since this update attempt is interactive.";
David Zeuthen8f191b22013-08-06 12:27:50 -0700347 }
348 }
349 }
350
Gilad Arnold74b5f552014-10-07 08:17:16 -0700351 PayloadStateInterface* const payload_state = system_state_->payload_state();
352 payload_state->SetUsingP2PForDownloading(use_p2p_for_downloading);
353 payload_state->SetUsingP2PForSharing(use_p2p_for_sharing);
David Zeuthen8f191b22013-08-06 12:27:50 -0700354}
355
Jay Srinivasan480ddfa2012-06-01 19:15:26 -0700356bool UpdateAttempter::CalculateUpdateParams(const string& app_version,
357 const string& omaha_url,
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700358 const string& target_channel,
359 const string& target_version_prefix,
Marton Hunyadyba51c3f2018-04-25 15:18:10 +0200360 bool rollback_allowed,
Zentaro Kavanagh28def4f2019-01-15 17:15:01 -0800361 bool rollback_data_save_requested,
Zentaro Kavanagh0ef9a2f2018-07-02 12:05:07 -0700362 int rollback_allowed_milestones,
Jay Srinivasan480ddfa2012-06-01 19:15:26 -0700363 bool obey_proxies,
Nam T. Nguyen7d623eb2014-05-13 16:06:28 -0700364 bool interactive) {
Darin Petkov1023a602010-08-30 13:47:51 -0700365 http_response_code_ = 0;
Gilad Arnold74b5f552014-10-07 08:17:16 -0700366 PayloadStateInterface* const payload_state = system_state_->payload_state();
Patrick Dubroy7fbbe8a2011-08-01 17:28:22 +0200367
Alex Deymo749ecf12014-10-21 20:06:57 -0700368 // Refresh the policy before computing all the update parameters.
369 RefreshDevicePolicy();
370
Marton Hunyadye58bddb2018-04-10 20:27:26 +0200371 // Check whether we need to clear the rollback-happened preference after
372 // policy is available again.
373 UpdateRollbackHappened();
374
Xiyuan Xiac0e8f9a2017-02-22 13:19:35 -0800375 // Update the target version prefix.
376 omaha_request_params_->set_target_version_prefix(target_version_prefix);
Jay Srinivasan480ddfa2012-06-01 19:15:26 -0700377
Marton Hunyadyba51c3f2018-04-25 15:18:10 +0200378 // Set whether rollback is allowed.
379 omaha_request_params_->set_rollback_allowed(rollback_allowed);
380
Zentaro Kavanagh28def4f2019-01-15 17:15:01 -0800381 // Set whether saving data over rollback is requested.
382 omaha_request_params_->set_rollback_data_save_requested(
383 rollback_data_save_requested);
384
Adolfo Victoria497044c2018-07-18 07:51:42 -0700385 CalculateStagingParams(interactive);
386 // If staging_wait_time_ wasn't set, staging is off, use scattering instead.
387 if (staging_wait_time_.InSeconds() == 0) {
388 CalculateScatteringParams(interactive);
389 }
Patrick Dubroy7fbbe8a2011-08-01 17:28:22 +0200390
Zentaro Kavanagh0ef9a2f2018-07-02 12:05:07 -0700391 // Set how many milestones of rollback are allowed.
392 omaha_request_params_->set_rollback_allowed_milestones(
393 rollback_allowed_milestones);
394
David Zeuthen8f191b22013-08-06 12:27:50 -0700395 CalculateP2PParams(interactive);
Gilad Arnold74b5f552014-10-07 08:17:16 -0700396 if (payload_state->GetUsingP2PForDownloading() ||
397 payload_state->GetUsingP2PForSharing()) {
David Zeuthen8f191b22013-08-06 12:27:50 -0700398 // OK, p2p is to be used - start it and perform housekeeping.
399 if (!StartP2PAndPerformHousekeeping()) {
400 // If this fails, disable p2p for this attempt
401 LOG(INFO) << "Forcibly disabling use of p2p since starting p2p or "
402 << "performing housekeeping failed.";
Gilad Arnold74b5f552014-10-07 08:17:16 -0700403 payload_state->SetUsingP2PForDownloading(false);
404 payload_state->SetUsingP2PForSharing(false);
David Zeuthen8f191b22013-08-06 12:27:50 -0700405 }
406 }
407
Amin Hassani7cc8bb02019-01-14 16:29:47 -0800408 if (!omaha_request_params_->Init(app_version, omaha_url, interactive)) {
Jay Srinivasan1c0fe792013-03-28 16:45:25 -0700409 LOG(ERROR) << "Unable to initialize Omaha request params.";
Jay Srinivasan480ddfa2012-06-01 19:15:26 -0700410 return false;
Darin Petkova4a8a8c2010-07-15 22:21:12 -0700411 }
Darin Petkov3aefa862010-12-07 14:45:00 -0800412
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700413 // Set the target channel, if one was provided.
414 if (target_channel.empty()) {
415 LOG(INFO) << "No target channel mandated by policy.";
416 } else {
417 LOG(INFO) << "Setting target channel as mandated: " << target_channel;
418 // Pass in false for powerwash_allowed until we add it to the policy
419 // protobuf.
Alex Deymod942f9d2015-11-06 16:11:50 -0800420 string error_message;
Amin Hassani7cc8bb02019-01-14 16:29:47 -0800421 if (!omaha_request_params_->SetTargetChannel(
422 target_channel, false, &error_message)) {
Alex Deymod942f9d2015-11-06 16:11:50 -0800423 LOG(ERROR) << "Setting the channel failed: " << error_message;
424 }
Jay Srinivasan1c0fe792013-03-28 16:45:25 -0700425
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700426 // Since this is the beginning of a new attempt, update the download
427 // channel. The download channel won't be updated until the next attempt,
428 // even if target channel changes meanwhile, so that how we'll know if we
429 // should cancel the current download attempt if there's such a change in
430 // target channel.
431 omaha_request_params_->UpdateDownloadChannel();
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700432 }
Jae Hoon Kimc43f6bb2019-07-03 12:56:52 -0700433
Andrewe045aef2020-01-08 16:29:22 -0800434 // The function |CalculateDlcParams| makes use of the function |GetAppId| from
435 // |OmahaRequestParams|, so to ensure that the return from |GetAppId|
436 // doesn't change, no changes to the values |download_channel_|,
437 // |image_props_.product_id| and |image_props_.canary_product_id| from
438 // |omaha_request_params_| shall be made below this line.
439 CalculateDlcParams();
440
Xiaochu Liu88d90382018-08-29 16:09:11 -0700441 omaha_request_params_->set_is_install(is_install_);
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700442
Amr Aboelkher21ac9962019-05-15 14:50:05 +0200443 // Set Quick Fix Build token if policy is set and the device is enterprise
444 // enrolled.
Askar Aitzhan570ca872019-04-24 11:16:12 +0200445 string token;
446 if (system_state_ && system_state_->device_policy()) {
447 if (!system_state_->device_policy()->GetDeviceQuickFixBuildToken(&token))
448 token.clear();
449 }
450 omaha_request_params_->set_autoupdate_token(token);
451
Gilad Arnoldafd70ed2014-09-30 16:27:06 -0700452 LOG(INFO) << "target_version_prefix = "
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700453 << omaha_request_params_->target_version_prefix()
Marton Hunyadyba51c3f2018-04-25 15:18:10 +0200454 << ", rollback_allowed = "
455 << omaha_request_params_->rollback_allowed()
Jay Srinivasan480ddfa2012-06-01 19:15:26 -0700456 << ", scatter_factor_in_seconds = "
457 << utils::FormatSecs(scatter_factor_.InSeconds());
458
459 LOG(INFO) << "Wall Clock Based Wait Enabled = "
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700460 << omaha_request_params_->wall_clock_based_wait_enabled()
Jay Srinivasan480ddfa2012-06-01 19:15:26 -0700461 << ", Update Check Count Wait Enabled = "
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700462 << omaha_request_params_->update_check_count_wait_enabled()
Amin Hassani7cc8bb02019-01-14 16:29:47 -0800463 << ", Waiting Period = "
464 << utils::FormatSecs(
465 omaha_request_params_->waiting_period().InSeconds());
Jay Srinivasan0a708742012-03-20 11:26:12 -0700466
David Zeuthen8f191b22013-08-06 12:27:50 -0700467 LOG(INFO) << "Use p2p For Downloading = "
Gilad Arnold74b5f552014-10-07 08:17:16 -0700468 << payload_state->GetUsingP2PForDownloading()
David Zeuthen8f191b22013-08-06 12:27:50 -0700469 << ", Use p2p For Sharing = "
Gilad Arnold74b5f552014-10-07 08:17:16 -0700470 << payload_state->GetUsingP2PForSharing();
David Zeuthen8f191b22013-08-06 12:27:50 -0700471
Andrew de los Reyes45168102010-11-22 11:13:50 -0800472 obeying_proxies_ = true;
473 if (obey_proxies || proxy_manual_checks_ == 0) {
474 LOG(INFO) << "forced to obey proxies";
475 // If forced to obey proxies, every 20th request will not use proxies
476 proxy_manual_checks_++;
477 LOG(INFO) << "proxy manual checks: " << proxy_manual_checks_;
478 if (proxy_manual_checks_ >= kMaxConsecutiveObeyProxyRequests) {
479 proxy_manual_checks_ = 0;
480 obeying_proxies_ = false;
481 }
482 } else if (base::RandInt(0, 4) == 0) {
483 obeying_proxies_ = false;
484 }
Amin Hassani7cc8bb02019-01-14 16:29:47 -0800485 LOG_IF(INFO, !obeying_proxies_)
486 << "To help ensure updates work, this update check we are ignoring the "
487 << "proxy settings and using direct connections.";
Andrew de los Reyes45168102010-11-22 11:13:50 -0800488
Darin Petkov36275772010-10-01 11:40:57 -0700489 DisableDeltaUpdateIfNeeded();
Jay Srinivasan480ddfa2012-06-01 19:15:26 -0700490 return true;
491}
492
Gilad Arnoldb92f0df2013-01-10 16:32:45 -0800493void UpdateAttempter::CalculateScatteringParams(bool interactive) {
Jay Srinivasan21be0752012-07-25 15:44:56 -0700494 // Take a copy of the old scatter value before we update it, as
495 // we need to update the waiting period if this value changes.
496 TimeDelta old_scatter_factor = scatter_factor_;
Jay Srinivasan6f6ea002012-12-14 11:26:28 -0800497 const policy::DevicePolicy* device_policy = system_state_->device_policy();
Jay Srinivasan21be0752012-07-25 15:44:56 -0700498 if (device_policy) {
Ben Chan9abb7632014-08-07 00:10:53 -0700499 int64_t new_scatter_factor_in_secs = 0;
Jay Srinivasan21be0752012-07-25 15:44:56 -0700500 device_policy->GetScatterFactorInSeconds(&new_scatter_factor_in_secs);
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700501 if (new_scatter_factor_in_secs < 0) // sanitize input, just in case.
Amin Hassani7cc8bb02019-01-14 16:29:47 -0800502 new_scatter_factor_in_secs = 0;
Jay Srinivasan21be0752012-07-25 15:44:56 -0700503 scatter_factor_ = TimeDelta::FromSeconds(new_scatter_factor_in_secs);
504 }
505
506 bool is_scatter_enabled = false;
507 if (scatter_factor_.InSeconds() == 0) {
508 LOG(INFO) << "Scattering disabled since scatter factor is set to 0";
Gilad Arnoldb92f0df2013-01-10 16:32:45 -0800509 } else if (interactive) {
510 LOG(INFO) << "Scattering disabled as this is an interactive update check";
Alex Deymo46a9aae2016-05-04 20:20:11 -0700511 } else if (system_state_->hardware()->IsOOBEEnabled() &&
512 !system_state_->hardware()->IsOOBEComplete(nullptr)) {
513 LOG(INFO) << "Scattering disabled since OOBE is enabled but not complete "
514 "yet";
Jay Srinivasan21be0752012-07-25 15:44:56 -0700515 } else {
516 is_scatter_enabled = true;
517 LOG(INFO) << "Scattering is enabled";
518 }
519
520 if (is_scatter_enabled) {
521 // This means the scattering policy is turned on.
522 // Now check if we need to update the waiting period. The two cases
523 // in which we'd need to update the waiting period are:
524 // 1. First time in process or a scheduled check after a user-initiated one.
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700525 // (omaha_request_params_->waiting_period will be zero in this case).
Jay Srinivasan21be0752012-07-25 15:44:56 -0700526 // 2. Admin has changed the scattering policy value.
527 // (new scattering value will be different from old one in this case).
Ben Chan9abb7632014-08-07 00:10:53 -0700528 int64_t wait_period_in_secs = 0;
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700529 if (omaha_request_params_->waiting_period().InSeconds() == 0) {
Jay Srinivasan21be0752012-07-25 15:44:56 -0700530 // First case. Check if we have a suitable value to set for
531 // the waiting period.
Adolfo Victoriad3a1e352018-07-16 11:40:47 -0700532 if (prefs_->GetInt64(kPrefsWallClockScatteringWaitPeriod,
533 &wait_period_in_secs) &&
Jay Srinivasan21be0752012-07-25 15:44:56 -0700534 wait_period_in_secs > 0 &&
535 wait_period_in_secs <= scatter_factor_.InSeconds()) {
536 // This means:
537 // 1. There's a persisted value for the waiting period available.
538 // 2. And that persisted value is still valid.
539 // So, in this case, we should reuse the persisted value instead of
540 // generating a new random value to improve the chances of a good
541 // distribution for scattering.
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700542 omaha_request_params_->set_waiting_period(
Amin Hassani7cc8bb02019-01-14 16:29:47 -0800543 TimeDelta::FromSeconds(wait_period_in_secs));
544 LOG(INFO) << "Using persisted wall-clock waiting period: "
545 << utils::FormatSecs(
546 omaha_request_params_->waiting_period().InSeconds());
Alex Vakulenkod2779df2014-06-16 13:19:00 -0700547 } else {
Jay Srinivasan21be0752012-07-25 15:44:56 -0700548 // This means there's no persisted value for the waiting period
549 // available or its value is invalid given the new scatter_factor value.
550 // So, we should go ahead and regenerate a new value for the
551 // waiting period.
552 LOG(INFO) << "Persisted value not present or not valid ("
553 << utils::FormatSecs(wait_period_in_secs)
554 << ") for wall-clock waiting period.";
555 GenerateNewWaitingPeriod();
556 }
557 } else if (scatter_factor_ != old_scatter_factor) {
558 // This means there's already a waiting period value, but we detected
559 // a change in the scattering policy value. So, we should regenerate the
560 // waiting period to make sure it's within the bounds of the new scatter
561 // factor value.
562 GenerateNewWaitingPeriod();
563 } else {
564 // Neither the first time scattering is enabled nor the scattering value
565 // changed. Nothing to do.
Amin Hassani7cc8bb02019-01-14 16:29:47 -0800566 LOG(INFO) << "Keeping current wall-clock waiting period: "
567 << utils::FormatSecs(
568 omaha_request_params_->waiting_period().InSeconds());
Jay Srinivasan21be0752012-07-25 15:44:56 -0700569 }
570
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700571 // The invariant at this point is that omaha_request_params_->waiting_period
Jay Srinivasan21be0752012-07-25 15:44:56 -0700572 // is non-zero no matter which path we took above.
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700573 LOG_IF(ERROR, omaha_request_params_->waiting_period().InSeconds() == 0)
Jay Srinivasan21be0752012-07-25 15:44:56 -0700574 << "Waiting Period should NOT be zero at this point!!!";
575
576 // Since scattering is enabled, wall clock based wait will always be
577 // enabled.
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700578 omaha_request_params_->set_wall_clock_based_wait_enabled(true);
Jay Srinivasan21be0752012-07-25 15:44:56 -0700579
580 // If we don't have any issues in accessing the file system to update
581 // the update check count value, we'll turn that on as well.
582 bool decrement_succeeded = DecrementUpdateCheckCount();
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700583 omaha_request_params_->set_update_check_count_wait_enabled(
Amin Hassani7cc8bb02019-01-14 16:29:47 -0800584 decrement_succeeded);
Jay Srinivasan21be0752012-07-25 15:44:56 -0700585 } else {
586 // This means the scattering feature is turned off or disabled for
587 // this particular update check. Make sure to disable
588 // all the knobs and artifacts so that we don't invoke any scattering
589 // related code.
Jay Srinivasanae4697c2013-03-18 17:08:08 -0700590 omaha_request_params_->set_wall_clock_based_wait_enabled(false);
591 omaha_request_params_->set_update_check_count_wait_enabled(false);
592 omaha_request_params_->set_waiting_period(TimeDelta::FromSeconds(0));
Adolfo Victoriad3a1e352018-07-16 11:40:47 -0700593 prefs_->Delete(kPrefsWallClockScatteringWaitPeriod);
Jay Srinivasan21be0752012-07-25 15:44:56 -0700594 prefs_->Delete(kPrefsUpdateCheckCount);
595 // Don't delete the UpdateFirstSeenAt file as we don't want manual checks
596 // that result in no-updates (e.g. due to server side throttling) to
597 // cause update starvation by having the client generate a new
598 // UpdateFirstSeenAt for each scheduled check that follows a manual check.
599 }
600}
601
602void UpdateAttempter::GenerateNewWaitingPeriod() {
Amin Hassani7cc8bb02019-01-14 16:29:47 -0800603 omaha_request_params_->set_waiting_period(
604 TimeDelta::FromSeconds(base::RandInt(1, scatter_factor_.InSeconds())));
Jay Srinivasan21be0752012-07-25 15:44:56 -0700605
Amin Hassani7cc8bb02019-01-14 16:29:47 -0800606 LOG(INFO) << "Generated new wall-clock waiting period: "
607 << utils::FormatSecs(
608 omaha_request_params_->waiting_period().InSeconds());
Jay Srinivasan21be0752012-07-25 15:44:56 -0700609
610 // Do a best-effort to persist this in all cases. Even if the persistence
611 // fails, we'll still be able to scatter based on our in-memory value.
612 // The persistence only helps in ensuring a good overall distribution
613 // across multiple devices if they tend to reboot too often.
Gilad Arnold519cfc72014-10-02 10:34:54 -0700614 system_state_->payload_state()->SetScatteringWaitPeriod(
615 omaha_request_params_->waiting_period());
Jay Srinivasan21be0752012-07-25 15:44:56 -0700616}
617
Adolfo Victoria497044c2018-07-18 07:51:42 -0700618void UpdateAttempter::CalculateStagingParams(bool interactive) {
619 bool oobe_complete = system_state_->hardware()->IsOOBEEnabled() &&
620 system_state_->hardware()->IsOOBEComplete(nullptr);
621 auto device_policy = system_state_->device_policy();
622 StagingCase staging_case = StagingCase::kOff;
623 if (device_policy && !interactive && oobe_complete) {
624 staging_wait_time_ = omaha_request_params_->waiting_period();
625 staging_case = CalculateStagingCase(
626 device_policy, prefs_, &staging_wait_time_, &staging_schedule_);
627 }
628 switch (staging_case) {
629 case StagingCase::kOff:
630 // Staging is off, get rid of persisted value.
631 prefs_->Delete(kPrefsWallClockStagingWaitPeriod);
632 // Set |staging_wait_time_| to its default value so scattering can still
633 // be turned on
634 staging_wait_time_ = TimeDelta();
635 break;
636 // Let the cases fall through since they just add, and never remove, steps
637 // to turning staging on.
638 case StagingCase::kNoSavedValue:
639 prefs_->SetInt64(kPrefsWallClockStagingWaitPeriod,
640 staging_wait_time_.InDays());
Denis Nikitin8f2fa742019-05-29 10:36:52 -0700641 FALLTHROUGH;
Adolfo Victoria497044c2018-07-18 07:51:42 -0700642 case StagingCase::kSetStagingFromPref:
643 omaha_request_params_->set_waiting_period(staging_wait_time_);
Denis Nikitin8f2fa742019-05-29 10:36:52 -0700644 FALLTHROUGH;
Adolfo Victoria497044c2018-07-18 07:51:42 -0700645 case StagingCase::kNoAction:
646 // Staging is on, enable wallclock based wait so that its values get used.
647 omaha_request_params_->set_wall_clock_based_wait_enabled(true);
648 // Use UpdateCheckCount if possible to prevent devices updating all at
649 // once.
650 omaha_request_params_->set_update_check_count_wait_enabled(
651 DecrementUpdateCheckCount());
652 // Scattering should not be turned on if staging is on, delete the
653 // existing scattering configuration.
654 prefs_->Delete(kPrefsWallClockScatteringWaitPeriod);
655 scatter_factor_ = TimeDelta();
656 }
Chris Sosad317e402013-06-12 13:47:09 -0700657}
658
Andrewe045aef2020-01-08 16:29:22 -0800659int64_t UpdateAttempter::GetPingMetadata(
660 const PrefsInterface& prefs, const std::string& metadata_name) const {
661 // The first time a ping is sent, the metadata files containing the values
662 // sent back by the server still don't exist. A value of -1 is used to
663 // indicate this.
664 if (!prefs.Exists(metadata_name))
665 return kPingNeverPinged;
666
667 int64_t value;
668 if (prefs.GetInt64(metadata_name, &value))
669 return value;
670
671 // Return -2 when the file exists and there is a problem reading from it, or
672 // the value cannot be converted to an integer.
673 return kPingUnknownValue;
674}
675
676void UpdateAttempter::CalculateDlcParams() {
677 // Set the |dlc_module_ids_| only for an update. This is required to get the
678 // currently installed DLC(s).
679 if (!is_install_ &&
680 !system_state_->dlcservice()->GetInstalled(&dlc_module_ids_)) {
681 LOG(INFO) << "Failed to retrieve DLC module IDs from dlcservice. Check the "
682 "state of dlcservice, will not update DLC modules.";
683 }
684 std::map<std::string, OmahaRequestParams::AppParams> dlc_apps_params;
685 for (auto dlc_id : dlc_module_ids_) {
686 OmahaRequestParams::AppParams dlc_params{
687 .active_counting_type = OmahaRequestParams::kDateBased,
688 .name = dlc_id,
689 .send_ping = false};
690 // Only send the ping when the request is to update DLCs. When installing
691 // DLCs, we don't want to send the ping yet, since the DLCs might fail to
692 // install or might not really be active yet.
693 if (!is_install_) {
694 base::FilePath metadata_path =
695 base::FilePath(omaha_request_params_->dlc_prefs_root())
696 .Append(dlc_id);
697 Prefs prefs;
698 if (!prefs.Init(metadata_path)) {
699 LOG(ERROR) << "Failed to initialize the preferences path:"
700 << metadata_path.value() << ".";
701 } else {
702 dlc_params.ping_active = kPingActiveValue;
703 if (!prefs.GetInt64(kPrefsPingActive, &dlc_params.ping_active) ||
704 dlc_params.ping_active != kPingActiveValue) {
705 dlc_params.ping_active = kPingInactiveValue;
706 }
707 dlc_params.ping_date_last_active =
708 GetPingMetadata(prefs, kPrefsPingLastActive);
709 dlc_params.ping_date_last_rollcall =
710 GetPingMetadata(prefs, kPrefsPingLastRollcall);
711 dlc_params.send_ping = true;
712 }
713 }
714 dlc_apps_params[omaha_request_params_->GetDlcAppId(dlc_id)] = dlc_params;
715 }
716 omaha_request_params_->set_dlc_apps_params(dlc_apps_params);
717}
718
Jay Srinivasan480ddfa2012-06-01 19:15:26 -0700719void UpdateAttempter::BuildUpdateActions(bool interactive) {
Darin Petkovf42cc1c2010-09-01 09:03:02 -0700720 CHECK(!processor_->IsRunning());
721 processor_->set_delegate(this);
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700722
Jae Hoon Kimedb65502019-06-14 11:52:17 -0700723 // The session ID needs to be kept throughout the update flow. The value
724 // of the session ID will reset/update only when it is a new update flow.
725 session_id_ = base::GenerateGUID();
726
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700727 // Actions:
Amin Hassanid3f4bea2018-04-30 14:52:40 -0700728 auto update_check_fetcher = std::make_unique<LibcurlHttpFetcher>(
729 GetProxyResolver(), system_state_->hardware());
Alex Deymo33e91e72015-12-01 18:26:08 -0300730 update_check_fetcher->set_server_to_check(ServerToCheck::kUpdate);
Andrew de los Reyesfb2f4612011-06-09 18:21:49 -0700731 // Try harder to connect to the network, esp when not interactive.
732 // See comment in libcurl_http_fetcher.cc.
733 update_check_fetcher->set_no_network_max_retries(interactive ? 1 : 3);
Xiaochu Liu4a1173a2019-04-10 10:49:08 -0700734 update_check_fetcher->set_is_update_check(true);
Jae Hoon Kimedb65502019-06-14 11:52:17 -0700735 auto update_check_action =
736 std::make_unique<OmahaRequestAction>(system_state_,
737 nullptr,
738 std::move(update_check_fetcher),
739 false,
740 session_id_);
Amin Hassanid3f4bea2018-04-30 14:52:40 -0700741 auto response_handler_action =
742 std::make_unique<OmahaResponseHandlerAction>(system_state_);
Amin Hassani0882a512018-04-05 16:25:44 -0700743 auto update_boot_flags_action =
744 std::make_unique<UpdateBootFlagsAction>(system_state_->boot_control());
Amin Hassanid3f4bea2018-04-30 14:52:40 -0700745 auto download_started_action = std::make_unique<OmahaRequestAction>(
Sen Jiang18414082018-01-11 14:50:36 -0800746 system_state_,
747 new OmahaEvent(OmahaEvent::kTypeUpdateDownloadStarted),
748 std::make_unique<LibcurlHttpFetcher>(GetProxyResolver(),
749 system_state_->hardware()),
Jae Hoon Kimedb65502019-06-14 11:52:17 -0700750 false,
751 session_id_);
Alex Deymo33e91e72015-12-01 18:26:08 -0300752
Bruno Rocha7f9aea22011-09-12 14:31:24 -0700753 LibcurlHttpFetcher* download_fetcher =
Alex Deymo33e91e72015-12-01 18:26:08 -0300754 new LibcurlHttpFetcher(GetProxyResolver(), system_state_->hardware());
755 download_fetcher->set_server_to_check(ServerToCheck::kDownload);
Sen Jiangee174a12017-12-21 17:38:08 -0800756 if (interactive)
757 download_fetcher->set_max_retry_count(kDownloadMaxRetryCountInteractive);
Jae Hoon Kim0ae8fe12019-06-26 14:32:50 -0700758 download_fetcher->SetHeader(kXGoogleUpdateSessionId, session_id_);
Amin Hassanid3f4bea2018-04-30 14:52:40 -0700759 auto download_action =
760 std::make_unique<DownloadAction>(prefs_,
761 system_state_->boot_control(),
762 system_state_->hardware(),
763 system_state_,
764 download_fetcher, // passes ownership
765 interactive);
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700766 download_action->set_delegate(this);
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700767
Amin Hassanid3f4bea2018-04-30 14:52:40 -0700768 auto download_finished_action = std::make_unique<OmahaRequestAction>(
769 system_state_,
770 new OmahaEvent(OmahaEvent::kTypeUpdateDownloadFinished),
771 std::make_unique<LibcurlHttpFetcher>(GetProxyResolver(),
772 system_state_->hardware()),
Jae Hoon Kimedb65502019-06-14 11:52:17 -0700773 false,
774 session_id_);
Amin Hassanid3f4bea2018-04-30 14:52:40 -0700775 auto filesystem_verifier_action =
776 std::make_unique<FilesystemVerifierAction>();
777 auto update_complete_action = std::make_unique<OmahaRequestAction>(
778 system_state_,
779 new OmahaEvent(OmahaEvent::kTypeUpdateComplete),
780 std::make_unique<LibcurlHttpFetcher>(GetProxyResolver(),
781 system_state_->hardware()),
Jae Hoon Kimedb65502019-06-14 11:52:17 -0700782 false,
783 session_id_);
Amin Hassanid3f4bea2018-04-30 14:52:40 -0700784
785 auto postinstall_runner_action = std::make_unique<PostinstallRunnerAction>(
786 system_state_->boot_control(), system_state_->hardware());
787 postinstall_runner_action->set_delegate(this);
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700788
789 // Bond them together. We have to use the leaf-types when calling
790 // BondActions().
Amin Hassanid3f4bea2018-04-30 14:52:40 -0700791 BondActions(update_check_action.get(), response_handler_action.get());
792 BondActions(response_handler_action.get(), download_action.get());
793 BondActions(download_action.get(), filesystem_verifier_action.get());
794 BondActions(filesystem_verifier_action.get(),
795 postinstall_runner_action.get());
Chris Sosad317e402013-06-12 13:47:09 -0700796
Amin Hassanid3f4bea2018-04-30 14:52:40 -0700797 processor_->EnqueueAction(std::move(update_check_action));
798 processor_->EnqueueAction(std::move(response_handler_action));
Amin Hassani0882a512018-04-05 16:25:44 -0700799 processor_->EnqueueAction(std::move(update_boot_flags_action));
Amin Hassanid3f4bea2018-04-30 14:52:40 -0700800 processor_->EnqueueAction(std::move(download_started_action));
801 processor_->EnqueueAction(std::move(download_action));
802 processor_->EnqueueAction(std::move(download_finished_action));
803 processor_->EnqueueAction(std::move(filesystem_verifier_action));
804 processor_->EnqueueAction(std::move(postinstall_runner_action));
805 processor_->EnqueueAction(std::move(update_complete_action));
Chris Sosad317e402013-06-12 13:47:09 -0700806}
807
Chris Sosa44b9b7e2014-04-02 13:53:46 -0700808bool UpdateAttempter::Rollback(bool powerwash) {
Colin Howes978c1082018-12-03 11:46:12 -0800809 is_install_ = false;
Chris Sosa44b9b7e2014-04-02 13:53:46 -0700810 if (!CanRollback()) {
811 return false;
812 }
Chris Sosad317e402013-06-12 13:47:09 -0700813
Chris Sosa44b9b7e2014-04-02 13:53:46 -0700814 // Extra check for enterprise-enrolled devices since they don't support
815 // powerwash.
816 if (powerwash) {
817 // Enterprise-enrolled devices have an empty owner in their device policy.
818 string owner;
819 RefreshDevicePolicy();
820 const policy::DevicePolicy* device_policy = system_state_->device_policy();
821 if (device_policy && (!device_policy->GetOwner(&owner) || owner.empty())) {
822 LOG(ERROR) << "Enterprise device detected. "
823 << "Cannot perform a powerwash for enterprise devices.";
824 return false;
825 }
826 }
827
828 processor_->set_delegate(this);
Chris Sosaaa18e162013-06-20 13:20:30 -0700829
Chris Sosa28e479c2013-07-12 11:39:53 -0700830 // Initialize the default request params.
831 if (!omaha_request_params_->Init("", "", true)) {
832 LOG(ERROR) << "Unable to initialize Omaha request params.";
833 return false;
834 }
835
Chris Sosad317e402013-06-12 13:47:09 -0700836 LOG(INFO) << "Setting rollback options.";
Amin Hassanid3f4bea2018-04-30 14:52:40 -0700837 install_plan_.reset(new InstallPlan());
838 install_plan_->target_slot = GetRollbackSlot();
839 install_plan_->source_slot = system_state_->boot_control()->GetCurrentSlot();
Chris Sosa76a29ae2013-07-11 17:59:24 -0700840
Alex Deymo706a5ab2015-11-23 17:48:30 -0300841 TEST_AND_RETURN_FALSE(
Amin Hassanid3f4bea2018-04-30 14:52:40 -0700842 install_plan_->LoadPartitionsFromSlots(system_state_->boot_control()));
843 install_plan_->powerwash_required = powerwash;
Chris Sosad317e402013-06-12 13:47:09 -0700844
845 LOG(INFO) << "Using this install plan:";
Amin Hassanid3f4bea2018-04-30 14:52:40 -0700846 install_plan_->Dump();
Chris Sosad317e402013-06-12 13:47:09 -0700847
Amin Hassanid3f4bea2018-04-30 14:52:40 -0700848 auto install_plan_action =
849 std::make_unique<InstallPlanAction>(*install_plan_);
850 auto postinstall_runner_action = std::make_unique<PostinstallRunnerAction>(
851 system_state_->boot_control(), system_state_->hardware());
852 postinstall_runner_action->set_delegate(this);
853 BondActions(install_plan_action.get(), postinstall_runner_action.get());
854 processor_->EnqueueAction(std::move(install_plan_action));
855 processor_->EnqueueAction(std::move(postinstall_runner_action));
Chris Sosaaa18e162013-06-20 13:20:30 -0700856
857 // Update the payload state for Rollback.
858 system_state_->payload_state()->Rollback();
859
Christopher Wileycc8ce0e2015-10-01 16:48:47 -0700860 SetStatusAndNotify(UpdateStatus::ATTEMPTING_ROLLBACK);
Chris Sosad317e402013-06-12 13:47:09 -0700861
Amin Hassani0882a512018-04-05 16:25:44 -0700862 ScheduleProcessingStart();
Chris Sosaaa18e162013-06-20 13:20:30 -0700863 return true;
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -0700864}
865
Alex Vakulenko59e253e2014-02-24 10:40:21 -0800866bool UpdateAttempter::CanRollback() const {
Chris Sosa44b9b7e2014-04-02 13:53:46 -0700867 // We can only rollback if the update_engine isn't busy and we have a valid
868 // rollback partition.
Christopher Wileycc8ce0e2015-10-01 16:48:47 -0700869 return (status_ == UpdateStatus::IDLE &&
Alex Deymo763e7db2015-08-27 21:08:08 -0700870 GetRollbackSlot() != BootControlInterface::kInvalidSlot);
Alex Vakulenko2bddadd2014-03-27 13:23:46 -0700871}
872
Alex Deymo763e7db2015-08-27 21:08:08 -0700873BootControlInterface::Slot UpdateAttempter::GetRollbackSlot() const {
874 LOG(INFO) << "UpdateAttempter::GetRollbackSlot";
875 const unsigned int num_slots = system_state_->boot_control()->GetNumSlots();
876 const BootControlInterface::Slot current_slot =
877 system_state_->boot_control()->GetCurrentSlot();
Alex Vakulenko59e253e2014-02-24 10:40:21 -0800878
Alex Deymo763e7db2015-08-27 21:08:08 -0700879 LOG(INFO) << " Installed slots: " << num_slots;
880 LOG(INFO) << " Booted from slot: "
881 << BootControlInterface::SlotName(current_slot);
Alex Vakulenko59e253e2014-02-24 10:40:21 -0800882
Alex Deymo763e7db2015-08-27 21:08:08 -0700883 if (current_slot == BootControlInterface::kInvalidSlot || num_slots < 2) {
884 LOG(INFO) << "Device is not updateable.";
885 return BootControlInterface::kInvalidSlot;
Alex Vakulenko59e253e2014-02-24 10:40:21 -0800886 }
887
Alex Deymo763e7db2015-08-27 21:08:08 -0700888 vector<BootControlInterface::Slot> bootable_slots;
Alex Deymof7ead812015-10-23 17:37:27 -0700889 for (BootControlInterface::Slot slot = 0; slot < num_slots; slot++) {
Alex Deymo763e7db2015-08-27 21:08:08 -0700890 if (slot != current_slot &&
891 system_state_->boot_control()->IsSlotBootable(slot)) {
892 LOG(INFO) << "Found bootable slot "
893 << BootControlInterface::SlotName(slot);
894 return slot;
Alex Vakulenko59e253e2014-02-24 10:40:21 -0800895 }
896 }
Alex Deymo763e7db2015-08-27 21:08:08 -0700897 LOG(INFO) << "No other bootable slot found.";
898 return BootControlInterface::kInvalidSlot;
Alex Vakulenko2bddadd2014-03-27 13:23:46 -0700899}
900
Aaron Wood081c0232017-10-19 17:14:58 -0700901bool UpdateAttempter::CheckForUpdate(const string& app_version,
Jay Srinivasane73acab2012-07-10 14:34:03 -0700902 const string& omaha_url,
Aaron Wood081c0232017-10-19 17:14:58 -0700903 UpdateAttemptFlags flags) {
Jae Hoon Kimc437ea52019-07-11 11:20:38 -0700904 if (status_ != UpdateStatus::IDLE) {
905 LOG(INFO) << "Refusing to do an update as there is an "
906 << (is_install_ ? "install" : "update")
907 << " already in progress.";
Aaron Wood081c0232017-10-19 17:14:58 -0700908 return false;
909 }
910
Jae Hoon Kimc437ea52019-07-11 11:20:38 -0700911 bool interactive = !(flags & UpdateAttemptFlags::kFlagNonInteractive);
Jae Hoon Kimc437ea52019-07-11 11:20:38 -0700912 is_install_ = false;
913
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700914 LOG(INFO) << "Forced update check requested.";
David Pursell02c18642014-11-06 11:26:11 -0800915 forced_app_version_.clear();
916 forced_omaha_url_.clear();
917
918 // Certain conditions must be met to allow setting custom version and update
919 // server URLs. However, kScheduledAUTestURLRequest and kAUTestURLRequest are
920 // always allowed regardless of device state.
921 if (IsAnyUpdateSourceAllowed()) {
922 forced_app_version_ = app_version;
923 forced_omaha_url_ = omaha_url;
924 }
925 if (omaha_url == kScheduledAUTestURLRequest) {
Alex Deymoac41a822015-09-15 20:52:53 -0700926 forced_omaha_url_ = constants::kOmahaDefaultAUTestURL;
David Pursell02c18642014-11-06 11:26:11 -0800927 // Pretend that it's not user-initiated even though it is,
928 // so as to test scattering logic, etc. which get kicked off
929 // only in scheduled update checks.
930 interactive = false;
931 } else if (omaha_url == kAUTestURLRequest) {
Alex Deymoac41a822015-09-15 20:52:53 -0700932 forced_omaha_url_ = constants::kOmahaDefaultAUTestURL;
David Pursell02c18642014-11-06 11:26:11 -0800933 }
934
Aaron Wood081c0232017-10-19 17:14:58 -0700935 if (interactive) {
936 // Use the passed-in update attempt flags for this update attempt instead
937 // of the previously set ones.
938 current_update_attempt_flags_ = flags;
939 // Note: The caching for non-interactive update checks happens in
Jae Hoon Kim75daa382019-07-02 11:17:24 -0700940 // |OnUpdateScheduled()|.
Aaron Wood081c0232017-10-19 17:14:58 -0700941 }
942
Jae Hoon Kim2b73ac22019-07-02 11:17:24 -0700943 // |forced_update_pending_callback_| should always be set, but even in the
944 // case that it is not, we still return true indicating success because the
945 // scheduled periodic check will pick up these changes.
Gilad Arnold54fa66d2014-09-29 13:14:29 -0700946 if (forced_update_pending_callback_.get()) {
Jae Hoon Kim2b73ac22019-07-02 11:17:24 -0700947 // Always call |ScheduleUpdates()| before forcing an update. This is because
948 // we need an update to be scheduled for the
949 // |forced_update_pending_callback_| to have an effect. Here we don't need
950 // to care about the return value from |ScheduleUpdate()|.
Gilad Arnold54fa66d2014-09-29 13:14:29 -0700951 ScheduleUpdates();
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700952 forced_update_pending_callback_->Run(true, interactive);
Gilad Arnold54fa66d2014-09-29 13:14:29 -0700953 }
Aaron Wood081c0232017-10-19 17:14:58 -0700954 return true;
Andrew de los Reyes63b96d72010-05-10 13:08:54 -0700955}
956
Xiaochu Liuf53a5d32018-11-26 13:48:59 -0800957bool UpdateAttempter::CheckForInstall(const vector<string>& dlc_module_ids,
Xiaochu Liu88d90382018-08-29 16:09:11 -0700958 const string& omaha_url) {
Jae Hoon Kimc437ea52019-07-11 11:20:38 -0700959 if (status_ != UpdateStatus::IDLE) {
960 LOG(INFO) << "Refusing to do an install as there is an "
961 << (is_install_ ? "install" : "update")
962 << " already in progress.";
963 return false;
964 }
965
Xiaochu Liuf53a5d32018-11-26 13:48:59 -0800966 dlc_module_ids_ = dlc_module_ids;
Xiaochu Liu88d90382018-08-29 16:09:11 -0700967 is_install_ = true;
968 forced_omaha_url_.clear();
969
970 // Certain conditions must be met to allow setting custom version and update
971 // server URLs. However, kScheduledAUTestURLRequest and kAUTestURLRequest are
972 // always allowed regardless of device state.
973 if (IsAnyUpdateSourceAllowed()) {
974 forced_omaha_url_ = omaha_url;
975 }
Jae Hoon Kimc43f6bb2019-07-03 12:56:52 -0700976
977 if (omaha_url == kScheduledAUTestURLRequest ||
978 omaha_url == kAUTestURLRequest) {
Xiaochu Liu88d90382018-08-29 16:09:11 -0700979 forced_omaha_url_ = constants::kOmahaDefaultAUTestURL;
980 }
981
Jae Hoon Kim2b73ac22019-07-02 11:17:24 -0700982 // |forced_update_pending_callback_| should always be set, but even in the
983 // case that it is not, we still return true indicating success because the
984 // scheduled periodic check will pick up these changes.
985 if (forced_update_pending_callback_.get()) {
986 // Always call |ScheduleUpdates()| before forcing an update. This is because
987 // we need an update to be scheduled for the
988 // |forced_update_pending_callback_| to have an effect. Here we don't need
989 // to care about the return value from |ScheduleUpdate()|.
990 ScheduleUpdates();
991 forced_update_pending_callback_->Run(true, true);
Xiaochu Liu88d90382018-08-29 16:09:11 -0700992 }
993 return true;
994}
995
Darin Petkov296889c2010-07-23 16:20:54 -0700996bool UpdateAttempter::RebootIfNeeded() {
Amin Hassanie79eab62018-03-06 11:55:57 -0800997#ifdef __ANDROID__
Christopher Wileycc8ce0e2015-10-01 16:48:47 -0700998 if (status_ != UpdateStatus::UPDATED_NEED_REBOOT) {
Darin Petkov296889c2010-07-23 16:20:54 -0700999 LOG(INFO) << "Reboot requested, but status is "
1000 << UpdateStatusToString(status_) << ", so not rebooting.";
1001 return false;
1002 }
Amin Hassanie79eab62018-03-06 11:55:57 -08001003#endif // __ANDROID__
Daniel Erat65f1da02014-06-27 22:05:38 -07001004
Sen Jiangb8c6a8f2016-06-07 17:33:17 -07001005 if (system_state_->power_manager()->RequestReboot())
Daniel Erat65f1da02014-06-27 22:05:38 -07001006 return true;
1007
1008 return RebootDirectly();
Darin Petkov296889c2010-07-23 16:20:54 -07001009}
1010
David Zeuthen3c55abd2013-10-14 12:48:03 -07001011void UpdateAttempter::WriteUpdateCompletedMarker() {
Alex Deymo906191f2015-10-12 12:22:44 -07001012 string boot_id;
1013 if (!utils::GetBootId(&boot_id))
David Zeuthen3c55abd2013-10-14 12:48:03 -07001014 return;
Alex Deymo906191f2015-10-12 12:22:44 -07001015 prefs_->SetString(kPrefsUpdateCompletedOnBootId, boot_id);
David Zeuthen3c55abd2013-10-14 12:48:03 -07001016
1017 int64_t value = system_state_->clock()->GetBootTime().ToInternalValue();
Alex Deymo906191f2015-10-12 12:22:44 -07001018 prefs_->SetInt64(kPrefsUpdateCompletedBootTime, value);
David Zeuthen3c55abd2013-10-14 12:48:03 -07001019}
1020
Daniel Erat65f1da02014-06-27 22:05:38 -07001021bool UpdateAttempter::RebootDirectly() {
Amin Hassani3a4caa12019-11-06 11:12:28 -08001022 vector<string> command = {"/sbin/shutdown", "-r", "now"};
Daniel Erat65f1da02014-06-27 22:05:38 -07001023 int rc = 0;
Amin Hassani3a4caa12019-11-06 11:12:28 -08001024 Subprocess::SynchronousExec(command, &rc, nullptr, nullptr);
Daniel Erat65f1da02014-06-27 22:05:38 -07001025 return rc == 0;
1026}
1027
Gilad Arnoldec7f9162014-07-15 13:24:46 -07001028void UpdateAttempter::OnUpdateScheduled(EvalStatus status,
1029 const UpdateCheckParams& params) {
1030 waiting_for_scheduled_check_ = false;
1031
1032 if (status == EvalStatus::kSucceeded) {
1033 if (!params.updates_enabled) {
1034 LOG(WARNING) << "Updates permanently disabled.";
Gilad Arnold54fa66d2014-09-29 13:14:29 -07001035 // Signal disabled status, then switch right back to idle. This is
1036 // necessary for ensuring that observers waiting for a signal change will
1037 // actually notice one on subsequent calls. Note that we don't need to
1038 // re-schedule a check in this case as updates are permanently disabled;
1039 // further (forced) checks may still initiate a scheduling call.
Christopher Wileycc8ce0e2015-10-01 16:48:47 -07001040 SetStatusAndNotify(UpdateStatus::DISABLED);
1041 SetStatusAndNotify(UpdateStatus::IDLE);
Gilad Arnoldec7f9162014-07-15 13:24:46 -07001042 return;
1043 }
1044
Amin Hassanied37d682018-04-06 13:22:00 -07001045 LOG(INFO) << "Running " << (params.interactive ? "interactive" : "periodic")
Gilad Arnoldec7f9162014-07-15 13:24:46 -07001046 << " update.";
1047
Amin Hassanied37d682018-04-06 13:22:00 -07001048 if (!params.interactive) {
Aaron Wood081c0232017-10-19 17:14:58 -07001049 // Cache the update attempt flags that will be used by this update attempt
1050 // so that they can't be changed mid-way through.
1051 current_update_attempt_flags_ = update_attempt_flags_;
1052 }
1053
Aaron Woodbf5a2522017-10-04 10:58:36 -07001054 LOG(INFO) << "Update attempt flags in use = 0x" << std::hex
1055 << current_update_attempt_flags_;
1056
Amin Hassanied37d682018-04-06 13:22:00 -07001057 Update(forced_app_version_,
1058 forced_omaha_url_,
1059 params.target_channel,
1060 params.target_version_prefix,
Marton Hunyadyba51c3f2018-04-25 15:18:10 +02001061 params.rollback_allowed,
Zentaro Kavanagh28def4f2019-01-15 17:15:01 -08001062 params.rollback_data_save_requested,
Zentaro Kavanagh0ef9a2f2018-07-02 12:05:07 -07001063 params.rollback_allowed_milestones,
Marton Hunyadyba51c3f2018-04-25 15:18:10 +02001064 /*obey_proxies=*/false,
Amin Hassanied37d682018-04-06 13:22:00 -07001065 params.interactive);
Alex Deymo71479082016-03-25 17:54:28 -07001066 // Always clear the forced app_version and omaha_url after an update attempt
1067 // so the next update uses the defaults.
1068 forced_app_version_.clear();
1069 forced_omaha_url_.clear();
Gilad Arnoldec7f9162014-07-15 13:24:46 -07001070 } else {
1071 LOG(WARNING)
1072 << "Update check scheduling failed (possibly timed out); retrying.";
1073 ScheduleUpdates();
1074 }
1075
1076 // This check ensures that future update checks will be or are already
1077 // scheduled. The check should never fail. A check failure means that there's
1078 // a bug that will most likely prevent further automatic update checks. It
1079 // seems better to crash in such cases and restart the update_engine daemon
1080 // into, hopefully, a known good state.
Jae Hoon Kimba2fdce2019-07-11 13:18:58 -07001081 CHECK(IsBusyOrUpdateScheduled());
Gilad Arnoldec7f9162014-07-15 13:24:46 -07001082}
1083
1084void UpdateAttempter::UpdateLastCheckedTime() {
1085 last_checked_time_ = system_state_->clock()->GetWallclockTime().ToTimeT();
1086}
1087
Marton Hunyadye58bddb2018-04-10 20:27:26 +02001088void UpdateAttempter::UpdateRollbackHappened() {
1089 DCHECK(system_state_);
1090 DCHECK(system_state_->payload_state());
1091 DCHECK(policy_provider_);
1092 if (system_state_->payload_state()->GetRollbackHappened() &&
1093 (policy_provider_->device_policy_is_loaded() ||
1094 policy_provider_->IsConsumerDevice())) {
1095 // Rollback happened, but we already went through OOBE and policy is
1096 // present or it's a consumer device.
1097 system_state_->payload_state()->SetRollbackHappened(false);
1098 }
1099}
1100
Jae Hoon Kimed3fcc02019-07-11 14:35:38 -07001101void UpdateAttempter::ProcessingDoneInternal(const ActionProcessor* processor,
1102 ErrorCode code) {
Chris Sosa4f8ee272012-11-30 13:01:54 -08001103 // Reset cpu shares back to normal.
Alex Deymoab0d9762016-02-02 10:52:56 -08001104 cpu_limiter_.StopLimiter();
Darin Petkovc6c135c2010-08-11 13:36:18 -07001105
Amin Hassaniecb60d32019-06-17 18:09:10 -07001106 ResetInteractivityFlags();
Adolfo Victoria20262ad2018-08-06 10:40:11 -07001107
Christopher Wileycc8ce0e2015-10-01 16:48:47 -07001108 if (status_ == UpdateStatus::REPORTING_ERROR_EVENT) {
Darin Petkov09f96c32010-07-20 09:24:57 -07001109 LOG(INFO) << "Error event sent.";
Gilad Arnold1ebd8132012-03-05 10:19:29 -08001110
Amin Hassaniecb60d32019-06-17 18:09:10 -07001111 // Inform scheduler of new status.
Christopher Wileycc8ce0e2015-10-01 16:48:47 -07001112 SetStatusAndNotify(UpdateStatus::IDLE);
Gilad Arnold54fa66d2014-09-29 13:14:29 -07001113 ScheduleUpdates();
Gilad Arnold1ebd8132012-03-05 10:19:29 -08001114
Andrew de los Reyesc1d5c932011-04-20 17:15:47 -07001115 if (!fake_update_success_) {
1116 return;
1117 }
1118 LOG(INFO) << "Booted from FW B and tried to install new firmware, "
Amin Hassani7cc8bb02019-01-14 16:29:47 -08001119 "so requesting reboot from user.";
Darin Petkov09f96c32010-07-20 09:24:57 -07001120 }
1121
Sen Jiang89e24c12018-03-22 18:05:44 -07001122 attempt_error_code_ = utils::GetBaseErrorCode(code);
1123
Jae Hoon Kimed3fcc02019-07-11 14:35:38 -07001124 if (code != ErrorCode::kSuccess) {
1125 if (ScheduleErrorEventAction()) {
Colin Howesac170d92018-11-20 16:29:28 -08001126 return;
1127 }
Jae Hoon Kimed3fcc02019-07-11 14:35:38 -07001128 LOG(INFO) << "No update.";
1129 SetStatusAndNotify(UpdateStatus::IDLE);
Gilad Arnold54fa66d2014-09-29 13:14:29 -07001130 ScheduleUpdates();
Darin Petkov09f96c32010-07-20 09:24:57 -07001131 return;
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -07001132 }
Darin Petkov09f96c32010-07-20 09:24:57 -07001133
Jae Hoon Kimed3fcc02019-07-11 14:35:38 -07001134 ReportTimeToUpdateAppliedMetric();
1135 prefs_->SetInt64(kPrefsDeltaUpdateFailures, 0);
1136 prefs_->SetString(kPrefsPreviousVersion,
1137 omaha_request_params_->app_version());
1138 DeltaPerformer::ResetUpdateProgress(prefs_, false);
1139
1140 system_state_->payload_state()->UpdateSucceeded();
1141
1142 // Since we're done with scattering fully at this point, this is the
1143 // safest point delete the state files, as we're sure that the status is
1144 // set to reboot (which means no more updates will be applied until reboot)
1145 // This deletion is required for correctness as we want the next update
1146 // check to re-create a new random number for the update check count.
1147 // Similarly, we also delete the wall-clock-wait period that was persisted
1148 // so that we start with a new random value for the next update check
1149 // after reboot so that the same device is not favored or punished in any
1150 // way.
1151 prefs_->Delete(kPrefsUpdateCheckCount);
1152 system_state_->payload_state()->SetScatteringWaitPeriod(TimeDelta());
1153 system_state_->payload_state()->SetStagingWaitPeriod(TimeDelta());
1154 prefs_->Delete(kPrefsUpdateFirstSeenAt);
1155
1156 // Note: below this comment should only be on |ErrorCode::kSuccess|.
1157 if (is_install_) {
1158 ProcessingDoneInstall(processor, code);
1159 } else {
1160 ProcessingDoneUpdate(processor, code);
Darin Petkov1023a602010-08-30 13:47:51 -07001161 }
Jae Hoon Kimed3fcc02019-07-11 14:35:38 -07001162}
1163
1164void UpdateAttempter::ProcessingDoneInstall(const ActionProcessor* processor,
1165 ErrorCode code) {
Christopher Wileycc8ce0e2015-10-01 16:48:47 -07001166 SetStatusAndNotify(UpdateStatus::IDLE);
Gilad Arnold54fa66d2014-09-29 13:14:29 -07001167 ScheduleUpdates();
Jae Hoon Kimed3fcc02019-07-11 14:35:38 -07001168 LOG(INFO) << "DLC successfully installed, no reboot needed.";
1169}
1170
1171void UpdateAttempter::ProcessingDoneUpdate(const ActionProcessor* processor,
1172 ErrorCode code) {
1173 WriteUpdateCompletedMarker();
1174
1175 SetStatusAndNotify(UpdateStatus::UPDATED_NEED_REBOOT);
1176 ScheduleUpdates();
1177 LOG(INFO) << "Update successfully applied, waiting to reboot.";
1178
1179 // |install_plan_| is null during rollback operations, and the stats don't
1180 // make much sense then anyway.
1181 if (install_plan_) {
1182 // Generate an unique payload identifier.
1183 string target_version_uid;
1184 for (const auto& payload : install_plan_->payloads) {
1185 target_version_uid += brillo::data_encoding::Base64Encode(payload.hash) +
1186 ":" + payload.metadata_signature + ":";
1187 }
1188
1189 // If we just downloaded a rollback image, we should preserve this fact
1190 // over the following powerwash.
1191 if (install_plan_->is_rollback) {
1192 system_state_->payload_state()->SetRollbackHappened(true);
1193 system_state_->metrics_reporter()->ReportEnterpriseRollbackMetrics(
1194 /*success=*/true, install_plan_->version);
1195 }
1196
1197 // Expect to reboot into the new version to send the proper metric during
1198 // next boot.
1199 system_state_->payload_state()->ExpectRebootInNewVersion(
1200 target_version_uid);
1201 } else {
1202 // If we just finished a rollback, then we expect to have no Omaha
1203 // response. Otherwise, it's an error.
1204 if (system_state_->payload_state()->GetRollbackVersion().empty()) {
1205 LOG(ERROR) << "Can't send metrics because there was no Omaha response";
1206 }
1207 }
1208}
1209
1210// Delegate methods:
1211void UpdateAttempter::ProcessingDone(const ActionProcessor* processor,
1212 ErrorCode code) {
1213 LOG(INFO) << "Processing Done.";
1214 ProcessingDoneInternal(processor, code);
1215
1216 // Note: do cleanups here for any variables that need to be reset after a
1217 // failure, error, update, or install.
1218 is_install_ = false;
Andrew de los Reyes63b96d72010-05-10 13:08:54 -07001219}
1220
1221void UpdateAttempter::ProcessingStopped(const ActionProcessor* processor) {
Chris Sosa4f8ee272012-11-30 13:01:54 -08001222 // Reset cpu shares back to normal.
Alex Deymoab0d9762016-02-02 10:52:56 -08001223 cpu_limiter_.StopLimiter();
Andrew de los Reyes63b96d72010-05-10 13:08:54 -07001224 download_progress_ = 0.0;
Amin Hassaniecb60d32019-06-17 18:09:10 -07001225
1226 ResetInteractivityFlags();
1227
Christopher Wileycc8ce0e2015-10-01 16:48:47 -07001228 SetStatusAndNotify(UpdateStatus::IDLE);
Gilad Arnold54fa66d2014-09-29 13:14:29 -07001229 ScheduleUpdates();
Alex Vakulenko88b591f2014-08-28 16:48:57 -07001230 error_event_.reset(nullptr);
Andrew de los Reyes63b96d72010-05-10 13:08:54 -07001231}
1232
1233// Called whenever an action has finished processing, either successfully
1234// or otherwise.
1235void UpdateAttempter::ActionCompleted(ActionProcessor* processor,
1236 AbstractAction* action,
David Zeuthena99981f2013-04-29 13:42:47 -07001237 ErrorCode code) {
Darin Petkov1023a602010-08-30 13:47:51 -07001238 // Reset download progress regardless of whether or not the download
1239 // action succeeded. Also, get the response code from HTTP request
1240 // actions (update download as well as the initial update check
1241 // actions).
Andrew de los Reyes63b96d72010-05-10 13:08:54 -07001242 const string type = action->Type();
Darin Petkov1023a602010-08-30 13:47:51 -07001243 if (type == DownloadAction::StaticType()) {
Andrew de los Reyes63b96d72010-05-10 13:08:54 -07001244 download_progress_ = 0.0;
Gilad Arnoldcf175a02014-07-10 16:48:47 -07001245 DownloadAction* download_action = static_cast<DownloadAction*>(action);
Darin Petkov1023a602010-08-30 13:47:51 -07001246 http_response_code_ = download_action->GetHTTPResponseCode();
1247 } else if (type == OmahaRequestAction::StaticType()) {
1248 OmahaRequestAction* omaha_request_action =
Gilad Arnoldcf175a02014-07-10 16:48:47 -07001249 static_cast<OmahaRequestAction*>(action);
Darin Petkov1023a602010-08-30 13:47:51 -07001250 // If the request is not an event, then it's the update-check.
1251 if (!omaha_request_action->IsEvent()) {
1252 http_response_code_ = omaha_request_action->GetHTTPResponseCode();
Gilad Arnolda6dab942014-04-25 11:46:03 -07001253
1254 // Record the number of consecutive failed update checks.
1255 if (http_response_code_ == kHttpResponseInternalServerError ||
1256 http_response_code_ == kHttpResponseServiceUnavailable) {
1257 consecutive_failed_update_checks_++;
1258 } else {
1259 consecutive_failed_update_checks_ = 0;
1260 }
1261
Weidong Guo421ff332017-04-17 10:08:38 -07001262 const OmahaResponse& omaha_response =
1263 omaha_request_action->GetOutputObject();
Gilad Arnolda0258a52014-07-10 16:21:19 -07001264 // Store the server-dictated poll interval, if any.
1265 server_dictated_poll_interval_ =
Weidong Guo421ff332017-04-17 10:08:38 -07001266 std::max(0, omaha_response.poll_interval);
1267
1268 // This update is ignored by omaha request action because update over
1269 // cellular connection is not allowed. Needs to ask for user's permissions
1270 // to update.
1271 if (code == ErrorCode::kOmahaUpdateIgnoredOverCellular) {
1272 new_version_ = omaha_response.version;
1273 new_payload_size_ = 0;
1274 for (const auto& package : omaha_response.packages) {
1275 new_payload_size_ += package.size;
1276 }
1277 SetStatusAndNotify(UpdateStatus::NEED_PERMISSION_TO_UPDATE);
1278 }
Darin Petkov1023a602010-08-30 13:47:51 -07001279 }
Aaron Wood23bd3392017-10-06 14:48:25 -07001280 } else if (type == OmahaResponseHandlerAction::StaticType()) {
1281 // Depending on the returned error code, note that an update is available.
1282 if (code == ErrorCode::kOmahaUpdateDeferredPerPolicy ||
1283 code == ErrorCode::kSuccess) {
1284 // Note that the status will be updated to DOWNLOADING when some bytes
1285 // get actually downloaded from the server and the BytesReceived
1286 // callback is invoked. This avoids notifying the user that a download
1287 // has started in cases when the server and the client are unable to
1288 // initiate the download.
Amin Hassanid3f4bea2018-04-30 14:52:40 -07001289 auto omaha_response_handler_action =
1290 static_cast<OmahaResponseHandlerAction*>(action);
1291 install_plan_.reset(
1292 new InstallPlan(omaha_response_handler_action->install_plan()));
Aaron Wood23bd3392017-10-06 14:48:25 -07001293 UpdateLastCheckedTime();
Amin Hassanid3f4bea2018-04-30 14:52:40 -07001294 new_version_ = install_plan_->version;
Aaron Wood23bd3392017-10-06 14:48:25 -07001295 new_payload_size_ = 0;
Amin Hassanid3f4bea2018-04-30 14:52:40 -07001296 for (const auto& payload : install_plan_->payloads)
Aaron Wood23bd3392017-10-06 14:48:25 -07001297 new_payload_size_ += payload.size;
1298 cpu_limiter_.StartLimiter();
1299 SetStatusAndNotify(UpdateStatus::UPDATE_AVAILABLE);
1300 }
Darin Petkov1023a602010-08-30 13:47:51 -07001301 }
Aaron Wood23bd3392017-10-06 14:48:25 -07001302 // General failure cases.
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -07001303 if (code != ErrorCode::kSuccess) {
Darin Petkov7ed561b2011-10-04 02:59:03 -07001304 // If the current state is at or past the download phase, count the failure
1305 // in case a switch to full update becomes necessary. Ignore network
1306 // transfer timeouts and failures.
Amin Hassani89a37122018-03-23 12:59:24 -07001307 if (code != ErrorCode::kDownloadTransferError) {
1308 switch (status_) {
1309 case UpdateStatus::IDLE:
1310 case UpdateStatus::CHECKING_FOR_UPDATE:
1311 case UpdateStatus::UPDATE_AVAILABLE:
1312 case UpdateStatus::NEED_PERMISSION_TO_UPDATE:
1313 break;
1314 case UpdateStatus::DOWNLOADING:
1315 case UpdateStatus::VERIFYING:
1316 case UpdateStatus::FINALIZING:
1317 case UpdateStatus::UPDATED_NEED_REBOOT:
1318 case UpdateStatus::REPORTING_ERROR_EVENT:
1319 case UpdateStatus::ATTEMPTING_ROLLBACK:
1320 case UpdateStatus::DISABLED:
1321 MarkDeltaUpdateFailure();
1322 break;
1323 }
Darin Petkov36275772010-10-01 11:40:57 -07001324 }
Sen Jiang89e24c12018-03-22 18:05:44 -07001325 if (code != ErrorCode::kNoUpdate) {
1326 // On failure, schedule an error event to be sent to Omaha.
1327 CreatePendingErrorEvent(action, code);
1328 }
Andrew de los Reyes63b96d72010-05-10 13:08:54 -07001329 return;
Darin Petkov09f96c32010-07-20 09:24:57 -07001330 }
Aaron Wood23bd3392017-10-06 14:48:25 -07001331 // Find out which action completed (successfully).
1332 if (type == DownloadAction::StaticType()) {
Christopher Wileycc8ce0e2015-10-01 16:48:47 -07001333 SetStatusAndNotify(UpdateStatus::FINALIZING);
Amin Hassaniafd8cea2017-12-04 14:20:00 -08001334 } else if (type == FilesystemVerifierAction::StaticType()) {
1335 // Log the system properties before the postinst and after the file system
1336 // is verified. It used to be done in the postinst itself. But postinst
1337 // cannot do this anymore. On the other hand, these logs are frequently
1338 // looked at and it is preferable not to scatter them in random location in
1339 // the log and rather log it right before the postinst. The reason not do
1340 // this in the |PostinstallRunnerAction| is to prevent dependency from
1341 // libpayload_consumer to libupdate_engine.
1342 LogImageProperties();
Andrew de los Reyes63b96d72010-05-10 13:08:54 -07001343 }
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -07001344}
1345
Alex Deymo542c19b2015-12-03 07:43:31 -03001346void UpdateAttempter::BytesReceived(uint64_t bytes_progressed,
1347 uint64_t bytes_received,
1348 uint64_t total) {
1349 // The PayloadState keeps track of how many bytes were actually downloaded
1350 // from a given URL for the URL skipping logic.
1351 system_state_->payload_state()->DownloadProgress(bytes_progressed);
1352
Alex Deymo0d298542016-03-30 18:31:49 -07001353 double progress = 0;
1354 if (total)
1355 progress = static_cast<double>(bytes_received) / static_cast<double>(total);
1356 if (status_ != UpdateStatus::DOWNLOADING || bytes_received == total) {
Darin Petkovaf183052010-08-23 12:07:13 -07001357 download_progress_ = progress;
Christopher Wileycc8ce0e2015-10-01 16:48:47 -07001358 SetStatusAndNotify(UpdateStatus::DOWNLOADING);
Alex Deymo0d298542016-03-30 18:31:49 -07001359 } else {
1360 ProgressUpdate(progress);
Andrew de los Reyes63b96d72010-05-10 13:08:54 -07001361 }
1362}
1363
Alex Deymo542c19b2015-12-03 07:43:31 -03001364void UpdateAttempter::DownloadComplete() {
1365 system_state_->payload_state()->DownloadComplete();
1366}
1367
Alex Deymo0d298542016-03-30 18:31:49 -07001368void UpdateAttempter::ProgressUpdate(double progress) {
1369 // Self throttle based on progress. Also send notifications if progress is
1370 // too slow.
1371 if (progress == 1.0 ||
1372 progress - download_progress_ >= kBroadcastThresholdProgress ||
1373 TimeTicks::Now() - last_notify_time_ >=
1374 TimeDelta::FromSeconds(kBroadcastThresholdSeconds)) {
1375 download_progress_ = progress;
1376 BroadcastStatus();
1377 }
1378}
1379
Amin Hassaniecb60d32019-06-17 18:09:10 -07001380void UpdateAttempter::ResetInteractivityFlags() {
1381 // Reset the state that's only valid for a single update pass.
1382 current_update_attempt_flags_ = UpdateAttemptFlags::kNone;
1383
1384 if (forced_update_pending_callback_.get())
1385 // Clear prior interactive requests once the processor is done.
1386 forced_update_pending_callback_->Run(false, false);
1387}
1388
Jay Srinivasanc1ba09a2012-08-14 14:15:57 -07001389bool UpdateAttempter::ResetStatus() {
1390 LOG(INFO) << "Attempting to reset state from "
Christopher Wileycc8ce0e2015-10-01 16:48:47 -07001391 << UpdateStatusToString(status_) << " to UpdateStatus::IDLE";
Jay Srinivasanc1ba09a2012-08-14 14:15:57 -07001392
1393 switch (status_) {
Christopher Wileycc8ce0e2015-10-01 16:48:47 -07001394 case UpdateStatus::IDLE:
Jay Srinivasanc1ba09a2012-08-14 14:15:57 -07001395 // no-op.
1396 return true;
1397
Amin Hassani7cc8bb02019-01-14 16:29:47 -08001398 case UpdateStatus::UPDATED_NEED_REBOOT: {
Jay Srinivasan1c0fe792013-03-28 16:45:25 -07001399 bool ret_value = true;
Christopher Wileycc8ce0e2015-10-01 16:48:47 -07001400 status_ = UpdateStatus::IDLE;
Jay Srinivasanc1ba09a2012-08-14 14:15:57 -07001401
Jay Srinivasan1c0fe792013-03-28 16:45:25 -07001402 // Remove the reboot marker so that if the machine is rebooted
Jay Srinivasanc1ba09a2012-08-14 14:15:57 -07001403 // after resetting to idle state, it doesn't go back to
Christopher Wileycc8ce0e2015-10-01 16:48:47 -07001404 // UpdateStatus::UPDATED_NEED_REBOOT state.
Alex Deymo906191f2015-10-12 12:22:44 -07001405 ret_value = prefs_->Delete(kPrefsUpdateCompletedOnBootId) && ret_value;
1406 ret_value = prefs_->Delete(kPrefsUpdateCompletedBootTime) && ret_value;
Jay Srinivasan1c0fe792013-03-28 16:45:25 -07001407
Alex Deymo9870c0e2015-09-23 13:58:31 -07001408 // Update the boot flags so the current slot has higher priority.
1409 BootControlInterface* boot_control = system_state_->boot_control();
1410 if (!boot_control->SetActiveBootSlot(boot_control->GetCurrentSlot()))
1411 ret_value = false;
1412
Alex Deymo52590332016-11-29 18:29:13 -08001413 // Mark the current slot as successful again, since marking it as active
1414 // may reset the successful bit. We ignore the result of whether marking
1415 // the current slot as successful worked.
Amin Hassani7cc8bb02019-01-14 16:29:47 -08001416 if (!boot_control->MarkBootSuccessfulAsync(Bind([](bool successful) {})))
Alex Deymo52590332016-11-29 18:29:13 -08001417 ret_value = false;
1418
Alex Deymo42432912013-07-12 20:21:15 -07001419 // Notify the PayloadState that the successful payload was canceled.
1420 system_state_->payload_state()->ResetUpdateStatus();
1421
Alex Deymo87c08862015-10-30 21:56:55 -07001422 // The previous version is used to report back to omaha after reboot that
1423 // we actually rebooted into the new version from this "prev-version". We
1424 // need to clear out this value now to prevent it being sent on the next
1425 // updatecheck request.
1426 ret_value = prefs_->SetString(kPrefsPreviousVersion, "") && ret_value;
1427
Alex Deymo906191f2015-10-12 12:22:44 -07001428 LOG(INFO) << "Reset status " << (ret_value ? "successful" : "failed");
Jay Srinivasan1c0fe792013-03-28 16:45:25 -07001429 return ret_value;
Jay Srinivasanc1ba09a2012-08-14 14:15:57 -07001430 }
1431
1432 default:
1433 LOG(ERROR) << "Reset not allowed in this state.";
1434 return false;
1435 }
1436}
1437
Aaron Wood7f92e2b2017-08-28 14:51:21 -07001438bool UpdateAttempter::GetStatus(UpdateEngineStatus* out_status) {
Aaron Wood795c5b42017-12-05 16:06:13 -08001439 out_status->last_checked_time = last_checked_time_;
Aaron Wood7f92e2b2017-08-28 14:51:21 -07001440 out_status->status = status_;
1441 out_status->current_version = omaha_request_params_->app_version();
Aaron Wood7f92e2b2017-08-28 14:51:21 -07001442 out_status->progress = download_progress_;
1443 out_status->new_size_bytes = new_payload_size_;
1444 out_status->new_version = new_version_;
Amin Hassani9be122e2019-08-29 09:20:12 -07001445 out_status->is_enterprise_rollback =
1446 install_plan_ && install_plan_->is_rollback;
Jae Hoon Kim2f78c1c2019-07-25 13:20:43 -07001447 out_status->is_install = is_install_;
Jae Hoon Kim051627a2019-09-03 12:56:32 -07001448
1449 string str_eol_date;
1450 system_state_->prefs()->GetString(kPrefsOmahaEolDate, &str_eol_date);
1451 out_status->eol_date = StringToEolDate(str_eol_date);
1452
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -07001453 return true;
1454}
1455
Darin Petkov61635a92011-05-18 16:20:36 -07001456void UpdateAttempter::BroadcastStatus() {
Aaron Wood7f92e2b2017-08-28 14:51:21 -07001457 UpdateEngineStatus broadcast_status;
1458 // Use common method for generating the current status.
1459 GetStatus(&broadcast_status);
1460
Alex Deymofa78f142016-01-26 21:36:16 -08001461 for (const auto& observer : service_observers_) {
Aaron Wood7f92e2b2017-08-28 14:51:21 -07001462 observer->SendStatusUpdate(broadcast_status);
Alex Deymofa78f142016-01-26 21:36:16 -08001463 }
Darin Petkovaf183052010-08-23 12:07:13 -07001464 last_notify_time_ = TimeTicks::Now();
Alex Deymofa78f142016-01-26 21:36:16 -08001465}
1466
Amin Hassani7cc8bb02019-01-14 16:29:47 -08001467uint32_t UpdateAttempter::GetErrorCodeFlags() {
Jay Srinivasan55f50c22013-01-10 19:24:35 -08001468 uint32_t flags = 0;
1469
J. Richard Barnette056b0ab2013-10-29 15:24:56 -07001470 if (!system_state_->hardware()->IsNormalBootMode())
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -07001471 flags |= static_cast<uint32_t>(ErrorCode::kDevModeFlag);
Jay Srinivasan55f50c22013-01-10 19:24:35 -08001472
Amin Hassanid3f4bea2018-04-30 14:52:40 -07001473 if (install_plan_ && install_plan_->is_resume)
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -07001474 flags |= static_cast<uint32_t>(ErrorCode::kResumedFlag);
Jay Srinivasan55f50c22013-01-10 19:24:35 -08001475
J. Richard Barnette056b0ab2013-10-29 15:24:56 -07001476 if (!system_state_->hardware()->IsOfficialBuild())
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -07001477 flags |= static_cast<uint32_t>(ErrorCode::kTestImageFlag);
Jay Srinivasan55f50c22013-01-10 19:24:35 -08001478
Sen Jiangdaeaa432018-10-09 18:18:45 -07001479 if (!omaha_request_params_->IsUpdateUrlOfficial()) {
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -07001480 flags |= static_cast<uint32_t>(ErrorCode::kTestOmahaUrlFlag);
Alex Deymoac41a822015-09-15 20:52:53 -07001481 }
Jay Srinivasan55f50c22013-01-10 19:24:35 -08001482
1483 return flags;
1484}
1485
David Zeuthena99981f2013-04-29 13:42:47 -07001486bool UpdateAttempter::ShouldCancel(ErrorCode* cancel_reason) {
Jay Srinivasan1c0fe792013-03-28 16:45:25 -07001487 // Check if the channel we're attempting to update to is the same as the
1488 // target channel currently chosen by the user.
1489 OmahaRequestParams* params = system_state_->request_params();
1490 if (params->download_channel() != params->target_channel()) {
1491 LOG(ERROR) << "Aborting download as target channel: "
1492 << params->target_channel()
1493 << " is different from the download channel: "
1494 << params->download_channel();
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -07001495 *cancel_reason = ErrorCode::kUpdateCanceledByChannelChange;
Jay Srinivasan1c0fe792013-03-28 16:45:25 -07001496 return true;
1497 }
1498
1499 return false;
1500}
1501
Nam T. Nguyen7d623eb2014-05-13 16:06:28 -07001502void UpdateAttempter::SetStatusAndNotify(UpdateStatus status) {
Darin Petkov61635a92011-05-18 16:20:36 -07001503 status_ = status;
Darin Petkov61635a92011-05-18 16:20:36 -07001504 BroadcastStatus();
1505}
1506
Darin Petkov777dbfa2010-07-20 15:03:37 -07001507void UpdateAttempter::CreatePendingErrorEvent(AbstractAction* action,
David Zeuthena99981f2013-04-29 13:42:47 -07001508 ErrorCode code) {
Sen Jiang89e24c12018-03-22 18:05:44 -07001509 if (error_event_.get() || status_ == UpdateStatus::REPORTING_ERROR_EVENT) {
Darin Petkov09f96c32010-07-20 09:24:57 -07001510 // This shouldn't really happen.
1511 LOG(WARNING) << "There's already an existing pending error event.";
1512 return;
1513 }
Darin Petkov777dbfa2010-07-20 15:03:37 -07001514
Jay Srinivasan56d5aa42012-03-26 14:27:59 -07001515 // Classify the code to generate the appropriate result so that
1516 // the Borgmon charts show up the results correctly.
1517 // Do this before calling GetErrorCodeForAction which could potentially
1518 // augment the bit representation of code and thus cause no matches for
1519 // the switch cases below.
1520 OmahaEvent::Result event_result;
1521 switch (code) {
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -07001522 case ErrorCode::kOmahaUpdateIgnoredPerPolicy:
1523 case ErrorCode::kOmahaUpdateDeferredPerPolicy:
1524 case ErrorCode::kOmahaUpdateDeferredForBackoff:
Jay Srinivasan56d5aa42012-03-26 14:27:59 -07001525 event_result = OmahaEvent::kResultUpdateDeferred;
1526 break;
1527 default:
1528 event_result = OmahaEvent::kResultError;
1529 break;
1530 }
1531
Darin Petkov777dbfa2010-07-20 15:03:37 -07001532 code = GetErrorCodeForAction(action, code);
Gilad Arnoldd1c4d2d2014-06-05 14:07:53 -07001533 fake_update_success_ = code == ErrorCode::kPostinstallBootedFromFirmwareB;
Darin Petkov18c7bce2011-06-16 14:07:00 -07001534
Jay Srinivasan55f50c22013-01-10 19:24:35 -08001535 // Compute the final error code with all the bit flags to be sent to Omaha.
Amin Hassani7cc8bb02019-01-14 16:29:47 -08001536 code =
1537 static_cast<ErrorCode>(static_cast<uint32_t>(code) | GetErrorCodeFlags());
1538 error_event_.reset(
1539 new OmahaEvent(OmahaEvent::kTypeUpdateComplete, event_result, code));
Darin Petkov09f96c32010-07-20 09:24:57 -07001540}
1541
1542bool UpdateAttempter::ScheduleErrorEventAction() {
Alex Vakulenko88b591f2014-08-28 16:48:57 -07001543 if (error_event_.get() == nullptr)
Darin Petkov09f96c32010-07-20 09:24:57 -07001544 return false;
1545
Jay Srinivasan6f6ea002012-12-14 11:26:28 -08001546 LOG(ERROR) << "Update failed.";
1547 system_state_->payload_state()->UpdateFailed(error_event_->error_code);
1548
Marton Hunyadya0302682018-05-16 18:52:13 +02001549 // Send metrics if it was a rollback.
Amin Hassanid3f4bea2018-04-30 14:52:40 -07001550 if (install_plan_ && install_plan_->is_rollback) {
1551 system_state_->metrics_reporter()->ReportEnterpriseRollbackMetrics(
1552 /*success=*/false, install_plan_->version);
Marton Hunyadya0302682018-05-16 18:52:13 +02001553 }
1554
Jay Srinivasan55f50c22013-01-10 19:24:35 -08001555 // Send it to Omaha.
Alex Deymoaf9a8632015-09-23 18:51:48 -07001556 LOG(INFO) << "Reporting the error event";
Amin Hassanid3f4bea2018-04-30 14:52:40 -07001557 auto error_event_action = std::make_unique<OmahaRequestAction>(
1558 system_state_,
1559 error_event_.release(), // Pass ownership.
1560 std::make_unique<LibcurlHttpFetcher>(GetProxyResolver(),
1561 system_state_->hardware()),
Jae Hoon Kimedb65502019-06-14 11:52:17 -07001562 false,
1563 session_id_);
Amin Hassanid3f4bea2018-04-30 14:52:40 -07001564 processor_->EnqueueAction(std::move(error_event_action));
Christopher Wileycc8ce0e2015-10-01 16:48:47 -07001565 SetStatusAndNotify(UpdateStatus::REPORTING_ERROR_EVENT);
Darin Petkovf42cc1c2010-09-01 09:03:02 -07001566 processor_->StartProcessing();
Darin Petkov09f96c32010-07-20 09:24:57 -07001567 return true;
1568}
1569
Darin Petkov58dd1342011-05-06 12:05:13 -07001570void UpdateAttempter::ScheduleProcessingStart() {
1571 LOG(INFO) << "Scheduling an action processor start.";
Alex Deymo60ca1a72015-06-18 18:19:15 -07001572 MessageLoop::current()->PostTask(
1573 FROM_HERE,
Luis Hector Chavezf1cf3482016-07-19 14:29:19 -07001574 Bind([](ActionProcessor* processor) { processor->StartProcessing(); },
1575 base::Unretained(processor_.get())));
Darin Petkov58dd1342011-05-06 12:05:13 -07001576}
1577
Darin Petkov36275772010-10-01 11:40:57 -07001578void UpdateAttempter::DisableDeltaUpdateIfNeeded() {
1579 int64_t delta_failures;
Jay Srinivasanae4697c2013-03-18 17:08:08 -07001580 if (omaha_request_params_->delta_okay() &&
Darin Petkov36275772010-10-01 11:40:57 -07001581 prefs_->GetInt64(kPrefsDeltaUpdateFailures, &delta_failures) &&
1582 delta_failures >= kMaxDeltaUpdateFailures) {
1583 LOG(WARNING) << "Too many delta update failures, forcing full update.";
Jay Srinivasanae4697c2013-03-18 17:08:08 -07001584 omaha_request_params_->set_delta_okay(false);
Darin Petkov36275772010-10-01 11:40:57 -07001585 }
1586}
1587
1588void UpdateAttempter::MarkDeltaUpdateFailure() {
Darin Petkov2dd01092010-10-08 15:43:05 -07001589 // Don't try to resume a failed delta update.
1590 DeltaPerformer::ResetUpdateProgress(prefs_, false);
Darin Petkov36275772010-10-01 11:40:57 -07001591 int64_t delta_failures;
1592 if (!prefs_->GetInt64(kPrefsDeltaUpdateFailures, &delta_failures) ||
1593 delta_failures < 0) {
1594 delta_failures = 0;
1595 }
1596 prefs_->SetInt64(kPrefsDeltaUpdateFailures, ++delta_failures);
1597}
1598
Thieu Le116fda32011-04-19 11:01:54 -07001599void UpdateAttempter::PingOmaha() {
Thieu Led88a8572011-05-26 09:09:19 -07001600 if (!processor_->IsRunning()) {
Amin Hassaniecb60d32019-06-17 18:09:10 -07001601 ResetInteractivityFlags();
1602
Amin Hassanid3f4bea2018-04-30 14:52:40 -07001603 auto ping_action = std::make_unique<OmahaRequestAction>(
Alex Deymoc1c17b42015-11-23 03:53:15 -03001604 system_state_,
1605 nullptr,
Ben Chanab5a0af2017-10-12 14:57:50 -07001606 std::make_unique<LibcurlHttpFetcher>(GetProxyResolver(),
Ben Chan5c02c132017-06-27 07:10:36 -07001607 system_state_->hardware()),
Jae Hoon Kimedb65502019-06-14 11:52:17 -07001608 true,
1609 "" /* session_id */);
Alex Vakulenko88b591f2014-08-28 16:48:57 -07001610 processor_->set_delegate(nullptr);
Amin Hassanid3f4bea2018-04-30 14:52:40 -07001611 processor_->EnqueueAction(std::move(ping_action));
Thieu Led88a8572011-05-26 09:09:19 -07001612 // Call StartProcessing() synchronously here to avoid any race conditions
1613 // caused by multiple outstanding ping Omaha requests. If we call
1614 // StartProcessing() asynchronously, the device can be suspended before we
1615 // get a chance to callback to StartProcessing(). When the device resumes
1616 // (assuming the device sleeps longer than the next update check period),
1617 // StartProcessing() is called back and at the same time, the next update
1618 // check is fired which eventually invokes StartProcessing(). A crash
1619 // can occur because StartProcessing() checks to make sure that the
1620 // processor is idle which it isn't due to the two concurrent ping Omaha
1621 // requests.
1622 processor_->StartProcessing();
1623 } else {
Darin Petkov58dd1342011-05-06 12:05:13 -07001624 LOG(WARNING) << "Action processor running, Omaha ping suppressed.";
Darin Petkov58dd1342011-05-06 12:05:13 -07001625 }
Thieu Led88a8572011-05-26 09:09:19 -07001626
Gilad Arnoldec7f9162014-07-15 13:24:46 -07001627 // Update the last check time here; it may be re-updated when an Omaha
1628 // response is received, but this will prevent us from repeatedly scheduling
1629 // checks in the case where a response is not received.
1630 UpdateLastCheckedTime();
1631
Thieu Led88a8572011-05-26 09:09:19 -07001632 // Update the status which will schedule the next update check
Christopher Wileycc8ce0e2015-10-01 16:48:47 -07001633 SetStatusAndNotify(UpdateStatus::UPDATED_NEED_REBOOT);
Gilad Arnold54fa66d2014-09-29 13:14:29 -07001634 ScheduleUpdates();
Thieu Le116fda32011-04-19 11:01:54 -07001635}
1636
Jay Srinivasan480ddfa2012-06-01 19:15:26 -07001637bool UpdateAttempter::DecrementUpdateCheckCount() {
Ben Chan9abb7632014-08-07 00:10:53 -07001638 int64_t update_check_count_value;
Jay Srinivasan480ddfa2012-06-01 19:15:26 -07001639
1640 if (!prefs_->Exists(kPrefsUpdateCheckCount)) {
1641 // This file does not exist. This means we haven't started our update
1642 // check count down yet, so nothing more to do. This file will be created
1643 // later when we first satisfy the wall-clock-based-wait period.
1644 LOG(INFO) << "No existing update check count. That's normal.";
1645 return true;
1646 }
1647
1648 if (prefs_->GetInt64(kPrefsUpdateCheckCount, &update_check_count_value)) {
1649 // Only if we're able to read a proper integer value, then go ahead
1650 // and decrement and write back the result in the same file, if needed.
1651 LOG(INFO) << "Update check count = " << update_check_count_value;
1652
1653 if (update_check_count_value == 0) {
1654 // It could be 0, if, for some reason, the file didn't get deleted
1655 // when we set our status to waiting for reboot. so we just leave it
1656 // as is so that we can prevent another update_check wait for this client.
1657 LOG(INFO) << "Not decrementing update check count as it's already 0.";
1658 return true;
1659 }
1660
1661 if (update_check_count_value > 0)
1662 update_check_count_value--;
1663 else
1664 update_check_count_value = 0;
1665
1666 // Write out the new value of update_check_count_value.
1667 if (prefs_->SetInt64(kPrefsUpdateCheckCount, update_check_count_value)) {
Sen Jiang771f6482018-04-04 17:59:10 -07001668 // We successfully wrote out the new value, so enable the
Jay Srinivasan480ddfa2012-06-01 19:15:26 -07001669 // update check based wait.
1670 LOG(INFO) << "New update check count = " << update_check_count_value;
1671 return true;
1672 }
1673 }
1674
1675 LOG(INFO) << "Deleting update check count state due to read/write errors.";
1676
1677 // We cannot read/write to the file, so disable the update check based wait
1678 // so that we don't get stuck in this OS version by any chance (which could
1679 // happen if there's some bug that causes to read/write incorrectly).
1680 // Also attempt to delete the file to do our best effort to cleanup.
1681 prefs_->Delete(kPrefsUpdateCheckCount);
1682 return false;
1683}
Chris Sosad317e402013-06-12 13:47:09 -07001684
David Zeuthene4c58bf2013-06-18 17:26:50 -07001685void UpdateAttempter::UpdateEngineStarted() {
Alex Vakulenkodea2eac2014-03-14 15:56:59 -07001686 // If we just booted into a new update, keep the previous OS version
1687 // in case we rebooted because of a crash of the old version, so we
Alex Vakulenko88b591f2014-08-28 16:48:57 -07001688 // can do a proper crash report with correct information.
Alex Vakulenkodea2eac2014-03-14 15:56:59 -07001689 // This must be done before calling
1690 // system_state_->payload_state()->UpdateEngineStarted() since it will
1691 // delete SystemUpdated marker file.
1692 if (system_state_->system_rebooted() &&
1693 prefs_->Exists(kPrefsSystemUpdatedMarker)) {
1694 if (!prefs_->GetString(kPrefsPreviousVersion, &prev_version_)) {
1695 // If we fail to get the version string, make sure it stays empty.
1696 prev_version_.clear();
1697 }
1698 }
1699
David Zeuthene4c58bf2013-06-18 17:26:50 -07001700 system_state_->payload_state()->UpdateEngineStarted();
David Zeuthen8f191b22013-08-06 12:27:50 -07001701 StartP2PAtStartup();
1702}
1703
1704bool UpdateAttempter::StartP2PAtStartup() {
Alex Vakulenko88b591f2014-08-28 16:48:57 -07001705 if (system_state_ == nullptr ||
David Zeuthen8f191b22013-08-06 12:27:50 -07001706 !system_state_->p2p_manager()->IsP2PEnabled()) {
1707 LOG(INFO) << "Not starting p2p at startup since it's not enabled.";
1708 return false;
1709 }
1710
1711 if (system_state_->p2p_manager()->CountSharedFiles() < 1) {
1712 LOG(INFO) << "Not starting p2p at startup since our application "
1713 << "is not sharing any files.";
1714 return false;
1715 }
1716
1717 return StartP2PAndPerformHousekeeping();
1718}
1719
1720bool UpdateAttempter::StartP2PAndPerformHousekeeping() {
Alex Vakulenko88b591f2014-08-28 16:48:57 -07001721 if (system_state_ == nullptr)
David Zeuthen8f191b22013-08-06 12:27:50 -07001722 return false;
1723
1724 if (!system_state_->p2p_manager()->IsP2PEnabled()) {
1725 LOG(INFO) << "Not starting p2p since it's not enabled.";
1726 return false;
1727 }
1728
1729 LOG(INFO) << "Ensuring that p2p is running.";
1730 if (!system_state_->p2p_manager()->EnsureP2PRunning()) {
1731 LOG(ERROR) << "Error starting p2p.";
1732 return false;
1733 }
1734
1735 LOG(INFO) << "Performing p2p housekeeping.";
1736 if (!system_state_->p2p_manager()->PerformHousekeeping()) {
1737 LOG(ERROR) << "Error performing housekeeping for p2p.";
1738 return false;
1739 }
1740
1741 LOG(INFO) << "Done performing p2p housekeeping.";
1742 return true;
David Zeuthene4c58bf2013-06-18 17:26:50 -07001743}
1744
Amin Hassani7cc8bb02019-01-14 16:29:47 -08001745bool UpdateAttempter::GetBootTimeAtUpdate(Time* out_boot_time) {
Alex Deymo906191f2015-10-12 12:22:44 -07001746 // In case of an update_engine restart without a reboot, we stored the boot_id
1747 // when the update was completed by setting a pref, so we can check whether
1748 // the last update was on this boot or a previous one.
1749 string boot_id;
1750 TEST_AND_RETURN_FALSE(utils::GetBootId(&boot_id));
1751
1752 string update_completed_on_boot_id;
1753 if (!prefs_->Exists(kPrefsUpdateCompletedOnBootId) ||
1754 !prefs_->GetString(kPrefsUpdateCompletedOnBootId,
1755 &update_completed_on_boot_id) ||
1756 update_completed_on_boot_id != boot_id)
David Zeuthen3c55abd2013-10-14 12:48:03 -07001757 return false;
1758
Alex Deymo906191f2015-10-12 12:22:44 -07001759 // Short-circuit avoiding the read in case out_boot_time is nullptr.
1760 if (out_boot_time) {
1761 int64_t boot_time = 0;
1762 // Since the kPrefsUpdateCompletedOnBootId was correctly set, this pref
1763 // should not fail.
1764 TEST_AND_RETURN_FALSE(
1765 prefs_->GetInt64(kPrefsUpdateCompletedBootTime, &boot_time));
1766 *out_boot_time = Time::FromInternalValue(boot_time);
David Zeuthen3c55abd2013-10-14 12:48:03 -07001767 }
David Zeuthen3c55abd2013-10-14 12:48:03 -07001768 return true;
1769}
1770
Jae Hoon Kimba2fdce2019-07-11 13:18:58 -07001771bool UpdateAttempter::IsBusyOrUpdateScheduled() {
Christopher Wileycc8ce0e2015-10-01 16:48:47 -07001772 return ((status_ != UpdateStatus::IDLE &&
1773 status_ != UpdateStatus::UPDATED_NEED_REBOOT) ||
Gilad Arnold54fa66d2014-09-29 13:14:29 -07001774 waiting_for_scheduled_check_);
1775}
1776
Sen Jiangdaeaa432018-10-09 18:18:45 -07001777bool UpdateAttempter::IsAnyUpdateSourceAllowed() const {
David Pursell907b4fa2015-01-27 10:27:38 -08001778 // We allow updates from any source if either of these are true:
1779 // * The device is running an unofficial (dev/test) image.
1780 // * The debugd dev features are accessible (i.e. in devmode with no owner).
1781 // This protects users running a base image, while still allowing a specific
1782 // window (gated by the debug dev features) where `cros flash` is usable.
David Pursell02c18642014-11-06 11:26:11 -08001783 if (!system_state_->hardware()->IsOfficialBuild()) {
1784 LOG(INFO) << "Non-official build; allowing any update source.";
1785 return true;
1786 }
1787
Sen Jiange67bb5b2016-06-20 15:53:56 -07001788 if (system_state_->hardware()->AreDevFeaturesEnabled()) {
1789 LOG(INFO) << "Developer features enabled; allowing custom update sources.";
David Pursell02c18642014-11-06 11:26:11 -08001790 return true;
1791 }
Sen Jiange67bb5b2016-06-20 15:53:56 -07001792
1793 LOG(INFO)
1794 << "Developer features disabled; disallowing custom update sources.";
David Pursell02c18642014-11-06 11:26:11 -08001795 return false;
1796}
1797
May Lippert60aa3ca2018-08-15 16:55:29 -07001798void UpdateAttempter::ReportTimeToUpdateAppliedMetric() {
1799 const policy::DevicePolicy* device_policy = system_state_->device_policy();
1800 if (device_policy && device_policy->IsEnterpriseEnrolled()) {
1801 vector<policy::DevicePolicy::WeeklyTimeInterval> parsed_intervals;
1802 bool has_time_restrictions =
1803 device_policy->GetDisallowedTimeIntervals(&parsed_intervals);
1804
1805 int64_t update_first_seen_at_int;
1806 if (system_state_->prefs()->Exists(kPrefsUpdateFirstSeenAt)) {
1807 if (system_state_->prefs()->GetInt64(kPrefsUpdateFirstSeenAt,
1808 &update_first_seen_at_int)) {
1809 TimeDelta update_delay =
1810 system_state_->clock()->GetWallclockTime() -
1811 Time::FromInternalValue(update_first_seen_at_int);
1812 system_state_->metrics_reporter()
1813 ->ReportEnterpriseUpdateSeenToDownloadDays(has_time_restrictions,
1814 update_delay.InDays());
1815 }
1816 }
1817 }
1818}
1819
Andrew de los Reyes4e9b9f42010-04-26 15:06:43 -07001820} // namespace chromeos_update_engine