blob: 268f3bb54cbad1e5f4411d6ee80a75dcdee559ea [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"
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070032#include "update_engine/omaha_request_params.h"
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070033#include "update_engine/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},
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700173};
174
Amin Hassani4b717432019-01-14 16:24:20 -0800175const Stage* StageVariable::GetValue(TimeDelta /* timeout */, string* errmsg) {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700176 GetStatusHelper raw(system_state(), errmsg);
177 if (!raw.is_success())
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700178 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700179
180 for (auto& key_val : curr_op_str_to_stage)
181 if (raw.update_status() == key_val.str)
182 return new Stage(key_val.stage);
183
184 if (errmsg)
185 *errmsg = string("Unknown update status: ") + raw.update_status();
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700186 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700187}
188
189// A variable reporting the version number that an update is updating to.
190class NewVersionVariable : public UpdaterVariableBase<string> {
191 public:
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700192 NewVersionVariable(const string& name, SystemState* system_state)
193 : UpdaterVariableBase<string>(name, kVariableModePoll, system_state) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700194
195 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -0700196 const string* GetValue(TimeDelta /* timeout */, string* errmsg) override {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700197 GetStatusHelper raw(system_state(), errmsg);
198 if (!raw.is_success())
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700199 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700200
201 return new string(raw.new_version());
202 }
203
204 DISALLOW_COPY_AND_ASSIGN(NewVersionVariable);
205};
206
207// A variable reporting the size of the update being processed in bytes.
Aaron Wood7f92e2b2017-08-28 14:51:21 -0700208class PayloadSizeVariable : public UpdaterVariableBase<uint64_t> {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700209 public:
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700210 PayloadSizeVariable(const string& name, SystemState* system_state)
Aaron Wood7f92e2b2017-08-28 14:51:21 -0700211 : UpdaterVariableBase<uint64_t>(name, kVariableModePoll, system_state) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700212
213 private:
Aaron Wood7f92e2b2017-08-28 14:51:21 -0700214 const uint64_t* GetValue(TimeDelta /* timeout */, string* errmsg) override {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700215 GetStatusHelper raw(system_state(), errmsg);
216 if (!raw.is_success())
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700217 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700218
Aaron Wood7f92e2b2017-08-28 14:51:21 -0700219 return new uint64_t(raw.payload_size());
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700220 }
221
222 DISALLOW_COPY_AND_ASSIGN(PayloadSizeVariable);
223};
224
225// A variable reporting the point in time an update last completed in the
226// current boot cycle.
227//
228// TODO(garnold) In general, both the current boottime and wallclock time
229// readings should come from the time provider and be moderated by the
230// evaluation context, so that they are uniform throughout the evaluation of a
231// policy request.
232class UpdateCompletedTimeVariable : public UpdaterVariableBase<Time> {
233 public:
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700234 UpdateCompletedTimeVariable(const string& name, SystemState* system_state)
235 : UpdaterVariableBase<Time>(name, kVariableModePoll, system_state) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700236
237 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -0700238 const Time* GetValue(TimeDelta /* timeout */, string* errmsg) override {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700239 Time update_boottime;
240 if (!system_state()->update_attempter()->GetBootTimeAtUpdate(
241 &update_boottime)) {
242 if (errmsg)
243 *errmsg = "Update completed time could not be read";
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700244 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700245 }
246
247 chromeos_update_engine::ClockInterface* clock = system_state()->clock();
248 Time curr_boottime = clock->GetBootTime();
249 if (curr_boottime < update_boottime) {
250 if (errmsg)
251 *errmsg = "Update completed time more recent than current time";
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700252 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700253 }
254 TimeDelta duration_since_update = curr_boottime - update_boottime;
255 return new Time(clock->GetWallclockTime() - duration_since_update);
256 }
257
258 DISALLOW_COPY_AND_ASSIGN(UpdateCompletedTimeVariable);
259};
260
261// Variables reporting the current image channel.
262class CurrChannelVariable : public UpdaterVariableBase<string> {
263 public:
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700264 CurrChannelVariable(const string& name, SystemState* system_state)
265 : UpdaterVariableBase<string>(name, kVariableModePoll, system_state) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700266
267 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -0700268 const string* GetValue(TimeDelta /* timeout */, string* errmsg) override {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700269 OmahaRequestParams* request_params = system_state()->request_params();
270 string channel = request_params->current_channel();
271 if (channel.empty()) {
272 if (errmsg)
273 *errmsg = "No current channel";
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700274 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700275 }
276 return new string(channel);
277 }
278
279 DISALLOW_COPY_AND_ASSIGN(CurrChannelVariable);
280};
281
282// Variables reporting the new image channel.
283class NewChannelVariable : public UpdaterVariableBase<string> {
284 public:
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700285 NewChannelVariable(const string& name, SystemState* system_state)
286 : UpdaterVariableBase<string>(name, kVariableModePoll, system_state) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700287
288 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -0700289 const string* GetValue(TimeDelta /* timeout */, string* errmsg) override {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700290 OmahaRequestParams* request_params = system_state()->request_params();
291 string channel = request_params->target_channel();
292 if (channel.empty()) {
293 if (errmsg)
294 *errmsg = "No new channel";
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700295 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700296 }
297 return new string(channel);
298 }
299
300 DISALLOW_COPY_AND_ASSIGN(NewChannelVariable);
301};
302
303// A variable class for reading Boolean prefs values.
Alex Deymod6f60072015-10-12 12:22:27 -0700304class BooleanPrefVariable
305 : public AsyncCopyVariable<bool>,
306 public chromeos_update_engine::PrefsInterface::ObserverInterface {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700307 public:
Alex Deymod6f60072015-10-12 12:22:27 -0700308 BooleanPrefVariable(const string& name,
309 chromeos_update_engine::PrefsInterface* prefs,
310 const char* key,
311 bool default_val)
312 : AsyncCopyVariable<bool>(name),
313 prefs_(prefs),
314 key_(key),
315 default_val_(default_val) {
316 prefs->AddObserver(key, this);
317 OnPrefSet(key);
318 }
Amin Hassani4b717432019-01-14 16:24:20 -0800319 ~BooleanPrefVariable() { prefs_->RemoveObserver(key_, this); }
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700320
321 private:
Alex Deymod6f60072015-10-12 12:22:27 -0700322 // Reads the actual value from the Prefs instance and updates the Variable
323 // value.
324 void OnPrefSet(const string& key) override {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700325 bool result = default_val_;
Alex Deymod6f60072015-10-12 12:22:27 -0700326 if (prefs_ && prefs_->Exists(key_) && !prefs_->GetBoolean(key_, &result))
327 result = default_val_;
328 // AsyncCopyVariable will take care of values that didn't change.
329 SetValue(result);
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700330 }
331
Amin Hassani4b717432019-01-14 16:24:20 -0800332 void OnPrefDeleted(const string& key) override { SetValue(default_val_); }
Alex Deymod6f60072015-10-12 12:22:27 -0700333
334 chromeos_update_engine::PrefsInterface* prefs_;
335
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700336 // The Boolean preference key and default value.
337 const char* const key_;
338 const bool default_val_;
339
340 DISALLOW_COPY_AND_ASSIGN(BooleanPrefVariable);
341};
342
Gilad Arnolda6dab942014-04-25 11:46:03 -0700343// A variable returning the number of consecutive failed update checks.
Gilad Arnoldcf175a02014-07-10 16:48:47 -0700344class ConsecutiveFailedUpdateChecksVariable
345 : public UpdaterVariableBase<unsigned int> {
Gilad Arnolda6dab942014-04-25 11:46:03 -0700346 public:
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700347 ConsecutiveFailedUpdateChecksVariable(const string& name,
348 SystemState* system_state)
Amin Hassani4b717432019-01-14 16:24:20 -0800349 : UpdaterVariableBase<unsigned int>(
350 name, kVariableModePoll, system_state) {}
Gilad Arnolda6dab942014-04-25 11:46:03 -0700351
352 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -0700353 const unsigned int* GetValue(TimeDelta /* timeout */,
354 string* /* errmsg */) override {
Gilad Arnolda6dab942014-04-25 11:46:03 -0700355 return new unsigned int(
356 system_state()->update_attempter()->consecutive_failed_update_checks());
357 }
358
359 DISALLOW_COPY_AND_ASSIGN(ConsecutiveFailedUpdateChecksVariable);
360};
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700361
Gilad Arnolda0258a52014-07-10 16:21:19 -0700362// A variable returning the server-dictated poll interval.
363class ServerDictatedPollIntervalVariable
364 : public UpdaterVariableBase<unsigned int> {
365 public:
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700366 ServerDictatedPollIntervalVariable(const string& name,
367 SystemState* system_state)
Amin Hassani4b717432019-01-14 16:24:20 -0800368 : UpdaterVariableBase<unsigned int>(
369 name, kVariableModePoll, system_state) {}
Gilad Arnolda0258a52014-07-10 16:21:19 -0700370
371 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -0700372 const unsigned int* GetValue(TimeDelta /* timeout */,
373 string* /* errmsg */) override {
Gilad Arnolda0258a52014-07-10 16:21:19 -0700374 return new unsigned int(
375 system_state()->update_attempter()->server_dictated_poll_interval());
376 }
377
378 DISALLOW_COPY_AND_ASSIGN(ServerDictatedPollIntervalVariable);
379};
380
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700381// An async variable that tracks changes to forced update requests.
382class ForcedUpdateRequestedVariable
383 : public UpdaterVariableBase<UpdateRequestStatus> {
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700384 public:
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700385 ForcedUpdateRequestedVariable(const string& name, SystemState* system_state)
386 : UpdaterVariableBase<UpdateRequestStatus>::UpdaterVariableBase(
Amin Hassani4b717432019-01-14 16:24:20 -0800387 name, kVariableModeAsync, system_state) {
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700388 system_state->update_attempter()->set_forced_update_pending_callback(
389 new base::Callback<void(bool, bool)>( // NOLINT(readability/function)
390 base::Bind(&ForcedUpdateRequestedVariable::Reset,
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700391 base::Unretained(this))));
392 }
393
394 private:
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700395 const UpdateRequestStatus* GetValue(TimeDelta /* timeout */,
396 string* /* errmsg */) override {
397 return new UpdateRequestStatus(update_request_status_);
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700398 }
399
Amin Hassanied37d682018-04-06 13:22:00 -0700400 void Reset(bool forced_update_requested, bool interactive) {
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700401 UpdateRequestStatus new_value = UpdateRequestStatus::kNone;
402 if (forced_update_requested)
Amin Hassanied37d682018-04-06 13:22:00 -0700403 new_value = (interactive ? UpdateRequestStatus::kInteractive
404 : UpdateRequestStatus::kPeriodic);
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700405 if (update_request_status_ != new_value) {
406 update_request_status_ = new_value;
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700407 NotifyValueChanged();
408 }
409 }
410
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700411 UpdateRequestStatus update_request_status_ = UpdateRequestStatus::kNone;
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700412
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700413 DISALLOW_COPY_AND_ASSIGN(ForcedUpdateRequestedVariable);
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700414};
415
Aaron Woodbf5a2522017-10-04 10:58:36 -0700416// A variable returning the current update restrictions that are in effect.
417class UpdateRestrictionsVariable
418 : public UpdaterVariableBase<UpdateRestrictions> {
419 public:
420 UpdateRestrictionsVariable(const string& name, SystemState* system_state)
421 : UpdaterVariableBase<UpdateRestrictions>(
422 name, kVariableModePoll, system_state) {}
423
424 private:
425 const UpdateRestrictions* GetValue(TimeDelta /* timeout */,
426 string* /* errmsg */) override {
427 UpdateAttemptFlags attempt_flags =
428 system_state()->update_attempter()->GetCurrentUpdateAttemptFlags();
429 UpdateRestrictions restriction_flags = UpdateRestrictions::kNone;
430 // Don't blindly copy the whole value, test and set bits that should
431 // transfer from one set of flags to the other.
432 if (attempt_flags & UpdateAttemptFlags::kFlagRestrictDownload) {
433 restriction_flags = static_cast<UpdateRestrictions>(
434 restriction_flags | UpdateRestrictions::kRestrictDownloading);
435 }
436
437 return new UpdateRestrictions(restriction_flags);
438 }
439
440 DISALLOW_COPY_AND_ASSIGN(UpdateRestrictionsVariable);
441};
442
Amin Hassani03277de2020-07-28 12:32:49 -0700443// A variable class for reading timeout interval prefs value.
444class TestUpdateCheckIntervalTimeoutVariable : public Variable<int64_t> {
445 public:
446 TestUpdateCheckIntervalTimeoutVariable(
447 const string& name, chromeos_update_engine::PrefsInterface* prefs)
448 : Variable<int64_t>(name, kVariableModePoll),
449 prefs_(prefs),
450 read_count_(0) {
451 SetMissingOk();
452 }
453 ~TestUpdateCheckIntervalTimeoutVariable() = default;
454
455 private:
456 const int64_t* GetValue(TimeDelta /* timeout */,
457 string* /* errmsg */) override {
458 auto key = chromeos_update_engine::kPrefsTestUpdateCheckIntervalTimeout;
459 int64_t result;
460 if (prefs_ && prefs_->Exists(key) && prefs_->GetInt64(key, &result)) {
461 // This specific value is used for testing only. So it should not be kept
462 // around and should be deleted after a few reads.
463 if (++read_count_ > 2)
464 prefs_->Delete(key);
465
466 // Limit the timeout interval to 10 minutes so it is not abused if it is
467 // seen on official images.
468 return new int64_t(std::min(result, static_cast<int64_t>(10 * 60)));
469 }
470 return nullptr;
471 }
472
473 chromeos_update_engine::PrefsInterface* prefs_;
474
475 // Counts how many times this variable is read. This is used to delete the
476 // underlying file defining the variable after a certain number of reads in
477 // order to prevent any abuse of this variable.
478 int read_count_;
479
480 DISALLOW_COPY_AND_ASSIGN(TestUpdateCheckIntervalTimeoutVariable);
481};
482
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700483// RealUpdaterProvider methods.
484
485RealUpdaterProvider::RealUpdaterProvider(SystemState* system_state)
Aaron Woodbf5a2522017-10-04 10:58:36 -0700486 : system_state_(system_state),
487 var_updater_started_time_("updater_started_time",
488 system_state->clock()->GetWallclockTime()),
489 var_last_checked_time_(
490 new LastCheckedTimeVariable("last_checked_time", system_state_)),
491 var_update_completed_time_(new UpdateCompletedTimeVariable(
492 "update_completed_time", system_state_)),
493 var_progress_(new ProgressVariable("progress", system_state_)),
494 var_stage_(new StageVariable("stage", system_state_)),
495 var_new_version_(new NewVersionVariable("new_version", system_state_)),
496 var_payload_size_(new PayloadSizeVariable("payload_size", system_state_)),
497 var_curr_channel_(new CurrChannelVariable("curr_channel", system_state_)),
498 var_new_channel_(new NewChannelVariable("new_channel", system_state_)),
499 var_p2p_enabled_(
500 new BooleanPrefVariable("p2p_enabled",
501 system_state_->prefs(),
502 chromeos_update_engine::kPrefsP2PEnabled,
503 false)),
504 var_cellular_enabled_(new BooleanPrefVariable(
505 "cellular_enabled",
506 system_state_->prefs(),
507 chromeos_update_engine::kPrefsUpdateOverCellularPermission,
508 false)),
509 var_consecutive_failed_update_checks_(
510 new ConsecutiveFailedUpdateChecksVariable(
511 "consecutive_failed_update_checks", system_state_)),
512 var_server_dictated_poll_interval_(new ServerDictatedPollIntervalVariable(
513 "server_dictated_poll_interval", system_state_)),
514 var_forced_update_requested_(new ForcedUpdateRequestedVariable(
515 "forced_update_requested", system_state_)),
Amin Hassani03277de2020-07-28 12:32:49 -0700516 var_update_restrictions_(
517 new UpdateRestrictionsVariable("update_restrictions", system_state_)),
518 var_test_update_check_interval_timeout_(
519 new TestUpdateCheckIntervalTimeoutVariable(
520 "test_update_check_interval_timeout", system_state_->prefs())) {}
Alex Deymo63784a52014-05-28 10:46:14 -0700521} // namespace chromeos_update_manager