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