extension_updater.h revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
1// Copyright (c) 2012 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 CHROME_BROWSER_EXTENSIONS_UPDATER_EXTENSION_UPDATER_H_
6#define CHROME_BROWSER_EXTENSIONS_UPDATER_EXTENSION_UPDATER_H_
7
8#include <list>
9#include <map>
10#include <set>
11#include <stack>
12#include <string>
13
14#include "base/callback_forward.h"
15#include "base/compiler_specific.h"
16#include "base/files/file_path.h"
17#include "base/gtest_prod_util.h"
18#include "base/memory/scoped_ptr.h"
19#include "base/memory/weak_ptr.h"
20#include "base/time/time.h"
21#include "base/timer/timer.h"
22#include "chrome/browser/extensions/updater/extension_downloader_delegate.h"
23#include "chrome/browser/extensions/updater/manifest_fetch_data.h"
24#include "content/public/browser/notification_observer.h"
25#include "content/public/browser/notification_registrar.h"
26#include "url/gurl.h"
27
28class ExtensionServiceInterface;
29class PrefService;
30class Profile;
31
32namespace extensions {
33
34class ExtensionCache;
35class ExtensionDownloader;
36class ExtensionPrefs;
37class ExtensionSet;
38class ExtensionUpdaterTest;
39
40// A class for doing auto-updates of installed Extensions. Used like this:
41//
42// ExtensionUpdater* updater = new ExtensionUpdater(my_extensions_service,
43//                                                  extension_prefs,
44//                                                  pref_service,
45//                                                  profile,
46//                                                  update_frequency_secs);
47// updater->Start();
48// ....
49// updater->Stop();
50class ExtensionUpdater : public ExtensionDownloaderDelegate,
51                         public content::NotificationObserver {
52 public:
53  typedef base::Closure FinishedCallback;
54
55  struct CheckParams {
56    // Creates a default CheckParams instance that checks for all extensions.
57    CheckParams();
58    ~CheckParams();
59
60    // The set of extensions that should be checked for updates. If empty
61    // all extensions will be included in the update check.
62    std::list<std::string> ids;
63
64    // Normally extension updates get installed only when the extension is idle.
65    // Setting this to true causes any updates that are found to be installed
66    // right away.
67    bool install_immediately;
68
69    // Callback to call when the update check is complete. Can be null, if
70    // you're not interested in when this happens.
71    FinishedCallback callback;
72  };
73
74  // Holds a pointer to the passed |service|, using it for querying installed
75  // extensions and installing updated ones. The |frequency_seconds| parameter
76  // controls how often update checks are scheduled.
77  ExtensionUpdater(ExtensionServiceInterface* service,
78                   ExtensionPrefs* extension_prefs,
79                   PrefService* prefs,
80                   Profile* profile,
81                   int frequency_seconds,
82                   ExtensionCache* cache);
83
84  virtual ~ExtensionUpdater();
85
86  // Starts the updater running.  Should be called at most once.
87  void Start();
88
89  // Stops the updater running, cancelling any outstanding update manifest and
90  // crx downloads. Does not cancel any in-progress installs.
91  void Stop();
92
93  // Posts a task to do an update check.  Does nothing if there is
94  // already a pending task that has not yet run.
95  void CheckSoon();
96
97  // Starts an update check for the specified extension soon. If a check
98  // is already running, or finished too recently without an update being
99  // installed, this method returns false and the check won't be scheduled.
100  bool CheckExtensionSoon(const std::string& extension_id,
101                          const FinishedCallback& callback);
102
103  // Starts an update check right now, instead of waiting for the next
104  // regularly scheduled check or a pending check from CheckSoon().
105  void CheckNow(const CheckParams& params);
106
107  // Returns true iff CheckSoon() has been called but the update check
108  // hasn't been performed yet.  This is used mostly by tests; calling
109  // code should just call CheckSoon().
110  bool WillCheckSoon() const;
111
112  // Changes the params that are used for the automatic periodic update checks,
113  // as well as for explicit calls to CheckSoon.
114  void set_default_check_params(const CheckParams& params) {
115    default_params_ = params;
116  }
117
118 private:
119  friend class ExtensionUpdaterTest;
120  friend class ExtensionUpdaterFileHandler;
121
122  // FetchedCRXFile holds information about a CRX file we fetched to disk,
123  // but have not yet installed.
124  struct FetchedCRXFile {
125    FetchedCRXFile();
126    FetchedCRXFile(const std::string& id,
127                   const base::FilePath& path,
128                   bool file_ownership_passed,
129                   const GURL& download_url,
130                   const std::set<int>& request_ids);
131    ~FetchedCRXFile();
132
133    std::string extension_id;
134    base::FilePath path;
135    bool file_ownership_passed;
136    GURL download_url;
137    std::set<int> request_ids;
138  };
139
140  struct InProgressCheck {
141    InProgressCheck();
142    ~InProgressCheck();
143
144    bool install_immediately;
145    FinishedCallback callback;
146    // The ids of extensions that have in-progress update checks.
147    std::list<std::string> in_progress_ids_;
148  };
149
150  struct ThrottleInfo;
151
152  // Computes when to schedule the first update check.
153  base::TimeDelta DetermineFirstCheckDelay();
154
155  // Sets the timer to call TimerFired after roughly |target_delay| from now.
156  // To help spread load evenly on servers, this method adds some random
157  // jitter. It also saves the scheduled time so it can be reloaded on
158  // browser restart.
159  void ScheduleNextCheck(const base::TimeDelta& target_delay);
160
161  // Add fetch records for extensions that are installed to the downloader,
162  // ignoring |pending_ids| so the extension isn't fetched again.
163  void AddToDownloader(const ExtensionSet* extensions,
164                       const std::list<std::string>& pending_ids,
165                       int request_id);
166
167  // BaseTimer::ReceiverMethod callback.
168  void TimerFired();
169
170  // Posted by CheckSoon().
171  void DoCheckSoon();
172
173  // Implenentation of ExtensionDownloaderDelegate.
174  virtual void OnExtensionDownloadFailed(
175      const std::string& id,
176      Error error,
177      const PingResult& ping,
178      const std::set<int>& request_ids) OVERRIDE;
179
180  virtual void OnExtensionDownloadFinished(
181      const std::string& id,
182      const base::FilePath& path,
183      bool file_ownership_passed,
184      const GURL& download_url,
185      const std::string& version,
186      const PingResult& ping,
187      const std::set<int>& request_id) OVERRIDE;
188
189  virtual bool GetPingDataForExtension(
190      const std::string& id,
191      ManifestFetchData::PingData* ping_data) OVERRIDE;
192
193  virtual std::string GetUpdateUrlData(const std::string& id) OVERRIDE;
194
195  virtual bool IsExtensionPending(const std::string& id) OVERRIDE;
196
197  virtual bool GetExtensionExistingVersion(const std::string& id,
198                                           std::string* version) OVERRIDE;
199
200  void UpdatePingData(const std::string& id, const PingResult& ping_result);
201
202  // Starts installing a crx file that has been fetched but not installed yet.
203  void MaybeInstallCRXFile();
204
205  // content::NotificationObserver implementation.
206  virtual void Observe(int type,
207                       const content::NotificationSource& source,
208                       const content::NotificationDetails& details) OVERRIDE;
209
210  // Send a notification that update checks are starting.
211  void NotifyStarted();
212
213  // Send a notification if we're finished updating.
214  void NotifyIfFinished(int request_id);
215
216  void ExtensionCheckFinished(const std::string& extension_id,
217                              const FinishedCallback& callback);
218
219  // Whether Start() has been called but not Stop().
220  bool alive_;
221
222  base::WeakPtrFactory<ExtensionUpdater> weak_ptr_factory_;
223
224  // Pointer back to the service that owns this ExtensionUpdater.
225  ExtensionServiceInterface* service_;
226
227  // Fetches the crx files for the extensions that have an available update.
228  scoped_ptr<ExtensionDownloader> downloader_;
229
230  base::OneShotTimer<ExtensionUpdater> timer_;
231  int frequency_seconds_;
232  bool will_check_soon_;
233
234  ExtensionPrefs* extension_prefs_;
235  PrefService* prefs_;
236  Profile* profile_;
237
238  std::map<int, InProgressCheck> requests_in_progress_;
239  int next_request_id_;
240
241  // Observes CRX installs we initiate.
242  content::NotificationRegistrar registrar_;
243
244  // True when a CrxInstaller is doing an install.  Used in MaybeUpdateCrxFile()
245  // to keep more than one install from running at once.
246  bool crx_install_is_running_;
247
248  // Fetched CRX files waiting to be installed.
249  std::stack<FetchedCRXFile> fetched_crx_files_;
250  FetchedCRXFile current_crx_file_;
251
252  CheckParams default_params_;
253
254  ExtensionCache* extension_cache_;
255
256  // Keeps track of when an extension tried to update itself, so we can throttle
257  // checks to prevent too many requests from being made.
258  std::map<std::string, ThrottleInfo> throttle_info_;
259
260  DISALLOW_COPY_AND_ASSIGN(ExtensionUpdater);
261};
262
263}  // namespace extensions
264
265#endif  // CHROME_BROWSER_EXTENSIONS_UPDATER_EXTENSION_UPDATER_H_
266