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

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: move commandline check 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 <set>
8 #include <vector> 9 #include <vector>
9 10
10 #include "base/at_exit.h" 11 #include "base/at_exit.h"
11 #include "base/bind.h" 12 #include "base/bind.h"
12 #include "base/file_path.h" 13 #include "base/file_path.h"
13 #include "base/file_util.h" 14 #include "base/file_util.h"
14 #include "base/logging.h" 15 #include "base/logging.h"
15 #include "base/memory/scoped_ptr.h" 16 #include "base/memory/scoped_ptr.h"
16 #include "base/stl_util.h" 17 #include "base/stl_util.h"
17 #include "base/string_piece.h" 18 #include "base/string_piece.h"
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 class CrxUpdateService : public ComponentUpdateService { 247 class CrxUpdateService : public ComponentUpdateService {
247 public: 248 public:
248 explicit CrxUpdateService(ComponentUpdateService::Configurator* config); 249 explicit CrxUpdateService(ComponentUpdateService::Configurator* config);
249 250
250 virtual ~CrxUpdateService(); 251 virtual ~CrxUpdateService();
251 252
252 // Overrides for ComponentUpdateService. 253 // Overrides for ComponentUpdateService.
253 virtual Status Start() OVERRIDE; 254 virtual Status Start() OVERRIDE;
254 virtual Status Stop() OVERRIDE; 255 virtual Status Stop() OVERRIDE;
255 virtual Status RegisterComponent(const CrxComponent& component) OVERRIDE; 256 virtual Status RegisterComponent(const CrxComponent& component) OVERRIDE;
257 virtual Status CheckForUpdateSoon(const CrxComponent& component) OVERRIDE;
256 258
257 // The only purpose of this class is to forward the 259 // The only purpose of this class is to forward the
258 // UtilityProcessHostClient callbacks so CrxUpdateService does 260 // UtilityProcessHostClient callbacks so CrxUpdateService does
259 // not have to derive from it because that is refcounted. 261 // not have to derive from it because that is refcounted.
260 class ManifestParserBridge : public UtilityProcessHostClient { 262 class ManifestParserBridge : public UtilityProcessHostClient {
261 public: 263 public:
262 explicit ManifestParserBridge(CrxUpdateService* service) 264 explicit ManifestParserBridge(CrxUpdateService* service)
263 : service_(service) {} 265 : service_(service) {}
264 266
265 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { 267 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 size_t ChangeItemStatus(CrxUpdateItem::Status from, 337 size_t ChangeItemStatus(CrxUpdateItem::Status from,
336 CrxUpdateItem::Status to); 338 CrxUpdateItem::Status to);
337 339
338 CrxUpdateItem* FindUpdateItemById(const std::string& id); 340 CrxUpdateItem* FindUpdateItemById(const std::string& id);
339 341
340 scoped_ptr<Config> config_; 342 scoped_ptr<Config> config_;
341 343
342 scoped_ptr<net::URLFetcher> url_fetcher_; 344 scoped_ptr<net::URLFetcher> url_fetcher_;
343 345
344 typedef std::vector<CrxUpdateItem*> UpdateItems; 346 typedef std::vector<CrxUpdateItem*> UpdateItems;
347 // A collection of every work item.
345 UpdateItems work_items_; 348 UpdateItems work_items_;
346 349
350 // A particular set of items from work_items_, which should be checked ASAP.
351 std::set<CrxUpdateItem*> requested_work_items_;
352
347 base::OneShotTimer<CrxUpdateService> timer_; 353 base::OneShotTimer<CrxUpdateService> timer_;
348 354
349 Version chrome_version_; 355 Version chrome_version_;
350 356
351 bool running_; 357 bool running_;
352 358
353 DISALLOW_COPY_AND_ASSIGN(CrxUpdateService); 359 DISALLOW_COPY_AND_ASSIGN(CrxUpdateService);
354 }; 360 };
355 361
356 ////////////////////////////////////////////////////////////////////////////// 362 //////////////////////////////////////////////////////////////////////////////
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 } 395 }
390 396
391 // Stop the main check + update loop. In flight operations will be 397 // Stop the main check + update loop. In flight operations will be
392 // completed. 398 // completed.
393 ComponentUpdateService::Status CrxUpdateService::Stop() { 399 ComponentUpdateService::Status CrxUpdateService::Stop() {
394 running_ = false; 400 running_ = false;
395 timer_.Stop(); 401 timer_.Stop();
396 return kOk; 402 return kOk;
397 } 403 }
398 404
399 // This function sets the timer which will call ProcessPendingItems() there 405 // This function sets the timer which will call ProcessPendingItems() or
400 // are two kind of waits, the short one (with step_delay = true) and the 406 // ProcessRequestedItem() if there is an important requested item. There
401 // long one. 407 // are two kinds of waits: a short step_delay (when step_status is
408 // kPrevInProgress) and a long one when a full check/update cycle
409 // has completed either successfully or with an error.
402 void CrxUpdateService::ScheduleNextRun(bool step_delay) { 410 void CrxUpdateService::ScheduleNextRun(bool step_delay) {
403 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 411 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
404 DCHECK(url_fetcher_.get() == NULL); 412 DCHECK(url_fetcher_.get() == NULL);
405 CHECK(!timer_.IsRunning()); 413 CHECK(!timer_.IsRunning());
406 // It could be the case that Stop() had been called while a url request 414 // It could be the case that Stop() had been called while a url request
407 // or unpacking was in flight, if so we arrive here but |running_| is 415 // or unpacking was in flight, if so we arrive here but |running_| is
408 // false. In that case do not loop again. 416 // false. In that case do not loop again.
409 if (!running_) 417 if (!running_)
410 return; 418 return;
411 419
412 int64 delay = step_delay ? config_->StepDelay() : config_->NextCheckDelay(); 420 // Keep the delay short if in the middle of an update (step_delay),
421 // or there are new requested_work_items_ that have not been processed yet.
422 int64 delay = (step_delay || requested_work_items_.size() > 0)
423 ? config_->StepDelay() : config_->NextCheckDelay();
413 424
414 if (!step_delay) { 425 if (!step_delay) {
415 content::NotificationService::current()->Notify( 426 content::NotificationService::current()->Notify(
416 chrome::NOTIFICATION_COMPONENT_UPDATER_SLEEPING, 427 chrome::NOTIFICATION_COMPONENT_UPDATER_SLEEPING,
417 content::Source<ComponentUpdateService>(this), 428 content::Source<ComponentUpdateService>(this),
418 content::NotificationService::NoDetails()); 429 content::NotificationService::NoDetails());
419 // Zero is only used for unit tests. 430 // Zero is only used for unit tests.
420 if (0 == delay) 431 if (0 == delay)
421 return; 432 return;
422 } 433 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
496 std::string* query) { 507 std::string* query) {
497 if (!AddQueryString(item->id, 508 if (!AddQueryString(item->id,
498 item->component.version.GetString(), 509 item->component.version.GetString(),
499 config_->UrlSizeLimit(), query)) 510 config_->UrlSizeLimit(), query))
500 return false; 511 return false;
501 item->status = CrxUpdateItem::kChecking; 512 item->status = CrxUpdateItem::kChecking;
502 item->last_check = base::Time::Now(); 513 item->last_check = base::Time::Now();
503 return true; 514 return true;
504 } 515 }
505 516
517 // Start the process of checking for an update, for a particular component
518 // that was previously registered.
519 ComponentUpdateService::Status CrxUpdateService::CheckForUpdateSoon(
520 const CrxComponent& component) {
521 if (component.pk_hash.empty() ||
522 !component.version.IsValid() ||
523 !component.installer)
524 return kError;
525
526 std::string id =
527 HexStringToID(StringToLowerASCII(base::HexEncode(&component.pk_hash[0],
528 component.pk_hash.size()/2)));
529
530 CrxUpdateItem* uit;
531 uit = FindUpdateItemById(id);
532 if (!uit)
533 return kError;
534
535 // Check if the request is too soon.
536 base::TimeDelta delta = base::Time::Now() - uit->last_check;
537 if (delta < base::TimeDelta::FromSeconds(config_->OnDemandDelay())) {
538 return kError;
539 }
540
541 switch (uit->status) {
542 // If the item is already in the process of being updated, there is
543 // no point in this call, so return kInProgress.
544 case CrxUpdateItem::kChecking:
545 case CrxUpdateItem::kCanUpdate:
546 case CrxUpdateItem::kDownloading:
547 case CrxUpdateItem::kUpdating:
548 return kInProgress;
549 // Otherwise the item was already checked a while back (or it is new),
550 // set its status to kNew to give it a slightly higher priority.
551 case CrxUpdateItem::kNew:
552 case CrxUpdateItem::kUpdated:
553 case CrxUpdateItem::kUpToDate:
554 case CrxUpdateItem::kNoUpdate:
555 uit->status = CrxUpdateItem::kNew;
556 requested_work_items_.insert(uit);
557 break;
558 case CrxUpdateItem::kLastStatus:
559 NOTREACHED() << uit->status;
560 }
561
562 // In case the current delay is long, set the timer to a shorter value
563 // to get the ball rolling.
564 if (timer_.IsRunning()) {
565 timer_.Stop();
566 timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(config_->StepDelay()),
567 this, &CrxUpdateService::ProcessPendingItems);
568 }
569
570 return kOk;
571 }
572
506 // Here is where the work gets scheduled. Given that our |work_items_| list 573 // 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. 574 // is expected to be ten or less items, we simply loop several times.
508 void CrxUpdateService::ProcessPendingItems() { 575 void CrxUpdateService::ProcessPendingItems() {
509 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 576 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
510 // First check for ready upgrades and do one. The first 577 // First check for ready upgrades and do one. The first
511 // step is to fetch the crx package. 578 // step is to fetch the crx package.
512 for (UpdateItems::const_iterator it = work_items_.begin(); 579 for (UpdateItems::const_iterator it = work_items_.begin();
513 it != work_items_.end(); ++it) { 580 it != work_items_.end(); ++it) {
514 CrxUpdateItem* item = *it; 581 CrxUpdateItem* item = *it;
515 if (item->status != CrxUpdateItem::kCanUpdate) 582 if (item->status != CrxUpdateItem::kCanUpdate)
(...skipping 19 matching lines...) Expand all
535 // checked against the server. We can batch some in a single url request. 602 // checked against the server. We can batch some in a single url request.
536 for (UpdateItems::const_iterator it = work_items_.begin(); 603 for (UpdateItems::const_iterator it = work_items_.begin();
537 it != work_items_.end(); ++it) { 604 it != work_items_.end(); ++it) {
538 CrxUpdateItem* item = *it; 605 CrxUpdateItem* item = *it;
539 if (item->status != CrxUpdateItem::kNew) 606 if (item->status != CrxUpdateItem::kNew)
540 continue; 607 continue;
541 if (item->component.source != manifest_source) 608 if (item->component.source != manifest_source)
542 continue; 609 continue;
543 if (!AddItemToUpdateCheck(item, &query)) 610 if (!AddItemToUpdateCheck(item, &query))
544 break; 611 break;
612 // Requested work items may speed up the update cycle up until
613 // the point that we start an update check. I.e., transition
614 // from kNew -> kChecking. Since the service doesn't guarantee that
615 // the requested items make it any further than kChecking,
616 // forget them now.
617 requested_work_items_.erase(item);
545 } 618 }
546 619
547 // Next we can go back to components we already checked, here 620 // 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 621 // we can also batch them in a single url request, as long as
549 // we have not checked them recently. 622 // we have not checked them recently.
550 const base::TimeDelta min_delta_time = 623 const base::TimeDelta min_delta_time =
551 base::TimeDelta::FromSeconds(config_->MinimumReCheckWait()); 624 base::TimeDelta::FromSeconds(config_->MinimumReCheckWait());
552 625
553 for (UpdateItems::const_iterator it = work_items_.begin(); 626 for (UpdateItems::const_iterator it = work_items_.begin();
554 it != work_items_.end(); ++it) { 627 it != work_items_.end(); ++it) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
595 0, GURL(full_query), net::URLFetcher::GET, 668 0, GURL(full_query), net::URLFetcher::GET,
596 MakeContextDelegate(this, new UpdateContext()))); 669 MakeContextDelegate(this, new UpdateContext())));
597 StartFetch(url_fetcher_.get(), config_->RequestContext(), false); 670 StartFetch(url_fetcher_.get(), config_->RequestContext(), false);
598 return; 671 return;
599 } 672 }
600 673
601 // No components to update. Next check after the long sleep. 674 // No components to update. Next check after the long sleep.
602 ScheduleNextRun(false); 675 ScheduleNextRun(false);
603 } 676 }
604 677
605 // Caled when we got a response from the update server. It consists of an xml 678 // Called when we got a response from the update server. It consists of an xml
606 // document following the omaha update scheme. 679 // document following the omaha update scheme.
607 void CrxUpdateService::OnURLFetchComplete(const net::URLFetcher* source, 680 void CrxUpdateService::OnURLFetchComplete(const net::URLFetcher* source,
608 UpdateContext* context) { 681 UpdateContext* context) {
609 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 682 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
610 if (FetchSuccess(*source)) { 683 if (FetchSuccess(*source)) {
611 std::string xml; 684 std::string xml;
612 source->GetResponseAsString(&xml); 685 source->GetResponseAsString(&xml);
613 url_fetcher_.reset(); 686 url_fetcher_.reset();
614 ParseManifest(xml); 687 ParseManifest(xml);
615 } else { 688 } else {
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 ScheduleNextRun(false); 872 ScheduleNextRun(false);
800 } 873 }
801 874
802 // The component update factory. Using the component updater as a singleton 875 // The component update factory. Using the component updater as a singleton
803 // is the job of the browser process. 876 // is the job of the browser process.
804 ComponentUpdateService* ComponentUpdateServiceFactory( 877 ComponentUpdateService* ComponentUpdateServiceFactory(
805 ComponentUpdateService::Configurator* config) { 878 ComponentUpdateService::Configurator* config) {
806 DCHECK(config); 879 DCHECK(config);
807 return new CrxUpdateService(config); 880 return new CrxUpdateService(config);
808 } 881 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698