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