| 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 |
| 11 #include "base/at_exit.h" | 11 #include "base/at_exit.h" |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
| 14 #include "base/file_util.h" | 14 #include "base/file_util.h" |
| 15 #include "base/files/file_path.h" | 15 #include "base/files/file_path.h" |
| 16 #include "base/logging.h" | 16 #include "base/logging.h" |
| 17 #include "base/memory/scoped_ptr.h" | 17 #include "base/memory/scoped_ptr.h" |
| 18 #include "base/memory/weak_ptr.h" | 18 #include "base/memory/weak_ptr.h" |
| 19 #include "base/observer_list.h" |
| 19 #include "base/sequenced_task_runner.h" | 20 #include "base/sequenced_task_runner.h" |
| 20 #include "base/stl_util.h" | 21 #include "base/stl_util.h" |
| 21 #include "base/threading/sequenced_worker_pool.h" | 22 #include "base/threading/sequenced_worker_pool.h" |
| 22 #include "base/timer/timer.h" | 23 #include "base/timer/timer.h" |
| 23 #include "chrome/browser/browser_process.h" | 24 #include "chrome/browser/browser_process.h" |
| 24 #include "chrome/browser/component_updater/component_unpacker.h" | 25 #include "chrome/browser/component_updater/component_unpacker.h" |
| 25 #include "chrome/browser/component_updater/component_updater_ping_manager.h" | 26 #include "chrome/browser/component_updater/component_updater_ping_manager.h" |
| 26 #include "chrome/browser/component_updater/component_updater_utils.h" | 27 #include "chrome/browser/component_updater/component_updater_utils.h" |
| 27 #include "chrome/browser/component_updater/crx_downloader.h" | 28 #include "chrome/browser/component_updater/crx_downloader.h" |
| 28 #include "chrome/browser/component_updater/crx_update_item.h" | 29 #include "chrome/browser/component_updater/crx_update_item.h" |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 diff_error_category(0), | 77 diff_error_category(0), |
| 77 diff_error_code(0), | 78 diff_error_code(0), |
| 78 diff_extra_code1(0) { | 79 diff_extra_code1(0) { |
| 79 } | 80 } |
| 80 | 81 |
| 81 CrxUpdateItem::~CrxUpdateItem() { | 82 CrxUpdateItem::~CrxUpdateItem() { |
| 82 } | 83 } |
| 83 | 84 |
| 84 CrxComponent::CrxComponent() | 85 CrxComponent::CrxComponent() |
| 85 : installer(NULL), | 86 : installer(NULL), |
| 86 observer(NULL), | |
| 87 allow_background_download(true) { | 87 allow_background_download(true) { |
| 88 } | 88 } |
| 89 | 89 |
| 90 CrxComponent::~CrxComponent() { | 90 CrxComponent::~CrxComponent() { |
| 91 } | 91 } |
| 92 | 92 |
| 93 CrxComponentInfo::CrxComponentInfo() { | 93 CrxComponentInfo::CrxComponentInfo() { |
| 94 } | 94 } |
| 95 | 95 |
| 96 CrxComponentInfo::~CrxComponentInfo() { | 96 CrxComponentInfo::~CrxComponentInfo() { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 // There are no locks in this code, the main structure |work_items_| is mutated | 156 // There are no locks in this code, the main structure |work_items_| is mutated |
| 157 // only from the UI thread. The unpack and installation is done in a blocking | 157 // only from the UI thread. The unpack and installation is done in a blocking |
| 158 // pool thread. The network requests are done in the IO thread or in the file | 158 // pool thread. The network requests are done in the IO thread or in the file |
| 159 // thread. | 159 // thread. |
| 160 class CrxUpdateService : public ComponentUpdateService { | 160 class CrxUpdateService : public ComponentUpdateService { |
| 161 public: | 161 public: |
| 162 explicit CrxUpdateService(ComponentUpdateService::Configurator* config); | 162 explicit CrxUpdateService(ComponentUpdateService::Configurator* config); |
| 163 virtual ~CrxUpdateService(); | 163 virtual ~CrxUpdateService(); |
| 164 | 164 |
| 165 // Overrides for ComponentUpdateService. | 165 // Overrides for ComponentUpdateService. |
| 166 virtual void AddObserver(Observer* observer) OVERRIDE; |
| 167 virtual void RemoveObserver(Observer* observer) OVERRIDE; |
| 166 virtual Status Start() OVERRIDE; | 168 virtual Status Start() OVERRIDE; |
| 167 virtual Status Stop() OVERRIDE; | 169 virtual Status Stop() OVERRIDE; |
| 168 virtual Status RegisterComponent(const CrxComponent& component) OVERRIDE; | 170 virtual Status RegisterComponent(const CrxComponent& component) OVERRIDE; |
| 169 virtual Status OnDemandUpdate(const std::string& component_id) OVERRIDE; | 171 virtual Status OnDemandUpdate(const std::string& component_id) OVERRIDE; |
| 170 virtual void GetComponents( | 172 virtual void GetComponents( |
| 171 std::vector<CrxComponentInfo>* components) OVERRIDE; | 173 std::vector<CrxComponentInfo>* components) OVERRIDE; |
| 172 virtual content::ResourceThrottle* GetOnDemandResourceThrottle( | 174 virtual content::ResourceThrottle* GetOnDemandResourceThrottle( |
| 173 net::URLRequest* request, const std::string& crx_id) OVERRIDE; | 175 net::URLRequest* request, const std::string& crx_id) OVERRIDE; |
| 174 | 176 |
| 175 // Context for a crx download url request. | 177 // Context for a crx download url request. |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 ComponentUnpacker::Error error, | 236 ComponentUnpacker::Error error, |
| 235 int extended_error); | 237 int extended_error); |
| 236 | 238 |
| 237 void ChangeItemState(CrxUpdateItem* item, CrxUpdateItem::Status to); | 239 void ChangeItemState(CrxUpdateItem* item, CrxUpdateItem::Status to); |
| 238 | 240 |
| 239 size_t ChangeItemStatus(CrxUpdateItem::Status from, | 241 size_t ChangeItemStatus(CrxUpdateItem::Status from, |
| 240 CrxUpdateItem::Status to); | 242 CrxUpdateItem::Status to); |
| 241 | 243 |
| 242 CrxUpdateItem* FindUpdateItemById(const std::string& id); | 244 CrxUpdateItem* FindUpdateItemById(const std::string& id); |
| 243 | 245 |
| 244 void NotifyComponentObservers(ComponentObserver::Events event, | 246 void NotifyObservers(Observer::Events event, const std::string& id); |
| 245 int extra) const; | |
| 246 | 247 |
| 247 bool HasOnDemandItems() const; | 248 bool HasOnDemandItems() const; |
| 248 | 249 |
| 249 void OnNewResourceThrottle(base::WeakPtr<CUResourceThrottle> rt, | 250 void OnNewResourceThrottle(base::WeakPtr<CUResourceThrottle> rt, |
| 250 const std::string& crx_id); | 251 const std::string& crx_id); |
| 251 | 252 |
| 252 scoped_ptr<ComponentUpdateService::Configurator> config_; | 253 scoped_ptr<ComponentUpdateService::Configurator> config_; |
| 253 | 254 |
| 254 scoped_ptr<UpdateChecker> update_checker_; | 255 scoped_ptr<UpdateChecker> update_checker_; |
| 255 | 256 |
| 256 scoped_ptr<PingManager> ping_manager_; | 257 scoped_ptr<PingManager> ping_manager_; |
| 257 | 258 |
| 258 scoped_refptr<ComponentUnpacker> unpacker_; | 259 scoped_refptr<ComponentUnpacker> unpacker_; |
| 259 | 260 |
| 260 scoped_ptr<CrxDownloader> crx_downloader_; | 261 scoped_ptr<CrxDownloader> crx_downloader_; |
| 261 | 262 |
| 262 // A collection of every work item. | 263 // A collection of every work item. |
| 263 typedef std::vector<CrxUpdateItem*> UpdateItems; | 264 typedef std::vector<CrxUpdateItem*> UpdateItems; |
| 264 UpdateItems work_items_; | 265 UpdateItems work_items_; |
| 265 | 266 |
| 266 base::OneShotTimer<CrxUpdateService> timer_; | 267 base::OneShotTimer<CrxUpdateService> timer_; |
| 267 | 268 |
| 268 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; | 269 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; |
| 269 | 270 |
| 270 const Version chrome_version_; | 271 const Version chrome_version_; |
| 271 | 272 |
| 272 bool running_; | 273 bool running_; |
| 273 | 274 |
| 275 ObserverList<Observer> observer_list_; |
| 276 |
| 274 DISALLOW_COPY_AND_ASSIGN(CrxUpdateService); | 277 DISALLOW_COPY_AND_ASSIGN(CrxUpdateService); |
| 275 }; | 278 }; |
| 276 | 279 |
| 277 ////////////////////////////////////////////////////////////////////////////// | 280 ////////////////////////////////////////////////////////////////////////////// |
| 278 | 281 |
| 279 CrxUpdateService::CrxUpdateService(ComponentUpdateService::Configurator* config) | 282 CrxUpdateService::CrxUpdateService(ComponentUpdateService::Configurator* config) |
| 280 : config_(config), | 283 : config_(config), |
| 281 ping_manager_(new PingManager(config->PingUrl(), | 284 ping_manager_(new PingManager(config->PingUrl(), |
| 282 config->RequestContext())), | 285 config->RequestContext())), |
| 283 blocking_task_runner_(BrowserThread::GetBlockingPool()-> | 286 blocking_task_runner_(BrowserThread::GetBlockingPool()-> |
| 284 GetSequencedTaskRunnerWithShutdownBehavior( | 287 GetSequencedTaskRunnerWithShutdownBehavior( |
| 285 BrowserThread::GetBlockingPool()->GetSequenceToken(), | 288 BrowserThread::GetBlockingPool()->GetSequenceToken(), |
| 286 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)), | 289 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)), |
| 287 chrome_version_(chrome::VersionInfo().Version()), | 290 chrome_version_(chrome::VersionInfo().Version()), |
| 288 running_(false) { | 291 running_(false) { |
| 289 } | 292 } |
| 290 | 293 |
| 291 CrxUpdateService::~CrxUpdateService() { | 294 CrxUpdateService::~CrxUpdateService() { |
| 292 // Because we are a singleton, at this point only the UI thread should be | 295 // Because we are a singleton, at this point only the UI thread should be |
| 293 // alive, this simplifies the management of the work that could be in | 296 // alive, this simplifies the management of the work that could be in |
| 294 // flight in other threads. | 297 // flight in other threads. |
| 295 Stop(); | 298 Stop(); |
| 296 STLDeleteElements(&work_items_); | 299 STLDeleteElements(&work_items_); |
| 297 } | 300 } |
| 298 | 301 |
| 302 void CrxUpdateService::AddObserver(Observer* observer) { |
| 303 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 304 observer_list_.AddObserver(observer); |
| 305 } |
| 306 |
| 307 void CrxUpdateService::RemoveObserver(Observer* observer) { |
| 308 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 309 observer_list_.RemoveObserver(observer); |
| 310 } |
| 311 |
| 299 ComponentUpdateService::Status CrxUpdateService::Start() { | 312 ComponentUpdateService::Status CrxUpdateService::Start() { |
| 300 // Note that RegisterComponent will call Start() when the first | 313 // Note that RegisterComponent will call Start() when the first |
| 301 // component is registered, so it can be called twice. This way | 314 // component is registered, so it can be called twice. This way |
| 302 // we avoid scheduling the timer if there is no work to do. | 315 // we avoid scheduling the timer if there is no work to do. |
| 303 running_ = true; | 316 running_ = true; |
| 304 if (work_items_.empty()) | 317 if (work_items_.empty()) |
| 305 return kOk; | 318 return kOk; |
| 306 | 319 |
| 307 NotifyComponentObservers(ComponentObserver::COMPONENT_UPDATER_STARTED, 0); | 320 NotifyObservers(Observer::COMPONENT_UPDATER_STARTED, ""); |
| 308 | 321 |
| 309 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(config_->InitialDelay()), | 322 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(config_->InitialDelay()), |
| 310 this, &CrxUpdateService::ProcessPendingItems); | 323 this, &CrxUpdateService::ProcessPendingItems); |
| 311 return kOk; | 324 return kOk; |
| 312 } | 325 } |
| 313 | 326 |
| 314 // Stop the main check + update loop. In flight operations will be | 327 // Stop the main check + update loop. In flight operations will be |
| 315 // completed. | 328 // completed. |
| 316 ComponentUpdateService::Status CrxUpdateService::Stop() { | 329 ComponentUpdateService::Status CrxUpdateService::Stop() { |
| 317 running_ = false; | 330 running_ = false; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 break; | 375 break; |
| 363 case kStepDelayLong: | 376 case kStepDelayLong: |
| 364 delay_seconds = config_->NextCheckDelay(); | 377 delay_seconds = config_->NextCheckDelay(); |
| 365 break; | 378 break; |
| 366 } | 379 } |
| 367 } else { | 380 } else { |
| 368 delay_seconds = config_->StepDelay(); | 381 delay_seconds = config_->StepDelay(); |
| 369 } | 382 } |
| 370 | 383 |
| 371 if (step_delay != kStepDelayShort) { | 384 if (step_delay != kStepDelayShort) { |
| 372 NotifyComponentObservers(ComponentObserver::COMPONENT_UPDATER_SLEEPING, 0); | 385 NotifyObservers(Observer::COMPONENT_UPDATER_SLEEPING, ""); |
| 373 | 386 |
| 374 // Zero is only used for unit tests. | 387 // Zero is only used for unit tests. |
| 375 if (0 == delay_seconds) | 388 if (0 == delay_seconds) |
| 376 return; | 389 return; |
| 377 } | 390 } |
| 378 | 391 |
| 379 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(delay_seconds), | 392 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(delay_seconds), |
| 380 this, &CrxUpdateService::ProcessPendingItems); | 393 this, &CrxUpdateService::ProcessPendingItems); |
| 381 } | 394 } |
| 382 | 395 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 398 CrxUpdateItem::Status to) { | 411 CrxUpdateItem::Status to) { |
| 399 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 412 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 400 if (to == CrxUpdateItem::kNoUpdate || | 413 if (to == CrxUpdateItem::kNoUpdate || |
| 401 to == CrxUpdateItem::kUpdated || | 414 to == CrxUpdateItem::kUpdated || |
| 402 to == CrxUpdateItem::kUpToDate) { | 415 to == CrxUpdateItem::kUpToDate) { |
| 403 item->on_demand = false; | 416 item->on_demand = false; |
| 404 } | 417 } |
| 405 | 418 |
| 406 item->status = to; | 419 item->status = to; |
| 407 | 420 |
| 408 ComponentObserver* observer = item->component.observer; | 421 switch (to) { |
| 409 if (observer) { | 422 case CrxUpdateItem::kCanUpdate: |
| 410 switch (to) { | 423 NotifyObservers(Observer::COMPONENT_UPDATE_FOUND, item->id); |
| 411 case CrxUpdateItem::kCanUpdate: | 424 break; |
| 412 observer->OnEvent(ComponentObserver::COMPONENT_UPDATE_FOUND, 0); | 425 case CrxUpdateItem::kUpdatingDiff: |
| 413 break; | 426 case CrxUpdateItem::kUpdating: |
| 414 case CrxUpdateItem::kUpdatingDiff: | 427 NotifyObservers(Observer::COMPONENT_UPDATE_READY, item->id); |
| 415 case CrxUpdateItem::kUpdating: | 428 break; |
| 416 observer->OnEvent(ComponentObserver::COMPONENT_UPDATE_READY, 0); | 429 case CrxUpdateItem::kUpdated: |
| 417 break; | 430 NotifyObservers(Observer::COMPONENT_UPDATED, item->id); |
| 418 case CrxUpdateItem::kUpdated: | 431 break; |
| 419 observer->OnEvent(ComponentObserver::COMPONENT_UPDATED, 0); | 432 case CrxUpdateItem::kUpToDate: |
| 420 break; | 433 case CrxUpdateItem::kNoUpdate: |
| 421 case CrxUpdateItem::kUpToDate: | 434 NotifyObservers(Observer::COMPONENT_NOT_UPDATED, item->id); |
| 422 case CrxUpdateItem::kNoUpdate: | 435 break; |
| 423 observer->OnEvent(ComponentObserver::COMPONENT_NOT_UPDATED, 0); | 436 case CrxUpdateItem::kNew: |
| 424 break; | 437 case CrxUpdateItem::kChecking: |
| 425 case CrxUpdateItem::kNew: | 438 case CrxUpdateItem::kDownloading: |
| 426 case CrxUpdateItem::kChecking: | 439 case CrxUpdateItem::kDownloadingDiff: |
| 427 case CrxUpdateItem::kDownloading: | 440 case CrxUpdateItem::kLastStatus: |
| 428 case CrxUpdateItem::kDownloadingDiff: | 441 // No notification for these states. |
| 429 case CrxUpdateItem::kLastStatus: | 442 break; |
| 430 // No notification for these states. | |
| 431 break; | |
| 432 } | |
| 433 } | 443 } |
| 434 | 444 |
| 435 // Free possible pending network requests. | 445 // Free possible pending network requests. |
| 436 if ((to == CrxUpdateItem::kUpdated) || | 446 if ((to == CrxUpdateItem::kUpdated) || |
| 437 (to == CrxUpdateItem::kUpToDate) || | 447 (to == CrxUpdateItem::kUpToDate) || |
| 438 (to == CrxUpdateItem::kNoUpdate)) { | 448 (to == CrxUpdateItem::kNoUpdate)) { |
| 439 UnblockandReapAllThrottles(&item->throttles); | 449 UnblockandReapAllThrottles(&item->throttles); |
| 440 } | 450 } |
| 441 } | 451 } |
| 442 | 452 |
| (...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 925 item->error_code = error; | 935 item->error_code = error; |
| 926 item->extra_code1 = extra_code; | 936 item->extra_code1 = extra_code; |
| 927 } | 937 } |
| 928 | 938 |
| 929 ping_manager_->OnUpdateComplete(item); | 939 ping_manager_->OnUpdateComplete(item); |
| 930 | 940 |
| 931 // Move on to the next update, if there is one available. | 941 // Move on to the next update, if there is one available. |
| 932 ScheduleNextRun(kStepDelayMedium); | 942 ScheduleNextRun(kStepDelayMedium); |
| 933 } | 943 } |
| 934 | 944 |
| 935 void CrxUpdateService::NotifyComponentObservers( | 945 void CrxUpdateService::NotifyObservers(Observer::Events event, |
| 936 ComponentObserver::Events event, int extra) const { | 946 const std::string& id) { |
| 937 for (UpdateItems::const_iterator it = work_items_.begin(); | 947 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 938 it != work_items_.end(); ++it) { | 948 FOR_EACH_OBSERVER(Observer, observer_list_, OnEvent(event, id)); |
| 939 ComponentObserver* observer = (*it)->component.observer; | |
| 940 if (observer) | |
| 941 observer->OnEvent(event, 0); | |
| 942 } | |
| 943 } | 949 } |
| 944 | 950 |
| 945 content::ResourceThrottle* CrxUpdateService::GetOnDemandResourceThrottle( | 951 content::ResourceThrottle* CrxUpdateService::GetOnDemandResourceThrottle( |
| 946 net::URLRequest* request, const std::string& crx_id) { | 952 net::URLRequest* request, const std::string& crx_id) { |
| 947 // We give the raw pointer to the caller, who will delete it at will | 953 // We give the raw pointer to the caller, who will delete it at will |
| 948 // and we keep for ourselves a weak pointer to it so we can post tasks | 954 // and we keep for ourselves a weak pointer to it so we can post tasks |
| 949 // from the UI thread without having to track lifetime directly. | 955 // from the UI thread without having to track lifetime directly. |
| 950 CUResourceThrottle* rt = new CUResourceThrottle(request); | 956 CUResourceThrottle* rt = new CUResourceThrottle(request); |
| 951 BrowserThread::PostTask( | 957 BrowserThread::PostTask( |
| 952 BrowserThread::UI, | 958 BrowserThread::UI, |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1009 // The component update factory. Using the component updater as a singleton | 1015 // The component update factory. Using the component updater as a singleton |
| 1010 // is the job of the browser process. | 1016 // is the job of the browser process. |
| 1011 ComponentUpdateService* ComponentUpdateServiceFactory( | 1017 ComponentUpdateService* ComponentUpdateServiceFactory( |
| 1012 ComponentUpdateService::Configurator* config) { | 1018 ComponentUpdateService::Configurator* config) { |
| 1013 DCHECK(config); | 1019 DCHECK(config); |
| 1014 return new CrxUpdateService(config); | 1020 return new CrxUpdateService(config); |
| 1015 } | 1021 } |
| 1016 | 1022 |
| 1017 } // namespace component_updater | 1023 } // namespace component_updater |
| 1018 | 1024 |
| OLD | NEW |