| 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/observer_list.h" | 18 #include "base/observer_list.h" |
| 19 #include "base/sequenced_task_runner.h" | 19 #include "base/sequenced_task_runner.h" |
| 20 #include "base/stl_util.h" | 20 #include "base/stl_util.h" |
| 21 #include "base/threading/sequenced_worker_pool.h" | 21 #include "base/threading/sequenced_worker_pool.h" |
| 22 #include "base/threading/thread_checker.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_configurator.h" | 26 #include "chrome/browser/component_updater/component_updater_configurator.h" |
| 26 #include "chrome/browser/component_updater/component_updater_ping_manager.h" | 27 #include "chrome/browser/component_updater/component_updater_ping_manager.h" |
| 27 #include "chrome/browser/component_updater/component_updater_utils.h" | 28 #include "chrome/browser/component_updater/component_updater_utils.h" |
| 28 #include "chrome/browser/component_updater/crx_downloader.h" | 29 #include "chrome/browser/component_updater/crx_downloader.h" |
| 29 #include "chrome/browser/component_updater/crx_update_item.h" | 30 #include "chrome/browser/component_updater/crx_update_item.h" |
| 30 #include "chrome/browser/component_updater/update_checker.h" | 31 #include "chrome/browser/component_updater/update_checker.h" |
| 31 #include "chrome/browser/component_updater/update_response.h" | 32 #include "chrome/browser/component_updater/update_response.h" |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 ////////////////////////////////////////////////////////////////////////////// | 133 ////////////////////////////////////////////////////////////////////////////// |
| 133 // The one and only implementation of the ComponentUpdateService interface. In | 134 // The one and only implementation of the ComponentUpdateService interface. In |
| 134 // charge of running the show. The main method is ProcessPendingItems() which | 135 // charge of running the show. The main method is ProcessPendingItems() which |
| 135 // is called periodically to do the upgrades/installs or the update checks. | 136 // is called periodically to do the upgrades/installs or the update checks. |
| 136 // An important consideration here is to be as "low impact" as we can to the | 137 // An important consideration here is to be as "low impact" as we can to the |
| 137 // rest of the browser, so even if we have many components registered and | 138 // rest of the browser, so even if we have many components registered and |
| 138 // eligible for update, we only do one thing at a time with pauses in between | 139 // eligible for update, we only do one thing at a time with pauses in between |
| 139 // the tasks. Also when we do network requests there is only one |url_fetcher_| | 140 // the tasks. Also when we do network requests there is only one |url_fetcher_| |
| 140 // in flight at a time. | 141 // in flight at a time. |
| 141 // There are no locks in this code, the main structure |work_items_| is mutated | 142 // There are no locks in this code, the main structure |work_items_| is mutated |
| 142 // only from the UI thread. The unpack and installation is done in a blocking | 143 // only from the main thread. The unpack and installation is done in a blocking |
| 143 // pool thread. The network requests are done in the IO thread or in the file | 144 // pool thread. The network requests are done in the IO thread or in the file |
| 144 // thread. | 145 // thread. |
| 145 class CrxUpdateService : public ComponentUpdateService, public OnDemandUpdater { | 146 class CrxUpdateService : public ComponentUpdateService, public OnDemandUpdater { |
| 146 public: | 147 public: |
| 147 explicit CrxUpdateService(Configurator* config); | 148 explicit CrxUpdateService(Configurator* config); |
| 148 virtual ~CrxUpdateService(); | 149 virtual ~CrxUpdateService(); |
| 149 | 150 |
| 150 // Overrides for ComponentUpdateService. | 151 // Overrides for ComponentUpdateService. |
| 151 virtual void AddObserver(Observer* observer) OVERRIDE; | 152 virtual void AddObserver(Observer* observer) OVERRIDE; |
| 152 virtual void RemoveObserver(Observer* observer) OVERRIDE; | 153 virtual void RemoveObserver(Observer* observer) OVERRIDE; |
| 153 virtual Status Start() OVERRIDE; | 154 virtual Status Start() OVERRIDE; |
| 154 virtual Status Stop() OVERRIDE; | 155 virtual Status Stop() OVERRIDE; |
| 155 virtual Status RegisterComponent(const CrxComponent& component) OVERRIDE; | 156 virtual Status RegisterComponent(const CrxComponent& component) OVERRIDE; |
| 156 virtual std::vector<std::string> GetComponentIDs() const OVERRIDE; | 157 virtual std::vector<std::string> GetComponentIDs() const OVERRIDE; |
| 157 virtual bool GetComponentDetails(const std::string& component_id, | 158 virtual bool GetComponentDetails(const std::string& component_id, |
| 158 CrxUpdateItem* item) const OVERRIDE; | 159 CrxUpdateItem* item) const OVERRIDE; |
| 159 virtual OnDemandUpdater& GetOnDemandUpdater() OVERRIDE; | 160 virtual OnDemandUpdater& GetOnDemandUpdater() OVERRIDE; |
| 161 virtual scoped_refptr<base::SequencedTaskRunner> GetSequencedTaskRunner() |
| 162 OVERRIDE; |
| 160 | 163 |
| 161 // Overrides for OnDemandUpdater. | 164 // Overrides for OnDemandUpdater. |
| 162 virtual content::ResourceThrottle* GetOnDemandResourceThrottle( | 165 virtual content::ResourceThrottle* GetOnDemandResourceThrottle( |
| 163 net::URLRequest* request, | 166 net::URLRequest* request, |
| 164 const std::string& crx_id) OVERRIDE; | 167 const std::string& crx_id) OVERRIDE; |
| 165 virtual Status OnDemandUpdate(const std::string& component_id) OVERRIDE; | 168 virtual Status OnDemandUpdate(const std::string& component_id) OVERRIDE; |
| 166 | 169 |
| 167 // Context for a crx download url request. | 170 // Context for a crx download url request. |
| 168 struct CRXContext { | 171 struct CRXContext { |
| 169 ComponentInstaller* installer; | 172 ComponentInstaller* installer; |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 scoped_refptr<ComponentUnpacker> unpacker_; | 256 scoped_refptr<ComponentUnpacker> unpacker_; |
| 254 | 257 |
| 255 scoped_ptr<CrxDownloader> crx_downloader_; | 258 scoped_ptr<CrxDownloader> crx_downloader_; |
| 256 | 259 |
| 257 // A collection of every work item. | 260 // A collection of every work item. |
| 258 typedef std::vector<CrxUpdateItem*> UpdateItems; | 261 typedef std::vector<CrxUpdateItem*> UpdateItems; |
| 259 UpdateItems work_items_; | 262 UpdateItems work_items_; |
| 260 | 263 |
| 261 base::OneShotTimer<CrxUpdateService> timer_; | 264 base::OneShotTimer<CrxUpdateService> timer_; |
| 262 | 265 |
| 266 base::ThreadChecker thread_checker_; |
| 267 |
| 263 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; | 268 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; |
| 264 | 269 |
| 265 bool running_; | 270 bool running_; |
| 266 | 271 |
| 267 ObserverList<Observer> observer_list_; | 272 ObserverList<Observer> observer_list_; |
| 268 | 273 |
| 269 DISALLOW_COPY_AND_ASSIGN(CrxUpdateService); | 274 DISALLOW_COPY_AND_ASSIGN(CrxUpdateService); |
| 270 }; | 275 }; |
| 271 | 276 |
| 272 ////////////////////////////////////////////////////////////////////////////// | 277 ////////////////////////////////////////////////////////////////////////////// |
| 273 | 278 |
| 274 CrxUpdateService::CrxUpdateService(Configurator* config) | 279 CrxUpdateService::CrxUpdateService(Configurator* config) |
| 275 : config_(config), | 280 : config_(config), |
| 276 ping_manager_(new PingManager(*config)), | 281 ping_manager_(new PingManager(*config)), |
| 277 blocking_task_runner_( | 282 blocking_task_runner_(config->GetSequencedTaskRunner()), |
| 278 BrowserThread::GetBlockingPool()-> | |
| 279 GetSequencedTaskRunnerWithShutdownBehavior( | |
| 280 BrowserThread::GetBlockingPool()->GetSequenceToken(), | |
| 281 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)), | |
| 282 running_(false) { | 283 running_(false) { |
| 283 } | 284 } |
| 284 | 285 |
| 285 CrxUpdateService::~CrxUpdateService() { | 286 CrxUpdateService::~CrxUpdateService() { |
| 286 // Because we are a singleton, at this point only the UI thread should be | 287 // Because we are a singleton, at this point only the main thread should be |
| 287 // alive, this simplifies the management of the work that could be in | 288 // alive, this simplifies the management of the work that could be in |
| 288 // flight in other threads. | 289 // flight in other threads. |
| 289 Stop(); | 290 Stop(); |
| 290 STLDeleteElements(&work_items_); | 291 STLDeleteElements(&work_items_); |
| 291 } | 292 } |
| 292 | 293 |
| 293 void CrxUpdateService::AddObserver(Observer* observer) { | 294 void CrxUpdateService::AddObserver(Observer* observer) { |
| 294 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 295 DCHECK(thread_checker_.CalledOnValidThread()); |
| 295 observer_list_.AddObserver(observer); | 296 observer_list_.AddObserver(observer); |
| 296 } | 297 } |
| 297 | 298 |
| 298 void CrxUpdateService::RemoveObserver(Observer* observer) { | 299 void CrxUpdateService::RemoveObserver(Observer* observer) { |
| 299 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 300 DCHECK(thread_checker_.CalledOnValidThread()); |
| 300 observer_list_.RemoveObserver(observer); | 301 observer_list_.RemoveObserver(observer); |
| 301 } | 302 } |
| 302 | 303 |
| 303 ComponentUpdateService::Status CrxUpdateService::Start() { | 304 ComponentUpdateService::Status CrxUpdateService::Start() { |
| 304 // Note that RegisterComponent will call Start() when the first | 305 // Note that RegisterComponent will call Start() when the first |
| 305 // component is registered, so it can be called twice. This way | 306 // component is registered, so it can be called twice. This way |
| 306 // we avoid scheduling the timer if there is no work to do. | 307 // we avoid scheduling the timer if there is no work to do. |
| 307 VLOG(1) << "CrxUpdateService starting up"; | 308 VLOG(1) << "CrxUpdateService starting up"; |
| 308 running_ = true; | 309 running_ = true; |
| 309 if (work_items_.empty()) | 310 if (work_items_.empty()) |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 | 342 |
| 342 // This function sets the timer which will call ProcessPendingItems() or | 343 // This function sets the timer which will call ProcessPendingItems() or |
| 343 // ProcessRequestedItem() if there is an on_demand item. There | 344 // ProcessRequestedItem() if there is an on_demand item. There |
| 344 // are three kinds of waits: | 345 // are three kinds of waits: |
| 345 // - a short delay, when there is immediate work to be done. | 346 // - a short delay, when there is immediate work to be done. |
| 346 // - a medium delay, when there are updates to be applied within the current | 347 // - a medium delay, when there are updates to be applied within the current |
| 347 // update cycle, or there are components that are still unchecked. | 348 // update cycle, or there are components that are still unchecked. |
| 348 // - a long delay when a full check/update cycle has completed for all | 349 // - a long delay when a full check/update cycle has completed for all |
| 349 // components. | 350 // components. |
| 350 void CrxUpdateService::ScheduleNextRun(StepDelayInterval step_delay) { | 351 void CrxUpdateService::ScheduleNextRun(StepDelayInterval step_delay) { |
| 351 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 352 DCHECK(thread_checker_.CalledOnValidThread()); |
| 352 DCHECK(!update_checker_); | 353 DCHECK(!update_checker_); |
| 353 CHECK(!timer_.IsRunning()); | 354 CHECK(!timer_.IsRunning()); |
| 354 // It could be the case that Stop() had been called while a url request | 355 // It could be the case that Stop() had been called while a url request |
| 355 // or unpacking was in flight, if so we arrive here but |running_| is | 356 // or unpacking was in flight, if so we arrive here but |running_| is |
| 356 // false. In that case do not loop again. | 357 // false. In that case do not loop again. |
| 357 if (!running_) | 358 if (!running_) |
| 358 return; | 359 return; |
| 359 | 360 |
| 360 // Keep the delay short if in the middle of an update (step_delay), | 361 // Keep the delay short if in the middle of an update (step_delay), |
| 361 // or there are new requested_work_items_ that have not been processed yet. | 362 // or there are new requested_work_items_ that have not been processed yet. |
| (...skipping 25 matching lines...) Expand all Loading... |
| 387 VLOG(1) << "Scheduling next run to occur in " << delay_seconds << " seconds"; | 388 VLOG(1) << "Scheduling next run to occur in " << delay_seconds << " seconds"; |
| 388 timer_.Start(FROM_HERE, | 389 timer_.Start(FROM_HERE, |
| 389 base::TimeDelta::FromSeconds(delay_seconds), | 390 base::TimeDelta::FromSeconds(delay_seconds), |
| 390 this, | 391 this, |
| 391 &CrxUpdateService::ProcessPendingItems); | 392 &CrxUpdateService::ProcessPendingItems); |
| 392 } | 393 } |
| 393 | 394 |
| 394 // Given a extension-like component id, find the associated component. | 395 // Given a extension-like component id, find the associated component. |
| 395 CrxUpdateItem* CrxUpdateService::FindUpdateItemById( | 396 CrxUpdateItem* CrxUpdateService::FindUpdateItemById( |
| 396 const std::string& id) const { | 397 const std::string& id) const { |
| 397 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 398 DCHECK(thread_checker_.CalledOnValidThread()); |
| 398 CrxUpdateItem::FindById finder(id); | 399 CrxUpdateItem::FindById finder(id); |
| 399 UpdateItems::const_iterator it = | 400 UpdateItems::const_iterator it = |
| 400 std::find_if(work_items_.begin(), work_items_.end(), finder); | 401 std::find_if(work_items_.begin(), work_items_.end(), finder); |
| 401 return it != work_items_.end() ? *it : NULL; | 402 return it != work_items_.end() ? *it : NULL; |
| 402 } | 403 } |
| 403 | 404 |
| 404 // Changes a component's status, clearing on_demand and firing notifications as | 405 // Changes a component's status, clearing on_demand and firing notifications as |
| 405 // necessary. By convention, this is the only function that can change a | 406 // necessary. By convention, this is the only function that can change a |
| 406 // CrxUpdateItem's |status|. | 407 // CrxUpdateItem's |status|. |
| 407 // TODO(waffles): Do we want to add DCHECKS for valid state transitions here? | 408 // TODO(waffles): Do we want to add DCHECKS for valid state transitions here? |
| 408 void CrxUpdateService::ChangeItemState(CrxUpdateItem* item, | 409 void CrxUpdateService::ChangeItemState(CrxUpdateItem* item, |
| 409 CrxUpdateItem::Status to) { | 410 CrxUpdateItem::Status to) { |
| 410 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 411 DCHECK(thread_checker_.CalledOnValidThread()); |
| 411 if (to == CrxUpdateItem::kNoUpdate || to == CrxUpdateItem::kUpdated || | 412 if (to == CrxUpdateItem::kNoUpdate || to == CrxUpdateItem::kUpdated || |
| 412 to == CrxUpdateItem::kUpToDate) { | 413 to == CrxUpdateItem::kUpToDate) { |
| 413 item->on_demand = false; | 414 item->on_demand = false; |
| 414 } | 415 } |
| 415 | 416 |
| 416 item->status = to; | 417 item->status = to; |
| 417 | 418 |
| 418 switch (to) { | 419 switch (to) { |
| 419 case CrxUpdateItem::kCanUpdate: | 420 case CrxUpdateItem::kCanUpdate: |
| 420 NotifyObservers(Observer::COMPONENT_UPDATE_FOUND, item->id); | 421 NotifyObservers(Observer::COMPONENT_UPDATE_FOUND, item->id); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 443 if ((to == CrxUpdateItem::kUpdated) || (to == CrxUpdateItem::kUpToDate) || | 444 if ((to == CrxUpdateItem::kUpdated) || (to == CrxUpdateItem::kUpToDate) || |
| 444 (to == CrxUpdateItem::kNoUpdate)) { | 445 (to == CrxUpdateItem::kNoUpdate)) { |
| 445 UnblockandReapAllThrottles(&item->throttles); | 446 UnblockandReapAllThrottles(&item->throttles); |
| 446 } | 447 } |
| 447 } | 448 } |
| 448 | 449 |
| 449 // Changes all the components in |work_items_| that have |from| status to | 450 // Changes all the components in |work_items_| that have |from| status to |
| 450 // |to| status and returns how many have been changed. | 451 // |to| status and returns how many have been changed. |
| 451 size_t CrxUpdateService::ChangeItemStatus(CrxUpdateItem::Status from, | 452 size_t CrxUpdateService::ChangeItemStatus(CrxUpdateItem::Status from, |
| 452 CrxUpdateItem::Status to) { | 453 CrxUpdateItem::Status to) { |
| 453 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 454 DCHECK(thread_checker_.CalledOnValidThread()); |
| 454 size_t count = 0; | 455 size_t count = 0; |
| 455 for (UpdateItems::iterator it = work_items_.begin(); | 456 for (UpdateItems::iterator it = work_items_.begin(); |
| 456 it != work_items_.end(); | 457 it != work_items_.end(); |
| 457 ++it) { | 458 ++it) { |
| 458 CrxUpdateItem* item = *it; | 459 CrxUpdateItem* item = *it; |
| 459 if (item->status == from) { | 460 if (item->status == from) { |
| 460 ChangeItemState(item, to); | 461 ChangeItemState(item, to); |
| 461 ++count; | 462 ++count; |
| 462 } | 463 } |
| 463 } | 464 } |
| 464 return count; | 465 return count; |
| 465 } | 466 } |
| 466 | 467 |
| 467 // Adds a component to be checked for upgrades. If the component exists it | 468 // Adds a component to be checked for upgrades. If the component exists it |
| 468 // it will be replaced and the return code is kReplaced. | 469 // it will be replaced and the return code is kReplaced. |
| 469 ComponentUpdateService::Status CrxUpdateService::RegisterComponent( | 470 ComponentUpdateService::Status CrxUpdateService::RegisterComponent( |
| 470 const CrxComponent& component) { | 471 const CrxComponent& component) { |
| 471 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 472 DCHECK(thread_checker_.CalledOnValidThread()); |
| 472 if (component.pk_hash.empty() || !component.version.IsValid() || | 473 if (component.pk_hash.empty() || !component.version.IsValid() || |
| 473 !component.installer) | 474 !component.installer) |
| 474 return kError; | 475 return kError; |
| 475 | 476 |
| 476 std::string id(GetCrxComponentID(component)); | 477 std::string id(GetCrxComponentID(component)); |
| 477 CrxUpdateItem* uit = FindUpdateItemById(id); | 478 CrxUpdateItem* uit = FindUpdateItemById(id); |
| 478 if (uit) { | 479 if (uit) { |
| 479 uit->component = component; | 480 uit->component = component; |
| 480 return kReplaced; | 481 return kReplaced; |
| 481 } | 482 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 500 base::TimeDelta::FromSeconds(config_->InitialDelay()), | 501 base::TimeDelta::FromSeconds(config_->InitialDelay()), |
| 501 this, | 502 this, |
| 502 &CrxUpdateService::ProcessPendingItems); | 503 &CrxUpdateService::ProcessPendingItems); |
| 503 } | 504 } |
| 504 } | 505 } |
| 505 | 506 |
| 506 return kOk; | 507 return kOk; |
| 507 } | 508 } |
| 508 | 509 |
| 509 std::vector<std::string> CrxUpdateService::GetComponentIDs() const { | 510 std::vector<std::string> CrxUpdateService::GetComponentIDs() const { |
| 510 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 511 DCHECK(thread_checker_.CalledOnValidThread()); |
| 511 std::vector<std::string> component_ids; | 512 std::vector<std::string> component_ids; |
| 512 for (UpdateItems::const_iterator it = work_items_.begin(); | 513 for (UpdateItems::const_iterator it = work_items_.begin(); |
| 513 it != work_items_.end(); | 514 it != work_items_.end(); |
| 514 ++it) { | 515 ++it) { |
| 515 const CrxUpdateItem* item = *it; | 516 const CrxUpdateItem* item = *it; |
| 516 component_ids.push_back(item->id); | 517 component_ids.push_back(item->id); |
| 517 } | 518 } |
| 518 return component_ids; | 519 return component_ids; |
| 519 } | 520 } |
| 520 | 521 |
| 521 bool CrxUpdateService::GetComponentDetails(const std::string& component_id, | 522 bool CrxUpdateService::GetComponentDetails(const std::string& component_id, |
| 522 CrxUpdateItem* item) const { | 523 CrxUpdateItem* item) const { |
| 523 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 524 DCHECK(thread_checker_.CalledOnValidThread()); |
| 524 const CrxUpdateItem* crx_update_item(FindUpdateItemById(component_id)); | 525 const CrxUpdateItem* crx_update_item(FindUpdateItemById(component_id)); |
| 525 if (crx_update_item) | 526 if (crx_update_item) |
| 526 *item = *crx_update_item; | 527 *item = *crx_update_item; |
| 527 return crx_update_item != NULL; | 528 return crx_update_item != NULL; |
| 528 } | 529 } |
| 529 | 530 |
| 530 OnDemandUpdater& CrxUpdateService::GetOnDemandUpdater() { | 531 OnDemandUpdater& CrxUpdateService::GetOnDemandUpdater() { |
| 531 return *this; | 532 return *this; |
| 532 } | 533 } |
| 533 | 534 |
| 535 scoped_refptr<base::SequencedTaskRunner> |
| 536 CrxUpdateService::GetSequencedTaskRunner() { |
| 537 return config_->GetSequencedTaskRunner(); |
| 538 } |
| 539 |
| 534 // This is the main loop of the component updater. It updates one component | 540 // This is the main loop of the component updater. It updates one component |
| 535 // at a time if updates are available. Otherwise, it does an update check or | 541 // at a time if updates are available. Otherwise, it does an update check or |
| 536 // takes a long sleep until the loop runs again. | 542 // takes a long sleep until the loop runs again. |
| 537 void CrxUpdateService::ProcessPendingItems() { | 543 void CrxUpdateService::ProcessPendingItems() { |
| 538 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 544 DCHECK(thread_checker_.CalledOnValidThread()); |
| 539 | 545 |
| 540 CrxUpdateItem* ready_upgrade = FindReadyComponent(); | 546 CrxUpdateItem* ready_upgrade = FindReadyComponent(); |
| 541 if (ready_upgrade) { | 547 if (ready_upgrade) { |
| 542 UpdateComponent(ready_upgrade); | 548 UpdateComponent(ready_upgrade); |
| 543 return; | 549 return; |
| 544 } | 550 } |
| 545 | 551 |
| 546 if (!CheckForUpdates()) | 552 if (!CheckForUpdates()) |
| 547 ScheduleNextRun(kStepDelayLong); | 553 ScheduleNextRun(kStepDelayLong); |
| 548 } | 554 } |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 648 allow_background_download = workitem->component.allow_background_download; | 654 allow_background_download = workitem->component.allow_background_download; |
| 649 urls = &workitem->crx_urls; | 655 urls = &workitem->crx_urls; |
| 650 ChangeItemState(workitem, CrxUpdateItem::kDownloading); | 656 ChangeItemState(workitem, CrxUpdateItem::kDownloading); |
| 651 } | 657 } |
| 652 | 658 |
| 653 // On demand component updates are always downloaded in foreground. | 659 // On demand component updates are always downloaded in foreground. |
| 654 const bool is_background_download = !workitem->on_demand && | 660 const bool is_background_download = !workitem->on_demand && |
| 655 allow_background_download && | 661 allow_background_download && |
| 656 config_->UseBackgroundDownloader(); | 662 config_->UseBackgroundDownloader(); |
| 657 | 663 |
| 658 crx_downloader_.reset(CrxDownloader::Create(is_background_download, | 664 crx_downloader_.reset( |
| 659 config_->RequestContext(), | 665 CrxDownloader::Create(is_background_download, |
| 660 blocking_task_runner_)); | 666 config_->RequestContext(), |
| 667 blocking_task_runner_, |
| 668 config_->GetSingleThreadTaskRunner())); |
| 661 crx_downloader_->set_progress_callback( | 669 crx_downloader_->set_progress_callback( |
| 662 base::Bind(&CrxUpdateService::DownloadProgress, | 670 base::Bind(&CrxUpdateService::DownloadProgress, |
| 663 base::Unretained(this), | 671 base::Unretained(this), |
| 664 crx_context->id)); | 672 crx_context->id)); |
| 665 crx_downloader_->StartDownload(*urls, | 673 crx_downloader_->StartDownload(*urls, |
| 666 base::Bind(&CrxUpdateService::DownloadComplete, | 674 base::Bind(&CrxUpdateService::DownloadComplete, |
| 667 base::Unretained(this), | 675 base::Unretained(this), |
| 668 base::Passed(&crx_context))); | 676 base::Passed(&crx_context))); |
| 669 } | 677 } |
| 670 | 678 |
| 671 void CrxUpdateService::UpdateCheckComplete( | 679 void CrxUpdateService::UpdateCheckComplete( |
| 672 int error, | 680 int error, |
| 673 const std::string& error_message, | 681 const std::string& error_message, |
| 674 const UpdateResponse::Results& results) { | 682 const UpdateResponse::Results& results) { |
| 675 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 683 DCHECK(thread_checker_.CalledOnValidThread()); |
| 676 update_checker_.reset(); | 684 update_checker_.reset(); |
| 677 if (!error) | 685 if (!error) |
| 678 OnUpdateCheckSucceeded(results); | 686 OnUpdateCheckSucceeded(results); |
| 679 else | 687 else |
| 680 OnUpdateCheckFailed(error, error_message); | 688 OnUpdateCheckFailed(error, error_message); |
| 681 } | 689 } |
| 682 | 690 |
| 683 // Handles a valid Omaha update check response by matching the results with | 691 // Handles a valid Omaha update check response by matching the results with |
| 684 // the registered components which were checked for updates. | 692 // the registered components which were checked for updates. |
| 685 // If updates are found, prepare the components for the actual version upgrade. | 693 // If updates are found, prepare the components for the actual version upgrade. |
| 686 // One of these components will be drafted for the upgrade next time | 694 // One of these components will be drafted for the upgrade next time |
| 687 // ProcessPendingItems is called. | 695 // ProcessPendingItems is called. |
| 688 void CrxUpdateService::OnUpdateCheckSucceeded( | 696 void CrxUpdateService::OnUpdateCheckSucceeded( |
| 689 const UpdateResponse::Results& results) { | 697 const UpdateResponse::Results& results) { |
| 690 size_t num_updates_pending = 0; | 698 size_t num_updates_pending = 0; |
| 691 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 699 DCHECK(thread_checker_.CalledOnValidThread()); |
| 692 VLOG(1) << "Update check succeeded."; | 700 VLOG(1) << "Update check succeeded."; |
| 693 std::vector<UpdateResponse::Result>::const_iterator it; | 701 std::vector<UpdateResponse::Result>::const_iterator it; |
| 694 for (it = results.list.begin(); it != results.list.end(); ++it) { | 702 for (it = results.list.begin(); it != results.list.end(); ++it) { |
| 695 CrxUpdateItem* crx = FindUpdateItemById(it->extension_id); | 703 CrxUpdateItem* crx = FindUpdateItemById(it->extension_id); |
| 696 if (!crx) | 704 if (!crx) |
| 697 continue; | 705 continue; |
| 698 | 706 |
| 699 if (crx->status != CrxUpdateItem::kChecking) { | 707 if (crx->status != CrxUpdateItem::kChecking) { |
| 700 NOTREACHED(); | 708 NOTREACHED(); |
| 701 continue; // Not updating this component now. | 709 continue; // Not updating this component now. |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 761 // considered up to date. | 769 // considered up to date. |
| 762 ChangeItemStatus(CrxUpdateItem::kChecking, CrxUpdateItem::kUpToDate); | 770 ChangeItemStatus(CrxUpdateItem::kChecking, CrxUpdateItem::kUpToDate); |
| 763 | 771 |
| 764 // If there are updates pending we do a short wait, otherwise we take | 772 // If there are updates pending we do a short wait, otherwise we take |
| 765 // a longer delay until we check the components again. | 773 // a longer delay until we check the components again. |
| 766 ScheduleNextRun(num_updates_pending > 0 ? kStepDelayShort : kStepDelayLong); | 774 ScheduleNextRun(num_updates_pending > 0 ? kStepDelayShort : kStepDelayLong); |
| 767 } | 775 } |
| 768 | 776 |
| 769 void CrxUpdateService::OnUpdateCheckFailed(int error, | 777 void CrxUpdateService::OnUpdateCheckFailed(int error, |
| 770 const std::string& error_message) { | 778 const std::string& error_message) { |
| 771 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 779 DCHECK(thread_checker_.CalledOnValidThread()); |
| 772 DCHECK(error); | 780 DCHECK(error); |
| 773 size_t count = | 781 size_t count = |
| 774 ChangeItemStatus(CrxUpdateItem::kChecking, CrxUpdateItem::kNoUpdate); | 782 ChangeItemStatus(CrxUpdateItem::kChecking, CrxUpdateItem::kNoUpdate); |
| 775 DCHECK_GT(count, 0ul); | 783 DCHECK_GT(count, 0ul); |
| 776 VLOG(1) << "Update check failed."; | 784 VLOG(1) << "Update check failed."; |
| 777 ScheduleNextRun(kStepDelayLong); | 785 ScheduleNextRun(kStepDelayLong); |
| 778 } | 786 } |
| 779 | 787 |
| 780 // Called when progress is being made downloading a CRX. The progress may | 788 // Called when progress is being made downloading a CRX. The progress may |
| 781 // not monotonically increase due to how the CRX downloader switches between | 789 // not monotonically increase due to how the CRX downloader switches between |
| 782 // different downloaders and fallback urls. | 790 // different downloaders and fallback urls. |
| 783 void CrxUpdateService::DownloadProgress( | 791 void CrxUpdateService::DownloadProgress( |
| 784 const std::string& component_id, | 792 const std::string& component_id, |
| 785 const CrxDownloader::Result& download_result) { | 793 const CrxDownloader::Result& download_result) { |
| 786 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 794 DCHECK(thread_checker_.CalledOnValidThread()); |
| 787 NotifyObservers(Observer::COMPONENT_UPDATE_DOWNLOADING, component_id); | 795 NotifyObservers(Observer::COMPONENT_UPDATE_DOWNLOADING, component_id); |
| 788 } | 796 } |
| 789 | 797 |
| 790 // Called when the CRX package has been downloaded to a temporary location. | 798 // Called when the CRX package has been downloaded to a temporary location. |
| 791 // Here we fire the notifications and schedule the component-specific installer | 799 // Here we fire the notifications and schedule the component-specific installer |
| 792 // to be called in the file thread. | 800 // to be called in the file thread. |
| 793 void CrxUpdateService::DownloadComplete( | 801 void CrxUpdateService::DownloadComplete( |
| 794 scoped_ptr<CRXContext> crx_context, | 802 scoped_ptr<CRXContext> crx_context, |
| 795 const CrxDownloader::Result& download_result) { | 803 const CrxDownloader::Result& download_result) { |
| 796 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 804 DCHECK(thread_checker_.CalledOnValidThread()); |
| 797 | 805 |
| 798 CrxUpdateItem* crx = FindUpdateItemById(crx_context->id); | 806 CrxUpdateItem* crx = FindUpdateItemById(crx_context->id); |
| 799 DCHECK(crx->status == CrxUpdateItem::kDownloadingDiff || | 807 DCHECK(crx->status == CrxUpdateItem::kDownloadingDiff || |
| 800 crx->status == CrxUpdateItem::kDownloading); | 808 crx->status == CrxUpdateItem::kDownloading); |
| 801 | 809 |
| 802 AppendDownloadMetrics(crx_downloader_->download_metrics(), | 810 AppendDownloadMetrics(crx_downloader_->download_metrics(), |
| 803 &crx->download_metrics); | 811 &crx->download_metrics); |
| 804 | 812 |
| 805 crx_downloader_.reset(); | 813 crx_downloader_.reset(); |
| 806 | 814 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 887 // Reset the unpacker last, otherwise we free our own arguments. | 895 // Reset the unpacker last, otherwise we free our own arguments. |
| 888 unpacker_ = NULL; | 896 unpacker_ = NULL; |
| 889 } | 897 } |
| 890 | 898 |
| 891 // Installation has been completed. Adjust the component status and | 899 // Installation has been completed. Adjust the component status and |
| 892 // schedule the next check. Schedule a short delay before trying the full | 900 // schedule the next check. Schedule a short delay before trying the full |
| 893 // update when the differential update failed. | 901 // update when the differential update failed. |
| 894 void CrxUpdateService::DoneInstalling(const std::string& component_id, | 902 void CrxUpdateService::DoneInstalling(const std::string& component_id, |
| 895 ComponentUnpacker::Error error, | 903 ComponentUnpacker::Error error, |
| 896 int extra_code) { | 904 int extra_code) { |
| 897 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 905 DCHECK(thread_checker_.CalledOnValidThread()); |
| 898 | 906 |
| 899 ErrorCategory error_category = kErrorNone; | 907 ErrorCategory error_category = kErrorNone; |
| 900 switch (error) { | 908 switch (error) { |
| 901 case ComponentUnpacker::kNone: | 909 case ComponentUnpacker::kNone: |
| 902 break; | 910 break; |
| 903 case ComponentUnpacker::kInstallerError: | 911 case ComponentUnpacker::kInstallerError: |
| 904 error_category = kInstallError; | 912 error_category = kInstallError; |
| 905 break; | 913 break; |
| 906 default: | 914 default: |
| 907 error_category = kUnpackError; | 915 error_category = kUnpackError; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 935 } | 943 } |
| 936 | 944 |
| 937 ping_manager_->OnUpdateComplete(item); | 945 ping_manager_->OnUpdateComplete(item); |
| 938 | 946 |
| 939 // Move on to the next update, if there is one available. | 947 // Move on to the next update, if there is one available. |
| 940 ScheduleNextRun(kStepDelayMedium); | 948 ScheduleNextRun(kStepDelayMedium); |
| 941 } | 949 } |
| 942 | 950 |
| 943 void CrxUpdateService::NotifyObservers(Observer::Events event, | 951 void CrxUpdateService::NotifyObservers(Observer::Events event, |
| 944 const std::string& id) { | 952 const std::string& id) { |
| 945 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 953 DCHECK(thread_checker_.CalledOnValidThread()); |
| 946 FOR_EACH_OBSERVER(Observer, observer_list_, OnEvent(event, id)); | 954 FOR_EACH_OBSERVER(Observer, observer_list_, OnEvent(event, id)); |
| 947 } | 955 } |
| 948 | 956 |
| 949 content::ResourceThrottle* CrxUpdateService::GetOnDemandResourceThrottle( | 957 content::ResourceThrottle* CrxUpdateService::GetOnDemandResourceThrottle( |
| 950 net::URLRequest* request, | 958 net::URLRequest* request, |
| 951 const std::string& crx_id) { | 959 const std::string& crx_id) { |
| 952 // We give the raw pointer to the caller, who will delete it at will | 960 // We give the raw pointer to the caller, who will delete it at will |
| 953 // and we keep for ourselves a weak pointer to it so we can post tasks | 961 // and we keep for ourselves a weak pointer to it so we can post tasks |
| 954 // from the UI thread without having to track lifetime directly. | 962 // from the UI thread without having to track lifetime directly. |
| 955 CUResourceThrottle* rt = new CUResourceThrottle(request); | 963 CUResourceThrottle* rt = new CUResourceThrottle(request); |
| 956 BrowserThread::PostTask(BrowserThread::UI, | 964 BrowserThread::PostTask(BrowserThread::UI, |
| 957 FROM_HERE, | 965 FROM_HERE, |
| 958 base::Bind(&CrxUpdateService::OnNewResourceThrottle, | 966 base::Bind(&CrxUpdateService::OnNewResourceThrottle, |
| 959 base::Unretained(this), | 967 base::Unretained(this), |
| 960 rt->AsWeakPtr(), | 968 rt->AsWeakPtr(), |
| 961 crx_id)); | 969 crx_id)); |
| 962 return rt; | 970 return rt; |
| 963 } | 971 } |
| 964 | 972 |
| 965 void CrxUpdateService::OnNewResourceThrottle( | 973 void CrxUpdateService::OnNewResourceThrottle( |
| 966 base::WeakPtr<CUResourceThrottle> rt, | 974 base::WeakPtr<CUResourceThrottle> rt, |
| 967 const std::string& crx_id) { | 975 const std::string& crx_id) { |
| 968 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 976 DCHECK(thread_checker_.CalledOnValidThread()); |
| 969 // Check if we can on-demand update, else unblock the request anyway. | 977 // Check if we can on-demand update, else unblock the request anyway. |
| 970 CrxUpdateItem* item = FindUpdateItemById(crx_id); | 978 CrxUpdateItem* item = FindUpdateItemById(crx_id); |
| 971 Status status = OnDemandUpdateWithCooldown(item); | 979 Status status = OnDemandUpdateWithCooldown(item); |
| 972 if (status == kOk || status == kInProgress) { | 980 if (status == kOk || status == kInProgress) { |
| 973 item->throttles.push_back(rt); | 981 item->throttles.push_back(rt); |
| 974 return; | 982 return; |
| 975 } | 983 } |
| 976 UnblockResourceThrottle(rt); | 984 UnblockResourceThrottle(rt); |
| 977 } | 985 } |
| 978 | 986 |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1089 } | 1097 } |
| 1090 | 1098 |
| 1091 // The component update factory. Using the component updater as a singleton | 1099 // The component update factory. Using the component updater as a singleton |
| 1092 // is the job of the browser process. | 1100 // is the job of the browser process. |
| 1093 ComponentUpdateService* ComponentUpdateServiceFactory(Configurator* config) { | 1101 ComponentUpdateService* ComponentUpdateServiceFactory(Configurator* config) { |
| 1094 DCHECK(config); | 1102 DCHECK(config); |
| 1095 return new CrxUpdateService(config); | 1103 return new CrxUpdateService(config); |
| 1096 } | 1104 } |
| 1097 | 1105 |
| 1098 } // namespace component_updater | 1106 } // namespace component_updater |
| OLD | NEW |