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 |