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 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 CrxUpdateItem::~CrxUpdateItem() { | 81 CrxUpdateItem::~CrxUpdateItem() { |
82 } | 82 } |
83 | 83 |
84 CrxComponent::CrxComponent() | 84 CrxComponent::CrxComponent() |
85 : installer(NULL), allow_background_download(true) { | 85 : installer(NULL), allow_background_download(true) { |
86 } | 86 } |
87 | 87 |
88 CrxComponent::~CrxComponent() { | 88 CrxComponent::~CrxComponent() { |
89 } | 89 } |
90 | 90 |
91 CrxComponentInfo::CrxComponentInfo() { | |
92 } | |
93 | |
94 CrxComponentInfo::~CrxComponentInfo() { | |
95 } | |
96 | |
97 /////////////////////////////////////////////////////////////////////////////// | 91 /////////////////////////////////////////////////////////////////////////////// |
98 // In charge of blocking url requests until the |crx_id| component has been | 92 // In charge of blocking url requests until the |crx_id| component has been |
99 // updated. This class is touched solely from the IO thread. The UI thread | 93 // updated. This class is touched solely from the IO thread. The UI thread |
100 // can post tasks to it via weak pointers. By default the request is blocked | 94 // can post tasks to it via weak pointers. By default the request is blocked |
101 // unless the CrxUpdateService calls Unblock(). | 95 // unless the CrxUpdateService calls Unblock(). |
102 // The lifetime is controlled by Chrome's resource loader so the component | 96 // The lifetime is controlled by Chrome's resource loader so the component |
103 // updater cannot touch objects from this class except via weak pointers. | 97 // updater cannot touch objects from this class except via weak pointers. |
104 class CUResourceThrottle : public content::ResourceThrottle, | 98 class CUResourceThrottle : public content::ResourceThrottle, |
105 public base::SupportsWeakPtr<CUResourceThrottle> { | 99 public base::SupportsWeakPtr<CUResourceThrottle> { |
106 public: | 100 public: |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 public: | 147 public: |
154 explicit CrxUpdateService(ComponentUpdateService::Configurator* config); | 148 explicit CrxUpdateService(ComponentUpdateService::Configurator* config); |
155 virtual ~CrxUpdateService(); | 149 virtual ~CrxUpdateService(); |
156 | 150 |
157 // Overrides for ComponentUpdateService. | 151 // Overrides for ComponentUpdateService. |
158 virtual void AddObserver(Observer* observer) OVERRIDE; | 152 virtual void AddObserver(Observer* observer) OVERRIDE; |
159 virtual void RemoveObserver(Observer* observer) OVERRIDE; | 153 virtual void RemoveObserver(Observer* observer) OVERRIDE; |
160 virtual Status Start() OVERRIDE; | 154 virtual Status Start() OVERRIDE; |
161 virtual Status Stop() OVERRIDE; | 155 virtual Status Stop() OVERRIDE; |
162 virtual Status RegisterComponent(const CrxComponent& component) OVERRIDE; | 156 virtual Status RegisterComponent(const CrxComponent& component) OVERRIDE; |
163 virtual void GetComponents( | 157 virtual std::vector<std::string> GetComponentIDs() const OVERRIDE; |
164 std::vector<CrxComponentInfo>* components) OVERRIDE; | 158 virtual CrxUpdateItem* GetComponentDetails( |
| 159 const std::string& component_id) const OVERRIDE; |
165 virtual OnDemandUpdater& GetOnDemandUpdater() OVERRIDE; | 160 virtual OnDemandUpdater& GetOnDemandUpdater() OVERRIDE; |
166 | 161 |
167 // Overrides for OnDemandUpdater. | 162 // Overrides for OnDemandUpdater. |
168 virtual content::ResourceThrottle* GetOnDemandResourceThrottle( | 163 virtual content::ResourceThrottle* GetOnDemandResourceThrottle( |
169 net::URLRequest* request, | 164 net::URLRequest* request, |
170 const std::string& crx_id) OVERRIDE; | 165 const std::string& crx_id) OVERRIDE; |
171 virtual Status OnDemandUpdate(const std::string& component_id) OVERRIDE; | 166 virtual Status OnDemandUpdate(const std::string& component_id) OVERRIDE; |
172 | 167 |
173 // Context for a crx download url request. | 168 // Context for a crx download url request. |
174 struct CRXContext { | 169 struct CRXContext { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 int extended_error); | 226 int extended_error); |
232 | 227 |
233 void DoneInstalling(const std::string& component_id, | 228 void DoneInstalling(const std::string& component_id, |
234 ComponentUnpacker::Error error, | 229 ComponentUnpacker::Error error, |
235 int extended_error); | 230 int extended_error); |
236 | 231 |
237 void ChangeItemState(CrxUpdateItem* item, CrxUpdateItem::Status to); | 232 void ChangeItemState(CrxUpdateItem* item, CrxUpdateItem::Status to); |
238 | 233 |
239 size_t ChangeItemStatus(CrxUpdateItem::Status from, CrxUpdateItem::Status to); | 234 size_t ChangeItemStatus(CrxUpdateItem::Status from, CrxUpdateItem::Status to); |
240 | 235 |
241 CrxUpdateItem* FindUpdateItemById(const std::string& id); | 236 CrxUpdateItem* FindUpdateItemById(const std::string& id) const; |
242 | 237 |
243 void NotifyObservers(Observer::Events event, const std::string& id); | 238 void NotifyObservers(Observer::Events event, const std::string& id); |
244 | 239 |
245 bool HasOnDemandItems() const; | 240 bool HasOnDemandItems() const; |
246 | 241 |
247 void OnNewResourceThrottle(base::WeakPtr<CUResourceThrottle> rt, | 242 void OnNewResourceThrottle(base::WeakPtr<CUResourceThrottle> rt, |
248 const std::string& crx_id); | 243 const std::string& crx_id); |
249 | 244 |
| 245 Status GetServiceStatus(const CrxUpdateItem::Status status); |
| 246 |
250 scoped_ptr<ComponentUpdateService::Configurator> config_; | 247 scoped_ptr<ComponentUpdateService::Configurator> config_; |
251 | 248 |
252 scoped_ptr<UpdateChecker> update_checker_; | 249 scoped_ptr<UpdateChecker> update_checker_; |
253 | 250 |
254 scoped_ptr<PingManager> ping_manager_; | 251 scoped_ptr<PingManager> ping_manager_; |
255 | 252 |
256 scoped_refptr<ComponentUnpacker> unpacker_; | 253 scoped_refptr<ComponentUnpacker> unpacker_; |
257 | 254 |
258 scoped_ptr<CrxDownloader> crx_downloader_; | 255 scoped_ptr<CrxDownloader> crx_downloader_; |
259 | 256 |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 } | 389 } |
393 | 390 |
394 VLOG(1) << "Scheduling next run to occur in " << delay_seconds << " seconds"; | 391 VLOG(1) << "Scheduling next run to occur in " << delay_seconds << " seconds"; |
395 timer_.Start(FROM_HERE, | 392 timer_.Start(FROM_HERE, |
396 base::TimeDelta::FromSeconds(delay_seconds), | 393 base::TimeDelta::FromSeconds(delay_seconds), |
397 this, | 394 this, |
398 &CrxUpdateService::ProcessPendingItems); | 395 &CrxUpdateService::ProcessPendingItems); |
399 } | 396 } |
400 | 397 |
401 // Given a extension-like component id, find the associated component. | 398 // Given a extension-like component id, find the associated component. |
402 CrxUpdateItem* CrxUpdateService::FindUpdateItemById(const std::string& id) { | 399 CrxUpdateItem* CrxUpdateService::FindUpdateItemById( |
| 400 const std::string& id) const { |
403 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 401 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
404 CrxUpdateItem::FindById finder(id); | 402 CrxUpdateItem::FindById finder(id); |
405 UpdateItems::iterator it = | 403 UpdateItems::const_iterator it = |
406 std::find_if(work_items_.begin(), work_items_.end(), finder); | 404 std::find_if(work_items_.begin(), work_items_.end(), finder); |
407 return it != work_items_.end() ? *it : NULL; | 405 return it != work_items_.end() ? *it : NULL; |
408 } | 406 } |
409 | 407 |
410 // Changes a component's status, clearing on_demand and firing notifications as | 408 // Changes a component's status, clearing on_demand and firing notifications as |
411 // necessary. By convention, this is the only function that can change a | 409 // necessary. By convention, this is the only function that can change a |
412 // CrxUpdateItem's |status|. | 410 // CrxUpdateItem's |status|. |
413 // TODO(waffles): Do we want to add DCHECKS for valid state transitions here? | 411 // TODO(waffles): Do we want to add DCHECKS for valid state transitions here? |
414 void CrxUpdateService::ChangeItemState(CrxUpdateItem* item, | 412 void CrxUpdateService::ChangeItemState(CrxUpdateItem* item, |
415 CrxUpdateItem::Status to) { | 413 CrxUpdateItem::Status to) { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 | 490 |
493 work_items_.push_back(uit); | 491 work_items_.push_back(uit); |
494 // If this is the first component registered we call Start to | 492 // If this is the first component registered we call Start to |
495 // schedule the first timer. | 493 // schedule the first timer. |
496 if (running_ && (work_items_.size() == 1)) | 494 if (running_ && (work_items_.size() == 1)) |
497 Start(); | 495 Start(); |
498 | 496 |
499 return kOk; | 497 return kOk; |
500 } | 498 } |
501 | 499 |
502 void CrxUpdateService::GetComponents( | 500 std::vector<std::string> CrxUpdateService::GetComponentIDs() const { |
503 std::vector<CrxComponentInfo>* components) { | |
504 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 501 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 502 std::vector<std::string> component_ids; |
505 for (UpdateItems::const_iterator it = work_items_.begin(); | 503 for (UpdateItems::const_iterator it = work_items_.begin(); |
506 it != work_items_.end(); | 504 it != work_items_.end(); |
507 ++it) { | 505 ++it) { |
508 const CrxUpdateItem* item = *it; | 506 const CrxUpdateItem* item = *it; |
509 CrxComponentInfo info; | 507 component_ids.push_back(item->id); |
510 info.id = GetCrxComponentID(item->component); | |
511 info.version = item->component.version.GetString(); | |
512 info.name = item->component.name; | |
513 components->push_back(info); | |
514 } | 508 } |
| 509 return component_ids; |
| 510 } |
| 511 |
| 512 CrxUpdateItem* CrxUpdateService::GetComponentDetails( |
| 513 const std::string& component_id) const { |
| 514 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 515 return FindUpdateItemById(component_id); |
515 } | 516 } |
516 | 517 |
517 OnDemandUpdater& CrxUpdateService::GetOnDemandUpdater() { | 518 OnDemandUpdater& CrxUpdateService::GetOnDemandUpdater() { |
518 return *this; | 519 return *this; |
519 } | 520 } |
520 | 521 |
521 // This is the main loop of the component updater. It updates one component | 522 // This is the main loop of the component updater. It updates one component |
522 // at a time if updates are available. Otherwise, it does an update check or | 523 // at a time if updates are available. Otherwise, it does an update check or |
523 // takes a long sleep until the loop runs again. | 524 // takes a long sleep until the loop runs again. |
524 void CrxUpdateService::ProcessPendingItems() { | 525 void CrxUpdateService::ProcessPendingItems() { |
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
956 // Check if we can on-demand update, else unblock the request anyway. | 957 // Check if we can on-demand update, else unblock the request anyway. |
957 CrxUpdateItem* item = FindUpdateItemById(crx_id); | 958 CrxUpdateItem* item = FindUpdateItemById(crx_id); |
958 Status status = OnDemandUpdateInternal(item); | 959 Status status = OnDemandUpdateInternal(item); |
959 if (status == kOk || status == kInProgress) { | 960 if (status == kOk || status == kInProgress) { |
960 item->throttles.push_back(rt); | 961 item->throttles.push_back(rt); |
961 return; | 962 return; |
962 } | 963 } |
963 UnblockResourceThrottle(rt); | 964 UnblockResourceThrottle(rt); |
964 } | 965 } |
965 | 966 |
| 967 // Start the process of checking for an update, for a particular component |
| 968 // that was previously registered. |
| 969 // |component_id| is a value returned from GetCrxComponentID(). |
966 ComponentUpdateService::Status CrxUpdateService::OnDemandUpdate( | 970 ComponentUpdateService::Status CrxUpdateService::OnDemandUpdate( |
967 const std::string& component_id) { | 971 const std::string& component_id) { |
968 return OnDemandUpdateInternal(FindUpdateItemById(component_id)); | 972 return OnDemandUpdateInternal(FindUpdateItemById(component_id)); |
969 } | 973 } |
970 | 974 |
971 ComponentUpdateService::Status CrxUpdateService::OnDemandUpdateInternal( | 975 ComponentUpdateService::Status CrxUpdateService::OnDemandUpdateInternal( |
972 CrxUpdateItem* uit) { | 976 CrxUpdateItem* uit) { |
973 if (!uit) | 977 if (!uit) |
974 return kError; | 978 return kError; |
975 | 979 |
976 // Check if the request is too soon. | 980 // Check if the request is too soon. |
977 base::TimeDelta delta = base::Time::Now() - uit->last_check; | 981 base::TimeDelta delta = base::Time::Now() - uit->last_check; |
978 if (delta < base::TimeDelta::FromSeconds(config_->OnDemandDelay())) | 982 if (delta < base::TimeDelta::FromSeconds(config_->OnDemandDelay())) |
979 return kError; | 983 return kError; |
980 | 984 |
981 switch (uit->status) { | 985 Status service_status = GetServiceStatus(uit->status); |
982 // If the item is already in the process of being updated, there is | 986 // If the item is already in the process of being updated, there is |
983 // no point in this call, so return kInProgress. | 987 // no point in this call, so return kInProgress. |
| 988 if (service_status == kInProgress) |
| 989 return service_status; |
| 990 |
| 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 ChangeItemState(uit, CrxUpdateItem::kNew); |
| 994 uit->on_demand = true; |
| 995 |
| 996 // In case the current delay is long, set the timer to a shorter value |
| 997 // to get the ball rolling. |
| 998 if (timer_.IsRunning()) { |
| 999 timer_.Stop(); |
| 1000 timer_.Start(FROM_HERE, |
| 1001 base::TimeDelta::FromSeconds(config_->StepDelay()), |
| 1002 this, |
| 1003 &CrxUpdateService::ProcessPendingItems); |
| 1004 } |
| 1005 |
| 1006 return kOk; |
| 1007 } |
| 1008 |
| 1009 ComponentUpdateService::Status CrxUpdateService::GetServiceStatus( |
| 1010 CrxUpdateItem::Status status) { |
| 1011 switch (status) { |
984 case CrxUpdateItem::kChecking: | 1012 case CrxUpdateItem::kChecking: |
985 case CrxUpdateItem::kCanUpdate: | 1013 case CrxUpdateItem::kCanUpdate: |
986 case CrxUpdateItem::kDownloadingDiff: | 1014 case CrxUpdateItem::kDownloadingDiff: |
987 case CrxUpdateItem::kDownloading: | 1015 case CrxUpdateItem::kDownloading: |
988 case CrxUpdateItem::kUpdatingDiff: | 1016 case CrxUpdateItem::kUpdatingDiff: |
989 case CrxUpdateItem::kUpdating: | 1017 case CrxUpdateItem::kUpdating: |
990 return kInProgress; | 1018 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: | 1019 case CrxUpdateItem::kNew: |
994 case CrxUpdateItem::kUpdated: | 1020 case CrxUpdateItem::kUpdated: |
995 case CrxUpdateItem::kUpToDate: | 1021 case CrxUpdateItem::kUpToDate: |
996 case CrxUpdateItem::kNoUpdate: | 1022 case CrxUpdateItem::kNoUpdate: |
997 ChangeItemState(uit, CrxUpdateItem::kNew); | 1023 return kOk; |
998 uit->on_demand = true; | |
999 break; | |
1000 case CrxUpdateItem::kLastStatus: | 1024 case CrxUpdateItem::kLastStatus: |
1001 NOTREACHED() << uit->status; | 1025 NOTREACHED() << status; |
1002 } | 1026 } |
1003 | 1027 return kError; |
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 } | 1028 } |
1016 | 1029 |
1017 /////////////////////////////////////////////////////////////////////////////// | 1030 /////////////////////////////////////////////////////////////////////////////// |
1018 | 1031 |
1019 CUResourceThrottle::CUResourceThrottle(const net::URLRequest* request) | 1032 CUResourceThrottle::CUResourceThrottle(const net::URLRequest* request) |
1020 : state_(NEW) { | 1033 : state_(NEW) { |
1021 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 1034 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
1022 } | 1035 } |
1023 | 1036 |
1024 CUResourceThrottle::~CUResourceThrottle() { | 1037 CUResourceThrottle::~CUResourceThrottle() { |
(...skipping 26 matching lines...) Expand all Loading... |
1051 | 1064 |
1052 // The component update factory. Using the component updater as a singleton | 1065 // The component update factory. Using the component updater as a singleton |
1053 // is the job of the browser process. | 1066 // is the job of the browser process. |
1054 ComponentUpdateService* ComponentUpdateServiceFactory( | 1067 ComponentUpdateService* ComponentUpdateServiceFactory( |
1055 ComponentUpdateService::Configurator* config) { | 1068 ComponentUpdateService::Configurator* config) { |
1056 DCHECK(config); | 1069 DCHECK(config); |
1057 return new CrxUpdateService(config); | 1070 return new CrxUpdateService(config); |
1058 } | 1071 } |
1059 | 1072 |
1060 } // namespace component_updater | 1073 } // namespace component_updater |
OLD | NEW |