blob: b360fd1e58be62da05c3f6dae84bdb38eed9d44e [file] [log] [blame]
sorin30474f02017-04-27 00:45:481// 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"
Sorin Jianu888ec292018-06-01 15:35:4219#include "base/optional.h"
sorin30474f02017-04-27 00:45:4820#include "base/threading/thread_checker.h"
21#include "base/time/time.h"
22#include "base/version.h"
sorin30474f02017-04-27 00:45:4823#include "components/update_client/crx_downloader.h"
sorin7cff6e52017-05-17 16:37:2324#include "components/update_client/protocol_parser.h"
sorin30474f02017-04-27 00:45:4825#include "components/update_client/update_client.h"
sorin30474f02017-04-27 00:45:4826#include "url/gurl.h"
27
Sorin Jianu039032b2018-10-12 21:48:1328namespace base {
29class Value;
30} // namespace base
sorin30474f02017-04-27 00:45:4831
32namespace update_client {
33
Sorin Jianu4ab7c292017-06-15 18:40:2134class ActionRunner;
Sorin Jianub3296162017-12-13 20:26:3235class Configurator;
sorin30474f02017-04-27 00:45:4836struct CrxUpdateItem;
37struct UpdateContext;
38
Sorin Jianudfb12a42020-03-10 04:12:0339// Describes a CRX component managed by the UpdateEngine. Each instance of
40// this class is associated with one instance of UpdateContext.
sorin30474f02017-04-27 00:45:4841class Component {
42 public:
43 using Events = UpdateClient::Observer::Events;
44
Sorin Jianua8ef73d2017-11-02 16:55:1745 using CallbackHandleComplete = base::OnceCallback<void()>;
sorin30474f02017-04-27 00:45:4846
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
Sorin Jianuee5c0db2018-04-12 23:38:4751 // to the next component state before |callback_handle_complete_| is invoked.
52 void Handle(CallbackHandleComplete callback_handle_complete);
sorin30474f02017-04-27 00:45:4853
54 CrxUpdateItem GetCrxUpdateItem() const;
55
sorin30474f02017-04-27 00:45:4856 // 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.
Sorin Jianu888ec292018-06-01 15:35:4260 void SetUpdateCheckResult(
61 const base::Optional<ProtocolParser::Result>& result,
62 ErrorCategory error_category,
63 int error);
sorin30474f02017-04-27 00:45:4864
Sorin Jianudfb12a42020-03-10 04:12:0365 // Called by the UpdateEngine when a component enters a wait for throttling
66 // purposes.
67 void NotifyWait();
68
sorin30474f02017-04-27 00:45:4869 // Returns true if the component has reached a final state and no further
70 // handling and state transitions are possible.
Sorin Jianuee5c0db2018-04-12 23:38:4771 bool IsHandled() const { return is_handled_; }
sorin30474f02017-04-27 00:45:4872
73 // Returns true if an update is available for this component, meaning that
74 // the update server has return a response containing an update.
75 bool IsUpdateAvailable() const { return is_update_available_; }
76
sorin30474f02017-04-27 00:45:4877 base::TimeDelta GetUpdateDuration() const;
78
79 ComponentState state() const { return state_->state(); }
80
81 std::string id() const { return id_; }
82
Sorin Jianu73900242018-08-17 01:11:5383 const base::Optional<CrxComponent>& crx_component() const {
84 return crx_component_;
85 }
86 void set_crx_component(const CrxComponent& crx_component) {
87 crx_component_ = crx_component;
sorin30474f02017-04-27 00:45:4888 }
89
90 const base::Version& previous_version() const { return previous_version_; }
91 void set_previous_version(const base::Version& previous_version) {
92 previous_version_ = previous_version;
93 }
94
95 const base::Version& next_version() const { return next_version_; }
96
97 std::string previous_fp() const { return previous_fp_; }
98 void set_previous_fp(const std::string& previous_fp) {
99 previous_fp_ = previous_fp;
100 }
101
102 std::string next_fp() const { return next_fp_; }
103 void set_next_fp(const std::string& next_fp) { next_fp_ = next_fp; }
104
Sorin Jianub41a592a2018-03-02 16:30:27105 bool is_foreground() const;
sorin30474f02017-04-27 00:45:48106
sorin30474f02017-04-27 00:45:48107 const std::vector<GURL>& crx_diffurls() const { return crx_diffurls_; }
108
109 bool diff_update_failed() const { return !!diff_error_code_; }
110
Minh X. Nguyena4640cb2018-05-23 21:29:10111 ErrorCategory error_category() const { return error_category_; }
sorin30474f02017-04-27 00:45:48112 int error_code() const { return error_code_; }
113 int extra_code1() const { return extra_code1_; }
Minh X. Nguyena4640cb2018-05-23 21:29:10114 ErrorCategory diff_error_category() const { return diff_error_category_; }
sorin30474f02017-04-27 00:45:48115 int diff_error_code() const { return diff_error_code_; }
116 int diff_extra_code1() const { return diff_extra_code1_; }
117
Sorin Jianu4ab7c292017-06-15 18:40:21118 std::string action_run() const { return action_run_; }
119
Sorin Jianub3296162017-12-13 20:26:32120 scoped_refptr<Configurator> config() const;
121
Sorin Jianud69d4372018-02-07 19:44:22122 std::string session_id() const;
123
Sorin Jianu039032b2018-10-12 21:48:13124 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
sorin30474f02017-04-27 00:45:48129 private:
Sorin Jianua8926bf2018-03-09 21:02:53130 friend class MockPingManagerImpl;
sorin30474f02017-04-27 00:45:48131 friend class UpdateCheckerTest;
132
133 FRIEND_TEST_ALL_PREFIXES(PingManagerTest, SendPing);
134 FRIEND_TEST_ALL_PREFIXES(PingManagerTest, RequiresEncryption);
sorin519656c2017-04-28 22:39:34135 FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, NoUpdateActionRun);
sorin30474f02017-04-27 00:45:48136 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 =
Sorin Jianua8ef73d2017-11-02 16:55:17149 base::OnceCallback<void(std::unique_ptr<State> next_state)>;
sorin30474f02017-04-27 00:45:48150
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
159 ComponentState state() const { return state_; }
160
sorin30474f02017-04-27 00:45:48161 protected:
162 // Initiates the transition to the new state.
163 void TransitionState(std::unique_ptr<State> new_state);
164
Sorin Jianuee5c0db2018-04-12 23:38:47165 // Makes the current state a final state where no other state transition
166 // can further occur.
167 void EndState();
168
sorin30474f02017-04-27 00:45:48169 Component& component() { return component_; }
170 const Component& component() const { return component_; }
171
sorin30474f02017-04-27 00:45:48172 base::ThreadChecker thread_checker_;
173
174 const ComponentState state_;
175
176 private:
177 virtual void DoHandle() = 0;
178
179 Component& component_;
Sorin Jianuee5c0db2018-04-12 23:38:47180 CallbackNextState callback_next_state_;
sorin30474f02017-04-27 00:45:48181 };
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
Antonio Gomes31237fb2018-08-27 19:11:03255 // Called when progress is being made downloading a CRX. Can be called
256 // multiple times due to how the CRX downloader switches between
sorin30474f02017-04-27 00:45:48257 // different downloaders and fallback urls.
Antonio Gomes31237fb2018-08-27 19:11:03258 void DownloadProgress(const std::string& id);
sorin30474f02017-04-27 00:45:48259
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
Antonio Gomes31237fb2018-08-27 19:11:03278 // Called when progress is being made downloading a CRX. Can be called
279 // multiple times due to how the CRX downloader switches between
sorin30474f02017-04-27 00:45:48280 // different downloaders and fallback urls.
Antonio Gomes31237fb2018-08-27 19:11:03281 void DownloadProgress(const std::string& id);
sorin30474f02017-04-27 00:45:48282
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
Minh X. Nguyena4640cb2018-05-23 21:29:10301 void InstallComplete(ErrorCategory error_category,
302 int error_code,
303 int extra_code1);
sorin30474f02017-04-27 00:45:48304
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
Minh X. Nguyena4640cb2018-05-23 21:29:10317 void InstallComplete(ErrorCategory error_category,
318 int error_code,
319 int extra_code1);
sorin30474f02017-04-27 00:45:48320
sorin30474f02017-04-27 00:45:48321 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
Sorin Jianu4ab7c292017-06-15 18:40:21348 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
sorin30474f02017-04-27 00:45:48366 // 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
Sorin Jianu039032b2018-10-12 21:48:13370 void AppendEvent(base::Value event);
sorin30474f02017-04-27 00:45:48371
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.
Sorin Jianudfb12a42020-03-10 04:12:03377 // 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.
sorin30474f02017-04-27 00:45:48380 void NotifyObservers(Events event) const;
381
Sorin Jianu888ec292018-06-01 15:35:42382 void SetParseResult(const ProtocolParser::Result& result);
383
Sorin Jianu039032b2018-10-12 21:48:13384 // 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
Sorin Jianu9d64af672020-02-05 19:14:34394 std::unique_ptr<CrxInstaller::InstallParams> install_params() const;
395
sorin30474f02017-04-27 00:45:48396 base::ThreadChecker thread_checker_;
397
398 const std::string id_;
Sorin Jianu73900242018-08-17 01:11:53399 base::Optional<CrxComponent> crx_component_;
sorin30474f02017-04-27 00:45:48400
Sorin Jianu4ab7c292017-06-15 18:40:21401 // The status of the updatecheck response.
sorin30474f02017-04-27 00:45:48402 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
Sorin Jianu4ab7c292017-06-15 18:40:21424 // 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.
sorin519656c2017-04-28 22:39:34426 std::string action_run_;
427
sorin30474f02017-04-27 00:45:48428 // True if the update check response for this component includes an update.
429 bool is_update_available_ = false;
430
sorin30474f02017-04-27 00:45:48431 // 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.
Minh X. Nguyena4640cb2018-05-23 21:29:10442 ErrorCategory error_category_ = ErrorCategory::kNone;
sorin30474f02017-04-27 00:45:48443 int error_code_ = 0;
444 int extra_code1_ = 0;
Minh X. Nguyena4640cb2018-05-23 21:29:10445 ErrorCategory diff_error_category_ = ErrorCategory::kNone;
sorin30474f02017-04-27 00:45:48446 int diff_error_code_ = 0;
447 int diff_extra_code1_ = 0;
448
Joshua Pawlickica4f8fa12020-02-25 23:46:06449 // 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
Sorin Jianu9d64af672020-02-05 19:14:34453 // 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
Sorin Jianu039032b2018-10-12 21:48:13457 // Contains the events which are therefore serialized in the requests.
458 std::vector<base::Value> events_;
sorin30474f02017-04-27 00:45:48459
460 CallbackHandleComplete callback_handle_complete_;
461 std::unique_ptr<State> state_;
462 const UpdateContext& update_context_;
463
Sorin Jianua8ef73d2017-11-02 16:55:17464 base::OnceClosure update_check_complete_;
sorin30474f02017-04-27 00:45:48465
Sorin Jianu4ab7c292017-06-15 18:40:21466 ComponentState previous_state_ = ComponentState::kLastStatus;
467
Sorin Jianuee5c0db2018-04-12 23:38:47468 // True if this component has reached a final state because all its states
469 // have been handled.
470 bool is_handled_ = false;
471
sorin30474f02017-04-27 00:45:48472 DISALLOW_COPY_AND_ASSIGN(Component);
473};
474
475using IdToComponentPtrMap = std::map<std::string, std::unique_ptr<Component>>;
476
477} // namespace update_client
478
479#endif // COMPONENTS_UPDATE_CLIENT_COMPONENT_H_