| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 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/component_updater/component_updater_service.h" | 5 #include "chrome/browser/component_updater/component_updater_service.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <set> | 8 #include <set> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 293 // alive, this simplifies the management of the work that could be in | 293 // alive, this simplifies the management of the work that could be in |
| 294 // flight in other threads. | 294 // flight in other threads. |
| 295 Stop(); | 295 Stop(); |
| 296 STLDeleteElements(&work_items_); | 296 STLDeleteElements(&work_items_); |
| 297 } | 297 } |
| 298 | 298 |
| 299 ComponentUpdateService::Status CrxUpdateService::Start() { | 299 ComponentUpdateService::Status CrxUpdateService::Start() { |
| 300 // Note that RegisterComponent will call Start() when the first | 300 // Note that RegisterComponent will call Start() when the first |
| 301 // component is registered, so it can be called twice. This way | 301 // component is registered, so it can be called twice. This way |
| 302 // we avoid scheduling the timer if there is no work to do. | 302 // we avoid scheduling the timer if there is no work to do. |
| 303 VLOG(1) << "CrxUpdateService starting up"; |
| 303 running_ = true; | 304 running_ = true; |
| 304 if (work_items_.empty()) | 305 if (work_items_.empty()) |
| 305 return kOk; | 306 return kOk; |
| 306 | 307 |
| 307 NotifyComponentObservers(ComponentObserver::COMPONENT_UPDATER_STARTED, 0); | 308 NotifyComponentObservers(ComponentObserver::COMPONENT_UPDATER_STARTED, 0); |
| 308 | 309 |
| 310 VLOG(1) << "First update attempt will take place in " |
| 311 << config_->InitialDelay() << " seconds"; |
| 309 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(config_->InitialDelay()), | 312 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(config_->InitialDelay()), |
| 310 this, &CrxUpdateService::ProcessPendingItems); | 313 this, &CrxUpdateService::ProcessPendingItems); |
| 311 return kOk; | 314 return kOk; |
| 312 } | 315 } |
| 313 | 316 |
| 314 // Stop the main check + update loop. In flight operations will be | 317 // Stop the main check + update loop. In flight operations will be |
| 315 // completed. | 318 // completed. |
| 316 ComponentUpdateService::Status CrxUpdateService::Stop() { | 319 ComponentUpdateService::Status CrxUpdateService::Stop() { |
| 320 VLOG(1) << "CrxUpdateService stopping"; |
| 317 running_ = false; | 321 running_ = false; |
| 318 timer_.Stop(); | 322 timer_.Stop(); |
| 319 return kOk; | 323 return kOk; |
| 320 } | 324 } |
| 321 | 325 |
| 322 bool CrxUpdateService::HasOnDemandItems() const { | 326 bool CrxUpdateService::HasOnDemandItems() const { |
| 323 class Helper { | 327 class Helper { |
| 324 public: | 328 public: |
| 325 static bool IsOnDemand(CrxUpdateItem* item) { | 329 static bool IsOnDemand(CrxUpdateItem* item) { |
| 326 return item->on_demand; | 330 return item->on_demand; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 369 } | 373 } |
| 370 | 374 |
| 371 if (step_delay != kStepDelayShort) { | 375 if (step_delay != kStepDelayShort) { |
| 372 NotifyComponentObservers(ComponentObserver::COMPONENT_UPDATER_SLEEPING, 0); | 376 NotifyComponentObservers(ComponentObserver::COMPONENT_UPDATER_SLEEPING, 0); |
| 373 | 377 |
| 374 // Zero is only used for unit tests. | 378 // Zero is only used for unit tests. |
| 375 if (0 == delay_seconds) | 379 if (0 == delay_seconds) |
| 376 return; | 380 return; |
| 377 } | 381 } |
| 378 | 382 |
| 383 VLOG(1) << "Scheduling next run to occur in " << delay_seconds << " seconds"; |
| 379 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(delay_seconds), | 384 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(delay_seconds), |
| 380 this, &CrxUpdateService::ProcessPendingItems); | 385 this, &CrxUpdateService::ProcessPendingItems); |
| 381 } | 386 } |
| 382 | 387 |
| 383 // Given a extension-like component id, find the associated component. | 388 // Given a extension-like component id, find the associated component. |
| 384 CrxUpdateItem* CrxUpdateService::FindUpdateItemById(const std::string& id) { | 389 CrxUpdateItem* CrxUpdateService::FindUpdateItemById(const std::string& id) { |
| 385 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 390 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 386 CrxUpdateItem::FindById finder(id); | 391 CrxUpdateItem::FindById finder(id); |
| 387 UpdateItems::iterator it = std::find_if(work_items_.begin(), | 392 UpdateItems::iterator it = std::find_if(work_items_.begin(), |
| 388 work_items_.end(), | 393 work_items_.end(), |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 603 CrxUpdateItem* item = work_items_[i]; | 608 CrxUpdateItem* item = work_items_[i]; |
| 604 DCHECK(item->status == CrxUpdateItem::kNew || | 609 DCHECK(item->status == CrxUpdateItem::kNew || |
| 605 item->status == CrxUpdateItem::kNoUpdate || | 610 item->status == CrxUpdateItem::kNoUpdate || |
| 606 item->status == CrxUpdateItem::kUpToDate || | 611 item->status == CrxUpdateItem::kUpToDate || |
| 607 item->status == CrxUpdateItem::kUpdated); | 612 item->status == CrxUpdateItem::kUpdated); |
| 608 | 613 |
| 609 const base::TimeDelta time_since_last_checked(now - item->last_check); | 614 const base::TimeDelta time_since_last_checked(now - item->last_check); |
| 610 | 615 |
| 611 if (!item->on_demand && | 616 if (!item->on_demand && |
| 612 time_since_last_checked < minimum_recheck_wait_time) { | 617 time_since_last_checked < minimum_recheck_wait_time) { |
| 618 VLOG(1) << "Skipping check for component update: id=" << item->id |
| 619 << ", time_since_last_checked=" << time_since_last_checked.InSeconds() |
| 620 << " seconds: too soon to check for an update"; |
| 613 continue; | 621 continue; |
| 614 } | 622 } |
| 615 | 623 |
| 624 VLOG(1) << "Scheduling update check for component id=" << item->id |
| 625 << ", time_since_last_checked=" << time_since_last_checked.InSeconds() |
| 626 << " seconds"; |
| 627 |
| 616 ChangeItemState(item, CrxUpdateItem::kChecking); | 628 ChangeItemState(item, CrxUpdateItem::kChecking); |
| 617 | 629 |
| 618 item->last_check = now; | 630 item->last_check = now; |
| 619 item->crx_urls.clear(); | 631 item->crx_urls.clear(); |
| 620 item->crx_diffurls.clear(); | 632 item->crx_diffurls.clear(); |
| 621 item->previous_version = item->component.version; | 633 item->previous_version = item->component.version; |
| 622 item->next_version = Version(); | 634 item->next_version = Version(); |
| 623 item->previous_fp = item->component.fingerprint; | 635 item->previous_fp = item->component.fingerprint; |
| 624 item->next_fp.clear(); | 636 item->next_fp.clear(); |
| 625 item->diff_update_failed = false; | 637 item->diff_update_failed = false; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 694 | 706 |
| 695 // Handles a valid Omaha update check response by matching the results with | 707 // Handles a valid Omaha update check response by matching the results with |
| 696 // the registered components which were checked for updates. | 708 // the registered components which were checked for updates. |
| 697 // If updates are found, prepare the components for the actual version upgrade. | 709 // If updates are found, prepare the components for the actual version upgrade. |
| 698 // One of these components will be drafted for the upgrade next time | 710 // One of these components will be drafted for the upgrade next time |
| 699 // ProcessPendingItems is called. | 711 // ProcessPendingItems is called. |
| 700 void CrxUpdateService::OnUpdateCheckSucceeded( | 712 void CrxUpdateService::OnUpdateCheckSucceeded( |
| 701 const UpdateResponse::Results& results) { | 713 const UpdateResponse::Results& results) { |
| 702 size_t num_updates_pending = 0; | 714 size_t num_updates_pending = 0; |
| 703 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 715 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 716 VLOG(1) << "Update check succeeded."; |
| 704 std::vector<UpdateResponse::Result>::const_iterator it; | 717 std::vector<UpdateResponse::Result>::const_iterator it; |
| 705 for (it = results.list.begin(); it != results.list.end(); ++it) { | 718 for (it = results.list.begin(); it != results.list.end(); ++it) { |
| 706 CrxUpdateItem* crx = FindUpdateItemById(it->extension_id); | 719 CrxUpdateItem* crx = FindUpdateItemById(it->extension_id); |
| 707 if (!crx) | 720 if (!crx) |
| 708 continue; | 721 continue; |
| 709 | 722 |
| 710 if (crx->status != CrxUpdateItem::kChecking) { | 723 if (crx->status != CrxUpdateItem::kChecking) { |
| 711 NOTREACHED(); | 724 NOTREACHED(); |
| 712 continue; // Not updating this component now. | 725 continue; // Not updating this component now. |
| 713 } | 726 } |
| 714 | 727 |
| 715 if (it->manifest.version.empty()) { | 728 if (it->manifest.version.empty()) { |
| 716 // No version means no update available. | 729 // No version means no update available. |
| 717 ChangeItemState(crx, CrxUpdateItem::kNoUpdate); | 730 ChangeItemState(crx, CrxUpdateItem::kNoUpdate); |
| 731 VLOG(1) << "No update available for component: " << crx->id; |
| 718 continue; | 732 continue; |
| 719 } | 733 } |
| 720 | 734 |
| 721 if (!IsVersionNewer(crx->component.version, it->manifest.version)) { | 735 if (!IsVersionNewer(crx->component.version, it->manifest.version)) { |
| 722 // The component is up to date. | 736 // The component is up to date. |
| 723 ChangeItemState(crx, CrxUpdateItem::kUpToDate); | 737 ChangeItemState(crx, CrxUpdateItem::kUpToDate); |
| 738 VLOG(1) << "Component already up-to-date: " << crx->id; |
| 724 continue; | 739 continue; |
| 725 } | 740 } |
| 726 | 741 |
| 727 if (!it->manifest.browser_min_version.empty()) { | 742 if (!it->manifest.browser_min_version.empty()) { |
| 728 if (IsVersionNewer(chrome_version_, it->manifest.browser_min_version)) { | 743 if (IsVersionNewer(chrome_version_, it->manifest.browser_min_version)) { |
| 729 // The component is not compatible with this Chrome version. | 744 // The component is not compatible with this Chrome version. |
| 745 VLOG(1) << "Ignoring incompatible component: " << crx->id; |
| 730 ChangeItemState(crx, CrxUpdateItem::kNoUpdate); | 746 ChangeItemState(crx, CrxUpdateItem::kNoUpdate); |
| 731 continue; | 747 continue; |
| 732 } | 748 } |
| 733 } | 749 } |
| 734 | 750 |
| 735 if (it->manifest.packages.size() != 1) { | 751 if (it->manifest.packages.size() != 1) { |
| 736 // Assume one and only one package per component. | 752 // Assume one and only one package per component. |
| 753 VLOG(1) << "Ignoring multiple packages for component: " << crx->id; |
| 737 ChangeItemState(crx, CrxUpdateItem::kNoUpdate); | 754 ChangeItemState(crx, CrxUpdateItem::kNoUpdate); |
| 738 continue; | 755 continue; |
| 739 } | 756 } |
| 740 | 757 |
| 741 // Parse the members of the result and queue an upgrade for this component. | 758 // Parse the members of the result and queue an upgrade for this component. |
| 742 crx->next_version = Version(it->manifest.version); | 759 crx->next_version = Version(it->manifest.version); |
| 743 | 760 |
| 761 VLOG(1) << "Update found for component: " << crx->id; |
| 762 |
| 744 typedef UpdateResponse::Result::Manifest::Package Package; | 763 typedef UpdateResponse::Result::Manifest::Package Package; |
| 745 const Package& package(it->manifest.packages[0]); | 764 const Package& package(it->manifest.packages[0]); |
| 746 crx->next_fp = package.fingerprint; | 765 crx->next_fp = package.fingerprint; |
| 747 | 766 |
| 748 // Resolve the urls by combining the base urls with the package names. | 767 // Resolve the urls by combining the base urls with the package names. |
| 749 for (size_t i = 0; i != it->crx_urls.size(); ++i) { | 768 for (size_t i = 0; i != it->crx_urls.size(); ++i) { |
| 750 const GURL url(it->crx_urls[i].Resolve(package.name)); | 769 const GURL url(it->crx_urls[i].Resolve(package.name)); |
| 751 if (url.is_valid()) | 770 if (url.is_valid()) |
| 752 crx->crx_urls.push_back(url); | 771 crx->crx_urls.push_back(url); |
| 753 } | 772 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 771 } | 790 } |
| 772 | 791 |
| 773 // TODO: record UMA stats. | 792 // TODO: record UMA stats. |
| 774 void CrxUpdateService::OnUpdateCheckFailed(int error, | 793 void CrxUpdateService::OnUpdateCheckFailed(int error, |
| 775 const std::string& error_message) { | 794 const std::string& error_message) { |
| 776 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 795 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 777 DCHECK(error); | 796 DCHECK(error); |
| 778 size_t count = ChangeItemStatus(CrxUpdateItem::kChecking, | 797 size_t count = ChangeItemStatus(CrxUpdateItem::kChecking, |
| 779 CrxUpdateItem::kNoUpdate); | 798 CrxUpdateItem::kNoUpdate); |
| 780 DCHECK_GT(count, 0ul); | 799 DCHECK_GT(count, 0ul); |
| 800 VLOG(1) << "Update check failed."; |
| 781 ScheduleNextRun(kStepDelayLong); | 801 ScheduleNextRun(kStepDelayLong); |
| 782 } | 802 } |
| 783 | 803 |
| 784 // Called when the CRX package has been downloaded to a temporary location. | 804 // Called when the CRX package has been downloaded to a temporary location. |
| 785 // Here we fire the notifications and schedule the component-specific installer | 805 // Here we fire the notifications and schedule the component-specific installer |
| 786 // to be called in the file thread. | 806 // to be called in the file thread. |
| 787 void CrxUpdateService::DownloadComplete( | 807 void CrxUpdateService::DownloadComplete( |
| 788 scoped_ptr<CRXContext> crx_context, | 808 scoped_ptr<CRXContext> crx_context, |
| 789 const CrxDownloader::Result& download_result) { | 809 const CrxDownloader::Result& download_result) { |
| 790 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 810 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1009 // The component update factory. Using the component updater as a singleton | 1029 // The component update factory. Using the component updater as a singleton |
| 1010 // is the job of the browser process. | 1030 // is the job of the browser process. |
| 1011 ComponentUpdateService* ComponentUpdateServiceFactory( | 1031 ComponentUpdateService* ComponentUpdateServiceFactory( |
| 1012 ComponentUpdateService::Configurator* config) { | 1032 ComponentUpdateService::Configurator* config) { |
| 1013 DCHECK(config); | 1033 DCHECK(config); |
| 1014 return new CrxUpdateService(config); | 1034 return new CrxUpdateService(config); |
| 1015 } | 1035 } |
| 1016 | 1036 |
| 1017 } // namespace component_updater | 1037 } // namespace component_updater |
| 1018 | 1038 |
| OLD | NEW |