blob: 6da30c96ab8bdea1da540add310d9257dd0345bf [file] [log] [blame]
Alex Deymoaea4c1c2015-08-19 20:24:43 -07001//
2// Copyright (C) 2014 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//
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070016
Alex Deymo63784a52014-05-28 10:46:14 -070017#include "update_engine/update_manager/real_updater_provider.h"
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070018
19#include <inttypes.h>
20
Amin Hassani03277de2020-07-28 12:32:49 -070021#include <algorithm>
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070022#include <string>
23
Gilad Arnold44dc3bf2014-07-18 23:39:38 -070024#include <base/bind.h>
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070025#include <base/strings/stringprintf.h>
Alex Deymoc7ab6162014-04-25 18:32:50 -070026#include <base/time/time.h>
Alex Deymod6deb1d2015-08-28 15:54:37 -070027#include <update_engine/dbus-constants.h>
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070028
Aaron Wood7f92e2b2017-08-28 14:51:21 -070029#include "update_engine/client_library/include/update_engine/update_status.h"
Alex Deymo39910dc2015-11-09 17:04:30 -080030#include "update_engine/common/clock_interface.h"
31#include "update_engine/common/prefs.h"
Amin Hassani538bd592020-11-04 20:46:08 -080032#include "update_engine/common/system_state.h"
Amin Hassaniec7bc112020-10-29 16:47:58 -070033#include "update_engine/cros/omaha_request_params.h"
34#include "update_engine/cros/update_attempter.h"
Aaron Wood7f92e2b2017-08-28 14:51:21 -070035#include "update_engine/update_status_utils.h"
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070036
37using base::StringPrintf;
38using base::Time;
39using base::TimeDelta;
40using chromeos_update_engine::OmahaRequestParams;
41using chromeos_update_engine::SystemState;
42using std::string;
Aaron Woodbf5a2522017-10-04 10:58:36 -070043using update_engine::UpdateAttemptFlags;
Aaron Wood7f92e2b2017-08-28 14:51:21 -070044using update_engine::UpdateEngineStatus;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070045
Alex Deymo63784a52014-05-28 10:46:14 -070046namespace chromeos_update_manager {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070047
48// A templated base class for all update related variables. Provides uniform
49// construction and a system state handle.
Amin Hassani4b717432019-01-14 16:24:20 -080050template <typename T>
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070051class UpdaterVariableBase : public Variable<T> {
52 public:
Amin Hassani538bd592020-11-04 20:46:08 -080053 UpdaterVariableBase(const string& name, VariableMode mode)
54 : Variable<T>(name, mode) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070055};
56
57// Helper class for issuing a GetStatus() to the UpdateAttempter.
58class GetStatusHelper {
59 public:
Amin Hassani538bd592020-11-04 20:46:08 -080060 explicit GetStatusHelper(string* errmsg) {
61 is_success_ = SystemState::Get()->update_attempter()->GetStatus(
62 &update_engine_status_);
Aaron Wood7f92e2b2017-08-28 14:51:21 -070063 if (!is_success_ && errmsg) {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070064 *errmsg = "Failed to get a status update from the update engine";
Aaron Wood7f92e2b2017-08-28 14:51:21 -070065 }
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070066 }
67
68 inline bool is_success() { return is_success_; }
Aaron Wood7f92e2b2017-08-28 14:51:21 -070069 inline int64_t last_checked_time() {
Aaron Wood795c5b42017-12-05 16:06:13 -080070 return update_engine_status_.last_checked_time;
Aaron Wood7f92e2b2017-08-28 14:51:21 -070071 }
72 inline double progress() { return update_engine_status_.progress; }
73 inline const string update_status() {
74 return chromeos_update_engine::UpdateStatusToString(
75 update_engine_status_.status);
76 }
77 inline const string& new_version() {
78 return update_engine_status_.new_version;
79 }
80 inline uint64_t payload_size() {
81 return update_engine_status_.new_size_bytes;
82 }
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070083
84 private:
85 bool is_success_;
Aaron Wood7f92e2b2017-08-28 14:51:21 -070086 UpdateEngineStatus update_engine_status_;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070087};
88
89// A variable reporting the time when a last update check was issued.
90class LastCheckedTimeVariable : public UpdaterVariableBase<Time> {
91 public:
Amin Hassani538bd592020-11-04 20:46:08 -080092 explicit LastCheckedTimeVariable(const string& name)
93 : UpdaterVariableBase<Time>(name, kVariableModePoll) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070094
95 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -070096 const Time* GetValue(TimeDelta /* timeout */, string* errmsg) override {
Amin Hassani538bd592020-11-04 20:46:08 -080097 GetStatusHelper raw(errmsg);
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070098 if (!raw.is_success())
Alex Vakulenko88b591f2014-08-28 16:48:57 -070099 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700100
101 return new Time(Time::FromTimeT(raw.last_checked_time()));
102 }
103
104 DISALLOW_COPY_AND_ASSIGN(LastCheckedTimeVariable);
105};
106
107// A variable reporting the update (download) progress as a decimal fraction
108// between 0.0 and 1.0.
109class ProgressVariable : public UpdaterVariableBase<double> {
110 public:
Amin Hassani538bd592020-11-04 20:46:08 -0800111 explicit ProgressVariable(const string& name)
112 : UpdaterVariableBase<double>(name, kVariableModePoll) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700113
114 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -0700115 const double* GetValue(TimeDelta /* timeout */, string* errmsg) override {
Amin Hassani538bd592020-11-04 20:46:08 -0800116 GetStatusHelper raw(errmsg);
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700117 if (!raw.is_success())
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700118 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700119
120 if (raw.progress() < 0.0 || raw.progress() > 1.0) {
121 if (errmsg) {
Amin Hassani4b717432019-01-14 16:24:20 -0800122 *errmsg =
123 StringPrintf("Invalid progress value received: %f", raw.progress());
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700124 }
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700125 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700126 }
127
128 return new double(raw.progress());
129 }
130
131 DISALLOW_COPY_AND_ASSIGN(ProgressVariable);
132};
133
134// A variable reporting the stage in which the update process is.
135class StageVariable : public UpdaterVariableBase<Stage> {
136 public:
Amin Hassani538bd592020-11-04 20:46:08 -0800137 explicit StageVariable(const string& name)
138 : UpdaterVariableBase<Stage>(name, kVariableModePoll) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700139
140 private:
141 struct CurrOpStrToStage {
142 const char* str;
143 Stage stage;
144 };
145 static const CurrOpStrToStage curr_op_str_to_stage[];
146
147 // Note: the method is defined outside the class so arraysize can work.
Alex Vakulenko157fe302014-08-11 15:59:58 -0700148 const Stage* GetValue(TimeDelta /* timeout */, string* errmsg) override;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700149
150 DISALLOW_COPY_AND_ASSIGN(StageVariable);
151};
152
153const StageVariable::CurrOpStrToStage StageVariable::curr_op_str_to_stage[] = {
Amin Hassani4b717432019-01-14 16:24:20 -0800154 {update_engine::kUpdateStatusIdle, Stage::kIdle},
155 {update_engine::kUpdateStatusCheckingForUpdate, Stage::kCheckingForUpdate},
156 {update_engine::kUpdateStatusUpdateAvailable, Stage::kUpdateAvailable},
157 {update_engine::kUpdateStatusDownloading, Stage::kDownloading},
158 {update_engine::kUpdateStatusVerifying, Stage::kVerifying},
159 {update_engine::kUpdateStatusFinalizing, Stage::kFinalizing},
160 {update_engine::kUpdateStatusUpdatedNeedReboot, Stage::kUpdatedNeedReboot},
161 {update_engine::kUpdateStatusReportingErrorEvent,
162 Stage::kReportingErrorEvent},
163 {update_engine::kUpdateStatusAttemptingRollback,
164 Stage::kAttemptingRollback},
Amin Hassani70a90f52020-09-15 15:30:09 -0700165 {update_engine::kUpdateStatusCleanupPreviousUpdate,
166 Stage::kCleanupPreviousUpdate},
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700167};
168
Amin Hassani4b717432019-01-14 16:24:20 -0800169const Stage* StageVariable::GetValue(TimeDelta /* timeout */, string* errmsg) {
Amin Hassani538bd592020-11-04 20:46:08 -0800170 GetStatusHelper raw(errmsg);
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700171 if (!raw.is_success())
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700172 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700173
174 for (auto& key_val : curr_op_str_to_stage)
175 if (raw.update_status() == key_val.str)
176 return new Stage(key_val.stage);
177
178 if (errmsg)
179 *errmsg = string("Unknown update status: ") + raw.update_status();
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700180 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700181}
182
183// A variable reporting the version number that an update is updating to.
184class NewVersionVariable : public UpdaterVariableBase<string> {
185 public:
Amin Hassani538bd592020-11-04 20:46:08 -0800186 explicit NewVersionVariable(const string& name)
187 : UpdaterVariableBase<string>(name, kVariableModePoll) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700188
189 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -0700190 const string* GetValue(TimeDelta /* timeout */, string* errmsg) override {
Amin Hassani538bd592020-11-04 20:46:08 -0800191 GetStatusHelper raw(errmsg);
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700192 if (!raw.is_success())
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700193 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700194
195 return new string(raw.new_version());
196 }
197
198 DISALLOW_COPY_AND_ASSIGN(NewVersionVariable);
199};
200
201// A variable reporting the size of the update being processed in bytes.
Aaron Wood7f92e2b2017-08-28 14:51:21 -0700202class PayloadSizeVariable : public UpdaterVariableBase<uint64_t> {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700203 public:
Amin Hassani538bd592020-11-04 20:46:08 -0800204 explicit PayloadSizeVariable(const string& name)
205 : UpdaterVariableBase<uint64_t>(name, kVariableModePoll) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700206
207 private:
Aaron Wood7f92e2b2017-08-28 14:51:21 -0700208 const uint64_t* GetValue(TimeDelta /* timeout */, string* errmsg) override {
Amin Hassani538bd592020-11-04 20:46:08 -0800209 GetStatusHelper raw(errmsg);
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700210 if (!raw.is_success())
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700211 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700212
Aaron Wood7f92e2b2017-08-28 14:51:21 -0700213 return new uint64_t(raw.payload_size());
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700214 }
215
216 DISALLOW_COPY_AND_ASSIGN(PayloadSizeVariable);
217};
218
219// A variable reporting the point in time an update last completed in the
220// current boot cycle.
221//
222// TODO(garnold) In general, both the current boottime and wallclock time
223// readings should come from the time provider and be moderated by the
224// evaluation context, so that they are uniform throughout the evaluation of a
225// policy request.
226class UpdateCompletedTimeVariable : public UpdaterVariableBase<Time> {
227 public:
Amin Hassani538bd592020-11-04 20:46:08 -0800228 explicit UpdateCompletedTimeVariable(const string& name)
229 : UpdaterVariableBase<Time>(name, kVariableModePoll) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700230
231 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -0700232 const Time* GetValue(TimeDelta /* timeout */, string* errmsg) override {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700233 Time update_boottime;
Amin Hassani538bd592020-11-04 20:46:08 -0800234 if (!SystemState::Get()->update_attempter()->GetBootTimeAtUpdate(
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700235 &update_boottime)) {
236 if (errmsg)
237 *errmsg = "Update completed time could not be read";
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700238 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700239 }
240
Amin Hassani538bd592020-11-04 20:46:08 -0800241 chromeos_update_engine::ClockInterface* clock = SystemState::Get()->clock();
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700242 Time curr_boottime = clock->GetBootTime();
243 if (curr_boottime < update_boottime) {
244 if (errmsg)
245 *errmsg = "Update completed time more recent than current time";
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700246 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700247 }
248 TimeDelta duration_since_update = curr_boottime - update_boottime;
249 return new Time(clock->GetWallclockTime() - duration_since_update);
250 }
251
252 DISALLOW_COPY_AND_ASSIGN(UpdateCompletedTimeVariable);
253};
254
255// Variables reporting the current image channel.
256class CurrChannelVariable : public UpdaterVariableBase<string> {
257 public:
Amin Hassani538bd592020-11-04 20:46:08 -0800258 explicit CurrChannelVariable(const string& name)
259 : UpdaterVariableBase<string>(name, kVariableModePoll) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700260
261 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -0700262 const string* GetValue(TimeDelta /* timeout */, string* errmsg) override {
Amin Hassani538bd592020-11-04 20:46:08 -0800263 OmahaRequestParams* request_params = SystemState::Get()->request_params();
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700264 string channel = request_params->current_channel();
265 if (channel.empty()) {
266 if (errmsg)
267 *errmsg = "No current channel";
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700268 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700269 }
270 return new string(channel);
271 }
272
273 DISALLOW_COPY_AND_ASSIGN(CurrChannelVariable);
274};
275
276// Variables reporting the new image channel.
277class NewChannelVariable : public UpdaterVariableBase<string> {
278 public:
Amin Hassani538bd592020-11-04 20:46:08 -0800279 explicit NewChannelVariable(const string& name)
280 : UpdaterVariableBase<string>(name, kVariableModePoll) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700281
282 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -0700283 const string* GetValue(TimeDelta /* timeout */, string* errmsg) override {
Amin Hassani538bd592020-11-04 20:46:08 -0800284 OmahaRequestParams* request_params = SystemState::Get()->request_params();
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700285 string channel = request_params->target_channel();
286 if (channel.empty()) {
287 if (errmsg)
288 *errmsg = "No new channel";
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700289 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700290 }
291 return new string(channel);
292 }
293
294 DISALLOW_COPY_AND_ASSIGN(NewChannelVariable);
295};
296
297// A variable class for reading Boolean prefs values.
Alex Deymod6f60072015-10-12 12:22:27 -0700298class BooleanPrefVariable
299 : public AsyncCopyVariable<bool>,
300 public chromeos_update_engine::PrefsInterface::ObserverInterface {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700301 public:
Alex Deymod6f60072015-10-12 12:22:27 -0700302 BooleanPrefVariable(const string& name,
303 chromeos_update_engine::PrefsInterface* prefs,
304 const char* key,
305 bool default_val)
306 : AsyncCopyVariable<bool>(name),
307 prefs_(prefs),
308 key_(key),
309 default_val_(default_val) {
310 prefs->AddObserver(key, this);
311 OnPrefSet(key);
312 }
Amin Hassani4b717432019-01-14 16:24:20 -0800313 ~BooleanPrefVariable() { prefs_->RemoveObserver(key_, this); }
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700314
315 private:
Alex Deymod6f60072015-10-12 12:22:27 -0700316 // Reads the actual value from the Prefs instance and updates the Variable
317 // value.
318 void OnPrefSet(const string& key) override {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700319 bool result = default_val_;
Alex Deymod6f60072015-10-12 12:22:27 -0700320 if (prefs_ && prefs_->Exists(key_) && !prefs_->GetBoolean(key_, &result))
321 result = default_val_;
322 // AsyncCopyVariable will take care of values that didn't change.
323 SetValue(result);
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700324 }
325
Amin Hassani4b717432019-01-14 16:24:20 -0800326 void OnPrefDeleted(const string& key) override { SetValue(default_val_); }
Alex Deymod6f60072015-10-12 12:22:27 -0700327
328 chromeos_update_engine::PrefsInterface* prefs_;
329
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700330 // The Boolean preference key and default value.
331 const char* const key_;
332 const bool default_val_;
333
334 DISALLOW_COPY_AND_ASSIGN(BooleanPrefVariable);
335};
336
Gilad Arnolda6dab942014-04-25 11:46:03 -0700337// A variable returning the number of consecutive failed update checks.
Gilad Arnoldcf175a02014-07-10 16:48:47 -0700338class ConsecutiveFailedUpdateChecksVariable
339 : public UpdaterVariableBase<unsigned int> {
Gilad Arnolda6dab942014-04-25 11:46:03 -0700340 public:
Amin Hassani538bd592020-11-04 20:46:08 -0800341 explicit ConsecutiveFailedUpdateChecksVariable(const string& name)
342 : UpdaterVariableBase<unsigned int>(name, kVariableModePoll) {}
Gilad Arnolda6dab942014-04-25 11:46:03 -0700343
344 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -0700345 const unsigned int* GetValue(TimeDelta /* timeout */,
346 string* /* errmsg */) override {
Amin Hassani538bd592020-11-04 20:46:08 -0800347 // NOLINTNEXTLINE(readability/casting)
348 return new unsigned int(SystemState::Get()
349 ->update_attempter()
350 ->consecutive_failed_update_checks());
Gilad Arnolda6dab942014-04-25 11:46:03 -0700351 }
352
353 DISALLOW_COPY_AND_ASSIGN(ConsecutiveFailedUpdateChecksVariable);
354};
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700355
Gilad Arnolda0258a52014-07-10 16:21:19 -0700356// A variable returning the server-dictated poll interval.
357class ServerDictatedPollIntervalVariable
358 : public UpdaterVariableBase<unsigned int> {
359 public:
Amin Hassani538bd592020-11-04 20:46:08 -0800360 explicit ServerDictatedPollIntervalVariable(const string& name)
361 : UpdaterVariableBase<unsigned int>(name, kVariableModePoll) {}
Gilad Arnolda0258a52014-07-10 16:21:19 -0700362
363 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -0700364 const unsigned int* GetValue(TimeDelta /* timeout */,
365 string* /* errmsg */) override {
Amin Hassani538bd592020-11-04 20:46:08 -0800366 // NOLINTNEXTLINE(readability/casting)
367 return new unsigned int(SystemState::Get()
368 ->update_attempter()
369 ->server_dictated_poll_interval());
Gilad Arnolda0258a52014-07-10 16:21:19 -0700370 }
371
372 DISALLOW_COPY_AND_ASSIGN(ServerDictatedPollIntervalVariable);
373};
374
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700375// An async variable that tracks changes to forced update requests.
376class ForcedUpdateRequestedVariable
377 : public UpdaterVariableBase<UpdateRequestStatus> {
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700378 public:
Amin Hassani538bd592020-11-04 20:46:08 -0800379 explicit ForcedUpdateRequestedVariable(const string& name)
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700380 : UpdaterVariableBase<UpdateRequestStatus>::UpdaterVariableBase(
Amin Hassani538bd592020-11-04 20:46:08 -0800381 name, kVariableModeAsync) {
382 SystemState::Get()->update_attempter()->set_forced_update_pending_callback(
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700383 new base::Callback<void(bool, bool)>( // NOLINT(readability/function)
384 base::Bind(&ForcedUpdateRequestedVariable::Reset,
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700385 base::Unretained(this))));
386 }
387
388 private:
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700389 const UpdateRequestStatus* GetValue(TimeDelta /* timeout */,
390 string* /* errmsg */) override {
391 return new UpdateRequestStatus(update_request_status_);
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700392 }
393
Amin Hassanied37d682018-04-06 13:22:00 -0700394 void Reset(bool forced_update_requested, bool interactive) {
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700395 UpdateRequestStatus new_value = UpdateRequestStatus::kNone;
396 if (forced_update_requested)
Amin Hassanied37d682018-04-06 13:22:00 -0700397 new_value = (interactive ? UpdateRequestStatus::kInteractive
398 : UpdateRequestStatus::kPeriodic);
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700399 if (update_request_status_ != new_value) {
400 update_request_status_ = new_value;
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700401 NotifyValueChanged();
402 }
403 }
404
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700405 UpdateRequestStatus update_request_status_ = UpdateRequestStatus::kNone;
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700406
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700407 DISALLOW_COPY_AND_ASSIGN(ForcedUpdateRequestedVariable);
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700408};
409
Aaron Woodbf5a2522017-10-04 10:58:36 -0700410// A variable returning the current update restrictions that are in effect.
411class UpdateRestrictionsVariable
412 : public UpdaterVariableBase<UpdateRestrictions> {
413 public:
Amin Hassani538bd592020-11-04 20:46:08 -0800414 explicit UpdateRestrictionsVariable(const string& name)
415 : UpdaterVariableBase<UpdateRestrictions>(name, kVariableModePoll) {}
Aaron Woodbf5a2522017-10-04 10:58:36 -0700416
417 private:
418 const UpdateRestrictions* GetValue(TimeDelta /* timeout */,
419 string* /* errmsg */) override {
420 UpdateAttemptFlags attempt_flags =
Amin Hassani538bd592020-11-04 20:46:08 -0800421 SystemState::Get()->update_attempter()->GetCurrentUpdateAttemptFlags();
Aaron Woodbf5a2522017-10-04 10:58:36 -0700422 UpdateRestrictions restriction_flags = UpdateRestrictions::kNone;
423 // Don't blindly copy the whole value, test and set bits that should
424 // transfer from one set of flags to the other.
425 if (attempt_flags & UpdateAttemptFlags::kFlagRestrictDownload) {
426 restriction_flags = static_cast<UpdateRestrictions>(
427 restriction_flags | UpdateRestrictions::kRestrictDownloading);
428 }
429
430 return new UpdateRestrictions(restriction_flags);
431 }
432
433 DISALLOW_COPY_AND_ASSIGN(UpdateRestrictionsVariable);
434};
435
Amin Hassani03277de2020-07-28 12:32:49 -0700436// A variable class for reading timeout interval prefs value.
437class TestUpdateCheckIntervalTimeoutVariable : public Variable<int64_t> {
438 public:
439 TestUpdateCheckIntervalTimeoutVariable(
440 const string& name, chromeos_update_engine::PrefsInterface* prefs)
441 : Variable<int64_t>(name, kVariableModePoll),
442 prefs_(prefs),
443 read_count_(0) {
444 SetMissingOk();
445 }
446 ~TestUpdateCheckIntervalTimeoutVariable() = default;
447
448 private:
449 const int64_t* GetValue(TimeDelta /* timeout */,
450 string* /* errmsg */) override {
451 auto key = chromeos_update_engine::kPrefsTestUpdateCheckIntervalTimeout;
452 int64_t result;
453 if (prefs_ && prefs_->Exists(key) && prefs_->GetInt64(key, &result)) {
454 // This specific value is used for testing only. So it should not be kept
455 // around and should be deleted after a few reads.
Amin Hassani7ad016b2020-09-03 14:19:13 -0700456 if (++read_count_ > 5)
Amin Hassani03277de2020-07-28 12:32:49 -0700457 prefs_->Delete(key);
458
459 // Limit the timeout interval to 10 minutes so it is not abused if it is
460 // seen on official images.
461 return new int64_t(std::min(result, static_cast<int64_t>(10 * 60)));
462 }
463 return nullptr;
464 }
465
466 chromeos_update_engine::PrefsInterface* prefs_;
467
468 // Counts how many times this variable is read. This is used to delete the
469 // underlying file defining the variable after a certain number of reads in
470 // order to prevent any abuse of this variable.
471 int read_count_;
472
473 DISALLOW_COPY_AND_ASSIGN(TestUpdateCheckIntervalTimeoutVariable);
474};
475
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700476// RealUpdaterProvider methods.
477
Amin Hassani538bd592020-11-04 20:46:08 -0800478RealUpdaterProvider::RealUpdaterProvider()
479 : var_updater_started_time_(
480 "updater_started_time",
481 SystemState::Get()->clock()->GetWallclockTime()),
482 var_last_checked_time_(new LastCheckedTimeVariable("last_checked_time")),
483 var_update_completed_time_(
484 new UpdateCompletedTimeVariable("update_completed_time")),
485 var_progress_(new ProgressVariable("progress")),
486 var_stage_(new StageVariable("stage")),
487 var_new_version_(new NewVersionVariable("new_version")),
488 var_payload_size_(new PayloadSizeVariable("payload_size")),
489 var_curr_channel_(new CurrChannelVariable("curr_channel")),
490 var_new_channel_(new NewChannelVariable("new_channel")),
Aaron Woodbf5a2522017-10-04 10:58:36 -0700491 var_p2p_enabled_(
492 new BooleanPrefVariable("p2p_enabled",
Amin Hassani538bd592020-11-04 20:46:08 -0800493 SystemState::Get()->prefs(),
Aaron Woodbf5a2522017-10-04 10:58:36 -0700494 chromeos_update_engine::kPrefsP2PEnabled,
495 false)),
496 var_cellular_enabled_(new BooleanPrefVariable(
497 "cellular_enabled",
Amin Hassani538bd592020-11-04 20:46:08 -0800498 SystemState::Get()->prefs(),
Aaron Woodbf5a2522017-10-04 10:58:36 -0700499 chromeos_update_engine::kPrefsUpdateOverCellularPermission,
500 false)),
501 var_consecutive_failed_update_checks_(
502 new ConsecutiveFailedUpdateChecksVariable(
Amin Hassani538bd592020-11-04 20:46:08 -0800503 "consecutive_failed_update_checks")),
Aaron Woodbf5a2522017-10-04 10:58:36 -0700504 var_server_dictated_poll_interval_(new ServerDictatedPollIntervalVariable(
Amin Hassani538bd592020-11-04 20:46:08 -0800505 "server_dictated_poll_interval")),
506 var_forced_update_requested_(
507 new ForcedUpdateRequestedVariable("forced_update_requested")),
Amin Hassani03277de2020-07-28 12:32:49 -0700508 var_update_restrictions_(
Amin Hassani538bd592020-11-04 20:46:08 -0800509 new UpdateRestrictionsVariable("update_restrictions")),
Amin Hassani03277de2020-07-28 12:32:49 -0700510 var_test_update_check_interval_timeout_(
511 new TestUpdateCheckIntervalTimeoutVariable(
Amin Hassani538bd592020-11-04 20:46:08 -0800512 "test_update_check_interval_timeout",
513 SystemState::Get()->prefs())) {}
Alex Deymo63784a52014-05-28 10:46:14 -0700514} // namespace chromeos_update_manager