Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(713)

Side by Side Diff: components/update_client/component.h

Issue 2835803002: Refactor the UpdateEngine and its actions in the component updater. (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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/threading/thread_checker.h"
20 #include "base/time/time.h"
21 #include "base/version.h"
22 #include "components/update_client/component_unpacker.h"
23 #include "components/update_client/crx_downloader.h"
24 #include "components/update_client/update_client.h"
25 #include "components/update_client/update_response.h"
26 #include "url/gurl.h"
27
28 namespace base {
29 class SingleThreadTaskRunner;
30 }
31
32 namespace update_client {
33
34 struct CrxUpdateItem;
35 struct UpdateContext;
36
37 // Describes a CRX component managed by the UpdateEngine. A |Component| can
38 // only exists if it is associated with an UpdateContext.
waffles 2017/04/24 18:57:22 exists → exist or "Each |Component| is associated
Sorin Jianu 2017/04/24 23:26:45 Done.
39 class Component {
40 public:
41 using Events = UpdateClient::Observer::Events;
42
43 using CallbackHandleComplete = base::Callback<void()>;
44
45 Component(const UpdateContext& update_context, const std::string& id);
46 ~Component();
47
48 // Handles the current state of the component and makes it transition
49 // to the next component state before |callback| is invoked.
50 void Handle(CallbackHandleComplete callback);
51
52 CrxUpdateItem GetCrxUpdateItem() const;
53
54 // Called by the UpdateChecker to set the update response for this component.
55 void SetParseResult(const UpdateResponse::Result& result);
56
57 // Sets the uninstall state for this component.
58 void Uninstall(const base::Version& cur_version, int reason);
59
60 // Called by the UpdateEngine when an update check for this component is done.
61 void UpdateCheckComplete() const;
62
63 // Returns true if the component has reached a final state and no further
64 // handling and state transitions are possible.
65 bool IsHandled() const { return state_->IsFinal(); }
66
67 // Returns true if an update is available for this component, meaning that
68 // the update server has return a response containing an update.
69 bool IsUpdateAvailable() const { return is_update_available_; }
70
71 // Returns true if a ping must be sent back to the server. As a general rule,
72 // a ping is sent only for server responses containing instructions to update.
73 bool CanPing() const {
74 return IsUpdateAvailable() || state() == ComponentState::kUninstalled;
75 }
76
77 base::TimeDelta GetUpdateDuration() const;
78
79 ComponentState state() const { return state_->state(); }
80
81 std::string id() const { return id_; }
82
83 const CrxComponent& crx_component() const { return crx_component_; }
84 void set_crx_component(const CrxComponent& crx_component) {
85 crx_component_ = crx_component;
86 }
87
88 const base::Version& previous_version() const { return previous_version_; }
89 void set_previous_version(const base::Version& previous_version) {
90 previous_version_ = previous_version;
91 }
92
93 const base::Version& next_version() const { return next_version_; }
94
95 std::string previous_fp() const { return previous_fp_; }
96 void set_previous_fp(const std::string& previous_fp) {
97 previous_fp_ = previous_fp;
98 }
99
100 std::string next_fp() const { return next_fp_; }
101 void set_next_fp(const std::string& next_fp) { next_fp_ = next_fp; }
102
103 int update_check_error() const { return update_check_error_; }
104 void set_update_check_error(int update_check_error) {
105 update_check_error_ = update_check_error;
106 }
107
108 // Returns the time when processing of an update for this component has
109 // begun, once the update has been discovered. Returns a null TimeTicks object
110 // if the handling of an update has not happened.
111 // base::TimeTicks update_begin() const { return update_begin_; }
112
113 bool on_demand() const { return on_demand_; }
114 void set_on_demand(bool on_demand) { on_demand_ = on_demand; }
115
116 const std::vector<CrxDownloader::DownloadMetrics>& download_metrics() const {
117 return download_metrics_;
118 }
119
120 const std::vector<GURL>& crx_diffurls() const { return crx_diffurls_; }
121
122 bool diff_update_failed() const { return !!diff_error_code_; }
123
124 int error_category() const { return error_category_; }
125 int error_code() const { return error_code_; }
126 int extra_code1() const { return extra_code1_; }
127 int diff_error_category() const { return diff_error_category_; }
128 int diff_error_code() const { return diff_error_code_; }
129 int diff_extra_code1() const { return diff_extra_code1_; }
130
131 private:
132 friend class FakePingManagerImpl;
133 friend class UpdateCheckerTest;
134
135 FRIEND_TEST_ALL_PREFIXES(PingManagerTest, SendPing);
136 FRIEND_TEST_ALL_PREFIXES(PingManagerTest, RequiresEncryption);
137 FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, UpdateCheckCupError);
138 FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, UpdateCheckError);
139 FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, UpdateCheckInvalidAp);
140 FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest,
141 UpdateCheckRequiresEncryptionError);
142 FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, UpdateCheckSuccess);
143 FRIEND_TEST_ALL_PREFIXES(UpdateCheckerTest, UpdateCheckUpdateDisabled);
144
145 // Describes an abstraction for implementing the behavior of a component and
146 // the transition from one state to another.
147 class State {
148 public:
149 using CallbackNextState =
150 base::Callback<void(std::unique_ptr<State> next_state)>;
151
152 State(Component* component, ComponentState state);
waffles 2017/04/24 18:57:22 Should this be protected?
Sorin Jianu 2017/04/24 23:26:45 It seems ok to be public. The inner base class is
153 virtual ~State();
154
155 // Handles the current state and initiates a transition to a new state.
156 // The transition to the new state is non-blocking and it is completed
157 // by the outer component, after the current state is fully handled.
158 void Handle(CallbackNextState callback);
159
160 ComponentState state() const { return state_; }
161
162 bool IsFinal() const { return is_final_; }
163
164 protected:
165 // Initiates the transition to the new state.
166 void TransitionState(std::unique_ptr<State> new_state);
167
168 Component& component() { return component_; }
169 const Component& component() const { return component_; }
170
171 CallbackNextState callback() const { return callback_; }
172
173 base::ThreadChecker thread_checker_;
174
175 const ComponentState state_;
176
177 private:
178 virtual void DoHandle() = 0;
179
180 Component& component_;
181 CallbackNextState callback_;
182
183 bool is_final_ = false;
184 };
185
186 class StateNew : public State {
187 public:
188 explicit StateNew(Component* component);
189 ~StateNew() override;
190
191 private:
192 // State overrides.
193 void DoHandle() override;
194
195 DISALLOW_COPY_AND_ASSIGN(StateNew);
196 };
197
198 class StateChecking : public State {
199 public:
200 explicit StateChecking(Component* component);
201 ~StateChecking() override;
202
203 private:
204 // State overrides.
205 void DoHandle() override;
206
207 void UpdateCheckComplete();
208
209 DISALLOW_COPY_AND_ASSIGN(StateChecking);
210 };
211
212 class StateUpdateError : public State {
213 public:
214 explicit StateUpdateError(Component* component);
215 ~StateUpdateError() override;
216
217 private:
218 // State overrides.
219 void DoHandle() override;
220
221 DISALLOW_COPY_AND_ASSIGN(StateUpdateError);
222 };
223
224 class StateCanUpdate : public State {
225 public:
226 explicit StateCanUpdate(Component* component);
227 ~StateCanUpdate() override;
228
229 private:
230 // State overrides.
231 void DoHandle() override;
232 bool CanTryDiffUpdate() const;
233
234 DISALLOW_COPY_AND_ASSIGN(StateCanUpdate);
235 };
236
237 class StateUpToDate : public State {
238 public:
239 explicit StateUpToDate(Component* component);
240 ~StateUpToDate() override;
241
242 private:
243 // State overrides.
244 void DoHandle() override;
245
246 DISALLOW_COPY_AND_ASSIGN(StateUpToDate);
247 };
248
249 class StateDownloadingDiff : public State {
250 public:
251 explicit StateDownloadingDiff(Component* component);
252 ~StateDownloadingDiff() override;
253
254 private:
255 // State overrides.
256 void DoHandle() override;
257
258 // Called when progress is being made downloading a CRX. The progress may
259 // not monotonically increase due to how the CRX downloader switches between
260 // different downloaders and fallback urls.
261 void DownloadProgress(const std::string& id,
262 const CrxDownloader::Result& download_result);
263
264 void DownloadComplete(const std::string& id,
265 const CrxDownloader::Result& download_result);
266
267 // Downloads updates for one CRX id only.
268 std::unique_ptr<CrxDownloader> crx_downloader_;
269
270 DISALLOW_COPY_AND_ASSIGN(StateDownloadingDiff);
271 };
272
273 class StateDownloading : public State {
274 public:
275 explicit StateDownloading(Component* component);
276 ~StateDownloading() override;
277
278 private:
279 // State overrides.
280 void DoHandle() override;
281
282 // Called when progress is being made downloading a CRX. The progress may
283 // not monotonically increase due to how the CRX downloader switches between
284 // different downloaders and fallback urls.
285 void DownloadProgress(const std::string& id,
286 const CrxDownloader::Result& download_result);
287
288 void DownloadComplete(const std::string& id,
289 const CrxDownloader::Result& download_result);
290
291 // Downloads updates for one CRX id only.
292 std::unique_ptr<CrxDownloader> crx_downloader_;
293
294 DISALLOW_COPY_AND_ASSIGN(StateDownloading);
295 };
296
297 class StateUpdatingDiff : public State {
298 public:
299 explicit StateUpdatingDiff(Component* component);
300 ~StateUpdatingDiff() override;
301
302 private:
303 // State overrides.
304 void DoHandle() override;
305
306 void InstallComplete(int error_category, int error_code, int extra_code1);
307
308 DISALLOW_COPY_AND_ASSIGN(StateUpdatingDiff);
309 };
310
311 class StateUpdating : public State {
312 public:
313 explicit StateUpdating(Component* component);
314 ~StateUpdating() override;
315
316 private:
317 // State overrides.
318 void DoHandle() override;
319
320 void InstallComplete(int error_category, int error_code, int extra_code1);
321
322 // Posts replies back to the main thread.
323 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
324
325 // Unpacks one CRX.
326 scoped_refptr<ComponentUnpacker> unpacker_;
327
328 base::FilePath unpack_path_;
329
330 DISALLOW_COPY_AND_ASSIGN(StateUpdating);
331 };
332
333 class StateUpdated : public State {
334 public:
335 explicit StateUpdated(Component* component);
336 ~StateUpdated() override;
337
338 private:
339 // State overrides.
340 void DoHandle() override;
341
342 DISALLOW_COPY_AND_ASSIGN(StateUpdated);
343 };
344
345 class StateUninstalled : public State {
346 public:
347 explicit StateUninstalled(Component* component);
348 ~StateUninstalled() override;
349
350 private:
351 // State overrides.
352 void DoHandle() override;
353
354 DISALLOW_COPY_AND_ASSIGN(StateUninstalled);
355 };
356
357 // Returns true is the update payload for this component can be downloaded
358 // by a downloader which can do bandwidth throttling on the client side.
359 bool CanDoBackgroundDownload() const;
360
361 void AppendDownloadMetrics(
362 const std::vector<CrxDownloader::DownloadMetrics>& download_metrics);
363
364 // Changes the component state and notifies the caller of the |Handle|
365 // function that the handling of this component state is complete.
366 void ChangeState(std::unique_ptr<State> next_state);
367
368 // Notifies registered observers about changes in the state of the component.
369 void NotifyObservers(Events event) const;
370
371 base::ThreadChecker thread_checker_;
372
373 const std::string id_;
374 CrxComponent crx_component_;
375
376 std::string status_;
377
378 // Time when an update check for this CRX has happened.
379 base::TimeTicks last_check_;
380
381 // Time when the update of this CRX has begun.
382 base::TimeTicks update_begin_;
383
384 // A component can be made available for download from several urls.
385 std::vector<GURL> crx_urls_;
386 std::vector<GURL> crx_diffurls_;
387
388 // The cryptographic hash values for the component payload.
389 std::string hash_sha256_;
390 std::string hashdiff_sha256_;
391
392 // The from/to version and fingerprint values.
393 base::Version previous_version_;
394 base::Version next_version_;
395 std::string previous_fp_;
396 std::string next_fp_;
397
398 // True if the update check response for this component includes an update.
399 bool is_update_available_ = false;
400
401 // True if the current update check cycle is on-demand.
402 bool on_demand_ = false;
403
404 // The error reported by the update checker.
405 int update_check_error_ = 0;
406
407 base::FilePath crx_path_;
408
409 // The error information for full and differential updates.
410 // The |error_category| contains a hint about which module in the component
411 // updater generated the error. The |error_code| constains the error and
412 // the |extra_code1| usually contains a system error, but it can contain
413 // any extended information that is relevant to either the category or the
414 // error itself.
415 int error_category_ = 0;
416 int error_code_ = 0;
417 int extra_code1_ = 0;
418 int diff_error_category_ = 0;
419 int diff_error_code_ = 0;
420 int diff_extra_code1_ = 0;
421
422 std::vector<CrxDownloader::DownloadMetrics> download_metrics_;
423
424 CallbackHandleComplete callback_handle_complete_;
425 std::unique_ptr<State> state_;
426 const UpdateContext& update_context_;
427
428 base::Closure update_check_complete_;
429
430 DISALLOW_COPY_AND_ASSIGN(Component);
431 };
432
433 using IdToComponentPtrMap = std::map<std::string, std::unique_ptr<Component>>;
434
435 } // namespace update_client
436
437 #endif // COMPONENTS_UPDATE_CLIENT_COMPONENT_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698