summaryrefslogtreecommitdiffstats
path: root/components/component_updater/component_updater_service.h
blob: 9ea5d30209d9e211c7e142180f212f0951ed99f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_COMPONENT_UPDATER_COMPONENT_UPDATER_SERVICE_H_
#define COMPONENTS_COMPONENT_UPDATER_COMPONENT_UPDATER_SERVICE_H_

#include <string>
#include <vector>

#include "base/callback_forward.h"
#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
#include "base/version.h"
#include "url/gurl.h"

class ComponentsUI;

namespace base {
class DictionaryValue;
class FilePath;
class SequencedTaskRunner;
}

namespace net {
class URLRequestContextGetter;
class URLRequest;
}

namespace content {
class ResourceThrottle;
}

namespace component_updater {

class Configurator;
class OnDemandUpdater;

// Component specific installers must derive from this class and implement
// OnUpdateError() and Install(). A valid instance of this class must be
// given to ComponentUpdateService::RegisterComponent().
class ComponentInstaller {
 public:
  // Called by the component updater on the main thread when there was a
  // problem unpacking or verifying the component. |error| is a non-zero
  // value which is only meaningful to the component updater.
  virtual void OnUpdateError(int error) = 0;

  // Called by the component updater when a component has been unpacked
  // and is ready to be installed. |manifest| contains the CRX manifest
  // json dictionary and |unpack_path| contains the temporary directory
  // with all the unpacked CRX files. This method may be called from
  // a thread other than the main thread.
  virtual bool Install(const base::DictionaryValue& manifest,
                       const base::FilePath& unpack_path) = 0;

  // Set |installed_file| to the full path to the installed |file|. |file| is
  // the filename of the file in this component's CRX. Returns false if this is
  // not possible (the file has been removed or modified, or its current
  // location is unknown). Otherwise, returns true.
  virtual bool GetInstalledFile(const std::string& file,
                                base::FilePath* installed_file) = 0;

  virtual ~ComponentInstaller() {}
};

// Describes a particular component that can be installed or updated. This
// structure is required to register a component with the component updater.
// |pk_hash| is the SHA256 hash of the component's public key. If the component
// is to be installed then version should be "0" or "0.0", else it should be
// the current version. |fingerprint|, and |name| are optional.
// |allow_background_download| specifies that the component can be background
// downloaded in some cases. The default for this value is |true| and the value
// can be overriden at the registration time. This is a temporary change until
// the issue 340448 is resolved.
struct CrxComponent {
  std::vector<uint8> pk_hash;
  ComponentInstaller* installer;
  Version version;
  std::string fingerprint;
  std::string name;
  bool allow_background_download;
  CrxComponent();
  ~CrxComponent();
};

struct CrxUpdateItem;

// The component update service is in charge of installing or upgrading
// select parts of chrome. Each part is called a component and managed by
// instances of CrxComponent registered using RegisterComponent(). On the
// server, each component is packaged as a CRX which is the same format used
// to package extensions. To the update service each component is identified
// by its public key hash (CrxComponent::pk_hash). If there is an update
// available and its version is bigger than (CrxComponent::version), it will
// be downloaded, verified and unpacked. Then component-specific installer
// ComponentInstaller::Install (of CrxComponent::installer) will be called.
//
// During the normal operation of the component updater some specific
// notifications are fired, like COMPONENT_UPDATER_STARTED and
// COMPONENT_UPDATE_FOUND. See notification_type.h for more details.
//
// All methods are safe to call ONLY from the browser's main thread.
class ComponentUpdateService {
 public:
  enum Status { kOk, kReplaced, kInProgress, kError };

  // Defines an interface to observe ComponentUpdateService. It provides
  // notifications when state changes occur for the service or for the
  // registered components.
  class Observer {
   public:
    enum Events {
      // Sent when the component updater starts doing update checks.
      COMPONENT_UPDATER_STARTED,

      // Sent when the component updater is going to take a long nap.
      COMPONENT_UPDATER_SLEEPING,

      // Sent when there is a new version of a registered component. After
      // the notification is sent the component will be downloaded.
      COMPONENT_UPDATE_FOUND,

      // Sent when the new component has been downloaded and an installation
      // or upgrade is about to be attempted.
      COMPONENT_UPDATE_READY,

      // Sent when a component has been successfully updated.
      COMPONENT_UPDATED,

      // Sent when a component has not been updated following an update check:
      // either there was no update available, or an update failed.
      COMPONENT_NOT_UPDATED,

      // Sent when component bytes are being downloaded.
      COMPONENT_UPDATE_DOWNLOADING,
    };

    virtual ~Observer() {}

    // The component updater service will call this function when an interesting
    // state change happens. If the |id| is specified, then the event is fired
    // on behalf of a specific component. The implementors of this interface are
    // expected to filter the relevant events based on the component id.
    virtual void OnEvent(Events event, const std::string& id) = 0;
  };

  // Adds an observer for this class. An observer should not be added more
  // than once. The caller retains the ownership of the observer object.
  virtual void AddObserver(Observer* observer) = 0;

  // Removes an observer. It is safe for an observer to be removed while
  // the observers are being notified.
  virtual void RemoveObserver(Observer* observer) = 0;

  // Start doing update checks and installing new versions of registered
  // components after Configurator::InitialDelay() seconds.
  virtual Status Start() = 0;

  // Stop doing update checks. In-flight requests and pending installations
  // will not be canceled.
  virtual Status Stop() = 0;

  // Add component to be checked for updates. You can call this method
  // before calling Start().
  virtual Status RegisterComponent(const CrxComponent& component) = 0;

  // Returns a list of registered components.
  virtual std::vector<std::string> GetComponentIDs() const = 0;

  // Returns an interface for on-demand updates. On-demand updates are
  // proactively triggered outside the normal component update service schedule.
  virtual OnDemandUpdater& GetOnDemandUpdater() = 0;

  // This method is used to trigger an on-demand update for component |crx_id|.
  // This can be used when loading a resource that depends on this component.
  //
  // |callback| is called on the main thread once the on-demand update is
  // complete, regardless of success. |callback| may be called immediately
  // within the method body.
  //
  // Additionally, this function implements an embedder-defined cooldown
  // interval between on demand update attempts. This behavior is intended
  // to be defensive against programming bugs, usually triggered by web fetches,
  // where the on-demand functionality is invoked too often. If this function
  // is called while still on cooldown, |callback| will be called immediately.
  virtual void MaybeThrottle(const std::string& crx_id,
                             const base::Closure& callback) = 0;

  // Returns a task runner suitable for use by component installers.
  virtual scoped_refptr<base::SequencedTaskRunner> GetSequencedTaskRunner() = 0;

  virtual ~ComponentUpdateService() {}

 private:
  // Returns details about registered component in the |item| parameter. The
  // function returns true in case of success and false in case of errors.
  virtual bool GetComponentDetails(const std::string& component_id,
                                   CrxUpdateItem* item) const = 0;

  friend class ::ComponentsUI;
};

typedef ComponentUpdateService::Observer ServiceObserver;

class OnDemandUpdater {
 public:
  virtual ~OnDemandUpdater() {}

 private:
  friend class OnDemandTester;
  friend class ::ComponentsUI;

  // Triggers an update check for a component. |component_id| is a value
  // returned by GetCrxComponentID(). If an update for this component is already
  // in progress, the function returns |kInProgress|. If an update is available,
  // the update will be applied. The caller can subscribe to component update
  // service notifications to get an indication about the outcome of the
  // on-demand update. The function does not implement any cooldown interval.
  virtual ComponentUpdateService::Status OnDemandUpdate(
      const std::string& component_id) = 0;
};

// Creates the component updater. You must pass a valid |config| allocated on
// the heap which the component updater will own.
ComponentUpdateService* ComponentUpdateServiceFactory(Configurator* config);

}  // namespace component_updater

#endif  // COMPONENTS_COMPONENT_UPDATER_COMPONENT_UPDATER_SERVICE_H_