blob: e577a8e7bc9c3dca7f99a96433bcf07c5e40a60e [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"
19#include "base/threading/thread_checker.h"
20#include "base/time/time.h"
21#include "base/version.h"
sorin30474f02017-04-27 00:45:4822#include "components/update_client/crx_downloader.h"
sorin7cff6e52017-05-17 16:37:2323#include "components/update_client/protocol_parser.h"
sorin30474f02017-04-27 00:45:4824#include "components/update_client/update_client.h"
sorin30474f02017-04-27 00:45:4825#include "url/gurl.h"
26
sorin30474f02017-04-27 00:45:4827
28namespace update_client {
29
Sorin Jianu4ab7c292017-06-15 18:40:2130class ActionRunner;
Sorin Jianub3296162017-12-13 20:26:3231class Configurator;
sorin30474f02017-04-27 00:45:4832struct CrxUpdateItem;
33struct UpdateContext;
34
35// Describes a CRX component managed by the UpdateEngine. Each |Component| is
36// associated with an UpdateContext.
37class Component {
38 public:
39 using Events = UpdateClient::Observer::Events;
40
Sorin Jianua8ef73d2017-11-02 16:55:1741 using CallbackHandleComplete = base::OnceCallback<void()>;
sorin30474f02017-04-27 00:45:4842
43 Component(const UpdateContext& update_context, const std::string& id);
44 ~Component();
45
46 // Handles the current state of the component and makes it transition
47 // to the next component state before |callback| is invoked.
48 void Handle(CallbackHandleComplete callback);
49
50 CrxUpdateItem GetCrxUpdateItem() const;
51
52 // Called by the UpdateChecker to set the update response for this component.
sorin7cff6e52017-05-17 16:37:2353 void SetParseResult(const ProtocolParser::Result& result);
sorin30474f02017-04-27 00:45:4854
55 // Sets the uninstall state for this component.
56 void Uninstall(const base::Version& cur_version, int reason);
57
58 // Called by the UpdateEngine when an update check for this component is done.
Sorin Jianua8ef73d2017-11-02 16:55:1759 void UpdateCheckComplete();
sorin30474f02017-04-27 00:45:4860
61 // Returns true if the component has reached a final state and no further
62 // handling and state transitions are possible.
63 bool IsHandled() const { return state_->IsFinal(); }
64
65 // Returns true if an update is available for this component, meaning that
66 // the update server has return a response containing an update.
67 bool IsUpdateAvailable() const { return is_update_available_; }
68
sorin30474f02017-04-27 00:45:4869 base::TimeDelta GetUpdateDuration() const;
70
71 ComponentState state() const { return state_->state(); }
72
73 std::string id() const { return id_; }
74
75 const CrxComponent& crx_component() const { return crx_component_; }
76 void set_crx_component(const CrxComponent& crx_component) {
77 crx_component_ = crx_component;
78 }
79
80 const base::Version& previous_version() const { return previous_version_; }
81 void set_previous_version(const base::Version& previous_version) {
82 previous_version_ = previous_version;
83 }
84
85 const base::Version& next_version() const { return next_version_; }
86
87 std::string previous_fp() const { return previous_fp_; }
88 void set_previous_fp(const std::string& previous_fp) {
89 previous_fp_ = previous_fp;
90 }
91
92 std::string next_fp() const { return next_fp_; }
93 void set_next_fp(const std::string& next_fp) { next_fp_ = next_fp; }
94
95 int update_check_error() const { return update_check_error_; }
96 void set_update_check_error(int update_check_error) {
97 update_check_error_ = update_check_error;
98 }
99
100 // Returns the time when processing of an update for this component has
101 // begun, once the update has been discovered. Returns a null TimeTicks object
102 // if the handling of an update has not happened.
103 // base::TimeTicks update_begin() const { return update_begin_; }
104
105 bool on_demand() const { return on_demand_; }
106 void set_on_demand(bool on_demand) { on_demand_ = on_demand; }
107
sorin117334f2017-05-19 02:36:25108 const std::vector<std::string>& events() const { return events_; }
sorin30474f02017-04-27 00:45:48109
110 const std::vector<GURL>& crx_diffurls() const { return crx_diffurls_; }
111
112 bool diff_update_failed() const { return !!diff_error_code_; }
113
114 int error_category() const { return error_category_; }
115 int error_code() const { return error_code_; }
116 int extra_code1() const { return extra_code1_; }
117 int diff_error_category() const { return diff_error_category_; }
118 int diff_error_code() const { return diff_error_code_; }
119 int diff_extra_code1() const { return diff_extra_code1_; }
120
Sorin Jianu4ab7c292017-06-15 18:40:21121 std::string action_run() const { return action_run_; }
122
Sorin Jianub3296162017-12-13 20:26:32123 scoped_refptr<Configurator> config() const;
124
sorin30474f02017-04-27 00:45:48125 private:
126 friend class FakePingManagerImpl;
127 friend class UpdateCheckerTest;
128
129 FRIEND_TEST_ALL_PREFIXES(PingManagerTest, SendPing);
130 FRIEND_TEST_ALL_PREFIXES(PingManagerTest, RequiresEncryption);
sorin519656c2017-04-28 22:39:34131 FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, NoUpdateActionRun);
sorin30474f02017-04-27 00:45:48132 FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, UpdateCheckCupError);
133 FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, UpdateCheckError);
134 FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, UpdateCheckInvalidAp);
135 FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest,
136 UpdateCheckRequiresEncryptionError);
137 FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, UpdateCheckSuccess);
138 FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, UpdateCheckUpdateDisabled);
139
140 // Describes an abstraction for implementing the behavior of a component and
141 // the transition from one state to another.
142 class State {
143 public:
144 using CallbackNextState =
Sorin Jianua8ef73d2017-11-02 16:55:17145 base::OnceCallback<void(std::unique_ptr<State> next_state)>;
sorin30474f02017-04-27 00:45:48146
147 State(Component* component, ComponentState state);
148 virtual ~State();
149
150 // Handles the current state and initiates a transition to a new state.
151 // The transition to the new state is non-blocking and it is completed
152 // by the outer component, after the current state is fully handled.
153 void Handle(CallbackNextState callback);
154
155 ComponentState state() const { return state_; }
156
157 bool IsFinal() const { return is_final_; }
158
159 protected:
160 // Initiates the transition to the new state.
161 void TransitionState(std::unique_ptr<State> new_state);
162
163 Component& component() { return component_; }
164 const Component& component() const { return component_; }
165
sorin30474f02017-04-27 00:45:48166 base::ThreadChecker thread_checker_;
167
168 const ComponentState state_;
169
170 private:
171 virtual void DoHandle() = 0;
172
173 Component& component_;
174 CallbackNextState callback_;
175
176 bool is_final_ = false;
177 };
178
179 class StateNew : public State {
180 public:
181 explicit StateNew(Component* component);
182 ~StateNew() override;
183
184 private:
185 // State overrides.
186 void DoHandle() override;
187
188 DISALLOW_COPY_AND_ASSIGN(StateNew);
189 };
190
191 class StateChecking : public State {
192 public:
193 explicit StateChecking(Component* component);
194 ~StateChecking() override;
195
196 private:
197 // State overrides.
198 void DoHandle() override;
199
200 void UpdateCheckComplete();
201
202 DISALLOW_COPY_AND_ASSIGN(StateChecking);
203 };
204
205 class StateUpdateError : public State {
206 public:
207 explicit StateUpdateError(Component* component);
208 ~StateUpdateError() override;
209
210 private:
211 // State overrides.
212 void DoHandle() override;
213
214 DISALLOW_COPY_AND_ASSIGN(StateUpdateError);
215 };
216
217 class StateCanUpdate : public State {
218 public:
219 explicit StateCanUpdate(Component* component);
220 ~StateCanUpdate() override;
221
222 private:
223 // State overrides.
224 void DoHandle() override;
225 bool CanTryDiffUpdate() const;
226
227 DISALLOW_COPY_AND_ASSIGN(StateCanUpdate);
228 };
229
230 class StateUpToDate : public State {
231 public:
232 explicit StateUpToDate(Component* component);
233 ~StateUpToDate() override;
234
235 private:
236 // State overrides.
237 void DoHandle() override;
238
239 DISALLOW_COPY_AND_ASSIGN(StateUpToDate);
240 };
241
242 class StateDownloadingDiff : public State {
243 public:
244 explicit StateDownloadingDiff(Component* component);
245 ~StateDownloadingDiff() override;
246
247 private:
248 // State overrides.
249 void DoHandle() override;
250
251 // Called when progress is being made downloading a CRX. The progress may
252 // not monotonically increase due to how the CRX downloader switches between
253 // different downloaders and fallback urls.
254 void DownloadProgress(const std::string& id,
255 const CrxDownloader::Result& download_result);
256
257 void DownloadComplete(const std::string& id,
258 const CrxDownloader::Result& download_result);
259
260 // Downloads updates for one CRX id only.
261 std::unique_ptr<CrxDownloader> crx_downloader_;
262
263 DISALLOW_COPY_AND_ASSIGN(StateDownloadingDiff);
264 };
265
266 class StateDownloading : public State {
267 public:
268 explicit StateDownloading(Component* component);
269 ~StateDownloading() override;
270
271 private:
272 // State overrides.
273 void DoHandle() override;
274
275 // Called when progress is being made downloading a CRX. The progress may
276 // not monotonically increase due to how the CRX downloader switches between
277 // different downloaders and fallback urls.
278 void DownloadProgress(const std::string& id,
279 const CrxDownloader::Result& download_result);
280
281 void DownloadComplete(const std::string& id,
282 const CrxDownloader::Result& download_result);
283
284 // Downloads updates for one CRX id only.
285 std::unique_ptr<CrxDownloader> crx_downloader_;
286
287 DISALLOW_COPY_AND_ASSIGN(StateDownloading);
288 };
289
290 class StateUpdatingDiff : public State {
291 public:
292 explicit StateUpdatingDiff(Component* component);
293 ~StateUpdatingDiff() override;
294
295 private:
296 // State overrides.
297 void DoHandle() override;
298
299 void InstallComplete(int error_category, int error_code, int extra_code1);
300
301 DISALLOW_COPY_AND_ASSIGN(StateUpdatingDiff);
302 };
303
304 class StateUpdating : public State {
305 public:
306 explicit StateUpdating(Component* component);
307 ~StateUpdating() override;
308
309 private:
310 // State overrides.
311 void DoHandle() override;
312
313 void InstallComplete(int error_category, int error_code, int extra_code1);
314
sorin30474f02017-04-27 00:45:48315 DISALLOW_COPY_AND_ASSIGN(StateUpdating);
316 };
317
318 class StateUpdated : public State {
319 public:
320 explicit StateUpdated(Component* component);
321 ~StateUpdated() override;
322
323 private:
324 // State overrides.
325 void DoHandle() override;
326
327 DISALLOW_COPY_AND_ASSIGN(StateUpdated);
328 };
329
330 class StateUninstalled : public State {
331 public:
332 explicit StateUninstalled(Component* component);
333 ~StateUninstalled() override;
334
335 private:
336 // State overrides.
337 void DoHandle() override;
338
339 DISALLOW_COPY_AND_ASSIGN(StateUninstalled);
340 };
341
Sorin Jianu4ab7c292017-06-15 18:40:21342 class StateRun : public State {
343 public:
344 explicit StateRun(Component* component);
345 ~StateRun() override;
346
347 private:
348 // State overrides.
349 void DoHandle() override;
350
351 void ActionRunComplete(bool succeeded, int error_code, int extra_code1);
352
353 // Runs the action referred by the |action_run_| member of the Component
354 // class.
355 std::unique_ptr<ActionRunner> action_runner_;
356
357 DISALLOW_COPY_AND_ASSIGN(StateRun);
358 };
359
sorin30474f02017-04-27 00:45:48360 // Returns true is the update payload for this component can be downloaded
361 // by a downloader which can do bandwidth throttling on the client side.
362 bool CanDoBackgroundDownload() const;
363
sorin117334f2017-05-19 02:36:25364 void AppendEvent(const std::string& event);
sorin30474f02017-04-27 00:45:48365
366 // Changes the component state and notifies the caller of the |Handle|
367 // function that the handling of this component state is complete.
368 void ChangeState(std::unique_ptr<State> next_state);
369
370 // Notifies registered observers about changes in the state of the component.
371 void NotifyObservers(Events event) const;
372
373 base::ThreadChecker thread_checker_;
374
375 const std::string id_;
376 CrxComponent crx_component_;
377
Sorin Jianu4ab7c292017-06-15 18:40:21378 // The status of the updatecheck response.
sorin30474f02017-04-27 00:45:48379 std::string status_;
380
381 // Time when an update check for this CRX has happened.
382 base::TimeTicks last_check_;
383
384 // Time when the update of this CRX has begun.
385 base::TimeTicks update_begin_;
386
387 // A component can be made available for download from several urls.
388 std::vector<GURL> crx_urls_;
389 std::vector<GURL> crx_diffurls_;
390
391 // The cryptographic hash values for the component payload.
392 std::string hash_sha256_;
393 std::string hashdiff_sha256_;
394
395 // The from/to version and fingerprint values.
396 base::Version previous_version_;
397 base::Version next_version_;
398 std::string previous_fp_;
399 std::string next_fp_;
400
Sorin Jianu4ab7c292017-06-15 18:40:21401 // Contains the file name of the payload to run. This member is set by
402 // the update response parser, when the update response includes a run action.
sorin519656c2017-04-28 22:39:34403 std::string action_run_;
404
sorin30474f02017-04-27 00:45:48405 // True if the update check response for this component includes an update.
406 bool is_update_available_ = false;
407
408 // True if the current update check cycle is on-demand.
409 bool on_demand_ = false;
410
411 // The error reported by the update checker.
412 int update_check_error_ = 0;
413
414 base::FilePath crx_path_;
415
416 // The error information for full and differential updates.
417 // The |error_category| contains a hint about which module in the component
418 // updater generated the error. The |error_code| constains the error and
419 // the |extra_code1| usually contains a system error, but it can contain
420 // any extended information that is relevant to either the category or the
421 // error itself.
422 int error_category_ = 0;
423 int error_code_ = 0;
424 int extra_code1_ = 0;
425 int diff_error_category_ = 0;
426 int diff_error_code_ = 0;
427 int diff_extra_code1_ = 0;
428
sorin117334f2017-05-19 02:36:25429 // Contains the events which are serialized in the pings.
430 std::vector<std::string> events_;
sorin30474f02017-04-27 00:45:48431
432 CallbackHandleComplete callback_handle_complete_;
433 std::unique_ptr<State> state_;
434 const UpdateContext& update_context_;
435
Sorin Jianua8ef73d2017-11-02 16:55:17436 base::OnceClosure update_check_complete_;
sorin30474f02017-04-27 00:45:48437
Sorin Jianu4ab7c292017-06-15 18:40:21438 ComponentState previous_state_ = ComponentState::kLastStatus;
439
sorin30474f02017-04-27 00:45:48440 DISALLOW_COPY_AND_ASSIGN(Component);
441};
442
443using IdToComponentPtrMap = std::map<std::string, std::unique_ptr<Component>>;
444
445} // namespace update_client
446
447#endif // COMPONENTS_UPDATE_CLIENT_COMPONENT_H_