| OLD | NEW |
| (Empty) |
| 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_DOWNLOADER_H_ | |
| 6 #define CHROME_BROWSER_EXTENSIONS_UPDATER_EXTENSION_DOWNLOADER_H_ | |
| 7 | |
| 8 #include <deque> | |
| 9 #include <map> | |
| 10 #include <set> | |
| 11 #include <string> | |
| 12 #include <utility> | |
| 13 #include <vector> | |
| 14 | |
| 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 "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" | |
| 28 #include "url/gurl.h" | |
| 29 | |
| 30 class IdentityProvider; | |
| 31 | |
| 32 namespace net { | |
| 33 class URLFetcher; | |
| 34 class URLRequestContextGetter; | |
| 35 class URLRequestStatus; | |
| 36 } | |
| 37 | |
| 38 namespace extensions { | |
| 39 | |
| 40 struct UpdateDetails { | |
| 41 UpdateDetails(const std::string& id, const base::Version& version); | |
| 42 ~UpdateDetails(); | |
| 43 | |
| 44 std::string id; | |
| 45 base::Version version; | |
| 46 }; | |
| 47 | |
| 48 class ExtensionCache; | |
| 49 class ExtensionUpdaterTest; | |
| 50 | |
| 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 | |
| 54 // the update check. | |
| 55 class ExtensionDownloader | |
| 56 : public net::URLFetcherDelegate, | |
| 57 public OAuth2TokenService::Consumer { | |
| 58 public: | |
| 59 // A closure which constructs a new ExtensionDownloader to be owned by the | |
| 60 // caller. | |
| 61 typedef base::Callback< | |
| 62 scoped_ptr<ExtensionDownloader>(ExtensionDownloaderDelegate* delegate)> | |
| 63 Factory; | |
| 64 | |
| 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(); | |
| 70 | |
| 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); | |
| 78 | |
| 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, | |
| 87 int request_id); | |
| 88 | |
| 89 // Schedules a fetch of the manifest of all the extensions added with | |
| 90 // AddExtension() and AddPendingExtension(). | |
| 91 void StartAllPending(ExtensionCache* cache); | |
| 92 | |
| 93 // Schedules an update check of the blacklist. | |
| 94 void StartBlacklistUpdate(const std::string& version, | |
| 95 const ManifestFetchData::PingData& ping_data, | |
| 96 int request_id); | |
| 97 | |
| 98 // Sets an IdentityProvider to be used for OAuth2 authentication on protected | |
| 99 // Webstore downloads. | |
| 100 void SetWebstoreIdentityProvider( | |
| 101 scoped_ptr<IdentityProvider> identity_provider); | |
| 102 | |
| 103 void set_brand_code(const std::string& brand_code) { | |
| 104 brand_code_ = brand_code; | |
| 105 } | |
| 106 | |
| 107 void set_manifest_query_params(const std::string& params) { | |
| 108 manifest_query_params_ = params; | |
| 109 } | |
| 110 | |
| 111 void set_ping_enabled_domain(const std::string& domain) { | |
| 112 ping_enabled_domain_ = domain; | |
| 113 } | |
| 114 | |
| 115 void set_enable_extra_update_metrics(bool enable) { | |
| 116 enable_extra_update_metrics_ = enable; | |
| 117 } | |
| 118 | |
| 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; | |
| 123 | |
| 124 // Update AppID for extension blacklist. | |
| 125 static const char kBlacklistAppID[]; | |
| 126 | |
| 127 static const int kMaxRetries = 10; | |
| 128 | |
| 129 private: | |
| 130 friend class ExtensionUpdaterTest; | |
| 131 | |
| 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. | |
| 134 struct URLStats { | |
| 135 URLStats() | |
| 136 : no_url_count(0), | |
| 137 google_url_count(0), | |
| 138 other_url_count(0), | |
| 139 extension_count(0), | |
| 140 theme_count(0), | |
| 141 app_count(0), | |
| 142 platform_app_count(0), | |
| 143 pending_count(0) {} | |
| 144 | |
| 145 int no_url_count, google_url_count, other_url_count; | |
| 146 int extension_count, theme_count, app_count, platform_app_count, | |
| 147 pending_count; | |
| 148 }; | |
| 149 | |
| 150 // We need to keep track of some information associated with a url | |
| 151 // when doing a fetch. | |
| 152 struct ExtensionFetch { | |
| 153 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); | |
| 157 ~ExtensionFetch(); | |
| 158 | |
| 159 std::string id; | |
| 160 GURL url; | |
| 161 std::string package_hash; | |
| 162 std::string version; | |
| 163 std::set<int> request_ids; | |
| 164 | |
| 165 enum CredentialsMode { | |
| 166 CREDENTIALS_NONE = 0, | |
| 167 CREDENTIALS_OAUTH2_TOKEN, | |
| 168 CREDENTIALS_COOKIES, | |
| 169 }; | |
| 170 | |
| 171 // Indicates the type of credentials to include with this fetch. | |
| 172 CredentialsMode credentials; | |
| 173 | |
| 174 // Counts the number of times OAuth2 authentication has been attempted for | |
| 175 // this fetch. | |
| 176 int oauth2_attempt_count; | |
| 177 }; | |
| 178 | |
| 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, | |
| 185 int request_id, | |
| 186 bool force_update, | |
| 187 const std::string& install_source_override); | |
| 188 | |
| 189 // Adds all recorded stats taken so far to histogram counts. | |
| 190 void ReportStats() const; | |
| 191 | |
| 192 // Begins an update check. | |
| 193 void StartUpdateCheck(scoped_ptr<ManifestFetchData> fetch_data); | |
| 194 | |
| 195 // Called by RequestQueue when a new manifest fetch request is started. | |
| 196 void CreateManifestFetcher(); | |
| 197 | |
| 198 // net::URLFetcherDelegate implementation. | |
| 199 virtual void OnURLFetchComplete(const net::URLFetcher* source) override; | |
| 200 | |
| 201 // Handles the result of a manifest fetch. | |
| 202 void OnManifestFetchComplete(const GURL& url, | |
| 203 const net::URLRequestStatus& status, | |
| 204 int response_code, | |
| 205 const base::TimeDelta& backoff_delay, | |
| 206 const std::string& data); | |
| 207 | |
| 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); | |
| 212 | |
| 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); | |
| 218 | |
| 219 // Begins (or queues up) download of an updated extension. | |
| 220 void FetchUpdatedExtension(scoped_ptr<ExtensionFetch> fetch_data); | |
| 221 | |
| 222 // Called by RequestQueue when a new extension fetch request is started. | |
| 223 void CreateExtensionFetcher(); | |
| 224 | |
| 225 // Handles the result of a crx fetch. | |
| 226 void OnCRXFetchComplete(const net::URLFetcher* source, | |
| 227 const GURL& url, | |
| 228 const net::URLRequestStatus& status, | |
| 229 int response_code, | |
| 230 const base::TimeDelta& backoff_delay); | |
| 231 | |
| 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); | |
| 237 | |
| 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); | |
| 241 | |
| 242 // Do real work of StartAllPending. If .crx cache is used, this function | |
| 243 // is called when cache is ready. | |
| 244 void DoStartAllPending(); | |
| 245 | |
| 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); | |
| 250 | |
| 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, | |
| 256 int response_code); | |
| 257 | |
| 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; | |
| 264 | |
| 265 ManifestFetchData* CreateManifestFetchData(const GURL& update_url, | |
| 266 int request_id); | |
| 267 | |
| 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_; | |
| 271 | |
| 272 // The request context to use for the URLFetchers. | |
| 273 scoped_refptr<net::URLRequestContextGetter> request_context_; | |
| 274 | |
| 275 // Collects UMA samples that are reported when ReportStats() is called. | |
| 276 URLStats url_stats_; | |
| 277 | |
| 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_; | |
| 285 | |
| 286 // Outstanding url fetch requests for manifests and updates. | |
| 287 scoped_ptr<net::URLFetcher> manifest_fetcher_; | |
| 288 scoped_ptr<net::URLFetcher> extension_fetcher_; | |
| 289 | |
| 290 // Pending manifests and extensions to be fetched when the appropriate fetcher | |
| 291 // is available. | |
| 292 RequestQueue<ManifestFetchData> manifests_queue_; | |
| 293 RequestQueue<ExtensionFetch> extensions_queue_; | |
| 294 | |
| 295 // Maps an extension-id to its PingResult data. | |
| 296 std::map<std::string, ExtensionDownloaderDelegate::PingResult> ping_results_; | |
| 297 | |
| 298 // Cache for .crx files. | |
| 299 ExtensionCache* extension_cache_; | |
| 300 | |
| 301 // An IdentityProvider which may be used for authentication on protected | |
| 302 // download requests. May be NULL. | |
| 303 scoped_ptr<IdentityProvider> identity_provider_; | |
| 304 | |
| 305 // A Webstore download-scoped access token for the |identity_provider_|'s | |
| 306 // active account, if any. | |
| 307 std::string access_token_; | |
| 308 | |
| 309 // A pending token fetch request. | |
| 310 scoped_ptr<OAuth2TokenService::Request> access_token_request_; | |
| 311 | |
| 312 // Brand code to include with manifest fetch queries if sending ping data. | |
| 313 std::string brand_code_; | |
| 314 | |
| 315 // Baseline parameters to include with manifest fetch queries. | |
| 316 std::string manifest_query_params_; | |
| 317 | |
| 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_; | |
| 321 | |
| 322 // Indicates whether or not extra metrics should be included with ping data. | |
| 323 // Defaults to |false|. | |
| 324 bool enable_extra_update_metrics_; | |
| 325 | |
| 326 // Used to create WeakPtrs to |this|. | |
| 327 base::WeakPtrFactory<ExtensionDownloader> weak_ptr_factory_; | |
| 328 | |
| 329 DISALLOW_COPY_AND_ASSIGN(ExtensionDownloader); | |
| 330 }; | |
| 331 | |
| 332 } // namespace extensions | |
| 333 | |
| 334 #endif // CHROME_BROWSER_EXTENSIONS_UPDATER_EXTENSION_DOWNLOADER_H_ | |
| OLD | NEW |