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/manifest_fetch_data.h"
23 #include "chrome/browser/extensions/updater/request_queue.h"
24 #include "chrome/common/extensions/update_manifest.h"
25 #include "extensions/common/extension.h"
26 #include "net/url_request/url_fetcher_delegate.h"
31 class URLRequestContextGetter;
32 class URLRequestStatus;
35 namespace extensions {
37 struct UpdateDetails {
38 UpdateDetails(const std::string& id, const base::Version& version);
42 base::Version version;
46 class ExtensionUpdaterTest;
48 // A class that checks for updates of a given list of extensions, and downloads
49 // the crx file when updates are found. It uses a |ExtensionDownloaderDelegate|
50 // that takes ownership of the downloaded crx files, and handles events during
52 class ExtensionDownloader : public net::URLFetcherDelegate {
54 // |delegate| is stored as a raw pointer and must outlive the
55 // ExtensionDownloader.
56 ExtensionDownloader(ExtensionDownloaderDelegate* delegate,
57 net::URLRequestContextGetter* request_context);
58 virtual ~ExtensionDownloader();
60 // Adds |extension| to the list of extensions to check for updates.
61 // Returns false if the |extension| can't be updated due to invalid details.
62 // In that case, no callbacks will be performed on the |delegate_|.
63 // The |request_id| is passed on as is to the various |delegate_| callbacks.
64 // This is used for example by ExtensionUpdater to keep track of when
65 // potentially concurrent update checks complete.
66 bool AddExtension(const Extension& extension, int request_id);
68 // Adds extension |id| to the list of extensions to check for updates.
69 // Returns false if the |id| can't be updated due to invalid details.
70 // In that case, no callbacks will be performed on the |delegate_|.
71 // The |request_id| is passed on as is to the various |delegate_| callbacks.
72 // This is used for example by ExtensionUpdater to keep track of when
73 // potentially concurrent update checks complete.
74 bool AddPendingExtension(const std::string& id,
75 const GURL& update_url,
78 // Schedules a fetch of the manifest of all the extensions added with
79 // AddExtension() and AddPendingExtension().
80 void StartAllPending(ExtensionCache* cache);
82 // Schedules an update check of the blacklist.
83 void StartBlacklistUpdate(const std::string& version,
84 const ManifestFetchData::PingData& ping_data,
87 // These are needed for unit testing, to help identify the correct mock
88 // URLFetcher objects.
89 static const int kManifestFetcherId = 1;
90 static const int kExtensionFetcherId = 2;
92 // Update AppID for extension blacklist.
93 static const char kBlacklistAppID[];
95 static const int kMaxRetries = 10;
98 friend class ExtensionUpdaterTest;
100 // These counters are bumped as extensions are added to be fetched. They
101 // are then recorded as UMA metrics when all the extensions have been added.
110 platform_app_count(0),
113 int no_url_count, google_url_count, other_url_count;
114 int extension_count, theme_count, app_count, platform_app_count,
118 // We need to keep track of some information associated with a url
119 // when doing a fetch.
120 struct ExtensionFetch {
122 ExtensionFetch(const std::string& id, const GURL& url,
123 const std::string& package_hash, const std::string& version,
124 const std::set<int>& request_ids);
129 std::string package_hash;
131 std::set<int> request_ids;
133 // Indicates whether or not the fetch is known to require credentials.
137 // Helper for AddExtension() and AddPendingExtension().
138 bool AddExtensionData(const std::string& id,
139 const base::Version& version,
140 Manifest::Type extension_type,
141 const GURL& extension_update_url,
142 const std::string& update_url_data,
145 // Adds all recorded stats taken so far to histogram counts.
146 void ReportStats() const;
148 // Begins an update check.
149 void StartUpdateCheck(scoped_ptr<ManifestFetchData> fetch_data);
151 // Called by RequestQueue when a new manifest fetch request is started.
152 void CreateManifestFetcher();
154 // net::URLFetcherDelegate implementation.
155 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
157 // Handles the result of a manifest fetch.
158 void OnManifestFetchComplete(const GURL& url,
159 const net::URLRequestStatus& status,
161 const base::TimeDelta& backoff_delay,
162 const std::string& data);
164 // Once a manifest is parsed, this starts fetches of any relevant crx files.
165 // If |results| is null, it means something went wrong when parsing it.
166 void HandleManifestResults(const ManifestFetchData& fetch_data,
167 const UpdateManifest::Results* results);
169 // Given a list of potential updates, returns the indices of the ones that are
170 // applicable (are actually a new version, etc.) in |result|.
171 void DetermineUpdates(const ManifestFetchData& fetch_data,
172 const UpdateManifest::Results& possible_updates,
173 std::vector<int>* result);
175 // Begins (or queues up) download of an updated extension.
176 void FetchUpdatedExtension(scoped_ptr<ExtensionFetch> fetch_data);
178 // Called by RequestQueue when a new extension fetch request is started.
179 void CreateExtensionFetcher();
181 // Handles the result of a crx fetch.
182 void OnCRXFetchComplete(const net::URLFetcher* source,
184 const net::URLRequestStatus& status,
186 const base::TimeDelta& backoff_delay);
188 // Invokes OnExtensionDownloadFailed() on the |delegate_| for each extension
189 // in the set, with |error| as the reason for failure.
190 void NotifyExtensionsDownloadFailed(const std::set<std::string>& id_set,
191 const std::set<int>& request_ids,
192 ExtensionDownloaderDelegate::Error error);
194 // Send a notification that an update was found for |id| that we'll
195 // attempt to download.
196 void NotifyUpdateFound(const std::string& id, const std::string& version);
198 // Do real work of StartAllPending. If .crx cache is used, this function
199 // is called when cache is ready.
200 void DoStartAllPending();
202 // Notify delegate and remove ping results.
203 void NotifyDelegateDownloadFinished(scoped_ptr<ExtensionFetch> fetch_data,
204 const base::FilePath& crx_path,
205 bool file_ownership_passed);
207 // The delegate that receives the crx files downloaded by the
208 // ExtensionDownloader, and that fills in optional ping and update url data.
209 ExtensionDownloaderDelegate* delegate_;
211 // The request context to use for the URLFetchers.
212 scoped_refptr<net::URLRequestContextGetter> request_context_;
214 // Used to create WeakPtrs to |this|.
215 base::WeakPtrFactory<ExtensionDownloader> weak_ptr_factory_;
217 // Collects UMA samples that are reported when ReportStats() is called.
220 // List of data on fetches we're going to do. We limit the number of
221 // extensions grouped together in one batch to avoid running into the limits
222 // on the length of http GET requests, so there might be multiple
223 // ManifestFetchData* objects with the same base_url.
224 typedef std::map<std::pair<int, GURL>,
225 std::vector<linked_ptr<ManifestFetchData> > > FetchMap;
226 FetchMap fetches_preparing_;
228 // Outstanding url fetch requests for manifests and updates.
229 scoped_ptr<net::URLFetcher> manifest_fetcher_;
230 scoped_ptr<net::URLFetcher> extension_fetcher_;
232 // Pending manifests and extensions to be fetched when the appropriate fetcher
234 RequestQueue<ManifestFetchData> manifests_queue_;
235 RequestQueue<ExtensionFetch> extensions_queue_;
237 // Maps an extension-id to its PingResult data.
238 std::map<std::string, ExtensionDownloaderDelegate::PingResult> ping_results_;
240 // Cache for .crx files.
241 ExtensionCache* extension_cache_;
243 DISALLOW_COPY_AND_ASSIGN(ExtensionDownloader);
246 } // namespace extensions
248 #endif // CHROME_BROWSER_EXTENSIONS_UPDATER_EXTENSION_DOWNLOADER_H_