1 // Copyright 2017 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef COMPONENTS_UPDATE_CLIENT_COMPONENT_H_ 6 #define COMPONENTS_UPDATE_CLIENT_COMPONENT_H_ 7 8 #include <map> 9 #include <memory> 10 #include <string> 11 #include <utility> 12 #include <vector> 13 14 #include "base/callback.h" 15 #include "base/files/file_path.h" 16 #include "base/gtest_prod_util.h" 17 #include "base/macros.h" 18 #include "base/memory/ref_counted.h" 19 #include "base/optional.h" 20 #include "base/threading/thread_checker.h" 21 #include "base/time/time.h" 22 #include "base/version.h" 23 #include "components/update_client/crx_downloader.h" 24 #include "components/update_client/protocol_parser.h" 25 #include "components/update_client/update_client.h" 26 #include "url/gurl.h" 27 28 namespace base { 29 class Value; 30 } // namespace base 31 32 namespace update_client { 33 34 class ActionRunner; 35 class Configurator; 36 struct CrxUpdateItem; 37 struct UpdateContext; 38 39 // Describes a CRX component managed by the UpdateEngine. Each instance of 40 // this class is associated with one instance of UpdateContext. 41 class Component { 42 public: 43 using Events = UpdateClient::Observer::Events; 44 45 using CallbackHandleComplete = base::OnceCallback<void()>; 46 47 Component(const UpdateContext& update_context, const std::string& id); 48 ~Component(); 49 50 // Handles the current state of the component and makes it transition 51 // to the next component state before |callback_handle_complete_| is invoked. 52 void Handle(CallbackHandleComplete callback_handle_complete); 53 54 CrxUpdateItem GetCrxUpdateItem() const; 55 56 // Sets the uninstall state for this component. 57 void Uninstall(const base::Version& cur_version, int reason); 58 59 // Called by the UpdateEngine when an update check for this component is done. 60 void SetUpdateCheckResult( 61 const base::Optional<ProtocolParser::Result>& result, 62 ErrorCategory error_category, 63 int error); 64 65 // Called by the UpdateEngine when a component enters a wait for throttling 66 // purposes. 67 void NotifyWait(); 68 69 // Returns true if the component has reached a final state and no further 70 // handling and state transitions are possible. IsHandled()71 bool IsHandled() const { return is_handled_; } 72 73 // Returns true if an update is available for this component, meaning that 74 // the update server has return a response containing an update. IsUpdateAvailable()75 bool IsUpdateAvailable() const { return is_update_available_; } 76 77 base::TimeDelta GetUpdateDuration() const; 78 state()79 ComponentState state() const { return state_->state(); } 80 id()81 std::string id() const { return id_; } 82 crx_component()83 const base::Optional<CrxComponent>& crx_component() const { 84 return crx_component_; 85 } set_crx_component(const CrxComponent & crx_component)86 void set_crx_component(const CrxComponent& crx_component) { 87 crx_component_ = crx_component; 88 } 89 previous_version()90 const base::Version& previous_version() const { return previous_version_; } set_previous_version(const base::Version & previous_version)91 void set_previous_version(const base::Version& previous_version) { 92 previous_version_ = previous_version; 93 } 94 next_version()95 const base::Version& next_version() const { return next_version_; } 96 previous_fp()97 std::string previous_fp() const { return previous_fp_; } set_previous_fp(const std::string & previous_fp)98 void set_previous_fp(const std::string& previous_fp) { 99 previous_fp_ = previous_fp; 100 } 101 next_fp()102 std::string next_fp() const { return next_fp_; } set_next_fp(const std::string & next_fp)103 void set_next_fp(const std::string& next_fp) { next_fp_ = next_fp; } 104 105 bool is_foreground() const; 106 crx_diffurls()107 const std::vector<GURL>& crx_diffurls() const { return crx_diffurls_; } 108 diff_update_failed()109 bool diff_update_failed() const { return !!diff_error_code_; } 110 error_category()111 ErrorCategory error_category() const { return error_category_; } error_code()112 int error_code() const { return error_code_; } extra_code1()113 int extra_code1() const { return extra_code1_; } diff_error_category()114 ErrorCategory diff_error_category() const { return diff_error_category_; } diff_error_code()115 int diff_error_code() const { return diff_error_code_; } diff_extra_code1()116 int diff_extra_code1() const { return diff_extra_code1_; } 117 action_run()118 std::string action_run() const { return action_run_; } 119 120 scoped_refptr<Configurator> config() const; 121 122 std::string session_id() const; 123 events()124 const std::vector<base::Value>& events() const { return events_; } 125 126 // Returns a clone of the component events. 127 std::vector<base::Value> GetEvents() const; 128 129 private: 130 friend class MockPingManagerImpl; 131 friend class UpdateCheckerTest; 132 133 FRIEND_TEST_ALL_PREFIXES(PingManagerTest, SendPing); 134 FRIEND_TEST_ALL_PREFIXES(PingManagerTest, RequiresEncryption); 135 FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, NoUpdateActionRun); 136 FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, UpdateCheckCupError); 137 FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, UpdateCheckError); 138 FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, UpdateCheckInvalidAp); 139 FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, 140 UpdateCheckRequiresEncryptionError); 141 FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, UpdateCheckSuccess); 142 FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, UpdateCheckUpdateDisabled); 143 144 // Describes an abstraction for implementing the behavior of a component and 145 // the transition from one state to another. 146 class State { 147 public: 148 using CallbackNextState = 149 base::OnceCallback<void(std::unique_ptr<State> next_state)>; 150 151 State(Component* component, ComponentState state); 152 virtual ~State(); 153 154 // Handles the current state and initiates a transition to a new state. 155 // The transition to the new state is non-blocking and it is completed 156 // by the outer component, after the current state is fully handled. 157 void Handle(CallbackNextState callback); 158 state()159 ComponentState state() const { return state_; } 160 161 protected: 162 // Initiates the transition to the new state. 163 void TransitionState(std::unique_ptr<State> new_state); 164 165 // Makes the current state a final state where no other state transition 166 // can further occur. 167 void EndState(); 168 component()169 Component& component() { return component_; } component()170 const Component& component() const { return component_; } 171 172 base::ThreadChecker thread_checker_; 173 174 const ComponentState state_; 175 176 private: 177 virtual void DoHandle() = 0; 178 179 Component& component_; 180 CallbackNextState callback_next_state_; 181 }; 182 183 class StateNew : public State { 184 public: 185 explicit StateNew(Component* component); 186 ~StateNew() override; 187 188 private: 189 // State overrides. 190 void DoHandle() override; 191 192 DISALLOW_COPY_AND_ASSIGN(StateNew); 193 }; 194 195 class StateChecking : public State { 196 public: 197 explicit StateChecking(Component* component); 198 ~StateChecking() override; 199 200 private: 201 // State overrides. 202 void DoHandle() override; 203 204 void UpdateCheckComplete(); 205 206 DISALLOW_COPY_AND_ASSIGN(StateChecking); 207 }; 208 209 class StateUpdateError : public State { 210 public: 211 explicit StateUpdateError(Component* component); 212 ~StateUpdateError() override; 213 214 private: 215 // State overrides. 216 void DoHandle() override; 217 218 DISALLOW_COPY_AND_ASSIGN(StateUpdateError); 219 }; 220 221 class StateCanUpdate : public State { 222 public: 223 explicit StateCanUpdate(Component* component); 224 ~StateCanUpdate() override; 225 226 private: 227 // State overrides. 228 void DoHandle() override; 229 bool CanTryDiffUpdate() const; 230 231 DISALLOW_COPY_AND_ASSIGN(StateCanUpdate); 232 }; 233 234 class StateUpToDate : public State { 235 public: 236 explicit StateUpToDate(Component* component); 237 ~StateUpToDate() override; 238 239 private: 240 // State overrides. 241 void DoHandle() override; 242 243 DISALLOW_COPY_AND_ASSIGN(StateUpToDate); 244 }; 245 246 class StateDownloadingDiff : public State { 247 public: 248 explicit StateDownloadingDiff(Component* component); 249 ~StateDownloadingDiff() override; 250 251 private: 252 // State overrides. 253 void DoHandle() override; 254 255 // Called when progress is being made downloading a CRX. Can be called 256 // multiple times due to how the CRX downloader switches between 257 // different downloaders and fallback urls. 258 void DownloadProgress(const std::string& id); 259 260 void DownloadComplete(const std::string& id, 261 const CrxDownloader::Result& download_result); 262 263 // Downloads updates for one CRX id only. 264 std::unique_ptr<CrxDownloader> crx_downloader_; 265 266 DISALLOW_COPY_AND_ASSIGN(StateDownloadingDiff); 267 }; 268 269 class StateDownloading : public State { 270 public: 271 explicit StateDownloading(Component* component); 272 ~StateDownloading() override; 273 274 private: 275 // State overrides. 276 void DoHandle() override; 277 278 // Called when progress is being made downloading a CRX. Can be called 279 // multiple times due to how the CRX downloader switches between 280 // different downloaders and fallback urls. 281 void DownloadProgress(const std::string& id); 282 283 void DownloadComplete(const std::string& id, 284 const CrxDownloader::Result& download_result); 285 286 // Downloads updates for one CRX id only. 287 std::unique_ptr<CrxDownloader> crx_downloader_; 288 289 DISALLOW_COPY_AND_ASSIGN(StateDownloading); 290 }; 291 292 class StateUpdatingDiff : public State { 293 public: 294 explicit StateUpdatingDiff(Component* component); 295 ~StateUpdatingDiff() override; 296 297 private: 298 // State overrides. 299 void DoHandle() override; 300 301 void InstallComplete(ErrorCategory error_category, 302 int error_code, 303 int extra_code1); 304 305 DISALLOW_COPY_AND_ASSIGN(StateUpdatingDiff); 306 }; 307 308 class StateUpdating : public State { 309 public: 310 explicit StateUpdating(Component* component); 311 ~StateUpdating() override; 312 313 private: 314 // State overrides. 315 void DoHandle() override; 316 317 void InstallComplete(ErrorCategory error_category, 318 int error_code, 319 int extra_code1); 320 321 DISALLOW_COPY_AND_ASSIGN(StateUpdating); 322 }; 323 324 class StateUpdated : public State { 325 public: 326 explicit StateUpdated(Component* component); 327 ~StateUpdated() override; 328 329 private: 330 // State overrides. 331 void DoHandle() override; 332 333 DISALLOW_COPY_AND_ASSIGN(StateUpdated); 334 }; 335 336 class StateUninstalled : public State { 337 public: 338 explicit StateUninstalled(Component* component); 339 ~StateUninstalled() override; 340 341 private: 342 // State overrides. 343 void DoHandle() override; 344 345 DISALLOW_COPY_AND_ASSIGN(StateUninstalled); 346 }; 347 348 class StateRun : public State { 349 public: 350 explicit StateRun(Component* component); 351 ~StateRun() override; 352 353 private: 354 // State overrides. 355 void DoHandle() override; 356 357 void ActionRunComplete(bool succeeded, int error_code, int extra_code1); 358 359 // Runs the action referred by the |action_run_| member of the Component 360 // class. 361 std::unique_ptr<ActionRunner> action_runner_; 362 363 DISALLOW_COPY_AND_ASSIGN(StateRun); 364 }; 365 366 // Returns true is the update payload for this component can be downloaded 367 // by a downloader which can do bandwidth throttling on the client side. 368 bool CanDoBackgroundDownload() const; 369 370 void AppendEvent(base::Value event); 371 372 // Changes the component state and notifies the caller of the |Handle| 373 // function that the handling of this component state is complete. 374 void ChangeState(std::unique_ptr<State> next_state); 375 376 // Notifies registered observers about changes in the state of the component. 377 // If an UpdateClient::CrxStateChangeCallback is provided as an argument to 378 // UpdateClient::Install or UpdateClient::Update function calls, then the 379 // callback is invoked as well. 380 void NotifyObservers(Events event) const; 381 382 void SetParseResult(const ProtocolParser::Result& result); 383 384 // These functions return a specific event. Each data member of the event is 385 // represented as a key-value pair in a dictionary value. 386 base::Value MakeEventUpdateComplete() const; 387 base::Value MakeEventDownloadMetrics( 388 const CrxDownloader::DownloadMetrics& download_metrics) const; 389 base::Value MakeEventUninstalled() const; 390 base::Value MakeEventActionRun(bool succeeded, 391 int error_code, 392 int extra_code1) const; 393 394 std::unique_ptr<CrxInstaller::InstallParams> install_params() const; 395 396 base::ThreadChecker thread_checker_; 397 398 const std::string id_; 399 base::Optional<CrxComponent> crx_component_; 400 401 // The status of the updatecheck response. 402 std::string status_; 403 404 // Time when an update check for this CRX has happened. 405 base::TimeTicks last_check_; 406 407 // Time when the update of this CRX has begun. 408 base::TimeTicks update_begin_; 409 410 // A component can be made available for download from several urls. 411 std::vector<GURL> crx_urls_; 412 std::vector<GURL> crx_diffurls_; 413 414 // The cryptographic hash values for the component payload. 415 std::string hash_sha256_; 416 std::string hashdiff_sha256_; 417 418 // The from/to version and fingerprint values. 419 base::Version previous_version_; 420 base::Version next_version_; 421 std::string previous_fp_; 422 std::string next_fp_; 423 424 // Contains the file name of the payload to run. This member is set by 425 // the update response parser, when the update response includes a run action. 426 std::string action_run_; 427 428 // True if the update check response for this component includes an update. 429 bool is_update_available_ = false; 430 431 // The error reported by the update checker. 432 int update_check_error_ = 0; 433 434 base::FilePath crx_path_; 435 436 // The error information for full and differential updates. 437 // The |error_category| contains a hint about which module in the component 438 // updater generated the error. The |error_code| constains the error and 439 // the |extra_code1| usually contains a system error, but it can contain 440 // any extended information that is relevant to either the category or the 441 // error itself. 442 ErrorCategory error_category_ = ErrorCategory::kNone; 443 int error_code_ = 0; 444 int extra_code1_ = 0; 445 ErrorCategory diff_error_category_ = ErrorCategory::kNone; 446 int diff_error_code_ = 0; 447 int diff_extra_code1_ = 0; 448 449 // Contains app-specific custom response attributes from the server, sent in 450 // the last update check. 451 std::map<std::string, std::string> custom_attrs_; 452 453 // Contains the optional |run| and |arguments| values in the update response 454 // manifest. This data is provided as an argument to the |Install| call. 455 base::Optional<CrxInstaller::InstallParams> install_params_; 456 457 // Contains the events which are therefore serialized in the requests. 458 std::vector<base::Value> events_; 459 460 CallbackHandleComplete callback_handle_complete_; 461 std::unique_ptr<State> state_; 462 const UpdateContext& update_context_; 463 464 base::OnceClosure update_check_complete_; 465 466 ComponentState previous_state_ = ComponentState::kLastStatus; 467 468 // True if this component has reached a final state because all its states 469 // have been handled. 470 bool is_handled_ = false; 471 472 DISALLOW_COPY_AND_ASSIGN(Component); 473 }; 474 475 using IdToComponentPtrMap = std::map<std::string, std::unique_ptr<Component>>; 476 477 } // namespace update_client 478 479 #endif // COMPONENTS_UPDATE_CLIENT_COMPONENT_H_ 480