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.
5 #ifndef CHROME_BROWSER_EXTENSIONS_UPDATER_EXTENSION_DOWNLOADER_H_
6 #define CHROME_BROWSER_EXTENSIONS_UPDATER_EXTENSION_DOWNLOADER_H_
15 #include "base/basictypes.h"
16 #include "base/compiler_specific.h"
17 #include "base/memory/linked_ptr.h"
18 #include "base/memory/scoped_ptr.h"
19 #include "base/memory/weak_ptr.h"
20 #include "base/version.h"
21 #include "chrome/browser/extensions/updater/extension_downloader_delegate.h"
22 #include "chrome/browser/extensions/updater/request_queue.h"
23 #include "extensions/browser/updater/manifest_fetch_data.h"
24 #include "extensions/common/extension.h"
25 #include "extensions/common/update_manifest.h"
26 #include "google_apis/gaia/oauth2_token_service.h"
27 #include "net/url_request/url_fetcher_delegate.h"
30 class IdentityProvider;
34 class URLRequestContextGetter;
35 class URLRequestStatus;
38 namespace extensions {
40 struct UpdateDetails {
41 UpdateDetails(const std::string& id, const base::Version& version);
45 base::Version version;
49 class ExtensionUpdaterTest;
51 // A class that checks for updates of a given list of extensions, and downloads
52 // the crx file when updates are found. It uses a |ExtensionDownloaderDelegate|
53 // that takes ownership of the downloaded crx files, and handles events during
55 class ExtensionDownloader
56 : public net::URLFetcherDelegate,
57 public OAuth2TokenService::Consumer {
59 // A closure which constructs a new ExtensionDownloader to be owned by the
61 typedef base::Callback<
62 scoped_ptr<ExtensionDownloader>(ExtensionDownloaderDelegate* delegate)>
65 // |delegate| is stored as a raw pointer and must outlive the
66 // ExtensionDownloader.
67 ExtensionDownloader(ExtensionDownloaderDelegate* delegate,
68 net::URLRequestContextGetter* request_context);
69 virtual ~ExtensionDownloader();
71 // Adds |extension| to the list of extensions to check for updates.
72 // Returns false if the |extension| can't be updated due to invalid details.
73 // In that case, no callbacks will be performed on the |delegate_|.
74 // The |request_id| is passed on as is to the various |delegate_| callbacks.
75 // This is used for example by ExtensionUpdater to keep track of when
76 // potentially concurrent update checks complete.
77 bool AddExtension(const Extension& extension, int request_id);
79 // Adds extension |id| to the list of extensions to check for updates.
80 // Returns false if the |id| can't be updated due to invalid details.
81 // In that case, no callbacks will be performed on the |delegate_|.
82 // The |request_id| is passed on as is to the various |delegate_| callbacks.
83 // This is used for example by ExtensionUpdater to keep track of when
84 // potentially concurrent update checks complete.
85 bool AddPendingExtension(const std::string& id,
86 const GURL& update_url,
89 // Schedules a fetch of the manifest of all the extensions added with
90 // AddExtension() and AddPendingExtension().
91 void StartAllPending(ExtensionCache* cache);
93 // Schedules an update check of the blacklist.
94 void StartBlacklistUpdate(const std::string& version,
95 const ManifestFetchData::PingData& ping_data,
98 // Sets an IdentityProvider to be used for OAuth2 authentication on protected
99 // Webstore downloads.
100 void SetWebstoreIdentityProvider(
101 scoped_ptr<IdentityProvider> identity_provider);
103 void set_brand_code(const std::string& brand_code) {
104 brand_code_ = brand_code;
107 void set_manifest_query_params(const std::string& params) {
108 manifest_query_params_ = params;
111 void set_ping_enabled_domain(const std::string& domain) {
112 ping_enabled_domain_ = domain;
115 void set_enable_extra_update_metrics(bool enable) {
116 enable_extra_update_metrics_ = enable;
119 // These are needed for unit testing, to help identify the correct mock
120 // URLFetcher objects.
121 static const int kManifestFetcherId = 1;
122 static const int kExtensionFetcherId = 2;
124 // Update AppID for extension blacklist.
125 static const char kBlacklistAppID[];
127 static const int kMaxRetries = 10;
130 friend class ExtensionUpdaterTest;
132 // These counters are bumped as extensions are added to be fetched. They
133 // are then recorded as UMA metrics when all the extensions have been added.
142 platform_app_count(0),
145 int no_url_count, google_url_count, other_url_count;
146 int extension_count, theme_count, app_count, platform_app_count,
150 // We need to keep track of some information associated with a url
151 // when doing a fetch.
152 struct ExtensionFetch {
154 ExtensionFetch(const std::string& id, const GURL& url,
155 const std::string& package_hash, const std::string& version,
156 const std::set<int>& request_ids);
161 std::string package_hash;
163 std::set<int> request_ids;
165 enum CredentialsMode {
166 CREDENTIALS_NONE = 0,
167 CREDENTIALS_OAUTH2_TOKEN,
171 // Indicates the type of credentials to include with this fetch.
172 CredentialsMode credentials;
174 // Counts the number of times OAuth2 authentication has been attempted for
176 int oauth2_attempt_count;
179 // Helper for AddExtension() and AddPendingExtension().
180 bool AddExtensionData(const std::string& id,
181 const base::Version& version,
182 Manifest::Type extension_type,
183 const GURL& extension_update_url,
184 const std::string& update_url_data,
187 const std::string& install_source_override);
189 // Adds all recorded stats taken so far to histogram counts.
190 void ReportStats() const;
192 // Begins an update check.
193 void StartUpdateCheck(scoped_ptr<ManifestFetchData> fetch_data);
195 // Called by RequestQueue when a new manifest fetch request is started.
196 void CreateManifestFetcher();
198 // net::URLFetcherDelegate implementation.
199 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
201 // Handles the result of a manifest fetch.
202 void OnManifestFetchComplete(const GURL& url,
203 const net::URLRequestStatus& status,
205 const base::TimeDelta& backoff_delay,
206 const std::string& data);
208 // Once a manifest is parsed, this starts fetches of any relevant crx files.
209 // If |results| is null, it means something went wrong when parsing it.
210 void HandleManifestResults(const ManifestFetchData& fetch_data,
211 const UpdateManifest::Results* results);
213 // Given a list of potential updates, returns the indices of the ones that are
214 // applicable (are actually a new version, etc.) in |result|.
215 void DetermineUpdates(const ManifestFetchData& fetch_data,
216 const UpdateManifest::Results& possible_updates,
217 std::vector<int>* result);
219 // Begins (or queues up) download of an updated extension.
220 void FetchUpdatedExtension(scoped_ptr<ExtensionFetch> fetch_data);
222 // Called by RequestQueue when a new extension fetch request is started.
223 void CreateExtensionFetcher();
225 // Handles the result of a crx fetch.
226 void OnCRXFetchComplete(const net::URLFetcher* source,
228 const net::URLRequestStatus& status,
230 const base::TimeDelta& backoff_delay);
232 // Invokes OnExtensionDownloadFailed() on the |delegate_| for each extension
233 // in the set, with |error| as the reason for failure.
234 void NotifyExtensionsDownloadFailed(const std::set<std::string>& id_set,
235 const std::set<int>& request_ids,
236 ExtensionDownloaderDelegate::Error error);
238 // Send a notification that an update was found for |id| that we'll
239 // attempt to download.
240 void NotifyUpdateFound(const std::string& id, const std::string& version);
242 // Do real work of StartAllPending. If .crx cache is used, this function
243 // is called when cache is ready.
244 void DoStartAllPending();
246 // Notify delegate and remove ping results.
247 void NotifyDelegateDownloadFinished(scoped_ptr<ExtensionFetch> fetch_data,
248 const base::FilePath& crx_path,
249 bool file_ownership_passed);
251 // Potentially updates an ExtensionFetch's authentication state and returns
252 // |true| if the fetch should be retried. Returns |false| if the failure was
253 // not related to authentication, leaving the ExtensionFetch data unmodified.
254 bool IterateFetchCredentialsAfterFailure(ExtensionFetch* fetch,
255 const net::URLRequestStatus& status,
258 // OAuth2TokenService::Consumer implementation.
259 virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
260 const std::string& access_token,
261 const base::Time& expiration_time) OVERRIDE;
262 virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
263 const GoogleServiceAuthError& error) OVERRIDE;
265 ManifestFetchData* CreateManifestFetchData(const GURL& update_url,
268 // The delegate that receives the crx files downloaded by the
269 // ExtensionDownloader, and that fills in optional ping and update url data.
270 ExtensionDownloaderDelegate* delegate_;
272 // The request context to use for the URLFetchers.
273 scoped_refptr<net::URLRequestContextGetter> request_context_;
275 // Collects UMA samples that are reported when ReportStats() is called.
278 // List of data on fetches we're going to do. We limit the number of
279 // extensions grouped together in one batch to avoid running into the limits
280 // on the length of http GET requests, so there might be multiple
281 // ManifestFetchData* objects with the same base_url.
282 typedef std::map<std::pair<int, GURL>,
283 std::vector<linked_ptr<ManifestFetchData> > > FetchMap;
284 FetchMap fetches_preparing_;
286 // Outstanding url fetch requests for manifests and updates.
287 scoped_ptr<net::URLFetcher> manifest_fetcher_;
288 scoped_ptr<net::URLFetcher> extension_fetcher_;
290 // Pending manifests and extensions to be fetched when the appropriate fetcher
292 RequestQueue<ManifestFetchData> manifests_queue_;
293 RequestQueue<ExtensionFetch> extensions_queue_;
295 // Maps an extension-id to its PingResult data.
296 std::map<std::string, ExtensionDownloaderDelegate::PingResult> ping_results_;
298 // Cache for .crx files.
299 ExtensionCache* extension_cache_;
301 // An IdentityProvider which may be used for authentication on protected
302 // download requests. May be NULL.
303 scoped_ptr<IdentityProvider> identity_provider_;
305 // A Webstore download-scoped access token for the |identity_provider_|'s
306 // active account, if any.
307 std::string access_token_;
309 // A pending token fetch request.
310 scoped_ptr<OAuth2TokenService::Request> access_token_request_;
312 // Brand code to include with manifest fetch queries if sending ping data.
313 std::string brand_code_;
315 // Baseline parameters to include with manifest fetch queries.
316 std::string manifest_query_params_;
318 // Domain to enable ping data. Ping data will be sent with manifest fetches
319 // to update URLs which match this domain. Defaults to empty (no domain).
320 std::string ping_enabled_domain_;
322 // Indicates whether or not extra metrics should be included with ping data.
323 // Defaults to |false|.
324 bool enable_extra_update_metrics_;
326 // Used to create WeakPtrs to |this|.
327 base::WeakPtrFactory<ExtensionDownloader> weak_ptr_factory_;
329 DISALLOW_COPY_AND_ASSIGN(ExtensionDownloader);
332 } // namespace extensions
334 #endif // CHROME_BROWSER_EXTENSIONS_UPDATER_EXTENSION_DOWNLOADER_H_