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