| 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_updater.h" | 5 #include "chrome/browser/extensions/updater/extension_updater.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <set> | 10 #include <set> |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 // Wait at least 5 minutes after browser startup before we do any checks. If you | 53 // Wait at least 5 minutes after browser startup before we do any checks. If you |
| 54 // change this value, make sure to update comments where it is used. | 54 // change this value, make sure to update comments where it is used. |
| 55 const int kStartupWaitSeconds = 60 * 5; | 55 const int kStartupWaitSeconds = 60 * 5; |
| 56 | 56 |
| 57 // For sanity checking on update frequency - enforced in release mode only. | 57 // For sanity checking on update frequency - enforced in release mode only. |
| 58 #if defined(NDEBUG) | 58 #if defined(NDEBUG) |
| 59 const int kMinUpdateFrequencySeconds = 30; | 59 const int kMinUpdateFrequencySeconds = 30; |
| 60 #endif | 60 #endif |
| 61 const int kMaxUpdateFrequencySeconds = 60 * 60 * 24 * 7; // 7 days | 61 const int kMaxUpdateFrequencySeconds = 60 * 60 * 24 * 7; // 7 days |
| 62 | 62 |
| 63 // Require at least 5 seconds between consecutive non-succesful extension update | |
| 64 // checks. | |
| 65 const int kMinUpdateThrottleTime = 5; | |
| 66 | |
| 67 // When we've computed a days value, we want to make sure we don't send a | 63 // When we've computed a days value, we want to make sure we don't send a |
| 68 // negative value (due to the system clock being set backwards, etc.), since -1 | 64 // negative value (due to the system clock being set backwards, etc.), since -1 |
| 69 // is a special sentinel value that means "never pinged", and other negative | 65 // is a special sentinel value that means "never pinged", and other negative |
| 70 // values don't make sense. | 66 // values don't make sense. |
| 71 int SanitizeDays(int days) { | 67 int SanitizeDays(int days) { |
| 72 if (days < 0) | 68 if (days < 0) |
| 73 return 0; | 69 return 0; |
| 74 return days; | 70 return days; |
| 75 } | 71 } |
| 76 | 72 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 ExtensionUpdater::FetchedCRXFile::~FetchedCRXFile() {} | 118 ExtensionUpdater::FetchedCRXFile::~FetchedCRXFile() {} |
| 123 | 119 |
| 124 ExtensionUpdater::InProgressCheck::InProgressCheck() | 120 ExtensionUpdater::InProgressCheck::InProgressCheck() |
| 125 : install_immediately(false) {} | 121 : install_immediately(false) {} |
| 126 | 122 |
| 127 ExtensionUpdater::InProgressCheck::InProgressCheck( | 123 ExtensionUpdater::InProgressCheck::InProgressCheck( |
| 128 const InProgressCheck& other) = default; | 124 const InProgressCheck& other) = default; |
| 129 | 125 |
| 130 ExtensionUpdater::InProgressCheck::~InProgressCheck() {} | 126 ExtensionUpdater::InProgressCheck::~InProgressCheck() {} |
| 131 | 127 |
| 132 struct ExtensionUpdater::ThrottleInfo { | |
| 133 ThrottleInfo() | |
| 134 : in_progress(true), | |
| 135 throttle_delay(kMinUpdateThrottleTime), | |
| 136 check_start(Time::Now()) {} | |
| 137 | |
| 138 bool in_progress; | |
| 139 int throttle_delay; | |
| 140 Time check_start; | |
| 141 }; | |
| 142 | |
| 143 ExtensionUpdater::ExtensionUpdater( | 128 ExtensionUpdater::ExtensionUpdater( |
| 144 ExtensionServiceInterface* service, | 129 ExtensionServiceInterface* service, |
| 145 ExtensionPrefs* extension_prefs, | 130 ExtensionPrefs* extension_prefs, |
| 146 PrefService* prefs, | 131 PrefService* prefs, |
| 147 Profile* profile, | 132 Profile* profile, |
| 148 int frequency_seconds, | 133 int frequency_seconds, |
| 149 ExtensionCache* cache, | 134 ExtensionCache* cache, |
| 150 const ExtensionDownloader::Factory& downloader_factory) | 135 const ExtensionDownloader::Factory& downloader_factory) |
| 151 : alive_(false), | 136 : alive_(false), |
| 152 service_(service), | 137 service_(service), |
| 153 downloader_factory_(downloader_factory), | 138 downloader_factory_(downloader_factory), |
| 154 frequency_seconds_(frequency_seconds), | 139 frequency_seconds_(frequency_seconds), |
| 155 will_check_soon_(false), | 140 will_check_soon_(false), |
| 156 extension_prefs_(extension_prefs), | 141 extension_prefs_(extension_prefs), |
| 157 prefs_(prefs), | 142 prefs_(prefs), |
| 158 profile_(profile), | 143 profile_(profile), |
| 159 next_request_id_(0), | 144 next_request_id_(0), |
| 160 extension_registry_observer_(this), | |
| 161 crx_install_is_running_(false), | 145 crx_install_is_running_(false), |
| 162 extension_cache_(cache), | 146 extension_cache_(cache), |
| 163 weak_ptr_factory_(this) { | 147 weak_ptr_factory_(this) { |
| 164 DCHECK_GE(frequency_seconds_, 5); | 148 DCHECK_GE(frequency_seconds_, 5); |
| 165 DCHECK_LE(frequency_seconds_, kMaxUpdateFrequencySeconds); | 149 DCHECK_LE(frequency_seconds_, kMaxUpdateFrequencySeconds); |
| 166 #if defined(NDEBUG) | 150 #if defined(NDEBUG) |
| 167 // In Release mode we enforce that update checks don't happen too often. | 151 // In Release mode we enforce that update checks don't happen too often. |
| 168 frequency_seconds_ = std::max(frequency_seconds_, kMinUpdateFrequencySeconds); | 152 frequency_seconds_ = std::max(frequency_seconds_, kMinUpdateFrequencySeconds); |
| 169 #endif | 153 #endif |
| 170 frequency_seconds_ = std::min(frequency_seconds_, kMaxUpdateFrequencySeconds); | 154 frequency_seconds_ = std::min(frequency_seconds_, kMaxUpdateFrequencySeconds); |
| 171 | |
| 172 extension_registry_observer_.Add(ExtensionRegistry::Get(profile)); | |
| 173 } | 155 } |
| 174 | 156 |
| 175 ExtensionUpdater::~ExtensionUpdater() { | 157 ExtensionUpdater::~ExtensionUpdater() { |
| 176 Stop(); | 158 Stop(); |
| 177 } | 159 } |
| 178 | 160 |
| 179 void ExtensionUpdater::EnsureDownloaderCreated() { | 161 void ExtensionUpdater::EnsureDownloaderCreated() { |
| 180 if (!downloader_.get()) { | 162 if (!downloader_.get()) { |
| 181 downloader_ = downloader_factory_.Run(this); | 163 downloader_ = downloader_factory_.Run(this); |
| 182 } | 164 } |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 415 bool noChecks = request.in_progress_ids_.empty(); | 397 bool noChecks = request.in_progress_ids_.empty(); |
| 416 | 398 |
| 417 // StartAllPending() will call OnExtensionDownloadFailed or | 399 // StartAllPending() will call OnExtensionDownloadFailed or |
| 418 // OnExtensionDownloadFinished for each extension that was checked. | 400 // OnExtensionDownloadFinished for each extension that was checked. |
| 419 downloader_->StartAllPending(extension_cache_); | 401 downloader_->StartAllPending(extension_cache_); |
| 420 | 402 |
| 421 if (noChecks) | 403 if (noChecks) |
| 422 NotifyIfFinished(request_id); | 404 NotifyIfFinished(request_id); |
| 423 } | 405 } |
| 424 | 406 |
| 425 bool ExtensionUpdater::CheckExtensionSoon(const std::string& extension_id, | 407 void ExtensionUpdater::CheckExtensionSoon(const std::string& extension_id, |
| 426 const FinishedCallback& callback) { | 408 const FinishedCallback& callback) { |
| 427 bool have_throttle_info = ContainsKey(throttle_info_, extension_id); | |
| 428 ThrottleInfo& info = throttle_info_[extension_id]; | |
| 429 if (have_throttle_info) { | |
| 430 // We already had a ThrottleInfo object for this extension, check if the | |
| 431 // update check request should be allowed. | |
| 432 | |
| 433 // If another check is in progress, don't start a new check. | |
| 434 if (info.in_progress) | |
| 435 return false; | |
| 436 | |
| 437 Time now = Time::Now(); | |
| 438 Time last = info.check_start; | |
| 439 // If somehow time moved back, we don't want to infinitely keep throttling. | |
| 440 if (now < last) { | |
| 441 last = now; | |
| 442 info.check_start = now; | |
| 443 } | |
| 444 Time earliest = last + TimeDelta::FromSeconds(info.throttle_delay); | |
| 445 // If check is too soon, throttle. | |
| 446 if (now < earliest) | |
| 447 return false; | |
| 448 | |
| 449 // TODO(mek): Somehow increase time between allowing checks when checks | |
| 450 // are repeatedly throttled and don't result in updates being installed. | |
| 451 | |
| 452 // It's okay to start a check, update values. | |
| 453 info.check_start = now; | |
| 454 info.in_progress = true; | |
| 455 } | |
| 456 | |
| 457 CheckParams params; | 409 CheckParams params; |
| 458 params.ids.push_back(extension_id); | 410 params.ids.push_back(extension_id); |
| 459 params.callback = base::Bind(&ExtensionUpdater::ExtensionCheckFinished, | 411 params.callback = callback; |
| 460 weak_ptr_factory_.GetWeakPtr(), | |
| 461 extension_id, callback); | |
| 462 CheckNow(params); | 412 CheckNow(params); |
| 463 return true; | |
| 464 } | |
| 465 | |
| 466 void ExtensionUpdater::ExtensionCheckFinished( | |
| 467 const std::string& extension_id, | |
| 468 const FinishedCallback& callback) { | |
| 469 std::map<std::string, ThrottleInfo>::iterator it = | |
| 470 throttle_info_.find(extension_id); | |
| 471 if (it != throttle_info_.end()) { | |
| 472 it->second.in_progress = false; | |
| 473 } | |
| 474 callback.Run(); | |
| 475 } | 413 } |
| 476 | 414 |
| 477 void ExtensionUpdater::OnExtensionDownloadFailed( | 415 void ExtensionUpdater::OnExtensionDownloadFailed( |
| 478 const std::string& id, | 416 const std::string& id, |
| 479 Error error, | 417 Error error, |
| 480 const PingResult& ping, | 418 const PingResult& ping, |
| 481 const std::set<int>& request_ids) { | 419 const std::set<int>& request_ids) { |
| 482 DCHECK(alive_); | 420 DCHECK(alive_); |
| 483 UpdatePingData(id, ping); | 421 UpdatePingData(id, ping); |
| 484 bool install_immediately = false; | 422 bool install_immediately = false; |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 652 } | 590 } |
| 653 if (!crx_file.callback.is_null()) { | 591 if (!crx_file.callback.is_null()) { |
| 654 crx_file.callback.Run(false); | 592 crx_file.callback.Run(false); |
| 655 } | 593 } |
| 656 } | 594 } |
| 657 | 595 |
| 658 // If any files are available to update, start one. | 596 // If any files are available to update, start one. |
| 659 MaybeInstallCRXFile(); | 597 MaybeInstallCRXFile(); |
| 660 } | 598 } |
| 661 | 599 |
| 662 void ExtensionUpdater::OnExtensionWillBeInstalled( | |
| 663 content::BrowserContext* browser_context, | |
| 664 const Extension* extension, | |
| 665 bool is_update, | |
| 666 const std::string& old_name) { | |
| 667 throttle_info_.erase(extension->id()); | |
| 668 } | |
| 669 | |
| 670 void ExtensionUpdater::NotifyStarted() { | 600 void ExtensionUpdater::NotifyStarted() { |
| 671 content::NotificationService::current()->Notify( | 601 content::NotificationService::current()->Notify( |
| 672 extensions::NOTIFICATION_EXTENSION_UPDATING_STARTED, | 602 extensions::NOTIFICATION_EXTENSION_UPDATING_STARTED, |
| 673 content::Source<Profile>(profile_), | 603 content::Source<Profile>(profile_), |
| 674 content::NotificationService::NoDetails()); | 604 content::NotificationService::NoDetails()); |
| 675 } | 605 } |
| 676 | 606 |
| 677 void ExtensionUpdater::NotifyIfFinished(int request_id) { | 607 void ExtensionUpdater::NotifyIfFinished(int request_id) { |
| 678 DCHECK(ContainsKey(requests_in_progress_, request_id)); | 608 DCHECK(ContainsKey(requests_in_progress_, request_id)); |
| 679 const InProgressCheck& request = requests_in_progress_[request_id]; | 609 const InProgressCheck& request = requests_in_progress_[request_id]; |
| 680 if (request.in_progress_ids_.empty()) { | 610 if (request.in_progress_ids_.empty()) { |
| 681 VLOG(2) << "Finished update check " << request_id; | 611 VLOG(2) << "Finished update check " << request_id; |
| 682 if (!request.callback.is_null()) | 612 if (!request.callback.is_null()) |
| 683 request.callback.Run(); | 613 request.callback.Run(); |
| 684 requests_in_progress_.erase(request_id); | 614 requests_in_progress_.erase(request_id); |
| 685 } | 615 } |
| 686 } | 616 } |
| 687 | 617 |
| 688 } // namespace extensions | 618 } // namespace extensions |
| OLD | NEW |