| Alex Deymo | aea4c1c | 2015-08-19 20:24:43 -0700 | [diff] [blame] | 1 | // | 
 | 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 Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 16 |  | 
| Alex Deymo | 63784a5 | 2014-05-28 10:46:14 -0700 | [diff] [blame] | 17 | #include "update_engine/update_manager/real_updater_provider.h" | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 18 |  | 
 | 19 | #include <inttypes.h> | 
 | 20 |  | 
 | 21 | #include <string> | 
 | 22 |  | 
| Gilad Arnold | 44dc3bf | 2014-07-18 23:39:38 -0700 | [diff] [blame] | 23 | #include <base/bind.h> | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 24 | #include <base/strings/stringprintf.h> | 
| Alex Deymo | c7ab616 | 2014-04-25 18:32:50 -0700 | [diff] [blame] | 25 | #include <base/time/time.h> | 
| Alex Deymo | d6deb1d | 2015-08-28 15:54:37 -0700 | [diff] [blame] | 26 | #include <update_engine/dbus-constants.h> | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 27 |  | 
| Alex Deymo | 39910dc | 2015-11-09 17:04:30 -0800 | [diff] [blame] | 28 | #include "update_engine/common/clock_interface.h" | 
 | 29 | #include "update_engine/common/prefs.h" | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 30 | #include "update_engine/omaha_request_params.h" | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 31 | #include "update_engine/update_attempter.h" | 
 | 32 |  | 
 | 33 | using base::StringPrintf; | 
 | 34 | using base::Time; | 
 | 35 | using base::TimeDelta; | 
 | 36 | using chromeos_update_engine::OmahaRequestParams; | 
 | 37 | using chromeos_update_engine::SystemState; | 
 | 38 | using std::string; | 
 | 39 |  | 
| Alex Deymo | 63784a5 | 2014-05-28 10:46:14 -0700 | [diff] [blame] | 40 | namespace chromeos_update_manager { | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 41 |  | 
 | 42 | // A templated base class for all update related variables. Provides uniform | 
 | 43 | // construction and a system state handle. | 
 | 44 | template<typename T> | 
 | 45 | class UpdaterVariableBase : public Variable<T> { | 
 | 46 |  public: | 
| Gilad Arnold | 44dc3bf | 2014-07-18 23:39:38 -0700 | [diff] [blame] | 47 |   UpdaterVariableBase(const string& name, VariableMode mode, | 
 | 48 |                       SystemState* system_state) | 
 | 49 |       : Variable<T>(name, mode), system_state_(system_state) {} | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 50 |  | 
 | 51 |  protected: | 
 | 52 |   // The system state used for pulling information from the updater. | 
 | 53 |   inline SystemState* system_state() const { return system_state_; } | 
 | 54 |  | 
 | 55 |  private: | 
 | 56 |   SystemState* const system_state_; | 
 | 57 | }; | 
 | 58 |  | 
 | 59 | // Helper class for issuing a GetStatus() to the UpdateAttempter. | 
 | 60 | class GetStatusHelper { | 
 | 61 |  public: | 
 | 62 |   GetStatusHelper(SystemState* system_state, string* errmsg) { | 
 | 63 |     is_success_ = system_state->update_attempter()->GetStatus( | 
 | 64 |         &last_checked_time_, &progress_, &update_status_, &new_version_, | 
 | 65 |         &payload_size_); | 
 | 66 |     if (!is_success_ && errmsg) | 
 | 67 |       *errmsg = "Failed to get a status update from the update engine"; | 
 | 68 |   } | 
 | 69 |  | 
 | 70 |   inline bool is_success() { return is_success_; } | 
 | 71 |   inline int64_t last_checked_time() { return last_checked_time_; } | 
 | 72 |   inline double progress() { return progress_; } | 
 | 73 |   inline const string& update_status() { return update_status_; } | 
 | 74 |   inline const string& new_version() { return new_version_; } | 
 | 75 |   inline int64_t payload_size() { return payload_size_; } | 
 | 76 |  | 
 | 77 |  private: | 
 | 78 |   bool is_success_; | 
 | 79 |   int64_t last_checked_time_; | 
 | 80 |   double progress_; | 
 | 81 |   string update_status_; | 
 | 82 |   string new_version_; | 
 | 83 |   int64_t payload_size_; | 
 | 84 | }; | 
 | 85 |  | 
 | 86 | // A variable reporting the time when a last update check was issued. | 
 | 87 | class LastCheckedTimeVariable : public UpdaterVariableBase<Time> { | 
 | 88 |  public: | 
| Gilad Arnold | 44dc3bf | 2014-07-18 23:39:38 -0700 | [diff] [blame] | 89 |   LastCheckedTimeVariable(const string& name, SystemState* system_state) | 
 | 90 |       : UpdaterVariableBase<Time>(name, kVariableModePoll, system_state) {} | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 91 |  | 
 | 92 |  private: | 
| Alex Vakulenko | 157fe30 | 2014-08-11 15:59:58 -0700 | [diff] [blame] | 93 |   const Time* GetValue(TimeDelta /* timeout */, string* errmsg) override { | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 94 |     GetStatusHelper raw(system_state(), errmsg); | 
 | 95 |     if (!raw.is_success()) | 
| Alex Vakulenko | 88b591f | 2014-08-28 16:48:57 -0700 | [diff] [blame] | 96 |       return nullptr; | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 97 |  | 
 | 98 |     return new Time(Time::FromTimeT(raw.last_checked_time())); | 
 | 99 |   } | 
 | 100 |  | 
 | 101 |   DISALLOW_COPY_AND_ASSIGN(LastCheckedTimeVariable); | 
 | 102 | }; | 
 | 103 |  | 
 | 104 | // A variable reporting the update (download) progress as a decimal fraction | 
 | 105 | // between 0.0 and 1.0. | 
 | 106 | class ProgressVariable : public UpdaterVariableBase<double> { | 
 | 107 |  public: | 
| Gilad Arnold | 44dc3bf | 2014-07-18 23:39:38 -0700 | [diff] [blame] | 108 |   ProgressVariable(const string& name, SystemState* system_state) | 
 | 109 |       : UpdaterVariableBase<double>(name, kVariableModePoll, system_state) {} | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 110 |  | 
 | 111 |  private: | 
| Alex Vakulenko | 157fe30 | 2014-08-11 15:59:58 -0700 | [diff] [blame] | 112 |   const double* GetValue(TimeDelta /* timeout */, string* errmsg) override { | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 113 |     GetStatusHelper raw(system_state(), errmsg); | 
 | 114 |     if (!raw.is_success()) | 
| Alex Vakulenko | 88b591f | 2014-08-28 16:48:57 -0700 | [diff] [blame] | 115 |       return nullptr; | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 116 |  | 
 | 117 |     if (raw.progress() < 0.0 || raw.progress() > 1.0) { | 
 | 118 |       if (errmsg) { | 
 | 119 |         *errmsg = StringPrintf("Invalid progress value received: %f", | 
 | 120 |                                raw.progress()); | 
 | 121 |       } | 
| Alex Vakulenko | 88b591f | 2014-08-28 16:48:57 -0700 | [diff] [blame] | 122 |       return nullptr; | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 123 |     } | 
 | 124 |  | 
 | 125 |     return new double(raw.progress()); | 
 | 126 |   } | 
 | 127 |  | 
 | 128 |   DISALLOW_COPY_AND_ASSIGN(ProgressVariable); | 
 | 129 | }; | 
 | 130 |  | 
 | 131 | // A variable reporting the stage in which the update process is. | 
 | 132 | class StageVariable : public UpdaterVariableBase<Stage> { | 
 | 133 |  public: | 
| Gilad Arnold | 44dc3bf | 2014-07-18 23:39:38 -0700 | [diff] [blame] | 134 |   StageVariable(const string& name, SystemState* system_state) | 
 | 135 |       : UpdaterVariableBase<Stage>(name, kVariableModePoll, system_state) {} | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 136 |  | 
 | 137 |  private: | 
 | 138 |   struct CurrOpStrToStage { | 
 | 139 |     const char* str; | 
 | 140 |     Stage stage; | 
 | 141 |   }; | 
 | 142 |   static const CurrOpStrToStage curr_op_str_to_stage[]; | 
 | 143 |  | 
 | 144 |   // Note: the method is defined outside the class so arraysize can work. | 
| Alex Vakulenko | 157fe30 | 2014-08-11 15:59:58 -0700 | [diff] [blame] | 145 |   const Stage* GetValue(TimeDelta /* timeout */, string* errmsg) override; | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 146 |  | 
 | 147 |   DISALLOW_COPY_AND_ASSIGN(StageVariable); | 
 | 148 | }; | 
 | 149 |  | 
 | 150 | const StageVariable::CurrOpStrToStage StageVariable::curr_op_str_to_stage[] = { | 
 | 151 |   {update_engine::kUpdateStatusIdle, Stage::kIdle}, | 
 | 152 |   {update_engine::kUpdateStatusCheckingForUpdate, Stage::kCheckingForUpdate}, | 
 | 153 |   {update_engine::kUpdateStatusUpdateAvailable, Stage::kUpdateAvailable}, | 
 | 154 |   {update_engine::kUpdateStatusDownloading, Stage::kDownloading}, | 
 | 155 |   {update_engine::kUpdateStatusVerifying, Stage::kVerifying}, | 
 | 156 |   {update_engine::kUpdateStatusFinalizing, Stage::kFinalizing}, | 
 | 157 |   {update_engine::kUpdateStatusUpdatedNeedReboot, Stage::kUpdatedNeedReboot}, | 
| Gilad Arnold | cf175a0 | 2014-07-10 16:48:47 -0700 | [diff] [blame] | 158 |   {  // NOLINT(whitespace/braces) | 
 | 159 |     update_engine::kUpdateStatusReportingErrorEvent, | 
 | 160 |     Stage::kReportingErrorEvent | 
 | 161 |   }, | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 162 |   {update_engine::kUpdateStatusAttemptingRollback, Stage::kAttemptingRollback}, | 
 | 163 | }; | 
 | 164 |  | 
 | 165 | const Stage* StageVariable::GetValue(TimeDelta /* timeout */, | 
 | 166 |                                      string* errmsg) { | 
 | 167 |   GetStatusHelper raw(system_state(), errmsg); | 
 | 168 |   if (!raw.is_success()) | 
| Alex Vakulenko | 88b591f | 2014-08-28 16:48:57 -0700 | [diff] [blame] | 169 |     return nullptr; | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 170 |  | 
 | 171 |   for (auto& key_val : curr_op_str_to_stage) | 
 | 172 |     if (raw.update_status() == key_val.str) | 
 | 173 |       return new Stage(key_val.stage); | 
 | 174 |  | 
 | 175 |   if (errmsg) | 
 | 176 |     *errmsg = string("Unknown update status: ") + raw.update_status(); | 
| Alex Vakulenko | 88b591f | 2014-08-28 16:48:57 -0700 | [diff] [blame] | 177 |   return nullptr; | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 178 | } | 
 | 179 |  | 
 | 180 | // A variable reporting the version number that an update is updating to. | 
 | 181 | class NewVersionVariable : public UpdaterVariableBase<string> { | 
 | 182 |  public: | 
| Gilad Arnold | 44dc3bf | 2014-07-18 23:39:38 -0700 | [diff] [blame] | 183 |   NewVersionVariable(const string& name, SystemState* system_state) | 
 | 184 |       : UpdaterVariableBase<string>(name, kVariableModePoll, system_state) {} | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 185 |  | 
 | 186 |  private: | 
| Alex Vakulenko | 157fe30 | 2014-08-11 15:59:58 -0700 | [diff] [blame] | 187 |   const string* GetValue(TimeDelta /* timeout */, string* errmsg) override { | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 188 |     GetStatusHelper raw(system_state(), errmsg); | 
 | 189 |     if (!raw.is_success()) | 
| Alex Vakulenko | 88b591f | 2014-08-28 16:48:57 -0700 | [diff] [blame] | 190 |       return nullptr; | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 191 |  | 
 | 192 |     return new string(raw.new_version()); | 
 | 193 |   } | 
 | 194 |  | 
 | 195 |   DISALLOW_COPY_AND_ASSIGN(NewVersionVariable); | 
 | 196 | }; | 
 | 197 |  | 
 | 198 | // A variable reporting the size of the update being processed in bytes. | 
| Alex Deymo | f967ebe | 2014-05-05 14:46:17 -0700 | [diff] [blame] | 199 | class PayloadSizeVariable : public UpdaterVariableBase<int64_t> { | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 200 |  public: | 
| Gilad Arnold | 44dc3bf | 2014-07-18 23:39:38 -0700 | [diff] [blame] | 201 |   PayloadSizeVariable(const string& name, SystemState* system_state) | 
 | 202 |       : UpdaterVariableBase<int64_t>(name, kVariableModePoll, system_state) {} | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 203 |  | 
 | 204 |  private: | 
| Alex Vakulenko | 157fe30 | 2014-08-11 15:59:58 -0700 | [diff] [blame] | 205 |   const int64_t* GetValue(TimeDelta /* timeout */, string* errmsg) override { | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 206 |     GetStatusHelper raw(system_state(), errmsg); | 
 | 207 |     if (!raw.is_success()) | 
| Alex Vakulenko | 88b591f | 2014-08-28 16:48:57 -0700 | [diff] [blame] | 208 |       return nullptr; | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 209 |  | 
 | 210 |     if (raw.payload_size() < 0) { | 
 | 211 |       if (errmsg) | 
 | 212 |         *errmsg = string("Invalid payload size: %" PRId64, raw.payload_size()); | 
| Alex Vakulenko | 88b591f | 2014-08-28 16:48:57 -0700 | [diff] [blame] | 213 |       return nullptr; | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 214 |     } | 
 | 215 |  | 
| Alex Deymo | f967ebe | 2014-05-05 14:46:17 -0700 | [diff] [blame] | 216 |     return new int64_t(raw.payload_size()); | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 217 |   } | 
 | 218 |  | 
 | 219 |   DISALLOW_COPY_AND_ASSIGN(PayloadSizeVariable); | 
 | 220 | }; | 
 | 221 |  | 
 | 222 | // A variable reporting the point in time an update last completed in the | 
 | 223 | // current boot cycle. | 
 | 224 | // | 
 | 225 | // TODO(garnold) In general, both the current boottime and wallclock time | 
 | 226 | // readings should come from the time provider and be moderated by the | 
 | 227 | // evaluation context, so that they are uniform throughout the evaluation of a | 
 | 228 | // policy request. | 
 | 229 | class UpdateCompletedTimeVariable : public UpdaterVariableBase<Time> { | 
 | 230 |  public: | 
| Gilad Arnold | 44dc3bf | 2014-07-18 23:39:38 -0700 | [diff] [blame] | 231 |   UpdateCompletedTimeVariable(const string& name, SystemState* system_state) | 
 | 232 |       : UpdaterVariableBase<Time>(name, kVariableModePoll, system_state) {} | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 233 |  | 
 | 234 |  private: | 
| Alex Vakulenko | 157fe30 | 2014-08-11 15:59:58 -0700 | [diff] [blame] | 235 |   const Time* GetValue(TimeDelta /* timeout */, string* errmsg) override { | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 236 |     Time update_boottime; | 
 | 237 |     if (!system_state()->update_attempter()->GetBootTimeAtUpdate( | 
 | 238 |             &update_boottime)) { | 
 | 239 |       if (errmsg) | 
 | 240 |         *errmsg = "Update completed time could not be read"; | 
| Alex Vakulenko | 88b591f | 2014-08-28 16:48:57 -0700 | [diff] [blame] | 241 |       return nullptr; | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 242 |     } | 
 | 243 |  | 
 | 244 |     chromeos_update_engine::ClockInterface* clock = system_state()->clock(); | 
 | 245 |     Time curr_boottime = clock->GetBootTime(); | 
 | 246 |     if (curr_boottime < update_boottime) { | 
 | 247 |       if (errmsg) | 
 | 248 |         *errmsg = "Update completed time more recent than current time"; | 
| Alex Vakulenko | 88b591f | 2014-08-28 16:48:57 -0700 | [diff] [blame] | 249 |       return nullptr; | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 250 |     } | 
 | 251 |     TimeDelta duration_since_update = curr_boottime - update_boottime; | 
 | 252 |     return new Time(clock->GetWallclockTime() - duration_since_update); | 
 | 253 |   } | 
 | 254 |  | 
 | 255 |   DISALLOW_COPY_AND_ASSIGN(UpdateCompletedTimeVariable); | 
 | 256 | }; | 
 | 257 |  | 
 | 258 | // Variables reporting the current image channel. | 
 | 259 | class CurrChannelVariable : public UpdaterVariableBase<string> { | 
 | 260 |  public: | 
| Gilad Arnold | 44dc3bf | 2014-07-18 23:39:38 -0700 | [diff] [blame] | 261 |   CurrChannelVariable(const string& name, SystemState* system_state) | 
 | 262 |       : UpdaterVariableBase<string>(name, kVariableModePoll, system_state) {} | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 263 |  | 
 | 264 |  private: | 
| Alex Vakulenko | 157fe30 | 2014-08-11 15:59:58 -0700 | [diff] [blame] | 265 |   const string* GetValue(TimeDelta /* timeout */, string* errmsg) override { | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 266 |     OmahaRequestParams* request_params = system_state()->request_params(); | 
 | 267 |     string channel = request_params->current_channel(); | 
 | 268 |     if (channel.empty()) { | 
 | 269 |       if (errmsg) | 
 | 270 |         *errmsg = "No current channel"; | 
| Alex Vakulenko | 88b591f | 2014-08-28 16:48:57 -0700 | [diff] [blame] | 271 |       return nullptr; | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 272 |     } | 
 | 273 |     return new string(channel); | 
 | 274 |   } | 
 | 275 |  | 
 | 276 |   DISALLOW_COPY_AND_ASSIGN(CurrChannelVariable); | 
 | 277 | }; | 
 | 278 |  | 
 | 279 | // Variables reporting the new image channel. | 
 | 280 | class NewChannelVariable : public UpdaterVariableBase<string> { | 
 | 281 |  public: | 
| Gilad Arnold | 44dc3bf | 2014-07-18 23:39:38 -0700 | [diff] [blame] | 282 |   NewChannelVariable(const string& name, SystemState* system_state) | 
 | 283 |       : UpdaterVariableBase<string>(name, kVariableModePoll, system_state) {} | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 284 |  | 
 | 285 |  private: | 
| Alex Vakulenko | 157fe30 | 2014-08-11 15:59:58 -0700 | [diff] [blame] | 286 |   const string* GetValue(TimeDelta /* timeout */, string* errmsg) override { | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 287 |     OmahaRequestParams* request_params = system_state()->request_params(); | 
 | 288 |     string channel = request_params->target_channel(); | 
 | 289 |     if (channel.empty()) { | 
 | 290 |       if (errmsg) | 
 | 291 |         *errmsg = "No new channel"; | 
| Alex Vakulenko | 88b591f | 2014-08-28 16:48:57 -0700 | [diff] [blame] | 292 |       return nullptr; | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 293 |     } | 
 | 294 |     return new string(channel); | 
 | 295 |   } | 
 | 296 |  | 
 | 297 |   DISALLOW_COPY_AND_ASSIGN(NewChannelVariable); | 
 | 298 | }; | 
 | 299 |  | 
 | 300 | // A variable class for reading Boolean prefs values. | 
| Alex Deymo | d6f6007 | 2015-10-12 12:22:27 -0700 | [diff] [blame] | 301 | class BooleanPrefVariable | 
 | 302 |     : public AsyncCopyVariable<bool>, | 
 | 303 |       public chromeos_update_engine::PrefsInterface::ObserverInterface { | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 304 |  public: | 
| Alex Deymo | d6f6007 | 2015-10-12 12:22:27 -0700 | [diff] [blame] | 305 |   BooleanPrefVariable(const string& name, | 
 | 306 |                       chromeos_update_engine::PrefsInterface* prefs, | 
 | 307 |                       const char* key, | 
 | 308 |                       bool default_val) | 
 | 309 |       : AsyncCopyVariable<bool>(name), | 
 | 310 |         prefs_(prefs), | 
 | 311 |         key_(key), | 
 | 312 |         default_val_(default_val) { | 
 | 313 |     prefs->AddObserver(key, this); | 
 | 314 |     OnPrefSet(key); | 
 | 315 |   } | 
 | 316 |   ~BooleanPrefVariable() { | 
 | 317 |     prefs_->RemoveObserver(key_, this); | 
 | 318 |   } | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 319 |  | 
 | 320 |  private: | 
| Alex Deymo | d6f6007 | 2015-10-12 12:22:27 -0700 | [diff] [blame] | 321 |   // Reads the actual value from the Prefs instance and updates the Variable | 
 | 322 |   // value. | 
 | 323 |   void OnPrefSet(const string& key) override { | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 324 |     bool result = default_val_; | 
| Alex Deymo | d6f6007 | 2015-10-12 12:22:27 -0700 | [diff] [blame] | 325 |     if (prefs_ && prefs_->Exists(key_) && !prefs_->GetBoolean(key_, &result)) | 
 | 326 |       result = default_val_; | 
 | 327 |     // AsyncCopyVariable will take care of values that didn't change. | 
 | 328 |     SetValue(result); | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 329 |   } | 
 | 330 |  | 
| Alex Deymo | d6f6007 | 2015-10-12 12:22:27 -0700 | [diff] [blame] | 331 |   void OnPrefDeleted(const string& key) override { | 
 | 332 |     SetValue(default_val_); | 
 | 333 |   } | 
 | 334 |  | 
 | 335 |   chromeos_update_engine::PrefsInterface* prefs_; | 
 | 336 |  | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 337 |   // The Boolean preference key and default value. | 
 | 338 |   const char* const key_; | 
 | 339 |   const bool default_val_; | 
 | 340 |  | 
 | 341 |   DISALLOW_COPY_AND_ASSIGN(BooleanPrefVariable); | 
 | 342 | }; | 
 | 343 |  | 
| Gilad Arnold | a6dab94 | 2014-04-25 11:46:03 -0700 | [diff] [blame] | 344 | // A variable returning the number of consecutive failed update checks. | 
| Gilad Arnold | cf175a0 | 2014-07-10 16:48:47 -0700 | [diff] [blame] | 345 | class ConsecutiveFailedUpdateChecksVariable | 
 | 346 |     : public UpdaterVariableBase<unsigned int> { | 
| Gilad Arnold | a6dab94 | 2014-04-25 11:46:03 -0700 | [diff] [blame] | 347 |  public: | 
| Gilad Arnold | 44dc3bf | 2014-07-18 23:39:38 -0700 | [diff] [blame] | 348 |   ConsecutiveFailedUpdateChecksVariable(const string& name, | 
 | 349 |                                         SystemState* system_state) | 
 | 350 |       : UpdaterVariableBase<unsigned int>(name, kVariableModePoll, | 
 | 351 |                                           system_state) {} | 
| Gilad Arnold | a6dab94 | 2014-04-25 11:46:03 -0700 | [diff] [blame] | 352 |  | 
 | 353 |  private: | 
| Alex Vakulenko | 157fe30 | 2014-08-11 15:59:58 -0700 | [diff] [blame] | 354 |   const unsigned int* GetValue(TimeDelta /* timeout */, | 
 | 355 |                                string* /* errmsg */) override { | 
| Gilad Arnold | a6dab94 | 2014-04-25 11:46:03 -0700 | [diff] [blame] | 356 |     return new unsigned int( | 
 | 357 |         system_state()->update_attempter()->consecutive_failed_update_checks()); | 
 | 358 |   } | 
 | 359 |  | 
 | 360 |   DISALLOW_COPY_AND_ASSIGN(ConsecutiveFailedUpdateChecksVariable); | 
 | 361 | }; | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 362 |  | 
| Gilad Arnold | a0258a5 | 2014-07-10 16:21:19 -0700 | [diff] [blame] | 363 | // A variable returning the server-dictated poll interval. | 
 | 364 | class ServerDictatedPollIntervalVariable | 
 | 365 |     : public UpdaterVariableBase<unsigned int> { | 
 | 366 |  public: | 
| Gilad Arnold | 44dc3bf | 2014-07-18 23:39:38 -0700 | [diff] [blame] | 367 |   ServerDictatedPollIntervalVariable(const string& name, | 
 | 368 |                                      SystemState* system_state) | 
 | 369 |       : UpdaterVariableBase<unsigned int>(name, kVariableModePoll, | 
 | 370 |                                           system_state) {} | 
| Gilad Arnold | a0258a5 | 2014-07-10 16:21:19 -0700 | [diff] [blame] | 371 |  | 
 | 372 |  private: | 
| Alex Vakulenko | 157fe30 | 2014-08-11 15:59:58 -0700 | [diff] [blame] | 373 |   const unsigned int* GetValue(TimeDelta /* timeout */, | 
 | 374 |                                string* /* errmsg */) override { | 
| Gilad Arnold | a0258a5 | 2014-07-10 16:21:19 -0700 | [diff] [blame] | 375 |     return new unsigned int( | 
 | 376 |         system_state()->update_attempter()->server_dictated_poll_interval()); | 
 | 377 |   } | 
 | 378 |  | 
 | 379 |   DISALLOW_COPY_AND_ASSIGN(ServerDictatedPollIntervalVariable); | 
 | 380 | }; | 
 | 381 |  | 
| Gilad Arnold | ec7f916 | 2014-07-15 13:24:46 -0700 | [diff] [blame] | 382 | // An async variable that tracks changes to forced update requests. | 
 | 383 | class ForcedUpdateRequestedVariable | 
 | 384 |     : public UpdaterVariableBase<UpdateRequestStatus> { | 
| Gilad Arnold | 44dc3bf | 2014-07-18 23:39:38 -0700 | [diff] [blame] | 385 |  public: | 
| Gilad Arnold | ec7f916 | 2014-07-15 13:24:46 -0700 | [diff] [blame] | 386 |   ForcedUpdateRequestedVariable(const string& name, SystemState* system_state) | 
 | 387 |       : UpdaterVariableBase<UpdateRequestStatus>::UpdaterVariableBase( | 
 | 388 |           name, kVariableModeAsync, system_state) { | 
 | 389 |     system_state->update_attempter()->set_forced_update_pending_callback( | 
 | 390 |         new base::Callback<void(bool, bool)>(  // NOLINT(readability/function) | 
 | 391 |             base::Bind(&ForcedUpdateRequestedVariable::Reset, | 
| Gilad Arnold | 44dc3bf | 2014-07-18 23:39:38 -0700 | [diff] [blame] | 392 |                        base::Unretained(this)))); | 
 | 393 |   } | 
 | 394 |  | 
 | 395 |  private: | 
| Gilad Arnold | ec7f916 | 2014-07-15 13:24:46 -0700 | [diff] [blame] | 396 |   const UpdateRequestStatus* GetValue(TimeDelta /* timeout */, | 
 | 397 |                                       string* /* errmsg */) override { | 
 | 398 |     return new UpdateRequestStatus(update_request_status_); | 
| Gilad Arnold | 44dc3bf | 2014-07-18 23:39:38 -0700 | [diff] [blame] | 399 |   } | 
 | 400 |  | 
| Gilad Arnold | ec7f916 | 2014-07-15 13:24:46 -0700 | [diff] [blame] | 401 |   void Reset(bool forced_update_requested, bool is_interactive) { | 
 | 402 |     UpdateRequestStatus new_value = UpdateRequestStatus::kNone; | 
 | 403 |     if (forced_update_requested) | 
 | 404 |       new_value = (is_interactive ? UpdateRequestStatus::kInteractive : | 
 | 405 |                    UpdateRequestStatus::kPeriodic); | 
 | 406 |     if (update_request_status_ != new_value) { | 
 | 407 |       update_request_status_ = new_value; | 
| Gilad Arnold | 44dc3bf | 2014-07-18 23:39:38 -0700 | [diff] [blame] | 408 |       NotifyValueChanged(); | 
 | 409 |     } | 
 | 410 |   } | 
 | 411 |  | 
| Gilad Arnold | ec7f916 | 2014-07-15 13:24:46 -0700 | [diff] [blame] | 412 |   UpdateRequestStatus update_request_status_ = UpdateRequestStatus::kNone; | 
| Gilad Arnold | 44dc3bf | 2014-07-18 23:39:38 -0700 | [diff] [blame] | 413 |  | 
| Gilad Arnold | ec7f916 | 2014-07-15 13:24:46 -0700 | [diff] [blame] | 414 |   DISALLOW_COPY_AND_ASSIGN(ForcedUpdateRequestedVariable); | 
| Gilad Arnold | 44dc3bf | 2014-07-18 23:39:38 -0700 | [diff] [blame] | 415 | }; | 
 | 416 |  | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 417 | // RealUpdaterProvider methods. | 
 | 418 |  | 
 | 419 | RealUpdaterProvider::RealUpdaterProvider(SystemState* system_state) | 
 | 420 |   : system_state_(system_state), | 
| Alex Deymo | c7ab616 | 2014-04-25 18:32:50 -0700 | [diff] [blame] | 421 |     var_updater_started_time_("updater_started_time", | 
 | 422 |                               system_state->clock()->GetWallclockTime()), | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 423 |     var_last_checked_time_( | 
 | 424 |         new LastCheckedTimeVariable("last_checked_time", system_state_)), | 
 | 425 |     var_update_completed_time_( | 
 | 426 |         new UpdateCompletedTimeVariable("update_completed_time", | 
 | 427 |                                         system_state_)), | 
 | 428 |     var_progress_(new ProgressVariable("progress", system_state_)), | 
 | 429 |     var_stage_(new StageVariable("stage", system_state_)), | 
 | 430 |     var_new_version_(new NewVersionVariable("new_version", system_state_)), | 
 | 431 |     var_payload_size_(new PayloadSizeVariable("payload_size", system_state_)), | 
 | 432 |     var_curr_channel_(new CurrChannelVariable("curr_channel", system_state_)), | 
 | 433 |     var_new_channel_(new NewChannelVariable("new_channel", system_state_)), | 
 | 434 |     var_p2p_enabled_( | 
| Alex Deymo | d6f6007 | 2015-10-12 12:22:27 -0700 | [diff] [blame] | 435 |         new BooleanPrefVariable("p2p_enabled", system_state_->prefs(), | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 436 |                                 chromeos_update_engine::kPrefsP2PEnabled, | 
 | 437 |                                 false)), | 
 | 438 |     var_cellular_enabled_( | 
 | 439 |         new BooleanPrefVariable( | 
| Alex Deymo | d6f6007 | 2015-10-12 12:22:27 -0700 | [diff] [blame] | 440 |             "cellular_enabled", system_state_->prefs(), | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 441 |             chromeos_update_engine::kPrefsUpdateOverCellularPermission, | 
| Gilad Arnold | a6dab94 | 2014-04-25 11:46:03 -0700 | [diff] [blame] | 442 |             false)), | 
 | 443 |     var_consecutive_failed_update_checks_( | 
 | 444 |         new ConsecutiveFailedUpdateChecksVariable( | 
| Gilad Arnold | a0258a5 | 2014-07-10 16:21:19 -0700 | [diff] [blame] | 445 |             "consecutive_failed_update_checks", system_state_)), | 
 | 446 |     var_server_dictated_poll_interval_( | 
 | 447 |         new ServerDictatedPollIntervalVariable( | 
| Gilad Arnold | 44dc3bf | 2014-07-18 23:39:38 -0700 | [diff] [blame] | 448 |             "server_dictated_poll_interval", system_state_)), | 
| Gilad Arnold | ec7f916 | 2014-07-15 13:24:46 -0700 | [diff] [blame] | 449 |     var_forced_update_requested_( | 
 | 450 |         new ForcedUpdateRequestedVariable( | 
 | 451 |             "forced_update_requested", system_state_)) {} | 
| Gilad Arnold | ae47a9a | 2014-03-26 12:16:47 -0700 | [diff] [blame] | 452 |  | 
| Alex Deymo | 63784a5 | 2014-05-28 10:46:14 -0700 | [diff] [blame] | 453 | }  // namespace chromeos_update_manager |