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 27 matching lines...) Expand all Loading... |
38 | 38 |
39 using content::BrowserThread; | 39 using content::BrowserThread; |
40 using content::UtilityProcessHost; | 40 using content::UtilityProcessHost; |
41 using content::UtilityProcessHostClient; | 41 using content::UtilityProcessHostClient; |
42 using extensions::Extension; | 42 using extensions::Extension; |
43 | 43 |
44 // The component updater is designed to live until process shutdown, so | 44 // The component updater is designed to live until process shutdown, so |
45 // base::Bind() calls are not refcounted. | 45 // base::Bind() calls are not refcounted. |
46 | 46 |
47 namespace { | 47 namespace { |
| 48 // Manifest sources, from most important to least important. |
| 49 const CrxComponent::UrlSource kManifestSources[] = { |
| 50 CrxComponent::BANDAID, |
| 51 CrxComponent::CWS_PUBLIC, |
| 52 CrxComponent::CWS_SANDBOX |
| 53 }; |
| 54 |
48 // Extends an omaha compatible update check url |query| string. Does | 55 // Extends an omaha compatible update check url |query| string. Does |
49 // not mutate the string if it would be longer than |limit| chars. | 56 // not mutate the string if it would be longer than |limit| chars. |
50 bool AddQueryString(const std::string& id, | 57 bool AddQueryString(const std::string& id, |
51 const std::string& version, | 58 const std::string& version, |
52 size_t limit, | 59 size_t limit, |
53 std::string* query) { | 60 std::string* query) { |
54 std::string additional = | 61 std::string additional = |
55 base::StringPrintf("id=%s&v=%s&uc", id.c_str(), version.c_str()); | 62 base::StringPrintf("id=%s&v=%s&uc", id.c_str(), version.c_str()); |
56 additional = "x=" + net::EscapeQueryParamValue(additional, true); | 63 additional = "x=" + net::EscapeQueryParamValue(additional, true); |
57 if ((additional.size() + query->size() + 1) > limit) | 64 if ((additional.size() + query->size() + 1) > limit) |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 } | 215 } |
209 private: | 216 private: |
210 const std::string& id_; | 217 const std::string& id_; |
211 }; | 218 }; |
212 }; | 219 }; |
213 | 220 |
214 } // namespace. | 221 } // namespace. |
215 | 222 |
216 typedef ComponentUpdateService::Configurator Config; | 223 typedef ComponentUpdateService::Configurator Config; |
217 | 224 |
218 CrxComponent::CrxComponent() : installer(NULL) {} | 225 CrxComponent::CrxComponent() |
219 CrxComponent::~CrxComponent() {} | 226 : installer(NULL), |
| 227 source(BANDAID) { |
| 228 } |
| 229 |
| 230 CrxComponent::~CrxComponent() { |
| 231 } |
220 | 232 |
221 ////////////////////////////////////////////////////////////////////////////// | 233 ////////////////////////////////////////////////////////////////////////////// |
222 // The one and only implementation of the ComponentUpdateService interface. In | 234 // The one and only implementation of the ComponentUpdateService interface. In |
223 // charge of running the show. The main method is ProcessPendingItems() which | 235 // charge of running the show. The main method is ProcessPendingItems() which |
224 // is called periodically to do the upgrades/installs or the update checks. | 236 // is called periodically to do the upgrades/installs or the update checks. |
225 // An important consideration here is to be as "low impact" as we can to the | 237 // An important consideration here is to be as "low impact" as we can to the |
226 // rest of the browser, so even if we have many components registered and | 238 // rest of the browser, so even if we have many components registered and |
227 // eligible for update, we only do one thing at a time with pauses in between | 239 // eligible for update, we only do one thing at a time with pauses in between |
228 // the tasks. Also when we do network requests there is only one |url_fetcher_| | 240 // the tasks. Also when we do network requests there is only one |url_fetcher_| |
229 // in flight at at a time. | 241 // in flight at at a time. |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 context->pk_hash = item->component.pk_hash; | 520 context->pk_hash = item->component.pk_hash; |
509 context->id = item->id; | 521 context->id = item->id; |
510 context->installer = item->component.installer; | 522 context->installer = item->component.installer; |
511 url_fetcher_.reset(net::URLFetcher::Create( | 523 url_fetcher_.reset(net::URLFetcher::Create( |
512 0, item->crx_url, net::URLFetcher::GET, | 524 0, item->crx_url, net::URLFetcher::GET, |
513 MakeContextDelegate(this, context))); | 525 MakeContextDelegate(this, context))); |
514 StartFetch(url_fetcher_.get(), config_->RequestContext(), true); | 526 StartFetch(url_fetcher_.get(), config_->RequestContext(), true); |
515 return; | 527 return; |
516 } | 528 } |
517 | 529 |
518 std::string query; | 530 for (size_t ix = 0; ix != arraysize(kManifestSources); ++ix) { |
519 // If no pending upgrades, we check the if there are new | 531 const CrxComponent::UrlSource manifest_source = kManifestSources[ix]; |
520 // components we have not checked against the server. We | 532 |
521 // can batch a bunch in a single url request. | 533 std::string query; |
522 for (UpdateItems::const_iterator it = work_items_.begin(); | 534 // If no pending upgrades, we check if there are new components we have not |
523 it != work_items_.end(); ++it) { | 535 // checked against the server. We can batch some in a single url request. |
524 CrxUpdateItem* item = *it; | 536 for (UpdateItems::const_iterator it = work_items_.begin(); |
525 if (item->status != CrxUpdateItem::kNew) | 537 it != work_items_.end(); ++it) { |
| 538 CrxUpdateItem* item = *it; |
| 539 if (item->status != CrxUpdateItem::kNew) |
| 540 continue; |
| 541 if (item->component.source != manifest_source) |
| 542 continue; |
| 543 if (!AddItemToUpdateCheck(item, &query)) |
| 544 break; |
| 545 } |
| 546 |
| 547 // 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 |
| 549 // we have not checked them recently. |
| 550 const base::TimeDelta min_delta_time = |
| 551 base::TimeDelta::FromSeconds(config_->MinimumReCheckWait()); |
| 552 |
| 553 for (UpdateItems::const_iterator it = work_items_.begin(); |
| 554 it != work_items_.end(); ++it) { |
| 555 CrxUpdateItem* item = *it; |
| 556 if ((item->status != CrxUpdateItem::kNoUpdate) && |
| 557 (item->status != CrxUpdateItem::kUpToDate)) |
| 558 continue; |
| 559 if (item->component.source != manifest_source) |
| 560 continue; |
| 561 base::TimeDelta delta = base::Time::Now() - item->last_check; |
| 562 if (delta < min_delta_time) |
| 563 continue; |
| 564 if (!AddItemToUpdateCheck(item, &query)) |
| 565 break; |
| 566 } |
| 567 |
| 568 // Finally, we check components that we already updated as long as |
| 569 // we have not checked them recently. |
| 570 for (UpdateItems::const_iterator it = work_items_.begin(); |
| 571 it != work_items_.end(); ++it) { |
| 572 CrxUpdateItem* item = *it; |
| 573 if (item->status != CrxUpdateItem::kUpdated) |
| 574 continue; |
| 575 if (item->component.source != manifest_source) |
| 576 continue; |
| 577 base::TimeDelta delta = base::Time::Now() - item->last_check; |
| 578 if (delta < min_delta_time) |
| 579 continue; |
| 580 if (!AddItemToUpdateCheck(item, &query)) |
| 581 break; |
| 582 } |
| 583 |
| 584 // If no components to update we move down to the next source. |
| 585 if (query.empty()) |
526 continue; | 586 continue; |
527 if (!AddItemToUpdateCheck(item, &query)) | |
528 break; | |
529 } | |
530 | 587 |
531 // Next we can go back to components we already checked, here | 588 // We got components to check. Start the url request and exit. |
532 // we can also batch them in a single url request, as long as | 589 const std::string full_query = |
533 // we have not checked them recently. | 590 MakeFinalQuery(config_->UpdateUrl(manifest_source).spec(), |
534 const base::TimeDelta min_delta_time = | 591 query, |
535 base::TimeDelta::FromSeconds(config_->MinimumReCheckWait()); | 592 config_->ExtraRequestParams()); |
536 | 593 |
537 for (UpdateItems::const_iterator it = work_items_.begin(); | 594 url_fetcher_.reset(net::URLFetcher::Create( |
538 it != work_items_.end(); ++it) { | 595 0, GURL(full_query), net::URLFetcher::GET, |
539 CrxUpdateItem* item = *it; | 596 MakeContextDelegate(this, new UpdateContext()))); |
540 if ((item->status != CrxUpdateItem::kNoUpdate) && | 597 StartFetch(url_fetcher_.get(), config_->RequestContext(), false); |
541 (item->status != CrxUpdateItem::kUpToDate)) | |
542 continue; | |
543 base::TimeDelta delta = base::Time::Now() - item->last_check; | |
544 if (delta < min_delta_time) | |
545 continue; | |
546 if (!AddItemToUpdateCheck(item, &query)) | |
547 break; | |
548 } | |
549 // Finally, we check components that we already updated. | |
550 for (UpdateItems::const_iterator it = work_items_.begin(); | |
551 it != work_items_.end(); ++it) { | |
552 CrxUpdateItem* item = *it; | |
553 if (item->status != CrxUpdateItem::kUpdated) | |
554 continue; | |
555 base::TimeDelta delta = base::Time::Now() - item->last_check; | |
556 if (delta < min_delta_time) | |
557 continue; | |
558 if (!AddItemToUpdateCheck(item, &query)) | |
559 break; | |
560 } | |
561 | |
562 if (query.empty()) { | |
563 // Next check after the long sleep. | |
564 ScheduleNextRun(false); | |
565 return; | 598 return; |
566 } | 599 } |
567 | 600 |
568 // We got components to check. Start the url request. | 601 // No components to update. Next check after the long sleep. |
569 const std::string full_query = MakeFinalQuery(config_->UpdateUrl().spec(), | 602 ScheduleNextRun(false); |
570 query, | |
571 config_->ExtraRequestParams()); | |
572 url_fetcher_.reset(net::URLFetcher::Create( | |
573 0, GURL(full_query), net::URLFetcher::GET, | |
574 MakeContextDelegate(this, new UpdateContext()))); | |
575 StartFetch(url_fetcher_.get(), config_->RequestContext(), false); | |
576 } | 603 } |
577 | 604 |
578 // Caled when we got a response from the update server. It consists of an xml | 605 // Caled when we got a response from the update server. It consists of an xml |
579 // document following the omaha update scheme. | 606 // document following the omaha update scheme. |
580 void CrxUpdateService::OnURLFetchComplete(const net::URLFetcher* source, | 607 void CrxUpdateService::OnURLFetchComplete(const net::URLFetcher* source, |
581 UpdateContext* context) { | 608 UpdateContext* context) { |
582 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 609 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
583 if (FetchSuccess(*source)) { | 610 if (FetchSuccess(*source)) { |
584 std::string xml; | 611 std::string xml; |
585 source->GetResponseAsString(&xml); | 612 source->GetResponseAsString(&xml); |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
772 ScheduleNextRun(false); | 799 ScheduleNextRun(false); |
773 } | 800 } |
774 | 801 |
775 // The component update factory. Using the component updater as a singleton | 802 // The component update factory. Using the component updater as a singleton |
776 // is the job of the browser process. | 803 // is the job of the browser process. |
777 ComponentUpdateService* ComponentUpdateServiceFactory( | 804 ComponentUpdateService* ComponentUpdateServiceFactory( |
778 ComponentUpdateService::Configurator* config) { | 805 ComponentUpdateService::Configurator* config) { |
779 DCHECK(config); | 806 DCHECK(config); |
780 return new CrxUpdateService(config); | 807 return new CrxUpdateService(config); |
781 } | 808 } |
OLD | NEW |