| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/updater/extension_downloader.h" | 5 #include "chrome/browser/extensions/updater/extension_downloader.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 return false; | 203 return false; |
| 204 } | 204 } |
| 205 | 205 |
| 206 // If the extension updates itself from the gallery, ignore any update URL | 206 // If the extension updates itself from the gallery, ignore any update URL |
| 207 // data. At the moment there is no extra data that an extension can | 207 // data. At the moment there is no extra data that an extension can |
| 208 // communicate to the the gallery update servers. | 208 // communicate to the the gallery update servers. |
| 209 std::string update_url_data; | 209 std::string update_url_data; |
| 210 if (!ManifestURL::UpdatesFromGallery(&extension)) | 210 if (!ManifestURL::UpdatesFromGallery(&extension)) |
| 211 update_url_data = delegate_->GetUpdateUrlData(extension.id()); | 211 update_url_data = delegate_->GetUpdateUrlData(extension.id()); |
| 212 | 212 |
| 213 return AddExtensionData(extension.id(), *extension.version(), | 213 std::string install_source; |
| 214 bool force_update = delegate_->ShouldForceUpdate(extension.id(), |
| 215 &install_source); |
| 216 return AddExtensionData(extension.id(), |
| 217 *extension.version(), |
| 214 extension.GetType(), | 218 extension.GetType(), |
| 215 ManifestURL::GetUpdateURL(&extension), | 219 ManifestURL::GetUpdateURL(&extension), |
| 216 update_url_data, request_id); | 220 update_url_data, |
| 221 request_id, |
| 222 force_update, |
| 223 install_source); |
| 217 } | 224 } |
| 218 | 225 |
| 219 bool ExtensionDownloader::AddPendingExtension(const std::string& id, | 226 bool ExtensionDownloader::AddPendingExtension(const std::string& id, |
| 220 const GURL& update_url, | 227 const GURL& update_url, |
| 221 int request_id) { | 228 int request_id) { |
| 222 // Use a zero version to ensure that a pending extension will always | 229 // Use a zero version to ensure that a pending extension will always |
| 223 // be updated, and thus installed (assuming all extensions have | 230 // be updated, and thus installed (assuming all extensions have |
| 224 // non-zero versions). | 231 // non-zero versions). |
| 225 Version version("0.0.0.0"); | 232 Version version("0.0.0.0"); |
| 226 DCHECK(version.IsValid()); | 233 DCHECK(version.IsValid()); |
| 227 | 234 |
| 228 return AddExtensionData(id, | 235 return AddExtensionData(id, |
| 229 version, | 236 version, |
| 230 Manifest::TYPE_UNKNOWN, | 237 Manifest::TYPE_UNKNOWN, |
| 231 update_url, | 238 update_url, |
| 232 std::string(), | 239 std::string(), |
| 233 request_id); | 240 request_id, |
| 241 false, |
| 242 std::string()); |
| 234 } | 243 } |
| 235 | 244 |
| 236 void ExtensionDownloader::StartAllPending(ExtensionCache* cache) { | 245 void ExtensionDownloader::StartAllPending(ExtensionCache* cache) { |
| 237 if (cache) { | 246 if (cache) { |
| 238 extension_cache_ = cache; | 247 extension_cache_ = cache; |
| 239 extension_cache_->Start(base::Bind( | 248 extension_cache_->Start(base::Bind( |
| 240 &ExtensionDownloader::DoStartAllPending, | 249 &ExtensionDownloader::DoStartAllPending, |
| 241 weak_ptr_factory_.GetWeakPtr())); | 250 weak_ptr_factory_.GetWeakPtr())); |
| 242 } else { | 251 } else { |
| 243 DoStartAllPending(); | 252 DoStartAllPending(); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 266 // url here to avoid DNS hijacking of the blacklist, which is not validated | 275 // url here to avoid DNS hijacking of the blacklist, which is not validated |
| 267 // by a public key signature like .crx files are. | 276 // by a public key signature like .crx files are. |
| 268 scoped_ptr<ManifestFetchData> blacklist_fetch( | 277 scoped_ptr<ManifestFetchData> blacklist_fetch( |
| 269 new ManifestFetchData(extension_urls::GetWebstoreUpdateUrl(), | 278 new ManifestFetchData(extension_urls::GetWebstoreUpdateUrl(), |
| 270 request_id)); | 279 request_id)); |
| 271 DCHECK(blacklist_fetch->base_url().SchemeIsSecure()); | 280 DCHECK(blacklist_fetch->base_url().SchemeIsSecure()); |
| 272 blacklist_fetch->AddExtension(kBlacklistAppID, | 281 blacklist_fetch->AddExtension(kBlacklistAppID, |
| 273 version, | 282 version, |
| 274 &ping_data, | 283 &ping_data, |
| 275 std::string(), | 284 std::string(), |
| 276 kDefaultInstallSource); | 285 kDefaultInstallSource, |
| 286 false); |
| 277 StartUpdateCheck(blacklist_fetch.Pass()); | 287 StartUpdateCheck(blacklist_fetch.Pass()); |
| 278 } | 288 } |
| 279 | 289 |
| 280 void ExtensionDownloader::SetWebstoreIdentityProvider( | 290 void ExtensionDownloader::SetWebstoreIdentityProvider( |
| 281 scoped_ptr<IdentityProvider> identity_provider) { | 291 scoped_ptr<IdentityProvider> identity_provider) { |
| 282 identity_provider_.swap(identity_provider); | 292 identity_provider_.swap(identity_provider); |
| 283 } | 293 } |
| 284 | 294 |
| 285 bool ExtensionDownloader::AddExtensionData(const std::string& id, | 295 bool ExtensionDownloader::AddExtensionData( |
| 286 const Version& version, | 296 const std::string& id, |
| 287 Manifest::Type extension_type, | 297 const Version& version, |
| 288 const GURL& extension_update_url, | 298 Manifest::Type extension_type, |
| 289 const std::string& update_url_data, | 299 const GURL& extension_update_url, |
| 290 int request_id) { | 300 const std::string& update_url_data, |
| 301 int request_id, |
| 302 bool force_update, |
| 303 const std::string& install_source_override) { |
| 291 GURL update_url(extension_update_url); | 304 GURL update_url(extension_update_url); |
| 292 // Skip extensions with non-empty invalid update URLs. | 305 // Skip extensions with non-empty invalid update URLs. |
| 293 if (!update_url.is_empty() && !update_url.is_valid()) { | 306 if (!update_url.is_empty() && !update_url.is_valid()) { |
| 294 LOG(WARNING) << "Extension " << id << " has invalid update url " | 307 LOG(WARNING) << "Extension " << id << " has invalid update url " |
| 295 << update_url; | 308 << update_url; |
| 296 return false; | 309 return false; |
| 297 } | 310 } |
| 298 | 311 |
| 299 // Make sure we use SSL for store-hosted extensions. | 312 // Make sure we use SSL for store-hosted extensions. |
| 300 if (extension_urls::IsWebstoreUpdateUrl(update_url) && | 313 if (extension_urls::IsWebstoreUpdateUrl(update_url) && |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 ChromeMetricsServiceAccessor::IsMetricsReportingEnabled()) { | 359 ChromeMetricsServiceAccessor::IsMetricsReportingEnabled()) { |
| 347 update_urls.push_back(extension_urls::GetWebstoreUpdateUrl()); | 360 update_urls.push_back(extension_urls::GetWebstoreUpdateUrl()); |
| 348 } | 361 } |
| 349 | 362 |
| 350 for (size_t i = 0; i < update_urls.size(); ++i) { | 363 for (size_t i = 0; i < update_urls.size(); ++i) { |
| 351 DCHECK(!update_urls[i].is_empty()); | 364 DCHECK(!update_urls[i].is_empty()); |
| 352 DCHECK(update_urls[i].is_valid()); | 365 DCHECK(update_urls[i].is_valid()); |
| 353 | 366 |
| 354 std::string install_source = i == 0 ? | 367 std::string install_source = i == 0 ? |
| 355 kDefaultInstallSource : kNotFromWebstoreInstallSource; | 368 kDefaultInstallSource : kNotFromWebstoreInstallSource; |
| 369 if (!install_source_override.empty()) { |
| 370 install_source = install_source_override; |
| 371 } |
| 356 | 372 |
| 357 ManifestFetchData::PingData ping_data; | 373 ManifestFetchData::PingData ping_data; |
| 358 ManifestFetchData::PingData* optional_ping_data = NULL; | 374 ManifestFetchData::PingData* optional_ping_data = NULL; |
| 359 if (delegate_->GetPingDataForExtension(id, &ping_data)) | 375 if (delegate_->GetPingDataForExtension(id, &ping_data)) |
| 360 optional_ping_data = &ping_data; | 376 optional_ping_data = &ping_data; |
| 361 | 377 |
| 362 // Find or create a ManifestFetchData to add this extension to. | 378 // Find or create a ManifestFetchData to add this extension to. |
| 363 bool added = false; | 379 bool added = false; |
| 364 FetchMap::iterator existing_iter = fetches_preparing_.find( | 380 FetchMap::iterator existing_iter = fetches_preparing_.find( |
| 365 std::make_pair(request_id, update_urls[i])); | 381 std::make_pair(request_id, update_urls[i])); |
| 366 if (existing_iter != fetches_preparing_.end() && | 382 if (existing_iter != fetches_preparing_.end() && |
| 367 !existing_iter->second.empty()) { | 383 !existing_iter->second.empty()) { |
| 368 // Try to add to the ManifestFetchData at the end of the list. | 384 // Try to add to the ManifestFetchData at the end of the list. |
| 369 ManifestFetchData* existing_fetch = existing_iter->second.back().get(); | 385 ManifestFetchData* existing_fetch = existing_iter->second.back().get(); |
| 370 if (existing_fetch->AddExtension(id, version.GetString(), | 386 if (existing_fetch->AddExtension(id, version.GetString(), |
| 371 optional_ping_data, update_url_data, | 387 optional_ping_data, update_url_data, |
| 372 install_source)) { | 388 install_source, |
| 389 force_update)) { |
| 373 added = true; | 390 added = true; |
| 374 } | 391 } |
| 375 } | 392 } |
| 376 if (!added) { | 393 if (!added) { |
| 377 // Otherwise add a new element to the list, if the list doesn't exist or | 394 // Otherwise add a new element to the list, if the list doesn't exist or |
| 378 // if its last element is already full. | 395 // if its last element is already full. |
| 379 linked_ptr<ManifestFetchData> fetch( | 396 linked_ptr<ManifestFetchData> fetch( |
| 380 new ManifestFetchData(update_urls[i], request_id)); | 397 new ManifestFetchData(update_urls[i], request_id)); |
| 381 fetches_preparing_[std::make_pair(request_id, update_urls[i])]. | 398 fetches_preparing_[std::make_pair(request_id, update_urls[i])]. |
| 382 push_back(fetch); | 399 push_back(fetch); |
| 383 added = fetch->AddExtension(id, version.GetString(), | 400 added = fetch->AddExtension(id, version.GetString(), |
| 384 optional_ping_data, | 401 optional_ping_data, |
| 385 update_url_data, | 402 update_url_data, |
| 386 install_source); | 403 install_source, |
| 404 force_update); |
| 387 DCHECK(added); | 405 DCHECK(added); |
| 388 } | 406 } |
| 389 } | 407 } |
| 390 | 408 |
| 391 return true; | 409 return true; |
| 392 } | 410 } |
| 393 | 411 |
| 394 void ExtensionDownloader::ReportStats() const { | 412 void ExtensionDownloader::ReportStats() const { |
| 395 UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateCheckExtension", | 413 UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateCheckExtension", |
| 396 url_stats_.extension_count); | 414 url_stats_.extension_count); |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 632 // version is the same or older than what's already installed, | 650 // version is the same or older than what's already installed, |
| 633 // we don't want it. | 651 // we don't want it. |
| 634 std::string version; | 652 std::string version; |
| 635 if (!delegate_->GetExtensionExistingVersion(id, &version)) { | 653 if (!delegate_->GetExtensionExistingVersion(id, &version)) { |
| 636 VLOG(2) << id << " is not installed"; | 654 VLOG(2) << id << " is not installed"; |
| 637 continue; | 655 continue; |
| 638 } | 656 } |
| 639 | 657 |
| 640 VLOG(2) << id << " is at '" << version << "'"; | 658 VLOG(2) << id << " is at '" << version << "'"; |
| 641 | 659 |
| 642 Version existing_version(version); | 660 // We should skip the version check if update was forced. |
| 643 Version update_version(update->version); | 661 if (!fetch_data.DidForceUpdate(id)) { |
| 644 | 662 Version existing_version(version); |
| 645 if (!update_version.IsValid() || | 663 Version update_version(update->version); |
| 646 update_version.CompareTo(existing_version) <= 0) { | 664 if (!update_version.IsValid() || |
| 647 continue; | 665 update_version.CompareTo(existing_version) <= 0) { |
| 666 continue; |
| 667 } |
| 648 } | 668 } |
| 649 } | 669 } |
| 650 | 670 |
| 651 // If the update specifies a browser minimum version, do we qualify? | 671 // If the update specifies a browser minimum version, do we qualify? |
| 652 if (update->browser_min_version.length() > 0) { | 672 if (update->browser_min_version.length() > 0) { |
| 653 // First determine the browser version if we haven't already. | 673 // First determine the browser version if we haven't already. |
| 654 if (!browser_version.IsValid()) { | 674 if (!browser_version.IsValid()) { |
| 655 chrome::VersionInfo version_info; | 675 chrome::VersionInfo version_info; |
| 656 if (version_info.is_valid()) | 676 if (version_info.is_valid()) |
| 657 browser_version = Version(version_info.Version()); | 677 browser_version = Version(version_info.Version()); |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 922 | 942 |
| 923 void ExtensionDownloader::OnGetTokenFailure( | 943 void ExtensionDownloader::OnGetTokenFailure( |
| 924 const OAuth2TokenService::Request* request, | 944 const OAuth2TokenService::Request* request, |
| 925 const GoogleServiceAuthError& error) { | 945 const GoogleServiceAuthError& error) { |
| 926 // If we fail to get an access token, kick the pending fetch and let it fall | 946 // If we fail to get an access token, kick the pending fetch and let it fall |
| 927 // back on cookies. | 947 // back on cookies. |
| 928 extension_fetcher_->Start(); | 948 extension_fetcher_->Start(); |
| 929 } | 949 } |
| 930 | 950 |
| 931 } // namespace extensions | 951 } // namespace extensions |
| OLD | NEW |