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 EXTENSIONS_BROWSER_UPDATER_EXTENSION_DOWNLOADER_H_
6 #define EXTENSIONS_BROWSER_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 "extensions/browser/updater/extension_downloader_delegate.h"
22 #include "extensions/browser/updater/manifest_fetch_data.h"
23 #include "extensions/browser/updater/request_queue.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
: public net::URLFetcherDelegate
,
56 public OAuth2TokenService::Consumer
{
58 // A closure which constructs a new ExtensionDownloader to be owned by the
60 typedef base::Callback
<scoped_ptr
<ExtensionDownloader
>(
61 ExtensionDownloaderDelegate
* delegate
)> Factory
;
63 // |delegate| is stored as a raw pointer and must outlive the
64 // ExtensionDownloader.
65 ExtensionDownloader(ExtensionDownloaderDelegate
* delegate
,
66 net::URLRequestContextGetter
* request_context
);
67 ~ExtensionDownloader() override
;
69 // Adds |extension| to the list of extensions to check for updates.
70 // Returns false if the |extension| can't be updated due to invalid details.
71 // In that case, no callbacks will be performed on the |delegate_|.
72 // The |request_id| is passed on as is to the various |delegate_| callbacks.
73 // This is used for example by ExtensionUpdater to keep track of when
74 // potentially concurrent update checks complete.
75 bool AddExtension(const Extension
& extension
, int request_id
);
77 // Adds extension |id| to the list of extensions to check for updates.
78 // Returns false if the |id| can't be updated due to invalid details.
79 // In that case, no callbacks will be performed on the |delegate_|.
80 // The |request_id| is passed on as is to the various |delegate_| callbacks.
81 // This is used for example by ExtensionUpdater to keep track of when
82 // potentially concurrent update checks complete.
83 bool AddPendingExtension(const std::string
& id
,
84 const GURL
& update_url
,
87 // Schedules a fetch of the manifest of all the extensions added with
88 // AddExtension() and AddPendingExtension().
89 void StartAllPending(ExtensionCache
* cache
);
91 // Schedules an update check of the blacklist.
92 void StartBlacklistUpdate(const std::string
& version
,
93 const ManifestFetchData::PingData
& ping_data
,
96 // Sets an IdentityProvider to be used for OAuth2 authentication on protected
97 // Webstore downloads.
98 void SetWebstoreIdentityProvider(
99 scoped_ptr
<IdentityProvider
> identity_provider
);
101 void set_brand_code(const std::string
& brand_code
) {
102 brand_code_
= brand_code
;
105 void set_manifest_query_params(const std::string
& params
) {
106 manifest_query_params_
= params
;
109 void set_ping_enabled_domain(const std::string
& domain
) {
110 ping_enabled_domain_
= domain
;
113 void set_enable_extra_update_metrics(bool enable
) {
114 enable_extra_update_metrics_
= enable
;
117 // These are needed for unit testing, to help identify the correct mock
118 // URLFetcher objects.
119 static const int kManifestFetcherId
= 1;
120 static const int kExtensionFetcherId
= 2;
122 // Update AppID for extension blacklist.
123 static const char kBlacklistAppID
[];
125 static const int kMaxRetries
= 10;
128 friend class ExtensionUpdaterTest
;
130 // These counters are bumped as extensions are added to be fetched. They
131 // are then recorded as UMA metrics when all the extensions have been added.
140 platform_app_count(0),
143 int no_url_count
, google_url_count
, other_url_count
;
144 int extension_count
, theme_count
, app_count
, platform_app_count
,
148 // We need to keep track of some information associated with a url
149 // when doing a fetch.
150 struct ExtensionFetch
{
152 ExtensionFetch(const std::string
& id
,
154 const std::string
& package_hash
,
155 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 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
,
249 const base::FilePath
& crx_path
,
250 bool file_ownership_passed
);
252 // Cached extension installation completed. If it was not successful, we will
253 // try to download it from the web store using already fetched manifest.
254 void CacheInstallDone(scoped_ptr
<ExtensionFetch
> fetch_data
, bool installed
);
256 // Potentially updates an ExtensionFetch's authentication state and returns
257 // |true| if the fetch should be retried. Returns |false| if the failure was
258 // not related to authentication, leaving the ExtensionFetch data unmodified.
259 bool IterateFetchCredentialsAfterFailure(ExtensionFetch
* fetch
,
260 const net::URLRequestStatus
& status
,
263 // OAuth2TokenService::Consumer implementation.
264 void OnGetTokenSuccess(const OAuth2TokenService::Request
* request
,
265 const std::string
& access_token
,
266 const base::Time
& expiration_time
) override
;
267 void OnGetTokenFailure(const OAuth2TokenService::Request
* request
,
268 const GoogleServiceAuthError
& error
) override
;
270 ManifestFetchData
* CreateManifestFetchData(const GURL
& update_url
,
273 // The delegate that receives the crx files downloaded by the
274 // ExtensionDownloader, and that fills in optional ping and update url data.
275 ExtensionDownloaderDelegate
* delegate_
;
277 // The request context to use for the URLFetchers.
278 scoped_refptr
<net::URLRequestContextGetter
> request_context_
;
280 // Collects UMA samples that are reported when ReportStats() is called.
283 // List of data on fetches we're going to do. We limit the number of
284 // extensions grouped together in one batch to avoid running into the limits
285 // on the length of http GET requests, so there might be multiple
286 // ManifestFetchData* objects with the same base_url.
287 typedef std::map
<std::pair
<int, GURL
>,
288 std::vector
<linked_ptr
<ManifestFetchData
>>> FetchMap
;
289 FetchMap fetches_preparing_
;
291 // Outstanding url fetch requests for manifests and updates.
292 scoped_ptr
<net::URLFetcher
> manifest_fetcher_
;
293 scoped_ptr
<net::URLFetcher
> extension_fetcher_
;
295 // Pending manifests and extensions to be fetched when the appropriate fetcher
297 RequestQueue
<ManifestFetchData
> manifests_queue_
;
298 RequestQueue
<ExtensionFetch
> extensions_queue_
;
300 // Maps an extension-id to its PingResult data.
301 std::map
<std::string
, ExtensionDownloaderDelegate::PingResult
> ping_results_
;
303 // Cache for .crx files.
304 ExtensionCache
* extension_cache_
;
306 // An IdentityProvider which may be used for authentication on protected
307 // download requests. May be NULL.
308 scoped_ptr
<IdentityProvider
> identity_provider_
;
310 // A Webstore download-scoped access token for the |identity_provider_|'s
311 // active account, if any.
312 std::string access_token_
;
314 // A pending token fetch request.
315 scoped_ptr
<OAuth2TokenService::Request
> access_token_request_
;
317 // Brand code to include with manifest fetch queries if sending ping data.
318 std::string brand_code_
;
320 // Baseline parameters to include with manifest fetch queries.
321 std::string manifest_query_params_
;
323 // Domain to enable ping data. Ping data will be sent with manifest fetches
324 // to update URLs which match this domain. Defaults to empty (no domain).
325 std::string ping_enabled_domain_
;
327 // Indicates whether or not extra metrics should be included with ping data.
328 // Defaults to |false|.
329 bool enable_extra_update_metrics_
;
331 // Used to create WeakPtrs to |this|.
332 base::WeakPtrFactory
<ExtensionDownloader
> weak_ptr_factory_
;
334 DISALLOW_COPY_AND_ASSIGN(ExtensionDownloader
);
337 } // namespace extensions
339 #endif // EXTENSIONS_BROWSER_UPDATER_EXTENSION_DOWNLOADER_H_