OLD | NEW |
---|---|
(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_ | |
OLD | NEW |