OLD | NEW |
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 Loading... |
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 Loading... |
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 void 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 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
481 uit->component = component; | 484 uit->component = component; |
482 work_items_.push_back(uit); | 485 work_items_.push_back(uit); |
483 // If this is the first component registered we call Start to | 486 // If this is the first component registered we call Start to |
484 // schedule the first timer. | 487 // schedule the first timer. |
485 if (running_ && (work_items_.size() == 1)) | 488 if (running_ && (work_items_.size() == 1)) |
486 Start(); | 489 Start(); |
487 | 490 |
488 return kOk; | 491 return kOk; |
489 } | 492 } |
490 | 493 |
| 494 // Start the process of checking for an update, for a particular component |
| 495 // that was previously registered. If the component does not exist return |
| 496 // kError, otherwise kOk. |
| 497 ComponentUpdateService::Status CrxUpdateService::PingUpdateCheck( |
| 498 const CrxComponent& component) { |
| 499 if (component.pk_hash.empty() || |
| 500 !component.version.IsValid() || |
| 501 !component.installer) |
| 502 return kError; |
| 503 |
| 504 std::string id = |
| 505 HexStringToID(StringToLowerASCII(base::HexEncode(&component.pk_hash[0], |
| 506 component.pk_hash.size()/2))); |
| 507 CrxUpdateItem* uit; |
| 508 uit = FindUpdateItemById(id); |
| 509 if (!uit) |
| 510 return kError; |
| 511 |
| 512 UpdateItems one_item; |
| 513 one_item.push_back(uit); |
| 514 |
| 515 ProcessWorkItems(one_item); |
| 516 return kOk; |
| 517 } |
| 518 |
491 // Sets a component to be checked for updates. | 519 // Sets a component to be checked for updates. |
492 // The componet to add is |crxit| and the |query| string is modified with the | 520 // The componet to add is |crxit| and the |query| string is modified with the |
493 // required omaha compatible query. Returns false when the query strings | 521 // required omaha compatible query. Returns false when the query strings |
494 // is longer than specified by UrlSizeLimit(). | 522 // is longer than specified by UrlSizeLimit(). |
495 bool CrxUpdateService::AddItemToUpdateCheck(CrxUpdateItem* item, | 523 bool CrxUpdateService::AddItemToUpdateCheck(CrxUpdateItem* item, |
496 std::string* query) { | 524 std::string* query) { |
497 if (!AddQueryString(item->id, | 525 if (!AddQueryString(item->id, |
498 item->component.version.GetString(), | 526 item->component.version.GetString(), |
499 config_->UrlSizeLimit(), query)) | 527 config_->UrlSizeLimit(), query)) |
500 return false; | 528 return false; |
501 item->status = CrxUpdateItem::kChecking; | 529 item->status = CrxUpdateItem::kChecking; |
502 item->last_check = base::Time::Now(); | 530 item->last_check = base::Time::Now(); |
503 return true; | 531 return true; |
504 } | 532 } |
505 | 533 |
506 // Here is where the work gets scheduled. Given that our |work_items_| list | 534 // Here is where the work gets scheduled. |
| 535 void CrxUpdateService::ProcessPendingItems() { |
| 536 ProcessWorkItems(work_items_); |
| 537 } |
| 538 |
| 539 // 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. | 540 // is expected to be ten or less items, we simply loop several times. |
508 void CrxUpdateService::ProcessPendingItems() { | 541 void CrxUpdateService::ProcessWorkItems(const UpdateItems& work_items) { |
509 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 542 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
510 // First check for ready upgrades and do one. The first | 543 // First check for ready upgrades and do one. The first |
511 // step is to fetch the crx package. | 544 // step is to fetch the crx package. |
512 for (UpdateItems::const_iterator it = work_items_.begin(); | 545 for (UpdateItems::const_iterator it = work_items.begin(); |
513 it != work_items_.end(); ++it) { | 546 it != work_items.end(); ++it) { |
514 CrxUpdateItem* item = *it; | 547 CrxUpdateItem* item = *it; |
515 if (item->status != CrxUpdateItem::kCanUpdate) | 548 if (item->status != CrxUpdateItem::kCanUpdate) |
516 continue; | 549 continue; |
517 // Found component to update, start the process. | 550 // Found component to update, start the process. |
518 item->status = CrxUpdateItem::kDownloading; | 551 item->status = CrxUpdateItem::kDownloading; |
519 CRXContext* context = new CRXContext; | 552 CRXContext* context = new CRXContext; |
520 context->pk_hash = item->component.pk_hash; | 553 context->pk_hash = item->component.pk_hash; |
521 context->id = item->id; | 554 context->id = item->id; |
522 context->installer = item->component.installer; | 555 context->installer = item->component.installer; |
523 url_fetcher_.reset(net::URLFetcher::Create( | 556 url_fetcher_.reset(net::URLFetcher::Create( |
524 0, item->crx_url, net::URLFetcher::GET, | 557 0, item->crx_url, net::URLFetcher::GET, |
525 MakeContextDelegate(this, context))); | 558 MakeContextDelegate(this, context))); |
526 StartFetch(url_fetcher_.get(), config_->RequestContext(), true); | 559 StartFetch(url_fetcher_.get(), config_->RequestContext(), true); |
527 return; | 560 return; |
528 } | 561 } |
529 | 562 |
530 for (size_t ix = 0; ix != arraysize(kManifestSources); ++ix) { | 563 for (size_t ix = 0; ix != arraysize(kManifestSources); ++ix) { |
531 const CrxComponent::UrlSource manifest_source = kManifestSources[ix]; | 564 const CrxComponent::UrlSource manifest_source = kManifestSources[ix]; |
532 | 565 |
533 std::string query; | 566 std::string query; |
534 // If no pending upgrades, we check if there are new components we have not | 567 // 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. | 568 // checked against the server. We can batch some in a single url request. |
536 for (UpdateItems::const_iterator it = work_items_.begin(); | 569 for (UpdateItems::const_iterator it = work_items.begin(); |
537 it != work_items_.end(); ++it) { | 570 it != work_items.end(); ++it) { |
538 CrxUpdateItem* item = *it; | 571 CrxUpdateItem* item = *it; |
539 if (item->status != CrxUpdateItem::kNew) | 572 if (item->status != CrxUpdateItem::kNew) |
540 continue; | 573 continue; |
541 if (item->component.source != manifest_source) | 574 if (item->component.source != manifest_source) |
542 continue; | 575 continue; |
543 if (!AddItemToUpdateCheck(item, &query)) | 576 if (!AddItemToUpdateCheck(item, &query)) |
544 break; | 577 break; |
545 } | 578 } |
546 | 579 |
547 // Next we can go back to components we already checked, here | 580 // 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 | 581 // we can also batch them in a single url request, as long as |
549 // we have not checked them recently. | 582 // we have not checked them recently. |
550 const base::TimeDelta min_delta_time = | 583 const base::TimeDelta min_delta_time = |
551 base::TimeDelta::FromSeconds(config_->MinimumReCheckWait()); | 584 base::TimeDelta::FromSeconds(config_->MinimumReCheckWait()); |
552 | 585 |
553 for (UpdateItems::const_iterator it = work_items_.begin(); | 586 for (UpdateItems::const_iterator it = work_items.begin(); |
554 it != work_items_.end(); ++it) { | 587 it != work_items.end(); ++it) { |
555 CrxUpdateItem* item = *it; | 588 CrxUpdateItem* item = *it; |
556 if ((item->status != CrxUpdateItem::kNoUpdate) && | 589 if ((item->status != CrxUpdateItem::kNoUpdate) && |
557 (item->status != CrxUpdateItem::kUpToDate)) | 590 (item->status != CrxUpdateItem::kUpToDate)) |
558 continue; | 591 continue; |
559 if (item->component.source != manifest_source) | 592 if (item->component.source != manifest_source) |
560 continue; | 593 continue; |
561 base::TimeDelta delta = base::Time::Now() - item->last_check; | 594 base::TimeDelta delta = base::Time::Now() - item->last_check; |
562 if (delta < min_delta_time) | 595 if (delta < min_delta_time) |
563 continue; | 596 continue; |
564 if (!AddItemToUpdateCheck(item, &query)) | 597 if (!AddItemToUpdateCheck(item, &query)) |
565 break; | 598 break; |
566 } | 599 } |
567 | 600 |
568 // Finally, we check components that we already updated as long as | 601 // Finally, we check components that we already updated as long as |
569 // we have not checked them recently. | 602 // we have not checked them recently. |
570 for (UpdateItems::const_iterator it = work_items_.begin(); | 603 for (UpdateItems::const_iterator it = work_items.begin(); |
571 it != work_items_.end(); ++it) { | 604 it != work_items.end(); ++it) { |
572 CrxUpdateItem* item = *it; | 605 CrxUpdateItem* item = *it; |
573 if (item->status != CrxUpdateItem::kUpdated) | 606 if (item->status != CrxUpdateItem::kUpdated) |
574 continue; | 607 continue; |
575 if (item->component.source != manifest_source) | 608 if (item->component.source != manifest_source) |
576 continue; | 609 continue; |
577 base::TimeDelta delta = base::Time::Now() - item->last_check; | 610 base::TimeDelta delta = base::Time::Now() - item->last_check; |
578 if (delta < min_delta_time) | 611 if (delta < min_delta_time) |
579 continue; | 612 continue; |
580 if (!AddItemToUpdateCheck(item, &query)) | 613 if (!AddItemToUpdateCheck(item, &query)) |
581 break; | 614 break; |
(...skipping 13 matching lines...) Expand all Loading... |
595 0, GURL(full_query), net::URLFetcher::GET, | 628 0, GURL(full_query), net::URLFetcher::GET, |
596 MakeContextDelegate(this, new UpdateContext()))); | 629 MakeContextDelegate(this, new UpdateContext()))); |
597 StartFetch(url_fetcher_.get(), config_->RequestContext(), false); | 630 StartFetch(url_fetcher_.get(), config_->RequestContext(), false); |
598 return; | 631 return; |
599 } | 632 } |
600 | 633 |
601 // No components to update. Next check after the long sleep. | 634 // No components to update. Next check after the long sleep. |
602 ScheduleNextRun(false); | 635 ScheduleNextRun(false); |
603 } | 636 } |
604 | 637 |
605 // Caled when we got a response from the update server. It consists of an xml | 638 // Called when we got a response from the update server. It consists of an xml |
606 // document following the omaha update scheme. | 639 // document following the omaha update scheme. |
607 void CrxUpdateService::OnURLFetchComplete(const net::URLFetcher* source, | 640 void CrxUpdateService::OnURLFetchComplete(const net::URLFetcher* source, |
608 UpdateContext* context) { | 641 UpdateContext* context) { |
609 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 642 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
610 if (FetchSuccess(*source)) { | 643 if (FetchSuccess(*source)) { |
611 std::string xml; | 644 std::string xml; |
612 source->GetResponseAsString(&xml); | 645 source->GetResponseAsString(&xml); |
613 url_fetcher_.reset(); | 646 url_fetcher_.reset(); |
614 ParseManifest(xml); | 647 ParseManifest(xml); |
615 } else { | 648 } else { |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
799 ScheduleNextRun(false); | 832 ScheduleNextRun(false); |
800 } | 833 } |
801 | 834 |
802 // The component update factory. Using the component updater as a singleton | 835 // The component update factory. Using the component updater as a singleton |
803 // is the job of the browser process. | 836 // is the job of the browser process. |
804 ComponentUpdateService* ComponentUpdateServiceFactory( | 837 ComponentUpdateService* ComponentUpdateServiceFactory( |
805 ComponentUpdateService::Configurator* config) { | 838 ComponentUpdateService::Configurator* config) { |
806 DCHECK(config); | 839 DCHECK(config); |
807 return new CrxUpdateService(config); | 840 return new CrxUpdateService(config); |
808 } | 841 } |
OLD | NEW |