blob: e975b80ed4e1663d6ea2391b3aea034e66355d64 [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 Hassaniec7bc112020-10-29 16:47:58 -070032#include "update_engine/cros/omaha_request_params.h"
33#include "update_engine/cros/update_attempter.h"
Aaron Wood7f92e2b2017-08-28 14:51:21 -070034#include "update_engine/update_status_utils.h"
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070035
36using base::StringPrintf;
37using base::Time;
38using base::TimeDelta;
39using chromeos_update_engine::OmahaRequestParams;
40using chromeos_update_engine::SystemState;
41using std::string;
Aaron Woodbf5a2522017-10-04 10:58:36 -070042using update_engine::UpdateAttemptFlags;
Aaron Wood7f92e2b2017-08-28 14:51:21 -070043using update_engine::UpdateEngineStatus;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070044
Alex Deymo63784a52014-05-28 10:46:14 -070045namespace chromeos_update_manager {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070046
47// A templated base class for all update related variables. Provides uniform
48// construction and a system state handle.
Amin Hassani4b717432019-01-14 16:24:20 -080049template <typename T>
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070050class UpdaterVariableBase : public Variable<T> {
51 public:
Amin Hassani4b717432019-01-14 16:24:20 -080052 UpdaterVariableBase(const string& name,
53 VariableMode mode,
Gilad Arnold44dc3bf2014-07-18 23:39:38 -070054 SystemState* system_state)
55 : Variable<T>(name, mode), system_state_(system_state) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070056
57 protected:
58 // The system state used for pulling information from the updater.
59 inline SystemState* system_state() const { return system_state_; }
60
61 private:
62 SystemState* const system_state_;
63};
64
65// Helper class for issuing a GetStatus() to the UpdateAttempter.
66class GetStatusHelper {
67 public:
68 GetStatusHelper(SystemState* system_state, string* errmsg) {
Aaron Wood7f92e2b2017-08-28 14:51:21 -070069 is_success_ =
70 system_state->update_attempter()->GetStatus(&update_engine_status_);
71 if (!is_success_ && errmsg) {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070072 *errmsg = "Failed to get a status update from the update engine";
Aaron Wood7f92e2b2017-08-28 14:51:21 -070073 }
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070074 }
75
76 inline bool is_success() { return is_success_; }
Aaron Wood7f92e2b2017-08-28 14:51:21 -070077 inline int64_t last_checked_time() {
Aaron Wood795c5b42017-12-05 16:06:13 -080078 return update_engine_status_.last_checked_time;
Aaron Wood7f92e2b2017-08-28 14:51:21 -070079 }
80 inline double progress() { return update_engine_status_.progress; }
81 inline const string update_status() {
82 return chromeos_update_engine::UpdateStatusToString(
83 update_engine_status_.status);
84 }
85 inline const string& new_version() {
86 return update_engine_status_.new_version;
87 }
88 inline uint64_t payload_size() {
89 return update_engine_status_.new_size_bytes;
90 }
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070091
92 private:
93 bool is_success_;
Aaron Wood7f92e2b2017-08-28 14:51:21 -070094 UpdateEngineStatus update_engine_status_;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070095};
96
97// A variable reporting the time when a last update check was issued.
98class LastCheckedTimeVariable : public UpdaterVariableBase<Time> {
99 public:
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700100 LastCheckedTimeVariable(const string& name, SystemState* system_state)
101 : UpdaterVariableBase<Time>(name, kVariableModePoll, system_state) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700102
103 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -0700104 const Time* GetValue(TimeDelta /* timeout */, string* errmsg) override {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700105 GetStatusHelper raw(system_state(), errmsg);
106 if (!raw.is_success())
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700107 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700108
109 return new Time(Time::FromTimeT(raw.last_checked_time()));
110 }
111
112 DISALLOW_COPY_AND_ASSIGN(LastCheckedTimeVariable);
113};
114
115// A variable reporting the update (download) progress as a decimal fraction
116// between 0.0 and 1.0.
117class ProgressVariable : public UpdaterVariableBase<double> {
118 public:
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700119 ProgressVariable(const string& name, SystemState* system_state)
120 : UpdaterVariableBase<double>(name, kVariableModePoll, system_state) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700121
122 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -0700123 const double* GetValue(TimeDelta /* timeout */, string* errmsg) override {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700124 GetStatusHelper raw(system_state(), errmsg);
125 if (!raw.is_success())
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700126 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700127
128 if (raw.progress() < 0.0 || raw.progress() > 1.0) {
129 if (errmsg) {
Amin Hassani4b717432019-01-14 16:24:20 -0800130 *errmsg =
131 StringPrintf("Invalid progress value received: %f", raw.progress());
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700132 }
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700133 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700134 }
135
136 return new double(raw.progress());
137 }
138
139 DISALLOW_COPY_AND_ASSIGN(ProgressVariable);
140};
141
142// A variable reporting the stage in which the update process is.
143class StageVariable : public UpdaterVariableBase<Stage> {
144 public:
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700145 StageVariable(const string& name, SystemState* system_state)
146 : UpdaterVariableBase<Stage>(name, kVariableModePoll, system_state) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700147
148 private:
149 struct CurrOpStrToStage {
150 const char* str;
151 Stage stage;
152 };
153 static const CurrOpStrToStage curr_op_str_to_stage[];
154
155 // Note: the method is defined outside the class so arraysize can work.
Alex Vakulenko157fe302014-08-11 15:59:58 -0700156 const Stage* GetValue(TimeDelta /* timeout */, string* errmsg) override;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700157
158 DISALLOW_COPY_AND_ASSIGN(StageVariable);
159};
160
161const StageVariable::CurrOpStrToStage StageVariable::curr_op_str_to_stage[] = {
Amin Hassani4b717432019-01-14 16:24:20 -0800162 {update_engine::kUpdateStatusIdle, Stage::kIdle},
163 {update_engine::kUpdateStatusCheckingForUpdate, Stage::kCheckingForUpdate},
164 {update_engine::kUpdateStatusUpdateAvailable, Stage::kUpdateAvailable},
165 {update_engine::kUpdateStatusDownloading, Stage::kDownloading},
166 {update_engine::kUpdateStatusVerifying, Stage::kVerifying},
167 {update_engine::kUpdateStatusFinalizing, Stage::kFinalizing},
168 {update_engine::kUpdateStatusUpdatedNeedReboot, Stage::kUpdatedNeedReboot},
169 {update_engine::kUpdateStatusReportingErrorEvent,
170 Stage::kReportingErrorEvent},
171 {update_engine::kUpdateStatusAttemptingRollback,
172 Stage::kAttemptingRollback},
Amin Hassani70a90f52020-09-15 15:30:09 -0700173 {update_engine::kUpdateStatusCleanupPreviousUpdate,
174 Stage::kCleanupPreviousUpdate},
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700175};
176
Amin Hassani4b717432019-01-14 16:24:20 -0800177const Stage* StageVariable::GetValue(TimeDelta /* timeout */, string* errmsg) {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700178 GetStatusHelper raw(system_state(), errmsg);
179 if (!raw.is_success())
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700180 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700181
182 for (auto& key_val : curr_op_str_to_stage)
183 if (raw.update_status() == key_val.str)
184 return new Stage(key_val.stage);
185
186 if (errmsg)
187 *errmsg = string("Unknown update status: ") + raw.update_status();
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700188 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700189}
190
191// A variable reporting the version number that an update is updating to.
192class NewVersionVariable : public UpdaterVariableBase<string> {
193 public:
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700194 NewVersionVariable(const string& name, SystemState* system_state)
195 : UpdaterVariableBase<string>(name, kVariableModePoll, system_state) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700196
197 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -0700198 const string* GetValue(TimeDelta /* timeout */, string* errmsg) override {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700199 GetStatusHelper raw(system_state(), errmsg);
200 if (!raw.is_success())
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700201 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700202
203 return new string(raw.new_version());
204 }
205
206 DISALLOW_COPY_AND_ASSIGN(NewVersionVariable);
207};
208
209// A variable reporting the size of the update being processed in bytes.
Aaron Wood7f92e2b2017-08-28 14:51:21 -0700210class PayloadSizeVariable : public UpdaterVariableBase<uint64_t> {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700211 public:
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700212 PayloadSizeVariable(const string& name, SystemState* system_state)
Aaron Wood7f92e2b2017-08-28 14:51:21 -0700213 : UpdaterVariableBase<uint64_t>(name, kVariableModePoll, system_state) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700214
215 private:
Aaron Wood7f92e2b2017-08-28 14:51:21 -0700216 const uint64_t* GetValue(TimeDelta /* timeout */, string* errmsg) override {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700217 GetStatusHelper raw(system_state(), errmsg);
218 if (!raw.is_success())
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700219 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700220
Aaron Wood7f92e2b2017-08-28 14:51:21 -0700221 return new uint64_t(raw.payload_size());
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700222 }
223
224 DISALLOW_COPY_AND_ASSIGN(PayloadSizeVariable);
225};
226
227// A variable reporting the point in time an update last completed in the
228// current boot cycle.
229//
230// TODO(garnold) In general, both the current boottime and wallclock time
231// readings should come from the time provider and be moderated by the
232// evaluation context, so that they are uniform throughout the evaluation of a
233// policy request.
234class UpdateCompletedTimeVariable : public UpdaterVariableBase<Time> {
235 public:
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700236 UpdateCompletedTimeVariable(const string& name, SystemState* system_state)
237 : UpdaterVariableBase<Time>(name, kVariableModePoll, system_state) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700238
239 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -0700240 const Time* GetValue(TimeDelta /* timeout */, string* errmsg) override {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700241 Time update_boottime;
242 if (!system_state()->update_attempter()->GetBootTimeAtUpdate(
243 &update_boottime)) {
244 if (errmsg)
245 *errmsg = "Update completed time could not be read";
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700246 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700247 }
248
249 chromeos_update_engine::ClockInterface* clock = system_state()->clock();
250 Time curr_boottime = clock->GetBootTime();
251 if (curr_boottime < update_boottime) {
252 if (errmsg)
253 *errmsg = "Update completed time more recent than current time";
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700254 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700255 }
256 TimeDelta duration_since_update = curr_boottime - update_boottime;
257 return new Time(clock->GetWallclockTime() - duration_since_update);
258 }
259
260 DISALLOW_COPY_AND_ASSIGN(UpdateCompletedTimeVariable);
261};
262
263// Variables reporting the current image channel.
264class CurrChannelVariable : public UpdaterVariableBase<string> {
265 public:
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700266 CurrChannelVariable(const string& name, SystemState* system_state)
267 : UpdaterVariableBase<string>(name, kVariableModePoll, system_state) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700268
269 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -0700270 const string* GetValue(TimeDelta /* timeout */, string* errmsg) override {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700271 OmahaRequestParams* request_params = system_state()->request_params();
272 string channel = request_params->current_channel();
273 if (channel.empty()) {
274 if (errmsg)
275 *errmsg = "No current channel";
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700276 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700277 }
278 return new string(channel);
279 }
280
281 DISALLOW_COPY_AND_ASSIGN(CurrChannelVariable);
282};
283
284// Variables reporting the new image channel.
285class NewChannelVariable : public UpdaterVariableBase<string> {
286 public:
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700287 NewChannelVariable(const string& name, SystemState* system_state)
288 : UpdaterVariableBase<string>(name, kVariableModePoll, system_state) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700289
290 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -0700291 const string* GetValue(TimeDelta /* timeout */, string* errmsg) override {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700292 OmahaRequestParams* request_params = system_state()->request_params();
293 string channel = request_params->target_channel();
294 if (channel.empty()) {
295 if (errmsg)
296 *errmsg = "No new channel";
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700297 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700298 }
299 return new string(channel);
300 }
301
302 DISALLOW_COPY_AND_ASSIGN(NewChannelVariable);
303};
304
305// A variable class for reading Boolean prefs values.
Alex Deymod6f60072015-10-12 12:22:27 -0700306class BooleanPrefVariable
307 : public AsyncCopyVariable<bool>,
308 public chromeos_update_engine::PrefsInterface::ObserverInterface {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700309 public:
Alex Deymod6f60072015-10-12 12:22:27 -0700310 BooleanPrefVariable(const string& name,
311 chromeos_update_engine::PrefsInterface* prefs,
312 const char* key,
313 bool default_val)
314 : AsyncCopyVariable<bool>(name),
315 prefs_(prefs),
316 key_(key),
317 default_val_(default_val) {
318 prefs->AddObserver(key, this);
319 OnPrefSet(key);
320 }
Amin Hassani4b717432019-01-14 16:24:20 -0800321 ~BooleanPrefVariable() { prefs_->RemoveObserver(key_, this); }
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700322
323 private:
Alex Deymod6f60072015-10-12 12:22:27 -0700324 // Reads the actual value from the Prefs instance and updates the Variable
325 // value.
326 void OnPrefSet(const string& key) override {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700327 bool result = default_val_;
Alex Deymod6f60072015-10-12 12:22:27 -0700328 if (prefs_ && prefs_->Exists(key_) && !prefs_->GetBoolean(key_, &result))
329 result = default_val_;
330 // AsyncCopyVariable will take care of values that didn't change.
331 SetValue(result);
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700332 }
333
Amin Hassani4b717432019-01-14 16:24:20 -0800334 void OnPrefDeleted(const string& key) override { SetValue(default_val_); }
Alex Deymod6f60072015-10-12 12:22:27 -0700335
336 chromeos_update_engine::PrefsInterface* prefs_;
337
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700338 // The Boolean preference key and default value.
339 const char* const key_;
340 const bool default_val_;
341
342 DISALLOW_COPY_AND_ASSIGN(BooleanPrefVariable);
343};
344
Gilad Arnolda6dab942014-04-25 11:46:03 -0700345// A variable returning the number of consecutive failed update checks.
Gilad Arnoldcf175a02014-07-10 16:48:47 -0700346class ConsecutiveFailedUpdateChecksVariable
347 : public UpdaterVariableBase<unsigned int> {
Gilad Arnolda6dab942014-04-25 11:46:03 -0700348 public:
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700349 ConsecutiveFailedUpdateChecksVariable(const string& name,
350 SystemState* system_state)
Amin Hassani4b717432019-01-14 16:24:20 -0800351 : UpdaterVariableBase<unsigned int>(
352 name, kVariableModePoll, system_state) {}
Gilad Arnolda6dab942014-04-25 11:46:03 -0700353
354 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -0700355 const unsigned int* GetValue(TimeDelta /* timeout */,
356 string* /* errmsg */) override {
Gilad Arnolda6dab942014-04-25 11:46:03 -0700357 return new unsigned int(
358 system_state()->update_attempter()->consecutive_failed_update_checks());
359 }
360
361 DISALLOW_COPY_AND_ASSIGN(ConsecutiveFailedUpdateChecksVariable);
362};
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700363
Gilad Arnolda0258a52014-07-10 16:21:19 -0700364// A variable returning the server-dictated poll interval.
365class ServerDictatedPollIntervalVariable
366 : public UpdaterVariableBase<unsigned int> {
367 public:
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700368 ServerDictatedPollIntervalVariable(const string& name,
369 SystemState* system_state)
Amin Hassani4b717432019-01-14 16:24:20 -0800370 : UpdaterVariableBase<unsigned int>(
371 name, kVariableModePoll, system_state) {}
Gilad Arnolda0258a52014-07-10 16:21:19 -0700372
373 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -0700374 const unsigned int* GetValue(TimeDelta /* timeout */,
375 string* /* errmsg */) override {
Gilad Arnolda0258a52014-07-10 16:21:19 -0700376 return new unsigned int(
377 system_state()->update_attempter()->server_dictated_poll_interval());
378 }
379
380 DISALLOW_COPY_AND_ASSIGN(ServerDictatedPollIntervalVariable);
381};
382
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700383// An async variable that tracks changes to forced update requests.
384class ForcedUpdateRequestedVariable
385 : public UpdaterVariableBase<UpdateRequestStatus> {
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700386 public:
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700387 ForcedUpdateRequestedVariable(const string& name, SystemState* system_state)
388 : UpdaterVariableBase<UpdateRequestStatus>::UpdaterVariableBase(
Amin Hassani4b717432019-01-14 16:24:20 -0800389 name, kVariableModeAsync, system_state) {
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700390 system_state->update_attempter()->set_forced_update_pending_callback(
391 new base::Callback<void(bool, bool)>( // NOLINT(readability/function)
392 base::Bind(&ForcedUpdateRequestedVariable::Reset,
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700393 base::Unretained(this))));
394 }
395
396 private:
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700397 const UpdateRequestStatus* GetValue(TimeDelta /* timeout */,
398 string* /* errmsg */) override {
399 return new UpdateRequestStatus(update_request_status_);
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700400 }
401
Amin Hassanied37d682018-04-06 13:22:00 -0700402 void Reset(bool forced_update_requested, bool interactive) {
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700403 UpdateRequestStatus new_value = UpdateRequestStatus::kNone;
404 if (forced_update_requested)
Amin Hassanied37d682018-04-06 13:22:00 -0700405 new_value = (interactive ? UpdateRequestStatus::kInteractive
406 : UpdateRequestStatus::kPeriodic);
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700407 if (update_request_status_ != new_value) {
408 update_request_status_ = new_value;
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700409 NotifyValueChanged();
410 }
411 }
412
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700413 UpdateRequestStatus update_request_status_ = UpdateRequestStatus::kNone;
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700414
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700415 DISALLOW_COPY_AND_ASSIGN(ForcedUpdateRequestedVariable);
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700416};
417
Aaron Woodbf5a2522017-10-04 10:58:36 -0700418// A variable returning the current update restrictions that are in effect.
419class UpdateRestrictionsVariable
420 : public UpdaterVariableBase<UpdateRestrictions> {
421 public:
422 UpdateRestrictionsVariable(const string& name, SystemState* system_state)
423 : UpdaterVariableBase<UpdateRestrictions>(
424 name, kVariableModePoll, system_state) {}
425
426 private:
427 const UpdateRestrictions* GetValue(TimeDelta /* timeout */,
428 string* /* errmsg */) override {
429 UpdateAttemptFlags attempt_flags =
430 system_state()->update_attempter()->GetCurrentUpdateAttemptFlags();
431 UpdateRestrictions restriction_flags = UpdateRestrictions::kNone;
432 // Don't blindly copy the whole value, test and set bits that should
433 // transfer from one set of flags to the other.
434 if (attempt_flags & UpdateAttemptFlags::kFlagRestrictDownload) {
435 restriction_flags = static_cast<UpdateRestrictions>(
436 restriction_flags | UpdateRestrictions::kRestrictDownloading);
437 }
438
439 return new UpdateRestrictions(restriction_flags);
440 }
441
442 DISALLOW_COPY_AND_ASSIGN(UpdateRestrictionsVariable);
443};
444
Amin Hassani03277de2020-07-28 12:32:49 -0700445// A variable class for reading timeout interval prefs value.
446class TestUpdateCheckIntervalTimeoutVariable : public Variable<int64_t> {
447 public:
448 TestUpdateCheckIntervalTimeoutVariable(
449 const string& name, chromeos_update_engine::PrefsInterface* prefs)
450 : Variable<int64_t>(name, kVariableModePoll),
451 prefs_(prefs),
452 read_count_(0) {
453 SetMissingOk();
454 }
455 ~TestUpdateCheckIntervalTimeoutVariable() = default;
456
457 private:
458 const int64_t* GetValue(TimeDelta /* timeout */,
459 string* /* errmsg */) override {
460 auto key = chromeos_update_engine::kPrefsTestUpdateCheckIntervalTimeout;
461 int64_t result;
462 if (prefs_ && prefs_->Exists(key) && prefs_->GetInt64(key, &result)) {
463 // This specific value is used for testing only. So it should not be kept
464 // around and should be deleted after a few reads.
Amin Hassani7ad016b2020-09-03 14:19:13 -0700465 if (++read_count_ > 5)
Amin Hassani03277de2020-07-28 12:32:49 -0700466 prefs_->Delete(key);
467
468 // Limit the timeout interval to 10 minutes so it is not abused if it is
469 // seen on official images.
470 return new int64_t(std::min(result, static_cast<int64_t>(10 * 60)));
471 }
472 return nullptr;
473 }
474
475 chromeos_update_engine::PrefsInterface* prefs_;
476
477 // Counts how many times this variable is read. This is used to delete the
478 // underlying file defining the variable after a certain number of reads in
479 // order to prevent any abuse of this variable.
480 int read_count_;
481
482 DISALLOW_COPY_AND_ASSIGN(TestUpdateCheckIntervalTimeoutVariable);
483};
484
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700485// RealUpdaterProvider methods.
486
487RealUpdaterProvider::RealUpdaterProvider(SystemState* system_state)
Aaron Woodbf5a2522017-10-04 10:58:36 -0700488 : system_state_(system_state),
489 var_updater_started_time_("updater_started_time",
490 system_state->clock()->GetWallclockTime()),
491 var_last_checked_time_(
492 new LastCheckedTimeVariable("last_checked_time", system_state_)),
493 var_update_completed_time_(new UpdateCompletedTimeVariable(
494 "update_completed_time", system_state_)),
495 var_progress_(new ProgressVariable("progress", system_state_)),
496 var_stage_(new StageVariable("stage", system_state_)),
497 var_new_version_(new NewVersionVariable("new_version", system_state_)),
498 var_payload_size_(new PayloadSizeVariable("payload_size", system_state_)),
499 var_curr_channel_(new CurrChannelVariable("curr_channel", system_state_)),
500 var_new_channel_(new NewChannelVariable("new_channel", system_state_)),
501 var_p2p_enabled_(
502 new BooleanPrefVariable("p2p_enabled",
503 system_state_->prefs(),
504 chromeos_update_engine::kPrefsP2PEnabled,
505 false)),
506 var_cellular_enabled_(new BooleanPrefVariable(
507 "cellular_enabled",
508 system_state_->prefs(),
509 chromeos_update_engine::kPrefsUpdateOverCellularPermission,
510 false)),
511 var_consecutive_failed_update_checks_(
512 new ConsecutiveFailedUpdateChecksVariable(
513 "consecutive_failed_update_checks", system_state_)),
514 var_server_dictated_poll_interval_(new ServerDictatedPollIntervalVariable(
515 "server_dictated_poll_interval", system_state_)),
516 var_forced_update_requested_(new ForcedUpdateRequestedVariable(
517 "forced_update_requested", system_state_)),
Amin Hassani03277de2020-07-28 12:32:49 -0700518 var_update_restrictions_(
519 new UpdateRestrictionsVariable("update_restrictions", system_state_)),
520 var_test_update_check_interval_timeout_(
521 new TestUpdateCheckIntervalTimeoutVariable(
522 "test_update_check_interval_timeout", system_state_->prefs())) {}
Alex Deymo63784a52014-05-28 10:46:14 -0700523} // namespace chromeos_update_manager