Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Side by Side Diff: chrome/browser/component_updater/component_updater_service.cc

Issue 7601019: Component updater eight piece (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 <vector> 8 #include <vector>
9 9
10 #include "base/at_exit.h" 10 #include "base/at_exit.h"
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 running_ = false; 337 running_ = false;
338 timer_.Stop(); 338 timer_.Stop();
339 return kOk; 339 return kOk;
340 } 340 }
341 341
342 // This function sets the timer which will call ProcessPendingItems() there 342 // This function sets the timer which will call ProcessPendingItems() there
343 // are two kind of waits, the short one (with step_delay = true) and the 343 // are two kind of waits, the short one (with step_delay = true) and the
344 // long one. 344 // long one.
345 void CrxUpdateService::ScheduleNextRun(bool step_delay) { 345 void CrxUpdateService::ScheduleNextRun(bool step_delay) {
346 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 346 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
347 DCHECK(url_fetcher_.get() == NULL);
347 CHECK(!timer_.IsRunning()); 348 CHECK(!timer_.IsRunning());
348 // It could be the case that Stop() had been called while a url request 349 // It could be the case that Stop() had been called while a url request
349 // or unpacking was in flight, if so we arrive here but |running_| is 350 // or unpacking was in flight, if so we arrive here but |running_| is
350 // false. In that case do not loop again. 351 // false. In that case do not loop again.
351 if (!running_) 352 if (!running_)
352 return; 353 return;
353 354
355 int64 delay = step_delay ? config_->StepDelay() : config_->NextCheckDelay();
356
354 if (!step_delay) { 357 if (!step_delay) {
355 NotificationService::current()->Notify( 358 NotificationService::current()->Notify(
356 chrome::NOTIFICATION_COMPONENT_UPDATER_SLEEPING, 359 chrome::NOTIFICATION_COMPONENT_UPDATER_SLEEPING,
357 Source<ComponentUpdateService>(this), 360 Source<ComponentUpdateService>(this),
358 NotificationService::NoDetails()); 361 NotificationService::NoDetails());
359 // Zero is only used for unit tests. 362 // Zero is only used for unit tests.
360 if (0 == config_->NextCheckDelay()) 363 if (0 == delay)
361 return; 364 return;
362 } 365 }
363 366
364 int64 delay = step_delay ? config_->StepDelay() : config_->NextCheckDelay();
365 timer_.Start(base::TimeDelta::FromSeconds(delay), 367 timer_.Start(base::TimeDelta::FromSeconds(delay),
366 this, &CrxUpdateService::ProcessPendingItems); 368 this, &CrxUpdateService::ProcessPendingItems);
367 } 369 }
368 370
369 // Given a extension-like component id, find the associated component. 371 // Given a extension-like component id, find the associated component.
370 CrxUpdateItem* CrxUpdateService::FindUpdateItemById(const std::string& id) { 372 CrxUpdateItem* CrxUpdateService::FindUpdateItemById(const std::string& id) {
371 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 373 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
372 CrxUpdateItem::FindById finder(id); 374 CrxUpdateItem::FindById finder(id);
373 UpdateItems::iterator it = std::find_if(work_items_.begin(), 375 UpdateItems::iterator it = std::find_if(work_items_.begin(),
374 work_items_.end(), 376 work_items_.end(),
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 484
483 // Next we can go back to components we already checked, here 485 // Next we can go back to components we already checked, here
484 // we can also batch them in a single url request, as long as 486 // we can also batch them in a single url request, as long as
485 // we have not checked them recently. 487 // we have not checked them recently.
486 base::TimeDelta min_delta_time = 488 base::TimeDelta min_delta_time =
487 base::TimeDelta::FromSeconds(config_->MinimumReCheckWait()); 489 base::TimeDelta::FromSeconds(config_->MinimumReCheckWait());
488 490
489 for (UpdateItems::const_iterator it = work_items_.begin(); 491 for (UpdateItems::const_iterator it = work_items_.begin();
490 it != work_items_.end(); ++it) { 492 it != work_items_.end(); ++it) {
491 CrxUpdateItem* item = *it; 493 CrxUpdateItem* item = *it;
492 if ((item->status != CrxUpdateItem::kNoUpdate) || 494 if ((item->status != CrxUpdateItem::kNoUpdate) &&
493 (item->status != CrxUpdateItem::kUpToDate)) 495 (item->status != CrxUpdateItem::kUpToDate))
494 continue; 496 continue;
495 base::TimeDelta delta = base::Time::Now() - item->last_check; 497 base::TimeDelta delta = base::Time::Now() - item->last_check;
496 if (delta < min_delta_time) 498 if (delta < min_delta_time)
497 continue; 499 continue;
498 if (!AddItemToUpdateCheck(item, &query)) 500 if (!AddItemToUpdateCheck(item, &query))
499 break; 501 break;
500 } 502 }
501 // Finally, we check components that we already updated. 503 // Finally, we check components that we already updated.
502 for (UpdateItems::const_iterator it = work_items_.begin(); 504 for (UpdateItems::const_iterator it = work_items_.begin();
(...skipping 22 matching lines...) Expand all
525 } 527 }
526 528
527 // Caled when we got a response from the update server. It consists of an xml 529 // Caled when we got a response from the update server. It consists of an xml
528 // document following the omaha update scheme. 530 // document following the omaha update scheme.
529 void CrxUpdateService::OnURLFetchComplete(const URLFetcher* source, 531 void CrxUpdateService::OnURLFetchComplete(const URLFetcher* source,
530 UpdateContext*) { 532 UpdateContext*) {
531 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 533 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
532 if (FetchSuccess(*source)) { 534 if (FetchSuccess(*source)) {
533 std::string xml; 535 std::string xml;
534 source->GetResponseAsString(&xml); 536 source->GetResponseAsString(&xml);
537 url_fetcher_.reset();
535 ParseManifest(xml); 538 ParseManifest(xml);
536 } else { 539 } else {
540 url_fetcher_.reset();
537 CrxUpdateService::OnParseUpdateManifestFailed("network error"); 541 CrxUpdateService::OnParseUpdateManifestFailed("network error");
538 } 542 }
539 url_fetcher_.reset();
540 } 543 }
541 544
542 // Parsing the manifest is either done right now for tests or in a sandboxed 545 // Parsing the manifest is either done right now for tests or in a sandboxed
543 // process for the production environment. This mitigates the case where an 546 // process for the production environment. This mitigates the case where an
544 // attacker was able to feed us a malicious xml string. 547 // attacker was able to feed us a malicious xml string.
545 void CrxUpdateService::ParseManifest(const std::string& xml) { 548 void CrxUpdateService::ParseManifest(const std::string& xml) {
546 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 549 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
547 if (config_->InProcess()) { 550 if (config_->InProcess()) {
548 UpdateManifest manifest; 551 UpdateManifest manifest;
549 if (!manifest.Parse(xml)) { 552 if (!manifest.Parse(xml)) {
(...skipping 20 matching lines...) Expand all
570 std::vector<UpdateManifest::Result>::const_iterator it; 573 std::vector<UpdateManifest::Result>::const_iterator it;
571 for (it = results.list.begin(); it != results.list.end(); ++it) { 574 for (it = results.list.begin(); it != results.list.end(); ++it) {
572 CrxUpdateItem* crx = FindUpdateItemById(it->extension_id); 575 CrxUpdateItem* crx = FindUpdateItemById(it->extension_id);
573 if (!crx) 576 if (!crx)
574 continue; 577 continue;
575 578
576 if (crx->status != CrxUpdateItem::kChecking) 579 if (crx->status != CrxUpdateItem::kChecking)
577 continue; // Not updating this component now. 580 continue; // Not updating this component now.
578 581
579 if (it->version.empty()) { 582 if (it->version.empty()) {
583 // No version means no update available.
580 crx->status = CrxUpdateItem::kNoUpdate; 584 crx->status = CrxUpdateItem::kNoUpdate;
581 continue; // No version means no update available. 585 continue;
582 } 586 }
583 if (!IsVersionNewer(crx->component.version, it->version)) { 587 if (!IsVersionNewer(crx->component.version, it->version)) {
588 // Our component is up to date.
584 crx->status = CrxUpdateItem::kUpToDate; 589 crx->status = CrxUpdateItem::kUpToDate;
585 continue; // Our component is up to date. 590 continue;
586 } 591 }
587 if (!it->browser_min_version.empty()) { 592 if (!it->browser_min_version.empty()) {
588 if (IsVersionNewer(chrome_version_, it->browser_min_version)) 593 if (IsVersionNewer(chrome_version_, it->browser_min_version)) {
589 continue; // Does not apply for this version. 594 // Does not apply for this chrome version.
595 crx->status = CrxUpdateItem::kNoUpdate;
596 continue;
597 }
590 } 598 }
591 // All test passed. Queue an upgrade for this component and fire the 599 // All test passed. Queue an upgrade for this component and fire the
592 // notifications. 600 // notifications.
593 crx->crx_url = it->crx_url; 601 crx->crx_url = it->crx_url;
594 crx->status = CrxUpdateItem::kCanUpdate; 602 crx->status = CrxUpdateItem::kCanUpdate;
595 ++update_pending; 603 ++update_pending;
596 604
597 NotificationService::current()->Notify( 605 NotificationService::current()->Notify(
598 chrome::NOTIFICATION_COMPONENT_UPDATE_FOUND, 606 chrome::NOTIFICATION_COMPONENT_UPDATE_FOUND,
599 Source<std::string>(&crx->id), 607 Source<std::string>(&crx->id),
600 NotificationService::NoDetails()); 608 NotificationService::NoDetails());
601 } 609 }
610
611 // All the components that are not mentioned in the manifest we
612 // consider them up to date.
613 ChangeItemStatus(CrxUpdateItem::kChecking, CrxUpdateItem::kUpToDate);
614
602 // If there are updates pending we do a short wait. 615 // If there are updates pending we do a short wait.
603 ScheduleNextRun(update_pending ? true : false); 616 ScheduleNextRun(update_pending ? true : false);
604 } 617 }
605 618
606 void CrxUpdateService::OnParseUpdateManifestFailed( 619 void CrxUpdateService::OnParseUpdateManifestFailed(
607 const std::string& error_message) { 620 const std::string& error_message) {
608 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 621 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
609 size_t count = ChangeItemStatus(CrxUpdateItem::kChecking, 622 size_t count = ChangeItemStatus(CrxUpdateItem::kChecking,
610 CrxUpdateItem::kNoUpdate); 623 CrxUpdateItem::kNoUpdate);
611 DCHECK_GT(count, 0ul); 624 DCHECK_GT(count, 0ul);
612 ScheduleNextRun(false); 625 ScheduleNextRun(false);
613 } 626 }
614 627
615 // Called when the CRX package has been downloaded to a temporary location. 628 // Called when the CRX package has been downloaded to a temporary location.
616 // Here we fire the notifications and schedule the component-specific installer 629 // Here we fire the notifications and schedule the component-specific installer
617 // to be called in the file thread. 630 // to be called in the file thread.
618 void CrxUpdateService::OnURLFetchComplete(const URLFetcher* source, 631 void CrxUpdateService::OnURLFetchComplete(const URLFetcher* source,
619 CRXContext* context) { 632 CRXContext* context) {
620 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 633 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
621 base::PlatformFileError error_code; 634 base::PlatformFileError error_code;
622 635
623 if (source->FileErrorOccurred(&error_code) || !FetchSuccess(*source)) { 636 if (source->FileErrorOccurred(&error_code) || !FetchSuccess(*source)) {
624 size_t count = ChangeItemStatus(CrxUpdateItem::kDownloading, 637 size_t count = ChangeItemStatus(CrxUpdateItem::kDownloading,
625 CrxUpdateItem::kNoUpdate); 638 CrxUpdateItem::kNoUpdate);
626 DCHECK_EQ(count, 1ul); 639 DCHECK_EQ(count, 1ul);
640 url_fetcher_.reset();
627 ScheduleNextRun(false); 641 ScheduleNextRun(false);
628 } else { 642 } else {
629 FilePath temp_crx_path; 643 FilePath temp_crx_path;
630 CHECK(source->GetResponseAsFilePath(true, &temp_crx_path)); 644 CHECK(source->GetResponseAsFilePath(true, &temp_crx_path));
631 size_t count = ChangeItemStatus(CrxUpdateItem::kDownloading, 645 size_t count = ChangeItemStatus(CrxUpdateItem::kDownloading,
632 CrxUpdateItem::kUpdating); 646 CrxUpdateItem::kUpdating);
633 DCHECK_EQ(count, 1ul); 647 DCHECK_EQ(count, 1ul);
648 url_fetcher_.reset();
649
634 NotificationService::current()->Notify( 650 NotificationService::current()->Notify(
635 chrome::NOTIFICATION_COMPONENT_UPDATE_READY, 651 chrome::NOTIFICATION_COMPONENT_UPDATE_READY,
636 Source<std::string>(&context->id), 652 Source<std::string>(&context->id),
637 NotificationService::NoDetails()); 653 NotificationService::NoDetails());
638 654
639 BrowserThread::PostDelayedTask(BrowserThread::FILE, FROM_HERE, 655 BrowserThread::PostDelayedTask(BrowserThread::FILE, FROM_HERE,
640 NewRunnableMethod(this, &CrxUpdateService::Install, 656 NewRunnableMethod(this, &CrxUpdateService::Install,
641 context, 657 context,
642 temp_crx_path), 658 temp_crx_path),
643 config_->StepDelay()); 659 config_->StepDelay());
644 } 660 }
645
646 url_fetcher_.reset();
647 } 661 }
648 662
649 // Install consists of digital signature verification, unpacking and then 663 // Install consists of digital signature verification, unpacking and then
650 // calling the component specific installer. All that is handled by the 664 // calling the component specific installer. All that is handled by the
651 // |unpacker|. If there is an error this function is in charge of deleting 665 // |unpacker|. If there is an error this function is in charge of deleting
652 // the files created. 666 // the files created.
653 void CrxUpdateService::Install(const CRXContext* context, 667 void CrxUpdateService::Install(const CRXContext* context,
654 const FilePath& crx_path) { 668 const FilePath& crx_path) {
655 // This function owns the |crx_path| and the |context| object. 669 // This function owns the |crx_path| and the |context| object.
656 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); 670 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
(...skipping 23 matching lines...) Expand all
680 } 694 }
681 695
682 // The component update factory. Using the component updater as a singleton 696 // The component update factory. Using the component updater as a singleton
683 // is the job of the browser process. 697 // is the job of the browser process.
684 ComponentUpdateService* ComponentUpdateServiceFactory( 698 ComponentUpdateService* ComponentUpdateServiceFactory(
685 ComponentUpdateService::Configurator* config) { 699 ComponentUpdateService::Configurator* config) {
686 DCHECK(config); 700 DCHECK(config);
687 return new CrxUpdateService(config); 701 return new CrxUpdateService(config);
688 } 702 }
689 703
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698