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

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

Issue 12054003: Add an API to component_updater that asks to do an update check "now". (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Do not use NextCheckDelay for non-running timer case (sideeffects). Created 7 years, 10 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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 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 <vector> 8 #include <vector>
9 9
10 #include "base/at_exit.h" 10 #include "base/at_exit.h"
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 class CrxUpdateService : public ComponentUpdateService { 246 class CrxUpdateService : public ComponentUpdateService {
247 public: 247 public:
248 explicit CrxUpdateService(ComponentUpdateService::Configurator* config); 248 explicit CrxUpdateService(ComponentUpdateService::Configurator* config);
249 249
250 virtual ~CrxUpdateService(); 250 virtual ~CrxUpdateService();
251 251
252 // Overrides for ComponentUpdateService. 252 // Overrides for ComponentUpdateService.
253 virtual Status Start() OVERRIDE; 253 virtual Status Start() OVERRIDE;
254 virtual Status Stop() OVERRIDE; 254 virtual Status Stop() OVERRIDE;
255 virtual Status RegisterComponent(const CrxComponent& component) OVERRIDE; 255 virtual Status RegisterComponent(const CrxComponent& component) OVERRIDE;
256 virtual Status PingUpdateCheck(const CrxComponent& component) OVERRIDE;
256 257
257 // The only purpose of this class is to forward the 258 // The only purpose of this class is to forward the
258 // UtilityProcessHostClient callbacks so CrxUpdateService does 259 // UtilityProcessHostClient callbacks so CrxUpdateService does
259 // not have to derive from it because that is refcounted. 260 // not have to derive from it because that is refcounted.
260 class ManifestParserBridge : public UtilityProcessHostClient { 261 class ManifestParserBridge : public UtilityProcessHostClient {
261 public: 262 public:
262 explicit ManifestParserBridge(CrxUpdateService* service) 263 explicit ManifestParserBridge(CrxUpdateService* service)
263 : service_(service) {} 264 : service_(service) {}
264 265
265 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { 266 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 const UpdateManifest::Results& results); 317 const UpdateManifest::Results& results);
317 318
318 // See ManifestParserBridge. 319 // See ManifestParserBridge.
319 void OnParseUpdateManifestFailed( 320 void OnParseUpdateManifestFailed(
320 const std::string& error_message); 321 const std::string& error_message);
321 322
322 bool AddItemToUpdateCheck(CrxUpdateItem* item, std::string* query); 323 bool AddItemToUpdateCheck(CrxUpdateItem* item, std::string* query);
323 324
324 void ProcessPendingItems(); 325 void ProcessPendingItems();
325 326
327 typedef std::vector<CrxUpdateItem*> UpdateItems;
328 bool ProcessWorkItems(const UpdateItems& work_items);
329
326 void ScheduleNextRun(bool step_delay); 330 void ScheduleNextRun(bool step_delay);
327 331
328 void ParseManifest(const std::string& xml); 332 void ParseManifest(const std::string& xml);
329 333
330 void Install(const CRXContext* context, const FilePath& crx_path); 334 void Install(const CRXContext* context, const FilePath& crx_path);
331 335
332 void DoneInstalling(const std::string& component_id, 336 void DoneInstalling(const std::string& component_id,
333 ComponentUnpacker::Error error); 337 ComponentUnpacker::Error error);
334 338
335 size_t ChangeItemStatus(CrxUpdateItem::Status from, 339 size_t ChangeItemStatus(CrxUpdateItem::Status from,
336 CrxUpdateItem::Status to); 340 CrxUpdateItem::Status to);
337 341
338 CrxUpdateItem* FindUpdateItemById(const std::string& id); 342 CrxUpdateItem* FindUpdateItemById(const std::string& id);
339 343
340 scoped_ptr<Config> config_; 344 scoped_ptr<Config> config_;
341 345
342 scoped_ptr<net::URLFetcher> url_fetcher_; 346 scoped_ptr<net::URLFetcher> url_fetcher_;
343 347
344 typedef std::vector<CrxUpdateItem*> UpdateItems;
345 UpdateItems work_items_; 348 UpdateItems work_items_;
346 349
347 base::OneShotTimer<CrxUpdateService> timer_; 350 base::OneShotTimer<CrxUpdateService> timer_;
348 351
349 Version chrome_version_; 352 Version chrome_version_;
350 353
351 bool running_; 354 bool running_;
352 355
353 DISALLOW_COPY_AND_ASSIGN(CrxUpdateService); 356 DISALLOW_COPY_AND_ASSIGN(CrxUpdateService);
354 }; 357 };
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 std::string* query) { 499 std::string* query) {
497 if (!AddQueryString(item->id, 500 if (!AddQueryString(item->id,
498 item->component.version.GetString(), 501 item->component.version.GetString(),
499 config_->UrlSizeLimit(), query)) 502 config_->UrlSizeLimit(), query))
500 return false; 503 return false;
501 item->status = CrxUpdateItem::kChecking; 504 item->status = CrxUpdateItem::kChecking;
502 item->last_check = base::Time::Now(); 505 item->last_check = base::Time::Now();
503 return true; 506 return true;
504 } 507 }
505 508
506 // Here is where the work gets scheduled. Given that our |work_items_| list 509 // Here is where the work gets scheduled.
510 void CrxUpdateService::ProcessPendingItems() {
511 if (!ProcessWorkItems(work_items_)) {
512 // No components to update. Next check after the long sleep.
513 ScheduleNextRun(false);
514 }
515 }
516
517 // Start the process of checking for an update, for a particular component
518 // that was previously registered. If the component does not exist return
519 // kError, otherwise kOk.
520 ComponentUpdateService::Status CrxUpdateService::PingUpdateCheck(
521 const CrxComponent& component) {
522 if (component.pk_hash.empty() ||
523 !component.version.IsValid() ||
524 !component.installer)
525 return kError;
526
527 std::string id =
528 HexStringToID(StringToLowerASCII(base::HexEncode(&component.pk_hash[0],
529 component.pk_hash.size()/2)));
530 CrxUpdateItem* uit;
531 uit = FindUpdateItemById(id);
532 if (!uit)
533 return kError;
534
535 UpdateItems one_item;
536 one_item.push_back(uit);
537
538 // The timer is may already be running when we do this ping.
539 // If the timer is running, cancel the currently scheduled timer,
540 // but remember the remaining time delta so that we can reset the timer
541 // to something comparable if there is nothing to do.
542 base::TimeDelta remaining_delay;
543 bool remaining_delay_set = false;
544 if (timer_.IsRunning()) {
545 remaining_delay = timer_.desired_run_time() - base::TimeTicks::Now();
546 remaining_delay_set = true;
547 timer_.Stop();
548 }
jvoung (off chromium) 2013/01/30 02:20:21 Good point about having fetches or installs in fli
549
550 if (!ProcessWorkItems(one_item)) {
551 // If there is work to do, the timer is re-scheduled by a work step.
552 // However, if there is nothing to actually do, we must schedule the
553 // timer here.
554 bool use_step_delay;
555 if (remaining_delay_set) {
556 use_step_delay =
557 remaining_delay < base::TimeDelta::FromSeconds(config_->StepDelay());
558 } else {
559 // Guess that it is not a step_delay.
560 use_step_delay = false;
561 }
562 ScheduleNextRun(use_step_delay);
563 }
564 return kOk;
565 }
566
567 // Here is where the work gets scheduled. Given that our |work_items| list
507 // is expected to be ten or less items, we simply loop several times. 568 // is expected to be ten or less items, we simply loop several times.
508 void CrxUpdateService::ProcessPendingItems() { 569 // Returns |true| if there is work to be done.
570 bool CrxUpdateService::ProcessWorkItems(const UpdateItems& work_items) {
509 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 571 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
510 // First check for ready upgrades and do one. The first 572 // First check for ready upgrades and do one. The first
511 // step is to fetch the crx package. 573 // step is to fetch the crx package.
512 for (UpdateItems::const_iterator it = work_items_.begin(); 574 for (UpdateItems::const_iterator it = work_items.begin();
513 it != work_items_.end(); ++it) { 575 it != work_items.end(); ++it) {
514 CrxUpdateItem* item = *it; 576 CrxUpdateItem* item = *it;
515 if (item->status != CrxUpdateItem::kCanUpdate) 577 if (item->status != CrxUpdateItem::kCanUpdate)
516 continue; 578 continue;
517 // Found component to update, start the process. 579 // Found component to update, start the process.
518 item->status = CrxUpdateItem::kDownloading; 580 item->status = CrxUpdateItem::kDownloading;
519 CRXContext* context = new CRXContext; 581 CRXContext* context = new CRXContext;
520 context->pk_hash = item->component.pk_hash; 582 context->pk_hash = item->component.pk_hash;
521 context->id = item->id; 583 context->id = item->id;
522 context->installer = item->component.installer; 584 context->installer = item->component.installer;
523 url_fetcher_.reset(net::URLFetcher::Create( 585 url_fetcher_.reset(net::URLFetcher::Create(
524 0, item->crx_url, net::URLFetcher::GET, 586 0, item->crx_url, net::URLFetcher::GET,
525 MakeContextDelegate(this, context))); 587 MakeContextDelegate(this, context)));
526 StartFetch(url_fetcher_.get(), config_->RequestContext(), true); 588 StartFetch(url_fetcher_.get(), config_->RequestContext(), true);
527 return; 589 return true;
528 } 590 }
529 591
530 for (size_t ix = 0; ix != arraysize(kManifestSources); ++ix) { 592 for (size_t ix = 0; ix != arraysize(kManifestSources); ++ix) {
531 const CrxComponent::UrlSource manifest_source = kManifestSources[ix]; 593 const CrxComponent::UrlSource manifest_source = kManifestSources[ix];
532 594
533 std::string query; 595 std::string query;
534 // If no pending upgrades, we check if there are new components we have not 596 // If no pending upgrades, we check if there are new components we have not
535 // checked against the server. We can batch some in a single url request. 597 // checked against the server. We can batch some in a single url request.
536 for (UpdateItems::const_iterator it = work_items_.begin(); 598 for (UpdateItems::const_iterator it = work_items.begin();
537 it != work_items_.end(); ++it) { 599 it != work_items.end(); ++it) {
538 CrxUpdateItem* item = *it; 600 CrxUpdateItem* item = *it;
539 if (item->status != CrxUpdateItem::kNew) 601 if (item->status != CrxUpdateItem::kNew)
540 continue; 602 continue;
541 if (item->component.source != manifest_source) 603 if (item->component.source != manifest_source)
542 continue; 604 continue;
543 if (!AddItemToUpdateCheck(item, &query)) 605 if (!AddItemToUpdateCheck(item, &query))
544 break; 606 break;
545 } 607 }
546 608
547 // Next we can go back to components we already checked, here 609 // Next we can go back to components we already checked, here
548 // we can also batch them in a single url request, as long as 610 // we can also batch them in a single url request, as long as
549 // we have not checked them recently. 611 // we have not checked them recently.
550 const base::TimeDelta min_delta_time = 612 const base::TimeDelta min_delta_time =
551 base::TimeDelta::FromSeconds(config_->MinimumReCheckWait()); 613 base::TimeDelta::FromSeconds(config_->MinimumReCheckWait());
552 614
553 for (UpdateItems::const_iterator it = work_items_.begin(); 615 for (UpdateItems::const_iterator it = work_items.begin();
554 it != work_items_.end(); ++it) { 616 it != work_items.end(); ++it) {
555 CrxUpdateItem* item = *it; 617 CrxUpdateItem* item = *it;
556 if ((item->status != CrxUpdateItem::kNoUpdate) && 618 if ((item->status != CrxUpdateItem::kNoUpdate) &&
557 (item->status != CrxUpdateItem::kUpToDate)) 619 (item->status != CrxUpdateItem::kUpToDate))
558 continue; 620 continue;
559 if (item->component.source != manifest_source) 621 if (item->component.source != manifest_source)
560 continue; 622 continue;
561 base::TimeDelta delta = base::Time::Now() - item->last_check; 623 base::TimeDelta delta = base::Time::Now() - item->last_check;
562 if (delta < min_delta_time) 624 if (delta < min_delta_time)
563 continue; 625 continue;
564 if (!AddItemToUpdateCheck(item, &query)) 626 if (!AddItemToUpdateCheck(item, &query))
565 break; 627 break;
566 } 628 }
567 629
568 // Finally, we check components that we already updated as long as 630 // Finally, we check components that we already updated as long as
569 // we have not checked them recently. 631 // we have not checked them recently.
570 for (UpdateItems::const_iterator it = work_items_.begin(); 632 for (UpdateItems::const_iterator it = work_items.begin();
571 it != work_items_.end(); ++it) { 633 it != work_items.end(); ++it) {
572 CrxUpdateItem* item = *it; 634 CrxUpdateItem* item = *it;
573 if (item->status != CrxUpdateItem::kUpdated) 635 if (item->status != CrxUpdateItem::kUpdated)
574 continue; 636 continue;
575 if (item->component.source != manifest_source) 637 if (item->component.source != manifest_source)
576 continue; 638 continue;
577 base::TimeDelta delta = base::Time::Now() - item->last_check; 639 base::TimeDelta delta = base::Time::Now() - item->last_check;
578 if (delta < min_delta_time) 640 if (delta < min_delta_time)
579 continue; 641 continue;
580 if (!AddItemToUpdateCheck(item, &query)) 642 if (!AddItemToUpdateCheck(item, &query))
581 break; 643 break;
582 } 644 }
583 645
584 // If no components to update we move down to the next source. 646 // If no components to update we move down to the next source.
585 if (query.empty()) 647 if (query.empty())
586 continue; 648 continue;
587 649
588 // We got components to check. Start the url request and exit. 650 // We got components to check. Start the url request and exit.
589 const std::string full_query = 651 const std::string full_query =
590 MakeFinalQuery(config_->UpdateUrl(manifest_source).spec(), 652 MakeFinalQuery(config_->UpdateUrl(manifest_source).spec(),
591 query, 653 query,
592 config_->ExtraRequestParams()); 654 config_->ExtraRequestParams());
593 655
594 url_fetcher_.reset(net::URLFetcher::Create( 656 url_fetcher_.reset(net::URLFetcher::Create(
595 0, GURL(full_query), net::URLFetcher::GET, 657 0, GURL(full_query), net::URLFetcher::GET,
596 MakeContextDelegate(this, new UpdateContext()))); 658 MakeContextDelegate(this, new UpdateContext())));
597 StartFetch(url_fetcher_.get(), config_->RequestContext(), false); 659 StartFetch(url_fetcher_.get(), config_->RequestContext(), false);
598 return; 660 return true;
599 } 661 }
600 662
601 // No components to update. Next check after the long sleep. 663 return false;
602 ScheduleNextRun(false);
603 } 664 }
604 665
605 // Caled when we got a response from the update server. It consists of an xml 666 // Called when we got a response from the update server. It consists of an xml
606 // document following the omaha update scheme. 667 // document following the omaha update scheme.
607 void CrxUpdateService::OnURLFetchComplete(const net::URLFetcher* source, 668 void CrxUpdateService::OnURLFetchComplete(const net::URLFetcher* source,
608 UpdateContext* context) { 669 UpdateContext* context) {
609 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 670 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
610 if (FetchSuccess(*source)) { 671 if (FetchSuccess(*source)) {
611 std::string xml; 672 std::string xml;
612 source->GetResponseAsString(&xml); 673 source->GetResponseAsString(&xml);
613 url_fetcher_.reset(); 674 url_fetcher_.reset();
614 ParseManifest(xml); 675 ParseManifest(xml);
615 } else { 676 } else {
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 ScheduleNextRun(false); 860 ScheduleNextRun(false);
800 } 861 }
801 862
802 // The component update factory. Using the component updater as a singleton 863 // The component update factory. Using the component updater as a singleton
803 // is the job of the browser process. 864 // is the job of the browser process.
804 ComponentUpdateService* ComponentUpdateServiceFactory( 865 ComponentUpdateService* ComponentUpdateServiceFactory(
805 ComponentUpdateService::Configurator* config) { 866 ComponentUpdateService::Configurator* config) {
806 DCHECK(config); 867 DCHECK(config);
807 return new CrxUpdateService(config); 868 return new CrxUpdateService(config);
808 } 869 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698