Chromium Code Reviews| 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 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 142 // is called periodically to do the upgrades/installs or the update checks. | 142 // is called periodically to do the upgrades/installs or the update checks. |
| 143 // An important consideration here is to be as "low impact" as we can to the | 143 // An important consideration here is to be as "low impact" as we can to the |
| 144 // rest of the browser, so even if we have many components registered and | 144 // rest of the browser, so even if we have many components registered and |
| 145 // eligible for update, we only do one thing at a time with pauses in between | 145 // eligible for update, we only do one thing at a time with pauses in between |
| 146 // the tasks. Also when we do network requests there is only one |url_fetcher_| | 146 // the tasks. Also when we do network requests there is only one |url_fetcher_| |
| 147 // in flight at a time. | 147 // in flight at a time. |
| 148 // There are no locks in this code, the main structure |work_items_| is mutated | 148 // There are no locks in this code, the main structure |work_items_| is mutated |
| 149 // only from the UI thread. The unpack and installation is done in a blocking | 149 // only from the UI thread. The unpack and installation is done in a blocking |
| 150 // pool thread. The network requests are done in the IO thread or in the file | 150 // pool thread. The network requests are done in the IO thread or in the file |
| 151 // thread. | 151 // thread. |
| 152 class CrxUpdateService : public ComponentUpdateService { | 152 class CrxUpdateService : public ComponentUpdateService, public OnDemandUpdater { |
| 153 public: | 153 public: |
| 154 explicit CrxUpdateService(ComponentUpdateService::Configurator* config); | 154 explicit CrxUpdateService(ComponentUpdateService::Configurator* config); |
| 155 virtual ~CrxUpdateService(); | 155 virtual ~CrxUpdateService(); |
| 156 | 156 |
| 157 // Overrides for ComponentUpdateService. | 157 // Overrides for ComponentUpdateService. |
| 158 virtual void AddObserver(Observer* observer) OVERRIDE; | 158 virtual void AddObserver(Observer* observer) OVERRIDE; |
| 159 virtual void RemoveObserver(Observer* observer) OVERRIDE; | 159 virtual void RemoveObserver(Observer* observer) OVERRIDE; |
| 160 virtual Status Start() OVERRIDE; | 160 virtual Status Start() OVERRIDE; |
| 161 virtual Status Stop() OVERRIDE; | 161 virtual Status Stop() OVERRIDE; |
| 162 virtual Status RegisterComponent(const CrxComponent& component) OVERRIDE; | 162 virtual Status RegisterComponent(const CrxComponent& component) OVERRIDE; |
| 163 virtual Status OnDemandUpdate(const std::string& component_id) OVERRIDE; | |
| 164 virtual void GetComponents( | 163 virtual void GetComponents( |
| 165 std::vector<CrxComponentInfo>* components) OVERRIDE; | 164 std::vector<CrxComponentInfo>* components) OVERRIDE; |
| 165 virtual OnDemandUpdater& GetOnDemandUpdater() OVERRIDE; | |
| 166 | |
| 167 // Overrides for OnDemandUpdater. | |
| 166 virtual content::ResourceThrottle* GetOnDemandResourceThrottle( | 168 virtual content::ResourceThrottle* GetOnDemandResourceThrottle( |
| 167 net::URLRequest* request, | 169 net::URLRequest* request, |
| 168 const std::string& crx_id) OVERRIDE; | 170 const std::string& crx_id) OVERRIDE; |
| 171 virtual Status OnDemandUpdate(const std::string& component_id) OVERRIDE; | |
|
waffles
2014/05/20 17:15:19
I don't understand why this should be public, thou
Sorin Jianu
2014/05/20 17:39:07
I can make all these members private, since they a
| |
| 169 | 172 |
| 170 // Context for a crx download url request. | 173 // Context for a crx download url request. |
| 171 struct CRXContext { | 174 struct CRXContext { |
| 172 ComponentInstaller* installer; | 175 ComponentInstaller* installer; |
| 173 std::vector<uint8> pk_hash; | 176 std::vector<uint8> pk_hash; |
| 174 std::string id; | 177 std::string id; |
| 175 std::string fingerprint; | 178 std::string fingerprint; |
| 176 CRXContext() : installer(NULL) {} | 179 CRXContext() : installer(NULL) {} |
| 177 }; | 180 }; |
| 178 | 181 |
| (...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 489 | 492 |
| 490 work_items_.push_back(uit); | 493 work_items_.push_back(uit); |
| 491 // If this is the first component registered we call Start to | 494 // If this is the first component registered we call Start to |
| 492 // schedule the first timer. | 495 // schedule the first timer. |
| 493 if (running_ && (work_items_.size() == 1)) | 496 if (running_ && (work_items_.size() == 1)) |
| 494 Start(); | 497 Start(); |
| 495 | 498 |
| 496 return kOk; | 499 return kOk; |
| 497 } | 500 } |
| 498 | 501 |
| 499 // Start the process of checking for an update, for a particular component | |
| 500 // that was previously registered. | |
| 501 // |component_id| is a value returned from GetCrxComponentID(). | |
| 502 ComponentUpdateService::Status CrxUpdateService::OnDemandUpdate( | |
| 503 const std::string& component_id) { | |
| 504 return OnDemandUpdateInternal(FindUpdateItemById(component_id)); | |
| 505 } | |
| 506 | |
| 507 ComponentUpdateService::Status CrxUpdateService::OnDemandUpdateInternal( | |
| 508 CrxUpdateItem* uit) { | |
| 509 if (!uit) | |
| 510 return kError; | |
| 511 | |
| 512 // Check if the request is too soon. | |
| 513 base::TimeDelta delta = base::Time::Now() - uit->last_check; | |
| 514 if (delta < base::TimeDelta::FromSeconds(config_->OnDemandDelay())) | |
| 515 return kError; | |
| 516 | |
| 517 switch (uit->status) { | |
| 518 // If the item is already in the process of being updated, there is | |
| 519 // no point in this call, so return kInProgress. | |
| 520 case CrxUpdateItem::kChecking: | |
| 521 case CrxUpdateItem::kCanUpdate: | |
| 522 case CrxUpdateItem::kDownloadingDiff: | |
| 523 case CrxUpdateItem::kDownloading: | |
| 524 case CrxUpdateItem::kUpdatingDiff: | |
| 525 case CrxUpdateItem::kUpdating: | |
| 526 return kInProgress; | |
| 527 // Otherwise the item was already checked a while back (or it is new), | |
| 528 // set its status to kNew to give it a slightly higher priority. | |
| 529 case CrxUpdateItem::kNew: | |
| 530 case CrxUpdateItem::kUpdated: | |
| 531 case CrxUpdateItem::kUpToDate: | |
| 532 case CrxUpdateItem::kNoUpdate: | |
| 533 ChangeItemState(uit, CrxUpdateItem::kNew); | |
| 534 uit->on_demand = true; | |
| 535 break; | |
| 536 case CrxUpdateItem::kLastStatus: | |
| 537 NOTREACHED() << uit->status; | |
| 538 } | |
| 539 | |
| 540 // In case the current delay is long, set the timer to a shorter value | |
| 541 // to get the ball rolling. | |
| 542 if (timer_.IsRunning()) { | |
| 543 timer_.Stop(); | |
| 544 timer_.Start(FROM_HERE, | |
| 545 base::TimeDelta::FromSeconds(config_->StepDelay()), | |
| 546 this, | |
| 547 &CrxUpdateService::ProcessPendingItems); | |
| 548 } | |
| 549 | |
| 550 return kOk; | |
| 551 } | |
| 552 | |
| 553 void CrxUpdateService::GetComponents( | 502 void CrxUpdateService::GetComponents( |
| 554 std::vector<CrxComponentInfo>* components) { | 503 std::vector<CrxComponentInfo>* components) { |
| 555 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 504 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 556 for (UpdateItems::const_iterator it = work_items_.begin(); | 505 for (UpdateItems::const_iterator it = work_items_.begin(); |
| 557 it != work_items_.end(); | 506 it != work_items_.end(); |
| 558 ++it) { | 507 ++it) { |
| 559 const CrxUpdateItem* item = *it; | 508 const CrxUpdateItem* item = *it; |
| 560 CrxComponentInfo info; | 509 CrxComponentInfo info; |
| 561 info.id = GetCrxComponentID(item->component); | 510 info.id = GetCrxComponentID(item->component); |
| 562 info.version = item->component.version.GetString(); | 511 info.version = item->component.version.GetString(); |
| 563 info.name = item->component.name; | 512 info.name = item->component.name; |
| 564 components->push_back(info); | 513 components->push_back(info); |
| 565 } | 514 } |
| 566 } | 515 } |
| 567 | 516 |
| 517 OnDemandUpdater& CrxUpdateService::GetOnDemandUpdater() { | |
| 518 return *this; | |
| 519 } | |
| 520 | |
| 568 // This is the main loop of the component updater. It updates one component | 521 // This is the main loop of the component updater. It updates one component |
| 569 // at a time if updates are available. Otherwise, it does an update check or | 522 // at a time if updates are available. Otherwise, it does an update check or |
| 570 // takes a long sleep until the loop runs again. | 523 // takes a long sleep until the loop runs again. |
| 571 void CrxUpdateService::ProcessPendingItems() { | 524 void CrxUpdateService::ProcessPendingItems() { |
| 572 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 525 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 573 | 526 |
| 574 CrxUpdateItem* ready_upgrade = FindReadyComponent(); | 527 CrxUpdateItem* ready_upgrade = FindReadyComponent(); |
| 575 if (ready_upgrade) { | 528 if (ready_upgrade) { |
| 576 UpdateComponent(ready_upgrade); | 529 UpdateComponent(ready_upgrade); |
| 577 return; | 530 return; |
| (...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1003 // Check if we can on-demand update, else unblock the request anyway. | 956 // Check if we can on-demand update, else unblock the request anyway. |
| 1004 CrxUpdateItem* item = FindUpdateItemById(crx_id); | 957 CrxUpdateItem* item = FindUpdateItemById(crx_id); |
| 1005 Status status = OnDemandUpdateInternal(item); | 958 Status status = OnDemandUpdateInternal(item); |
| 1006 if (status == kOk || status == kInProgress) { | 959 if (status == kOk || status == kInProgress) { |
| 1007 item->throttles.push_back(rt); | 960 item->throttles.push_back(rt); |
| 1008 return; | 961 return; |
| 1009 } | 962 } |
| 1010 UnblockResourceThrottle(rt); | 963 UnblockResourceThrottle(rt); |
| 1011 } | 964 } |
| 1012 | 965 |
| 966 ComponentUpdateService::Status CrxUpdateService::OnDemandUpdate( | |
| 967 const std::string& component_id) { | |
| 968 return OnDemandUpdateInternal(FindUpdateItemById(component_id)); | |
| 969 } | |
| 970 | |
| 971 ComponentUpdateService::Status CrxUpdateService::OnDemandUpdateInternal( | |
| 972 CrxUpdateItem* uit) { | |
| 973 if (!uit) | |
| 974 return kError; | |
| 975 | |
| 976 // Check if the request is too soon. | |
| 977 base::TimeDelta delta = base::Time::Now() - uit->last_check; | |
| 978 if (delta < base::TimeDelta::FromSeconds(config_->OnDemandDelay())) | |
| 979 return kError; | |
| 980 | |
| 981 switch (uit->status) { | |
| 982 // If the item is already in the process of being updated, there is | |
| 983 // no point in this call, so return kInProgress. | |
| 984 case CrxUpdateItem::kChecking: | |
| 985 case CrxUpdateItem::kCanUpdate: | |
| 986 case CrxUpdateItem::kDownloadingDiff: | |
| 987 case CrxUpdateItem::kDownloading: | |
| 988 case CrxUpdateItem::kUpdatingDiff: | |
| 989 case CrxUpdateItem::kUpdating: | |
| 990 return kInProgress; | |
| 991 // Otherwise the item was already checked a while back (or it is new), | |
| 992 // set its status to kNew to give it a slightly higher priority. | |
| 993 case CrxUpdateItem::kNew: | |
| 994 case CrxUpdateItem::kUpdated: | |
| 995 case CrxUpdateItem::kUpToDate: | |
| 996 case CrxUpdateItem::kNoUpdate: | |
| 997 ChangeItemState(uit, CrxUpdateItem::kNew); | |
| 998 uit->on_demand = true; | |
| 999 break; | |
| 1000 case CrxUpdateItem::kLastStatus: | |
| 1001 NOTREACHED() << uit->status; | |
| 1002 } | |
| 1003 | |
| 1004 // In case the current delay is long, set the timer to a shorter value | |
| 1005 // to get the ball rolling. | |
| 1006 if (timer_.IsRunning()) { | |
| 1007 timer_.Stop(); | |
| 1008 timer_.Start(FROM_HERE, | |
| 1009 base::TimeDelta::FromSeconds(config_->StepDelay()), | |
| 1010 this, | |
| 1011 &CrxUpdateService::ProcessPendingItems); | |
| 1012 } | |
| 1013 | |
| 1014 return kOk; | |
| 1015 } | |
| 1016 | |
| 1013 /////////////////////////////////////////////////////////////////////////////// | 1017 /////////////////////////////////////////////////////////////////////////////// |
| 1014 | 1018 |
| 1015 CUResourceThrottle::CUResourceThrottle(const net::URLRequest* request) | 1019 CUResourceThrottle::CUResourceThrottle(const net::URLRequest* request) |
| 1016 : state_(NEW) { | 1020 : state_(NEW) { |
| 1017 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 1021 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 1018 } | 1022 } |
| 1019 | 1023 |
| 1020 CUResourceThrottle::~CUResourceThrottle() { | 1024 CUResourceThrottle::~CUResourceThrottle() { |
| 1021 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 1025 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 1022 } | 1026 } |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 1047 | 1051 |
| 1048 // The component update factory. Using the component updater as a singleton | 1052 // The component update factory. Using the component updater as a singleton |
| 1049 // is the job of the browser process. | 1053 // is the job of the browser process. |
| 1050 ComponentUpdateService* ComponentUpdateServiceFactory( | 1054 ComponentUpdateService* ComponentUpdateServiceFactory( |
| 1051 ComponentUpdateService::Configurator* config) { | 1055 ComponentUpdateService::Configurator* config) { |
| 1052 DCHECK(config); | 1056 DCHECK(config); |
| 1053 return new CrxUpdateService(config); | 1057 return new CrxUpdateService(config); |
| 1054 } | 1058 } |
| 1055 | 1059 |
| 1056 } // namespace component_updater | 1060 } // namespace component_updater |
| OLD | NEW |