OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 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 <set> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
(...skipping 18 matching lines...) Expand all Loading... |
29 #include "chrome/browser/component_updater/update_checker.h" | 29 #include "chrome/browser/component_updater/update_checker.h" |
30 #include "chrome/browser/component_updater/update_response.h" | 30 #include "chrome/browser/component_updater/update_response.h" |
31 #include "chrome/common/chrome_version_info.h" | 31 #include "chrome/common/chrome_version_info.h" |
32 #include "content/public/browser/browser_thread.h" | 32 #include "content/public/browser/browser_thread.h" |
33 #include "content/public/browser/resource_controller.h" | 33 #include "content/public/browser/resource_controller.h" |
34 #include "content/public/browser/resource_throttle.h" | 34 #include "content/public/browser/resource_throttle.h" |
35 #include "url/gurl.h" | 35 #include "url/gurl.h" |
36 | 36 |
37 using content::BrowserThread; | 37 using content::BrowserThread; |
38 | 38 |
39 using component_updater::CrxDownloader; | 39 namespace component_updater { |
40 using component_updater::CrxUpdateItem; | |
41 | 40 |
42 // The component updater is designed to live until process shutdown, so | 41 // The component updater is designed to live until process shutdown, so |
43 // base::Bind() calls are not refcounted. | 42 // base::Bind() calls are not refcounted. |
44 | 43 |
45 namespace { | 44 namespace { |
46 | 45 |
47 // Returns true if the |proposed| version is newer than |current| version. | 46 // Returns true if the |proposed| version is newer than |current| version. |
48 bool IsVersionNewer(const Version& current, const std::string& proposed) { | 47 bool IsVersionNewer(const Version& current, const std::string& proposed) { |
49 Version proposed_ver(proposed); | 48 Version proposed_ver(proposed); |
50 return proposed_ver.IsValid() && current.CompareTo(proposed_ver) < 0; | 49 return proposed_ver.IsValid() && current.CompareTo(proposed_ver) < 0; |
51 } | 50 } |
52 | 51 |
53 // Returns true if a differential update is available, it has not failed yet, | 52 // Returns true if a differential update is available, it has not failed yet, |
54 // and the configuration allows it. | 53 // and the configuration allows it. |
55 bool CanTryDiffUpdate(const CrxUpdateItem* update_item, | 54 bool CanTryDiffUpdate(const CrxUpdateItem* update_item, |
56 const ComponentUpdateService::Configurator& config) { | 55 const ComponentUpdateService::Configurator& config) { |
57 return component_updater::HasDiffUpdate(update_item) && | 56 return HasDiffUpdate(update_item) && |
58 !update_item->diff_update_failed && | 57 !update_item->diff_update_failed && |
59 config.DeltasEnabled(); | 58 config.DeltasEnabled(); |
60 } | 59 } |
61 | 60 |
62 void AppendDownloadMetrics( | 61 void AppendDownloadMetrics( |
63 const std::vector<CrxDownloader::DownloadMetrics>& source, | 62 const std::vector<CrxDownloader::DownloadMetrics>& source, |
64 std::vector<CrxDownloader::DownloadMetrics>* destination) { | 63 std::vector<CrxDownloader::DownloadMetrics>* destination) { |
65 destination->insert(destination->end(), source.begin(), source.end()); | 64 destination->insert(destination->end(), source.begin(), source.end()); |
66 } | 65 } |
67 | 66 |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 kUnpackError, | 187 kUnpackError, |
189 kInstallError, | 188 kInstallError, |
190 }; | 189 }; |
191 | 190 |
192 enum StepDelayInterval { | 191 enum StepDelayInterval { |
193 kStepDelayShort = 0, | 192 kStepDelayShort = 0, |
194 kStepDelayMedium, | 193 kStepDelayMedium, |
195 kStepDelayLong, | 194 kStepDelayLong, |
196 }; | 195 }; |
197 | 196 |
198 void UpdateCheckComplete( | 197 void UpdateCheckComplete(int error, |
199 int error, | 198 const std::string& error_message, |
200 const std::string& error_message, | 199 const UpdateResponse::Results& results); |
201 const component_updater::UpdateResponse::Results& results); | 200 void OnUpdateCheckSucceeded(const UpdateResponse::Results& results); |
202 void OnUpdateCheckSucceeded( | |
203 const component_updater::UpdateResponse::Results& results); | |
204 void OnUpdateCheckFailed(int error, const std::string& error_message); | 201 void OnUpdateCheckFailed(int error, const std::string& error_message); |
205 | 202 |
206 void DownloadComplete( | 203 void DownloadComplete( |
207 scoped_ptr<CRXContext> crx_context, | 204 scoped_ptr<CRXContext> crx_context, |
208 const CrxDownloader::Result& download_result); | 205 const CrxDownloader::Result& download_result); |
209 | 206 |
210 Status OnDemandUpdateInternal(CrxUpdateItem* item); | 207 Status OnDemandUpdateInternal(CrxUpdateItem* item); |
211 | 208 |
212 void ProcessPendingItems(); | 209 void ProcessPendingItems(); |
213 | 210 |
(...skipping 29 matching lines...) Expand all Loading... |
243 | 240 |
244 bool HasOnDemandItems() const; | 241 bool HasOnDemandItems() const; |
245 | 242 |
246 void OnNewResourceThrottle(base::WeakPtr<CUResourceThrottle> rt, | 243 void OnNewResourceThrottle(base::WeakPtr<CUResourceThrottle> rt, |
247 const std::string& crx_id); | 244 const std::string& crx_id); |
248 | 245 |
249 scoped_ptr<ComponentUpdateService::Configurator> config_; | 246 scoped_ptr<ComponentUpdateService::Configurator> config_; |
250 | 247 |
251 scoped_ptr<ComponentPatcher> component_patcher_; | 248 scoped_ptr<ComponentPatcher> component_patcher_; |
252 | 249 |
253 scoped_ptr<component_updater::UpdateChecker> update_checker_; | 250 scoped_ptr<UpdateChecker> update_checker_; |
254 | 251 |
255 scoped_ptr<component_updater::PingManager> ping_manager_; | 252 scoped_ptr<PingManager> ping_manager_; |
256 | 253 |
257 scoped_ptr<component_updater::CrxDownloader> crx_downloader_; | 254 scoped_ptr<CrxDownloader> crx_downloader_; |
258 | 255 |
259 // A collection of every work item. | 256 // A collection of every work item. |
260 typedef std::vector<CrxUpdateItem*> UpdateItems; | 257 typedef std::vector<CrxUpdateItem*> UpdateItems; |
261 UpdateItems work_items_; | 258 UpdateItems work_items_; |
262 | 259 |
263 base::OneShotTimer<CrxUpdateService> timer_; | 260 base::OneShotTimer<CrxUpdateService> timer_; |
264 | 261 |
265 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; | 262 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; |
266 | 263 |
267 const Version chrome_version_; | 264 const Version chrome_version_; |
268 | 265 |
269 bool running_; | 266 bool running_; |
270 | 267 |
271 DISALLOW_COPY_AND_ASSIGN(CrxUpdateService); | 268 DISALLOW_COPY_AND_ASSIGN(CrxUpdateService); |
272 }; | 269 }; |
273 | 270 |
274 ////////////////////////////////////////////////////////////////////////////// | 271 ////////////////////////////////////////////////////////////////////////////// |
275 | 272 |
276 CrxUpdateService::CrxUpdateService(ComponentUpdateService::Configurator* config) | 273 CrxUpdateService::CrxUpdateService(ComponentUpdateService::Configurator* config) |
277 : config_(config), | 274 : config_(config), |
278 component_patcher_(config->CreateComponentPatcher()), | 275 component_patcher_(config->CreateComponentPatcher()), |
279 ping_manager_(new component_updater::PingManager( | 276 ping_manager_(new PingManager(config->PingUrl(), |
280 config->PingUrl(), | 277 config->RequestContext())), |
281 config->RequestContext())), | |
282 blocking_task_runner_(BrowserThread::GetBlockingPool()-> | 278 blocking_task_runner_(BrowserThread::GetBlockingPool()-> |
283 GetSequencedTaskRunnerWithShutdownBehavior( | 279 GetSequencedTaskRunnerWithShutdownBehavior( |
284 BrowserThread::GetBlockingPool()->GetSequenceToken(), | 280 BrowserThread::GetBlockingPool()->GetSequenceToken(), |
285 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)), | 281 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)), |
286 chrome_version_(chrome::VersionInfo().Version()), | 282 chrome_version_(chrome::VersionInfo().Version()), |
287 running_(false) { | 283 running_(false) { |
288 } | 284 } |
289 | 285 |
290 CrxUpdateService::~CrxUpdateService() { | 286 CrxUpdateService::~CrxUpdateService() { |
291 // Because we are a singleton, at this point only the UI thread should be | 287 // Because we are a singleton, at this point only the UI thread should be |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
459 // Adds a component to be checked for upgrades. If the component exists it | 455 // Adds a component to be checked for upgrades. If the component exists it |
460 // it will be replaced and the return code is kReplaced. | 456 // it will be replaced and the return code is kReplaced. |
461 ComponentUpdateService::Status CrxUpdateService::RegisterComponent( | 457 ComponentUpdateService::Status CrxUpdateService::RegisterComponent( |
462 const CrxComponent& component) { | 458 const CrxComponent& component) { |
463 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 459 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
464 if (component.pk_hash.empty() || | 460 if (component.pk_hash.empty() || |
465 !component.version.IsValid() || | 461 !component.version.IsValid() || |
466 !component.installer) | 462 !component.installer) |
467 return kError; | 463 return kError; |
468 | 464 |
469 std::string id(component_updater::GetCrxComponentID(component)); | 465 std::string id(GetCrxComponentID(component)); |
470 CrxUpdateItem* uit = FindUpdateItemById(id); | 466 CrxUpdateItem* uit = FindUpdateItemById(id); |
471 if (uit) { | 467 if (uit) { |
472 uit->component = component; | 468 uit->component = component; |
473 return kReplaced; | 469 return kReplaced; |
474 } | 470 } |
475 | 471 |
476 uit = new CrxUpdateItem; | 472 uit = new CrxUpdateItem; |
477 uit->id.swap(id); | 473 uit->id.swap(id); |
478 uit->component = component; | 474 uit->component = component; |
479 | 475 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 return kOk; | 534 return kOk; |
539 } | 535 } |
540 | 536 |
541 void CrxUpdateService::GetComponents( | 537 void CrxUpdateService::GetComponents( |
542 std::vector<CrxComponentInfo>* components) { | 538 std::vector<CrxComponentInfo>* components) { |
543 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 539 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
544 for (UpdateItems::const_iterator it = work_items_.begin(); | 540 for (UpdateItems::const_iterator it = work_items_.begin(); |
545 it != work_items_.end(); ++it) { | 541 it != work_items_.end(); ++it) { |
546 const CrxUpdateItem* item = *it; | 542 const CrxUpdateItem* item = *it; |
547 CrxComponentInfo info; | 543 CrxComponentInfo info; |
548 info.id = component_updater::GetCrxComponentID(item->component); | 544 info.id = GetCrxComponentID(item->component); |
549 info.version = item->component.version.GetString(); | 545 info.version = item->component.version.GetString(); |
550 info.name = item->component.name; | 546 info.name = item->component.name; |
551 components->push_back(info); | 547 components->push_back(info); |
552 } | 548 } |
553 } | 549 } |
554 | 550 |
555 // This is the main loop of the component updater. It updates one component | 551 // This is the main loop of the component updater. It updates one component |
556 // at a time if updates are available. Otherwise, it does an update check or | 552 // at a time if updates are available. Otherwise, it does an update check or |
557 // takes a long sleep until the loop runs again. | 553 // takes a long sleep until the loop runs again. |
558 void CrxUpdateService::ProcessPendingItems() { | 554 void CrxUpdateService::ProcessPendingItems() { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
619 item->diff_error_code = 0; | 615 item->diff_error_code = 0; |
620 item->diff_extra_code1 = 0; | 616 item->diff_extra_code1 = 0; |
621 item->download_metrics.clear(); | 617 item->download_metrics.clear(); |
622 | 618 |
623 items_to_check.push_back(item); | 619 items_to_check.push_back(item); |
624 } | 620 } |
625 | 621 |
626 if (items_to_check.empty()) | 622 if (items_to_check.empty()) |
627 return false; | 623 return false; |
628 | 624 |
629 update_checker_ = component_updater::UpdateChecker::Create( | 625 update_checker_ = UpdateChecker::Create( |
630 config_->UpdateUrl(), | 626 config_->UpdateUrl(), |
631 config_->RequestContext(), | 627 config_->RequestContext(), |
632 base::Bind(&CrxUpdateService::UpdateCheckComplete, | 628 base::Bind(&CrxUpdateService::UpdateCheckComplete, |
633 base::Unretained(this))).Pass(); | 629 base::Unretained(this))).Pass(); |
634 return update_checker_->CheckForUpdates(items_to_check, | 630 return update_checker_->CheckForUpdates(items_to_check, |
635 config_->ExtraRequestParams()); | 631 config_->ExtraRequestParams()); |
636 } | 632 } |
637 | 633 |
638 void CrxUpdateService::UpdateComponent(CrxUpdateItem* workitem) { | 634 void CrxUpdateService::UpdateComponent(CrxUpdateItem* workitem) { |
639 scoped_ptr<CRXContext> crx_context(new CRXContext); | 635 scoped_ptr<CRXContext> crx_context(new CRXContext); |
(...skipping 20 matching lines...) Expand all Loading... |
660 blocking_task_runner_, | 656 blocking_task_runner_, |
661 base::Bind(&CrxUpdateService::DownloadComplete, | 657 base::Bind(&CrxUpdateService::DownloadComplete, |
662 base::Unretained(this), | 658 base::Unretained(this), |
663 base::Passed(&crx_context)))); | 659 base::Passed(&crx_context)))); |
664 crx_downloader_->StartDownload(*urls); | 660 crx_downloader_->StartDownload(*urls); |
665 } | 661 } |
666 | 662 |
667 void CrxUpdateService::UpdateCheckComplete( | 663 void CrxUpdateService::UpdateCheckComplete( |
668 int error, | 664 int error, |
669 const std::string& error_message, | 665 const std::string& error_message, |
670 const component_updater::UpdateResponse::Results& results) { | 666 const UpdateResponse::Results& results) { |
671 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 667 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
672 update_checker_.reset(); | 668 update_checker_.reset(); |
673 if (!error) | 669 if (!error) |
674 OnUpdateCheckSucceeded(results); | 670 OnUpdateCheckSucceeded(results); |
675 else | 671 else |
676 OnUpdateCheckFailed(error, error_message); | 672 OnUpdateCheckFailed(error, error_message); |
677 } | 673 } |
678 | 674 |
679 // Handles a valid Omaha update check response by matching the results with | 675 // Handles a valid Omaha update check response by matching the results with |
680 // the registered components which were checked for updates. | 676 // the registered components which were checked for updates. |
681 // If updates are found, prepare the components for the actual version upgrade. | 677 // If updates are found, prepare the components for the actual version upgrade. |
682 // One of these components will be drafted for the upgrade next time | 678 // One of these components will be drafted for the upgrade next time |
683 // ProcessPendingItems is called. | 679 // ProcessPendingItems is called. |
684 void CrxUpdateService::OnUpdateCheckSucceeded( | 680 void CrxUpdateService::OnUpdateCheckSucceeded( |
685 const component_updater::UpdateResponse::Results& results) { | 681 const UpdateResponse::Results& results) { |
686 size_t num_updates_pending = 0; | 682 size_t num_updates_pending = 0; |
687 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 683 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
688 std::vector<component_updater::UpdateResponse::Result>::const_iterator it; | 684 std::vector<UpdateResponse::Result>::const_iterator it; |
689 for (it = results.list.begin(); it != results.list.end(); ++it) { | 685 for (it = results.list.begin(); it != results.list.end(); ++it) { |
690 CrxUpdateItem* crx = FindUpdateItemById(it->extension_id); | 686 CrxUpdateItem* crx = FindUpdateItemById(it->extension_id); |
691 if (!crx) | 687 if (!crx) |
692 continue; | 688 continue; |
693 | 689 |
694 if (crx->status != CrxUpdateItem::kChecking) { | 690 if (crx->status != CrxUpdateItem::kChecking) { |
695 NOTREACHED(); | 691 NOTREACHED(); |
696 continue; // Not updating this component now. | 692 continue; // Not updating this component now. |
697 } | 693 } |
698 | 694 |
(...skipping 19 matching lines...) Expand all Loading... |
718 | 714 |
719 if (it->manifest.packages.size() != 1) { | 715 if (it->manifest.packages.size() != 1) { |
720 // Assume one and only one package per component. | 716 // Assume one and only one package per component. |
721 ChangeItemState(crx, CrxUpdateItem::kNoUpdate); | 717 ChangeItemState(crx, CrxUpdateItem::kNoUpdate); |
722 continue; | 718 continue; |
723 } | 719 } |
724 | 720 |
725 // Parse the members of the result and queue an upgrade for this component. | 721 // Parse the members of the result and queue an upgrade for this component. |
726 crx->next_version = Version(it->manifest.version); | 722 crx->next_version = Version(it->manifest.version); |
727 | 723 |
728 typedef component_updater:: | 724 typedef UpdateResponse::Result::Manifest::Package Package; |
729 UpdateResponse::Result::Manifest::Package Package; | |
730 const Package& package(it->manifest.packages[0]); | 725 const Package& package(it->manifest.packages[0]); |
731 crx->next_fp = package.fingerprint; | 726 crx->next_fp = package.fingerprint; |
732 | 727 |
733 // Resolve the urls by combining the base urls with the package names. | 728 // Resolve the urls by combining the base urls with the package names. |
734 for (size_t i = 0; i != it->crx_urls.size(); ++i) { | 729 for (size_t i = 0; i != it->crx_urls.size(); ++i) { |
735 const GURL url(it->crx_urls[i].Resolve(package.name)); | 730 const GURL url(it->crx_urls[i].Resolve(package.name)); |
736 if (url.is_valid()) | 731 if (url.is_valid()) |
737 crx->crx_urls.push_back(url); | 732 crx->crx_urls.push_back(url); |
738 } | 733 } |
739 for (size_t i = 0; i != it->crx_diffurls.size(); ++i) { | 734 for (size_t i = 0; i != it->crx_diffurls.size(); ++i) { |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
835 // |unpacker|. If there is an error this function is in charge of deleting | 830 // |unpacker|. If there is an error this function is in charge of deleting |
836 // the files created. | 831 // the files created. |
837 void CrxUpdateService::Install(scoped_ptr<CRXContext> context, | 832 void CrxUpdateService::Install(scoped_ptr<CRXContext> context, |
838 const base::FilePath& crx_path) { | 833 const base::FilePath& crx_path) { |
839 // This function owns the file at |crx_path| and the |context| object. | 834 // This function owns the file at |crx_path| and the |context| object. |
840 ComponentUnpacker unpacker(context->pk_hash, | 835 ComponentUnpacker unpacker(context->pk_hash, |
841 crx_path, | 836 crx_path, |
842 context->fingerprint, | 837 context->fingerprint, |
843 component_patcher_.get(), | 838 component_patcher_.get(), |
844 context->installer); | 839 context->installer); |
845 if (!component_updater::DeleteFileAndEmptyParentDirectory(crx_path)) | 840 if (!DeleteFileAndEmptyParentDirectory(crx_path)) |
846 NOTREACHED() << crx_path.value(); | 841 NOTREACHED() << crx_path.value(); |
847 | 842 |
848 // Why unretained? See comment at top of file. | 843 // Why unretained? See comment at top of file. |
849 BrowserThread::PostDelayedTask( | 844 BrowserThread::PostDelayedTask( |
850 BrowserThread::UI, | 845 BrowserThread::UI, |
851 FROM_HERE, | 846 FROM_HERE, |
852 base::Bind(&CrxUpdateService::DoneInstalling, base::Unretained(this), | 847 base::Bind(&CrxUpdateService::DoneInstalling, base::Unretained(this), |
853 context->id, unpacker.error(), unpacker.extended_error()), | 848 context->id, unpacker.error(), unpacker.extended_error()), |
854 base::TimeDelta::FromMilliseconds(config_->StepDelay())); | 849 base::TimeDelta::FromMilliseconds(config_->StepDelay())); |
855 } | 850 } |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
981 } | 976 } |
982 | 977 |
983 // The component update factory. Using the component updater as a singleton | 978 // The component update factory. Using the component updater as a singleton |
984 // is the job of the browser process. | 979 // is the job of the browser process. |
985 ComponentUpdateService* ComponentUpdateServiceFactory( | 980 ComponentUpdateService* ComponentUpdateServiceFactory( |
986 ComponentUpdateService::Configurator* config) { | 981 ComponentUpdateService::Configurator* config) { |
987 DCHECK(config); | 982 DCHECK(config); |
988 return new CrxUpdateService(config); | 983 return new CrxUpdateService(config); |
989 } | 984 } |
990 | 985 |
| 986 } // namespace component_updater |
| 987 |
OLD | NEW |