1 // Copyright 2014 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_COMPONENT_UPDATER_COMPONENT_UPDATER_SERVICE_H_
6 #define COMPONENTS_COMPONENT_UPDATER_COMPONENT_UPDATER_SERVICE_H_
7 
8 #include <stdint.h>
9 
10 #include <memory>
11 #include <string>
12 #include <vector>
13 
14 #include "base/callback_forward.h"
15 #include "base/gtest_prod_util.h"
16 #include "base/memory/ref_counted.h"
17 #include "base/version.h"
18 #include "build/build_config.h"
19 #include "components/update_client/update_client.h"
20 #include "url/gurl.h"
21 
22 class ComponentsHandler;
23 class PluginObserver;
24 
25 namespace policy {
26 class ComponentUpdaterPolicyTest;
27 }
28 
29 namespace update_client {
30 class ComponentInstaller;
31 class Configurator;
32 struct CrxComponent;
33 struct CrxUpdateItem;
34 }
35 
36 namespace component_updater {
37 
38 // Called when a non-blocking call in this module completes.
39 using Callback = update_client::Callback;
40 
41 class OnDemandUpdater;
42 class UpdateScheduler;
43 
44 using Configurator = update_client::Configurator;
45 using CrxComponent = update_client::CrxComponent;
46 using CrxUpdateItem = update_client::CrxUpdateItem;
47 
48 struct ComponentInfo {
49   ComponentInfo(const std::string& id,
50                 const std::string& fingerprint,
51                 const base::string16& name,
52                 const base::Version& version);
53   ComponentInfo(const ComponentInfo& other);
54   ComponentInfo(ComponentInfo&& other);
55   ~ComponentInfo();
56 
57   const std::string id;
58   const std::string fingerprint;
59   const base::string16 name;
60   const base::Version version;
61 };
62 
63 // The component update service is in charge of installing or upgrading
64 // select parts of chrome. Each part is called a component and managed by
65 // instances of CrxComponent registered using RegisterComponent(). On the
66 // server, each component is packaged as a CRX which is the same format used
67 // to package extensions. To the update service each component is identified
68 // by its public key hash (CrxComponent::pk_hash). If there is an update
69 // available and its version is bigger than (CrxComponent::version), it will
70 // be downloaded, verified and unpacked. Then component-specific installer
71 // ComponentInstaller::Install (of CrxComponent::installer) will be called.
72 //
73 // During the normal operation of the component updater some specific
74 // notifications are fired, like COMPONENT_UPDATER_STARTED and
75 // COMPONENT_UPDATE_FOUND. See notification_type.h for more details.
76 //
77 // All methods are safe to call ONLY from the browser's main thread.
78 class ComponentUpdateService {
79  public:
80   using Observer = update_client::UpdateClient::Observer;
81 
82   // Adds an observer for this class. An observer should not be added more
83   // than once. The caller retains the ownership of the observer object.
84   virtual void AddObserver(Observer* observer) = 0;
85 
86   // Removes an observer. It is safe for an observer to be removed while
87   // the observers are being notified.
88   virtual void RemoveObserver(Observer* observer) = 0;
89 
90   // Add component to be checked for updates.
91   virtual bool RegisterComponent(const CrxComponent& component) = 0;
92 
93   // Unregisters the component with the given ID. This means that the component
94   // is not going to be included in future update checks. If a download or
95   // update operation for the component is currently in progress, it will
96   // silently finish without triggering the next step.
97   // Note that the installer for the component is responsible for removing any
98   // existing versions of the component from disk. Returns true if the
99   // uninstall has completed successfully and the component files have been
100   // removed, or if the uninstalled has been deferred because the component
101   // is being updated. Returns false if the component id is not known or the
102   /// uninstall encountered an error.
103   virtual bool UnregisterComponent(const std::string& id) = 0;
104 
105   // Returns a list of registered components.
106   virtual std::vector<std::string> GetComponentIDs() const = 0;
107 
108   // Returns a ComponentInfo describing a registered component that implements a
109   // handler for the specified |mime_type|. If multiple such components exist,
110   // returns information for the one that was most recently registered. If no
111   // such components exist, returns nullptr.
112   virtual std::unique_ptr<ComponentInfo> GetComponentForMimeType(
113       const std::string& mime_type) const = 0;
114 
115   // Returns a list of ComponentInfo objects describing all registered
116   // components.
117   virtual std::vector<ComponentInfo> GetComponents() const = 0;
118 
119   // Returns an interface for on-demand updates. On-demand updates are
120   // proactively triggered outside the normal component update service schedule.
121   virtual OnDemandUpdater& GetOnDemandUpdater() = 0;
122 
123   // This method is used to trigger an on-demand update for component |id|.
124   // This can be used when loading a resource that depends on this component.
125   //
126   // |callback| is called on the main thread once the on-demand update is
127   // complete, regardless of success. |callback| may be called immediately
128   // within the method body.
129   //
130   // Additionally, this function implements an embedder-defined cooldown
131   // interval between on demand update attempts. This behavior is intended
132   // to be defensive against programming bugs, usually triggered by web fetches,
133   // where the on-demand functionality is invoked too often. If this function
134   // is called while still on cooldown, |callback| will be called immediately.
135   virtual void MaybeThrottle(const std::string& id,
136                              base::OnceClosure callback) = 0;
137 
138   virtual ~ComponentUpdateService() = default;
139 
140  private:
141   // Returns details about registered component in the |item| parameter. The
142   // function returns true in case of success and false in case of errors.
143   virtual bool GetComponentDetails(const std::string& id,
144                                    CrxUpdateItem* item) const = 0;
145 
146   friend class ::ComponentsHandler;
147   FRIEND_TEST_ALL_PREFIXES(ComponentInstallerTest, RegisterComponent);
148 };
149 
150 using ServiceObserver = ComponentUpdateService::Observer;
151 
152 class OnDemandUpdater {
153  public:
154   // The priority of the on demand update. Calls with |BACKGROUND| priority may
155   // be queued up but calls with |FOREGROUND| priority may be processed right
156   // away.
157   enum class Priority { BACKGROUND = 0, FOREGROUND = 1 };
158 
159   virtual ~OnDemandUpdater() = default;
160 
161  private:
162   friend class OnDemandTester;
163   friend class policy::ComponentUpdaterPolicyTest;
164   friend class SupervisedUserWhitelistInstaller;
165   friend class ::ComponentsHandler;
166   friend class ::PluginObserver;
167   friend class SwReporterOnDemandFetcher;
168   friend class SODAComponentInstallerPolicy;
169 #if defined(OS_CHROMEOS)
170   friend class CrOSComponentInstaller;
171 #endif  // defined(OS_CHROMEOS)
172   friend class VrAssetsComponentInstallerPolicy;
173 
174   // Triggers an update check for a component. |id| is a value
175   // returned by GetCrxComponentID(). If an update for this component is already
176   // in progress, the function returns |kInProgress|. If an update is available,
177   // the update will be applied. The caller can subscribe to component update
178   // service notifications and provide an optional callback to get the result
179   // of the call. The function does not implement any cooldown interval.
180   virtual void OnDemandUpdate(const std::string& id,
181                               Priority priority,
182                               Callback callback) = 0;
183 };
184 
185 // Creates the component updater.
186 std::unique_ptr<ComponentUpdateService> ComponentUpdateServiceFactory(
187     scoped_refptr<Configurator> config,
188     std::unique_ptr<UpdateScheduler> scheduler);
189 
190 }  // namespace component_updater
191 
192 #endif  // COMPONENTS_COMPONENT_UPDATER_COMPONENT_UPDATER_SERVICE_H_
193