blob: 4bc28a942ece7220b89e234b3eb9630496b803cd [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/prefs.h"
Amin Hassani538bd592020-11-04 20:46:08 -080031#include "update_engine/common/system_state.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 Hassani538bd592020-11-04 20:46:08 -080052 UpdaterVariableBase(const string& name, VariableMode mode)
53 : Variable<T>(name, mode) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070054};
55
56// Helper class for issuing a GetStatus() to the UpdateAttempter.
57class GetStatusHelper {
58 public:
Amin Hassani538bd592020-11-04 20:46:08 -080059 explicit GetStatusHelper(string* errmsg) {
60 is_success_ = SystemState::Get()->update_attempter()->GetStatus(
61 &update_engine_status_);
Aaron Wood7f92e2b2017-08-28 14:51:21 -070062 if (!is_success_ && errmsg) {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070063 *errmsg = "Failed to get a status update from the update engine";
Aaron Wood7f92e2b2017-08-28 14:51:21 -070064 }
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070065 }
66
67 inline bool is_success() { return is_success_; }
Aaron Wood7f92e2b2017-08-28 14:51:21 -070068 inline int64_t last_checked_time() {
Aaron Wood795c5b42017-12-05 16:06:13 -080069 return update_engine_status_.last_checked_time;
Aaron Wood7f92e2b2017-08-28 14:51:21 -070070 }
71 inline double progress() { return update_engine_status_.progress; }
72 inline const string update_status() {
73 return chromeos_update_engine::UpdateStatusToString(
74 update_engine_status_.status);
75 }
76 inline const string& new_version() {
77 return update_engine_status_.new_version;
78 }
79 inline uint64_t payload_size() {
80 return update_engine_status_.new_size_bytes;
81 }
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070082
83 private:
84 bool is_success_;
Aaron Wood7f92e2b2017-08-28 14:51:21 -070085 UpdateEngineStatus update_engine_status_;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070086};
87
88// A variable reporting the time when a last update check was issued.
89class LastCheckedTimeVariable : public UpdaterVariableBase<Time> {
90 public:
Amin Hassani538bd592020-11-04 20:46:08 -080091 explicit LastCheckedTimeVariable(const string& name)
92 : UpdaterVariableBase<Time>(name, kVariableModePoll) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070093
94 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -070095 const Time* GetValue(TimeDelta /* timeout */, string* errmsg) override {
Amin Hassani538bd592020-11-04 20:46:08 -080096 GetStatusHelper raw(errmsg);
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070097 if (!raw.is_success())
Alex Vakulenko88b591f2014-08-28 16:48:57 -070098 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -070099
100 return new Time(Time::FromTimeT(raw.last_checked_time()));
101 }
102
103 DISALLOW_COPY_AND_ASSIGN(LastCheckedTimeVariable);
104};
105
106// A variable reporting the update (download) progress as a decimal fraction
107// between 0.0 and 1.0.
108class ProgressVariable : public UpdaterVariableBase<double> {
109 public:
Amin Hassani538bd592020-11-04 20:46:08 -0800110 explicit ProgressVariable(const string& name)
111 : UpdaterVariableBase<double>(name, kVariableModePoll) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700112
113 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -0700114 const double* GetValue(TimeDelta /* timeout */, string* errmsg) override {
Amin Hassani538bd592020-11-04 20:46:08 -0800115 GetStatusHelper raw(errmsg);
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700116 if (!raw.is_success())
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700117 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700118
119 if (raw.progress() < 0.0 || raw.progress() > 1.0) {
120 if (errmsg) {
Amin Hassani4b717432019-01-14 16:24:20 -0800121 *errmsg =
122 StringPrintf("Invalid progress value received: %f", raw.progress());
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700123 }
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700124 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700125 }
126
127 return new double(raw.progress());
128 }
129
130 DISALLOW_COPY_AND_ASSIGN(ProgressVariable);
131};
132
133// A variable reporting the stage in which the update process is.
134class StageVariable : public UpdaterVariableBase<Stage> {
135 public:
Amin Hassani538bd592020-11-04 20:46:08 -0800136 explicit StageVariable(const string& name)
137 : UpdaterVariableBase<Stage>(name, kVariableModePoll) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700138
139 private:
140 struct CurrOpStrToStage {
141 const char* str;
142 Stage stage;
143 };
144 static const CurrOpStrToStage curr_op_str_to_stage[];
145
146 // Note: the method is defined outside the class so arraysize can work.
Alex Vakulenko157fe302014-08-11 15:59:58 -0700147 const Stage* GetValue(TimeDelta /* timeout */, string* errmsg) override;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700148
149 DISALLOW_COPY_AND_ASSIGN(StageVariable);
150};
151
152const StageVariable::CurrOpStrToStage StageVariable::curr_op_str_to_stage[] = {
Amin Hassani4b717432019-01-14 16:24:20 -0800153 {update_engine::kUpdateStatusIdle, Stage::kIdle},
154 {update_engine::kUpdateStatusCheckingForUpdate, Stage::kCheckingForUpdate},
155 {update_engine::kUpdateStatusUpdateAvailable, Stage::kUpdateAvailable},
156 {update_engine::kUpdateStatusDownloading, Stage::kDownloading},
157 {update_engine::kUpdateStatusVerifying, Stage::kVerifying},
158 {update_engine::kUpdateStatusFinalizing, Stage::kFinalizing},
159 {update_engine::kUpdateStatusUpdatedNeedReboot, Stage::kUpdatedNeedReboot},
160 {update_engine::kUpdateStatusReportingErrorEvent,
161 Stage::kReportingErrorEvent},
162 {update_engine::kUpdateStatusAttemptingRollback,
163 Stage::kAttemptingRollback},
Amin Hassani70a90f52020-09-15 15:30:09 -0700164 {update_engine::kUpdateStatusCleanupPreviousUpdate,
165 Stage::kCleanupPreviousUpdate},
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700166};
167
Amin Hassani4b717432019-01-14 16:24:20 -0800168const Stage* StageVariable::GetValue(TimeDelta /* timeout */, string* errmsg) {
Amin Hassani538bd592020-11-04 20:46:08 -0800169 GetStatusHelper raw(errmsg);
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700170 if (!raw.is_success())
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700171 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700172
173 for (auto& key_val : curr_op_str_to_stage)
174 if (raw.update_status() == key_val.str)
175 return new Stage(key_val.stage);
176
177 if (errmsg)
178 *errmsg = string("Unknown update status: ") + raw.update_status();
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700179 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700180}
181
182// A variable reporting the version number that an update is updating to.
183class NewVersionVariable : public UpdaterVariableBase<string> {
184 public:
Amin Hassani538bd592020-11-04 20:46:08 -0800185 explicit NewVersionVariable(const string& name)
186 : UpdaterVariableBase<string>(name, kVariableModePoll) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700187
188 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -0700189 const string* GetValue(TimeDelta /* timeout */, string* errmsg) override {
Amin Hassani538bd592020-11-04 20:46:08 -0800190 GetStatusHelper raw(errmsg);
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700191 if (!raw.is_success())
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700192 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700193
194 return new string(raw.new_version());
195 }
196
197 DISALLOW_COPY_AND_ASSIGN(NewVersionVariable);
198};
199
200// A variable reporting the size of the update being processed in bytes.
Aaron Wood7f92e2b2017-08-28 14:51:21 -0700201class PayloadSizeVariable : public UpdaterVariableBase<uint64_t> {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700202 public:
Amin Hassani538bd592020-11-04 20:46:08 -0800203 explicit PayloadSizeVariable(const string& name)
204 : UpdaterVariableBase<uint64_t>(name, kVariableModePoll) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700205
206 private:
Aaron Wood7f92e2b2017-08-28 14:51:21 -0700207 const uint64_t* GetValue(TimeDelta /* timeout */, string* errmsg) override {
Amin Hassani538bd592020-11-04 20:46:08 -0800208 GetStatusHelper raw(errmsg);
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700209 if (!raw.is_success())
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700210 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700211
Aaron Wood7f92e2b2017-08-28 14:51:21 -0700212 return new uint64_t(raw.payload_size());
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700213 }
214
215 DISALLOW_COPY_AND_ASSIGN(PayloadSizeVariable);
216};
217
218// A variable reporting the point in time an update last completed in the
219// current boot cycle.
220//
221// TODO(garnold) In general, both the current boottime and wallclock time
222// readings should come from the time provider and be moderated by the
223// evaluation context, so that they are uniform throughout the evaluation of a
224// policy request.
225class UpdateCompletedTimeVariable : public UpdaterVariableBase<Time> {
226 public:
Amin Hassani538bd592020-11-04 20:46:08 -0800227 explicit UpdateCompletedTimeVariable(const string& name)
228 : UpdaterVariableBase<Time>(name, kVariableModePoll) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700229
230 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -0700231 const Time* GetValue(TimeDelta /* timeout */, string* errmsg) override {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700232 Time update_boottime;
Amin Hassani538bd592020-11-04 20:46:08 -0800233 if (!SystemState::Get()->update_attempter()->GetBootTimeAtUpdate(
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700234 &update_boottime)) {
235 if (errmsg)
236 *errmsg = "Update completed time could not be read";
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700237 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700238 }
239
Amin Hassani0468a762020-11-17 23:53:48 -0800240 const auto* clock = SystemState::Get()->clock();
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700241 Time curr_boottime = clock->GetBootTime();
242 if (curr_boottime < update_boottime) {
243 if (errmsg)
244 *errmsg = "Update completed time more recent than current time";
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700245 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700246 }
247 TimeDelta duration_since_update = curr_boottime - update_boottime;
248 return new Time(clock->GetWallclockTime() - duration_since_update);
249 }
250
251 DISALLOW_COPY_AND_ASSIGN(UpdateCompletedTimeVariable);
252};
253
254// Variables reporting the current image channel.
255class CurrChannelVariable : public UpdaterVariableBase<string> {
256 public:
Amin Hassani538bd592020-11-04 20:46:08 -0800257 explicit CurrChannelVariable(const string& name)
258 : UpdaterVariableBase<string>(name, kVariableModePoll) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700259
260 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -0700261 const string* GetValue(TimeDelta /* timeout */, string* errmsg) override {
Amin Hassani538bd592020-11-04 20:46:08 -0800262 OmahaRequestParams* request_params = SystemState::Get()->request_params();
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700263 string channel = request_params->current_channel();
264 if (channel.empty()) {
265 if (errmsg)
266 *errmsg = "No current channel";
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700267 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700268 }
269 return new string(channel);
270 }
271
272 DISALLOW_COPY_AND_ASSIGN(CurrChannelVariable);
273};
274
275// Variables reporting the new image channel.
276class NewChannelVariable : public UpdaterVariableBase<string> {
277 public:
Amin Hassani538bd592020-11-04 20:46:08 -0800278 explicit NewChannelVariable(const string& name)
279 : UpdaterVariableBase<string>(name, kVariableModePoll) {}
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700280
281 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -0700282 const string* GetValue(TimeDelta /* timeout */, string* errmsg) override {
Amin Hassani538bd592020-11-04 20:46:08 -0800283 OmahaRequestParams* request_params = SystemState::Get()->request_params();
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700284 string channel = request_params->target_channel();
285 if (channel.empty()) {
286 if (errmsg)
287 *errmsg = "No new channel";
Alex Vakulenko88b591f2014-08-28 16:48:57 -0700288 return nullptr;
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700289 }
290 return new string(channel);
291 }
292
293 DISALLOW_COPY_AND_ASSIGN(NewChannelVariable);
294};
295
296// A variable class for reading Boolean prefs values.
Alex Deymod6f60072015-10-12 12:22:27 -0700297class BooleanPrefVariable
298 : public AsyncCopyVariable<bool>,
299 public chromeos_update_engine::PrefsInterface::ObserverInterface {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700300 public:
Alex Deymod6f60072015-10-12 12:22:27 -0700301 BooleanPrefVariable(const string& name,
302 chromeos_update_engine::PrefsInterface* prefs,
303 const char* key,
304 bool default_val)
305 : AsyncCopyVariable<bool>(name),
306 prefs_(prefs),
307 key_(key),
308 default_val_(default_val) {
309 prefs->AddObserver(key, this);
310 OnPrefSet(key);
311 }
Amin Hassani4b717432019-01-14 16:24:20 -0800312 ~BooleanPrefVariable() { prefs_->RemoveObserver(key_, this); }
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700313
314 private:
Alex Deymod6f60072015-10-12 12:22:27 -0700315 // Reads the actual value from the Prefs instance and updates the Variable
316 // value.
317 void OnPrefSet(const string& key) override {
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700318 bool result = default_val_;
Alex Deymod6f60072015-10-12 12:22:27 -0700319 if (prefs_ && prefs_->Exists(key_) && !prefs_->GetBoolean(key_, &result))
320 result = default_val_;
321 // AsyncCopyVariable will take care of values that didn't change.
322 SetValue(result);
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700323 }
324
Amin Hassani4b717432019-01-14 16:24:20 -0800325 void OnPrefDeleted(const string& key) override { SetValue(default_val_); }
Alex Deymod6f60072015-10-12 12:22:27 -0700326
327 chromeos_update_engine::PrefsInterface* prefs_;
328
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700329 // The Boolean preference key and default value.
330 const char* const key_;
331 const bool default_val_;
332
333 DISALLOW_COPY_AND_ASSIGN(BooleanPrefVariable);
334};
335
Gilad Arnolda6dab942014-04-25 11:46:03 -0700336// A variable returning the number of consecutive failed update checks.
Gilad Arnoldcf175a02014-07-10 16:48:47 -0700337class ConsecutiveFailedUpdateChecksVariable
338 : public UpdaterVariableBase<unsigned int> {
Gilad Arnolda6dab942014-04-25 11:46:03 -0700339 public:
Amin Hassani538bd592020-11-04 20:46:08 -0800340 explicit ConsecutiveFailedUpdateChecksVariable(const string& name)
341 : UpdaterVariableBase<unsigned int>(name, kVariableModePoll) {}
Gilad Arnolda6dab942014-04-25 11:46:03 -0700342
343 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -0700344 const unsigned int* GetValue(TimeDelta /* timeout */,
345 string* /* errmsg */) override {
Amin Hassani538bd592020-11-04 20:46:08 -0800346 // NOLINTNEXTLINE(readability/casting)
347 return new unsigned int(SystemState::Get()
348 ->update_attempter()
349 ->consecutive_failed_update_checks());
Gilad Arnolda6dab942014-04-25 11:46:03 -0700350 }
351
352 DISALLOW_COPY_AND_ASSIGN(ConsecutiveFailedUpdateChecksVariable);
353};
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700354
Gilad Arnolda0258a52014-07-10 16:21:19 -0700355// A variable returning the server-dictated poll interval.
356class ServerDictatedPollIntervalVariable
357 : public UpdaterVariableBase<unsigned int> {
358 public:
Amin Hassani538bd592020-11-04 20:46:08 -0800359 explicit ServerDictatedPollIntervalVariable(const string& name)
360 : UpdaterVariableBase<unsigned int>(name, kVariableModePoll) {}
Gilad Arnolda0258a52014-07-10 16:21:19 -0700361
362 private:
Alex Vakulenko157fe302014-08-11 15:59:58 -0700363 const unsigned int* GetValue(TimeDelta /* timeout */,
364 string* /* errmsg */) override {
Amin Hassani538bd592020-11-04 20:46:08 -0800365 // NOLINTNEXTLINE(readability/casting)
366 return new unsigned int(SystemState::Get()
367 ->update_attempter()
368 ->server_dictated_poll_interval());
Gilad Arnolda0258a52014-07-10 16:21:19 -0700369 }
370
371 DISALLOW_COPY_AND_ASSIGN(ServerDictatedPollIntervalVariable);
372};
373
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700374// An async variable that tracks changes to forced update requests.
375class ForcedUpdateRequestedVariable
376 : public UpdaterVariableBase<UpdateRequestStatus> {
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700377 public:
Amin Hassani538bd592020-11-04 20:46:08 -0800378 explicit ForcedUpdateRequestedVariable(const string& name)
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700379 : UpdaterVariableBase<UpdateRequestStatus>::UpdaterVariableBase(
Amin Hassani538bd592020-11-04 20:46:08 -0800380 name, kVariableModeAsync) {
381 SystemState::Get()->update_attempter()->set_forced_update_pending_callback(
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700382 new base::Callback<void(bool, bool)>( // NOLINT(readability/function)
383 base::Bind(&ForcedUpdateRequestedVariable::Reset,
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700384 base::Unretained(this))));
385 }
386
387 private:
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700388 const UpdateRequestStatus* GetValue(TimeDelta /* timeout */,
389 string* /* errmsg */) override {
390 return new UpdateRequestStatus(update_request_status_);
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700391 }
392
Amin Hassanied37d682018-04-06 13:22:00 -0700393 void Reset(bool forced_update_requested, bool interactive) {
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700394 UpdateRequestStatus new_value = UpdateRequestStatus::kNone;
395 if (forced_update_requested)
Amin Hassanied37d682018-04-06 13:22:00 -0700396 new_value = (interactive ? UpdateRequestStatus::kInteractive
397 : UpdateRequestStatus::kPeriodic);
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700398 if (update_request_status_ != new_value) {
399 update_request_status_ = new_value;
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700400 NotifyValueChanged();
401 }
402 }
403
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700404 UpdateRequestStatus update_request_status_ = UpdateRequestStatus::kNone;
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700405
Gilad Arnoldec7f9162014-07-15 13:24:46 -0700406 DISALLOW_COPY_AND_ASSIGN(ForcedUpdateRequestedVariable);
Gilad Arnold44dc3bf2014-07-18 23:39:38 -0700407};
408
Aaron Woodbf5a2522017-10-04 10:58:36 -0700409// A variable returning the current update restrictions that are in effect.
410class UpdateRestrictionsVariable
411 : public UpdaterVariableBase<UpdateRestrictions> {
412 public:
Amin Hassani538bd592020-11-04 20:46:08 -0800413 explicit UpdateRestrictionsVariable(const string& name)
414 : UpdaterVariableBase<UpdateRestrictions>(name, kVariableModePoll) {}
Aaron Woodbf5a2522017-10-04 10:58:36 -0700415
416 private:
417 const UpdateRestrictions* GetValue(TimeDelta /* timeout */,
418 string* /* errmsg */) override {
419 UpdateAttemptFlags attempt_flags =
Amin Hassani538bd592020-11-04 20:46:08 -0800420 SystemState::Get()->update_attempter()->GetCurrentUpdateAttemptFlags();
Aaron Woodbf5a2522017-10-04 10:58:36 -0700421 UpdateRestrictions restriction_flags = UpdateRestrictions::kNone;
422 // Don't blindly copy the whole value, test and set bits that should
423 // transfer from one set of flags to the other.
424 if (attempt_flags & UpdateAttemptFlags::kFlagRestrictDownload) {
425 restriction_flags = static_cast<UpdateRestrictions>(
426 restriction_flags | UpdateRestrictions::kRestrictDownloading);
427 }
428
429 return new UpdateRestrictions(restriction_flags);
430 }
431
432 DISALLOW_COPY_AND_ASSIGN(UpdateRestrictionsVariable);
433};
434
Amin Hassani03277de2020-07-28 12:32:49 -0700435// A variable class for reading timeout interval prefs value.
436class TestUpdateCheckIntervalTimeoutVariable : public Variable<int64_t> {
437 public:
438 TestUpdateCheckIntervalTimeoutVariable(
439 const string& name, chromeos_update_engine::PrefsInterface* prefs)
440 : Variable<int64_t>(name, kVariableModePoll),
441 prefs_(prefs),
442 read_count_(0) {
443 SetMissingOk();
444 }
445 ~TestUpdateCheckIntervalTimeoutVariable() = default;
446
447 private:
448 const int64_t* GetValue(TimeDelta /* timeout */,
449 string* /* errmsg */) override {
450 auto key = chromeos_update_engine::kPrefsTestUpdateCheckIntervalTimeout;
451 int64_t result;
452 if (prefs_ && prefs_->Exists(key) && prefs_->GetInt64(key, &result)) {
453 // This specific value is used for testing only. So it should not be kept
454 // around and should be deleted after a few reads.
Amin Hassani7ad016b2020-09-03 14:19:13 -0700455 if (++read_count_ > 5)
Amin Hassani03277de2020-07-28 12:32:49 -0700456 prefs_->Delete(key);
457
458 // Limit the timeout interval to 10 minutes so it is not abused if it is
459 // seen on official images.
460 return new int64_t(std::min(result, static_cast<int64_t>(10 * 60)));
461 }
462 return nullptr;
463 }
464
465 chromeos_update_engine::PrefsInterface* prefs_;
466
467 // Counts how many times this variable is read. This is used to delete the
468 // underlying file defining the variable after a certain number of reads in
469 // order to prevent any abuse of this variable.
470 int read_count_;
471
472 DISALLOW_COPY_AND_ASSIGN(TestUpdateCheckIntervalTimeoutVariable);
473};
474
Gilad Arnoldae47a9a2014-03-26 12:16:47 -0700475// RealUpdaterProvider methods.
476
Amin Hassani538bd592020-11-04 20:46:08 -0800477RealUpdaterProvider::RealUpdaterProvider()
478 : var_updater_started_time_(
479 "updater_started_time",
480 SystemState::Get()->clock()->GetWallclockTime()),
481 var_last_checked_time_(new LastCheckedTimeVariable("last_checked_time")),
482 var_update_completed_time_(
483 new UpdateCompletedTimeVariable("update_completed_time")),
484 var_progress_(new ProgressVariable("progress")),
485 var_stage_(new StageVariable("stage")),
486 var_new_version_(new NewVersionVariable("new_version")),
487 var_payload_size_(new PayloadSizeVariable("payload_size")),
488 var_curr_channel_(new CurrChannelVariable("curr_channel")),
489 var_new_channel_(new NewChannelVariable("new_channel")),
Aaron Woodbf5a2522017-10-04 10:58:36 -0700490 var_p2p_enabled_(
491 new BooleanPrefVariable("p2p_enabled",
Amin Hassani538bd592020-11-04 20:46:08 -0800492 SystemState::Get()->prefs(),
Aaron Woodbf5a2522017-10-04 10:58:36 -0700493 chromeos_update_engine::kPrefsP2PEnabled,
494 false)),
495 var_cellular_enabled_(new BooleanPrefVariable(
496 "cellular_enabled",
Amin Hassani538bd592020-11-04 20:46:08 -0800497 SystemState::Get()->prefs(),
Aaron Woodbf5a2522017-10-04 10:58:36 -0700498 chromeos_update_engine::kPrefsUpdateOverCellularPermission,
499 false)),
500 var_consecutive_failed_update_checks_(
501 new ConsecutiveFailedUpdateChecksVariable(
Amin Hassani538bd592020-11-04 20:46:08 -0800502 "consecutive_failed_update_checks")),
Aaron Woodbf5a2522017-10-04 10:58:36 -0700503 var_server_dictated_poll_interval_(new ServerDictatedPollIntervalVariable(
Amin Hassani538bd592020-11-04 20:46:08 -0800504 "server_dictated_poll_interval")),
505 var_forced_update_requested_(
506 new ForcedUpdateRequestedVariable("forced_update_requested")),
Amin Hassani03277de2020-07-28 12:32:49 -0700507 var_update_restrictions_(
Amin Hassani538bd592020-11-04 20:46:08 -0800508 new UpdateRestrictionsVariable("update_restrictions")),
Amin Hassani03277de2020-07-28 12:32:49 -0700509 var_test_update_check_interval_timeout_(
510 new TestUpdateCheckIntervalTimeoutVariable(
Amin Hassani538bd592020-11-04 20:46:08 -0800511 "test_update_check_interval_timeout",
512 SystemState::Get()->prefs())) {}
Alex Deymo63784a52014-05-28 10:46:14 -0700513} // namespace chromeos_update_manager