| 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 |