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/extensions/extension_service.h" | 5 #include "chrome/browser/extensions/extension_service.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <iterator> |
8 #include <set> | 9 #include <set> |
9 | 10 |
10 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
11 #include "base/bind.h" | 12 #include "base/bind.h" |
12 #include "base/callback.h" | 13 #include "base/callback.h" |
13 #include "base/command_line.h" | 14 #include "base/command_line.h" |
14 #include "base/file_util.h" | 15 #include "base/file_util.h" |
15 #include "base/logging.h" | 16 #include "base/logging.h" |
16 #include "base/metrics/histogram.h" | 17 #include "base/metrics/histogram.h" |
17 #include "base/path_service.h" | 18 #include "base/path_service.h" |
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 const CommandLine* command_line, | 356 const CommandLine* command_line, |
356 const FilePath& install_directory, | 357 const FilePath& install_directory, |
357 extensions::ExtensionPrefs* extension_prefs, | 358 extensions::ExtensionPrefs* extension_prefs, |
358 extensions::Blacklist* blacklist, | 359 extensions::Blacklist* blacklist, |
359 bool autoupdate_enabled, | 360 bool autoupdate_enabled, |
360 bool extensions_enabled) | 361 bool extensions_enabled) |
361 : extensions::Blacklist::Observer(blacklist), | 362 : extensions::Blacklist::Observer(blacklist), |
362 profile_(profile), | 363 profile_(profile), |
363 system_(extensions::ExtensionSystem::Get(profile)), | 364 system_(extensions::ExtensionSystem::Get(profile)), |
364 extension_prefs_(extension_prefs), | 365 extension_prefs_(extension_prefs), |
| 366 blacklist_(blacklist), |
365 settings_frontend_(extensions::SettingsFrontend::Create(profile)), | 367 settings_frontend_(extensions::SettingsFrontend::Create(profile)), |
366 pending_extension_manager_(*ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 368 pending_extension_manager_(*ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
367 install_directory_(install_directory), | 369 install_directory_(install_directory), |
368 extensions_enabled_(extensions_enabled), | 370 extensions_enabled_(extensions_enabled), |
369 show_extensions_prompts_(true), | 371 show_extensions_prompts_(true), |
370 install_updates_when_idle_(true), | 372 install_updates_when_idle_(true), |
371 ready_(false), | 373 ready_(false), |
372 toolbar_model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 374 toolbar_model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
373 menu_manager_(profile), | 375 menu_manager_(profile), |
374 app_notification_manager_( | 376 app_notification_manager_( |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
460 } | 462 } |
461 | 463 |
462 const ExtensionSet* ExtensionService::disabled_extensions() const { | 464 const ExtensionSet* ExtensionService::disabled_extensions() const { |
463 return &disabled_extensions_; | 465 return &disabled_extensions_; |
464 } | 466 } |
465 | 467 |
466 const ExtensionSet* ExtensionService::terminated_extensions() const { | 468 const ExtensionSet* ExtensionService::terminated_extensions() const { |
467 return &terminated_extensions_; | 469 return &terminated_extensions_; |
468 } | 470 } |
469 | 471 |
470 const ExtensionSet* ExtensionService::GenerateInstalledExtensionsSet() const { | 472 const ExtensionSet* ExtensionService::blacklisted_extensions() const { |
471 ExtensionSet* installed_extensions = new ExtensionSet(); | 473 return &blacklisted_extensions_; |
| 474 } |
| 475 |
| 476 scoped_ptr<const ExtensionSet> |
| 477 ExtensionService::GenerateInstalledExtensionsSet() const { |
| 478 scoped_ptr<ExtensionSet> installed_extensions(new ExtensionSet()); |
472 installed_extensions->InsertAll(extensions_); | 479 installed_extensions->InsertAll(extensions_); |
473 installed_extensions->InsertAll(disabled_extensions_); | 480 installed_extensions->InsertAll(disabled_extensions_); |
474 installed_extensions->InsertAll(terminated_extensions_); | 481 installed_extensions->InsertAll(terminated_extensions_); |
475 return installed_extensions; | 482 installed_extensions->InsertAll(blacklisted_extensions_); |
| 483 return installed_extensions.PassAs<const ExtensionSet>(); |
476 } | 484 } |
477 | 485 |
478 const ExtensionSet* ExtensionService::GetWipedOutExtensions() const { | 486 scoped_ptr<const ExtensionSet> ExtensionService::GetWipedOutExtensions() const { |
479 ExtensionSet* extension_set = new ExtensionSet(); | 487 scoped_ptr<ExtensionSet> extension_set(new ExtensionSet()); |
480 for (ExtensionSet::const_iterator iter = disabled_extensions_.begin(); | 488 for (ExtensionSet::const_iterator iter = disabled_extensions_.begin(); |
481 iter != disabled_extensions_.end(); ++iter) { | 489 iter != disabled_extensions_.end(); ++iter) { |
482 int disabled_reason = extension_prefs_->GetDisableReasons((*iter)->id()); | 490 int disabled_reason = extension_prefs_->GetDisableReasons((*iter)->id()); |
483 if ((disabled_reason & Extension::DISABLE_SIDELOAD_WIPEOUT) != 0) | 491 if ((disabled_reason & Extension::DISABLE_SIDELOAD_WIPEOUT) != 0) |
484 extension_set->Insert(*iter); | 492 extension_set->Insert(*iter); |
485 } | 493 } |
486 return extension_set; | 494 return extension_set.PassAs<const ExtensionSet>(); |
487 } | 495 } |
488 | 496 |
489 extensions::PendingExtensionManager* | 497 extensions::PendingExtensionManager* |
490 ExtensionService::pending_extension_manager() { | 498 ExtensionService::pending_extension_manager() { |
491 return &pending_extension_manager_; | 499 return &pending_extension_manager_; |
492 } | 500 } |
493 | 501 |
494 ExtensionService::~ExtensionService() { | 502 ExtensionService::~ExtensionService() { |
495 // No need to unload extensions here because they are profile-scoped, and the | 503 // No need to unload extensions here because they are profile-scoped, and the |
496 // profile is in the process of being deleted. | 504 // profile is in the process of being deleted. |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 push_messaging_event_router_->Shutdown(); | 580 push_messaging_event_router_->Shutdown(); |
573 } | 581 } |
574 | 582 |
575 void ExtensionService::Shutdown() { | 583 void ExtensionService::Shutdown() { |
576 // Do nothing for now. | 584 // Do nothing for now. |
577 } | 585 } |
578 | 586 |
579 const Extension* ExtensionService::GetExtensionById( | 587 const Extension* ExtensionService::GetExtensionById( |
580 const std::string& id, bool include_disabled) const { | 588 const std::string& id, bool include_disabled) const { |
581 int include_mask = INCLUDE_ENABLED; | 589 int include_mask = INCLUDE_ENABLED; |
582 if (include_disabled) | 590 if (include_disabled) { |
583 include_mask |= INCLUDE_DISABLED; | 591 // Include blacklisted extensions here because there are hundreds of |
584 return GetExtensionByIdInternal(id, include_mask); | 592 // callers of this function, and many might assume that this includes those |
| 593 // that have been disabled due to blacklisting. |
| 594 include_mask |= INCLUDE_DISABLED | INCLUDE_BLACKLISTED; |
| 595 } |
| 596 return GetExtensionById(id, include_mask); |
| 597 } |
| 598 |
| 599 const Extension* ExtensionService::GetExtensionById( |
| 600 const std::string& id, int include_mask) const { |
| 601 std::string lowercase_id = StringToLowerASCII(id); |
| 602 if (include_mask & INCLUDE_ENABLED) { |
| 603 const Extension* extension = extensions_.GetByID(lowercase_id); |
| 604 if (extension) |
| 605 return extension; |
| 606 } |
| 607 if (include_mask & INCLUDE_DISABLED) { |
| 608 const Extension* extension = disabled_extensions_.GetByID(lowercase_id); |
| 609 if (extension) |
| 610 return extension; |
| 611 } |
| 612 if (include_mask & INCLUDE_TERMINATED) { |
| 613 const Extension* extension = terminated_extensions_.GetByID(lowercase_id); |
| 614 if (extension) |
| 615 return extension; |
| 616 } |
| 617 if (include_mask & INCLUDE_BLACKLISTED) { |
| 618 const Extension* extension = blacklisted_extensions_.GetByID(lowercase_id); |
| 619 if (extension) |
| 620 return extension; |
| 621 } |
| 622 return NULL; |
585 } | 623 } |
586 | 624 |
587 void ExtensionService::Init() { | 625 void ExtensionService::Init() { |
588 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 626 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
589 | 627 |
590 DCHECK(!ready_); // Can't redo init. | 628 DCHECK(!ready_); // Can't redo init. |
591 DCHECK_EQ(extensions_.size(), 0u); | 629 DCHECK_EQ(extensions_.size(), 0u); |
592 | 630 |
593 // TODO(mek): It might be cleaner to do the FinishIdleInstallInfo stuff here | 631 // TODO(mek): It might be cleaner to do the FinishIdleInstallInfo stuff here |
594 // instead of in installedloader | 632 // instead of in installedloader |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
630 LOG(WARNING) << "Skipping UpdateExtension due to browser shutdown"; | 668 LOG(WARNING) << "Skipping UpdateExtension due to browser shutdown"; |
631 // Leak the temp file at extension_path. We don't want to add to the disk | 669 // Leak the temp file at extension_path. We don't want to add to the disk |
632 // I/O burden at shutdown, we can't rely on the I/O completing anyway, and | 670 // I/O burden at shutdown, we can't rely on the I/O completing anyway, and |
633 // the file is in the OS temp directory which should be cleaned up for us. | 671 // the file is in the OS temp directory which should be cleaned up for us. |
634 return false; | 672 return false; |
635 } | 673 } |
636 | 674 |
637 const extensions::PendingExtensionInfo* pending_extension_info = | 675 const extensions::PendingExtensionInfo* pending_extension_info = |
638 pending_extension_manager()->GetById(id); | 676 pending_extension_manager()->GetById(id); |
639 | 677 |
640 int include_mask = INCLUDE_ENABLED | INCLUDE_DISABLED; | 678 const Extension* extension = GetInstalledExtension(id); |
641 const Extension* extension = | |
642 GetExtensionByIdInternal(id, include_mask); | |
643 if (!pending_extension_info && !extension) { | 679 if (!pending_extension_info && !extension) { |
644 LOG(WARNING) << "Will not update extension " << id | 680 LOG(WARNING) << "Will not update extension " << id |
645 << " because it is not installed or pending"; | 681 << " because it is not installed or pending"; |
646 // Delete extension_path since we're not creating a CrxInstaller | 682 // Delete extension_path since we're not creating a CrxInstaller |
647 // that would do it for us. | 683 // that would do it for us. |
648 if (!GetFileTaskRunner()->PostTask( | 684 if (!GetFileTaskRunner()->PostTask( |
649 FROM_HERE, | 685 FROM_HERE, |
650 base::Bind( | 686 base::Bind( |
651 &extension_file_util::DeleteFile, extension_path, false))) | 687 &extension_file_util::DeleteFile, extension_path, false))) |
652 NOTREACHED(); | 688 NOTREACHED(); |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
883 return true; | 919 return true; |
884 } | 920 } |
885 | 921 |
886 bool ExtensionService::IsExtensionEnabled( | 922 bool ExtensionService::IsExtensionEnabled( |
887 const std::string& extension_id) const { | 923 const std::string& extension_id) const { |
888 if (extensions_.Contains(extension_id) || | 924 if (extensions_.Contains(extension_id) || |
889 terminated_extensions_.Contains(extension_id)) { | 925 terminated_extensions_.Contains(extension_id)) { |
890 return true; | 926 return true; |
891 } | 927 } |
892 | 928 |
893 if (disabled_extensions_.Contains(extension_id)) | 929 if (disabled_extensions_.Contains(extension_id) || |
| 930 blacklisted_extensions_.Contains(extension_id)) { |
894 return false; | 931 return false; |
| 932 } |
895 | 933 |
896 // If the extension hasn't been loaded yet, check the prefs for it. Assume | 934 // If the extension hasn't been loaded yet, check the prefs for it. Assume |
897 // enabled unless otherwise noted. | 935 // enabled unless otherwise noted. |
898 return !extension_prefs_->IsExtensionDisabled(extension_id) && | 936 return !extension_prefs_->IsExtensionDisabled(extension_id) && |
899 !extension_prefs_->IsExternalExtensionUninstalled(extension_id); | 937 !extension_prefs_->IsExternalExtensionUninstalled(extension_id); |
900 } | 938 } |
901 | 939 |
902 bool ExtensionService::IsExternalExtensionUninstalled( | 940 bool ExtensionService::IsExternalExtensionUninstalled( |
903 const std::string& extension_id) const { | 941 const std::string& extension_id) const { |
904 return extension_prefs_->IsExternalExtensionUninstalled(extension_id); | 942 return extension_prefs_->IsExternalExtensionUninstalled(extension_id); |
905 } | 943 } |
906 | 944 |
907 void ExtensionService::EnableExtension(const std::string& extension_id) { | 945 void ExtensionService::EnableExtension(const std::string& extension_id) { |
908 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 946 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
909 | 947 |
910 if (IsExtensionEnabled(extension_id)) | 948 if (IsExtensionEnabled(extension_id)) |
911 return; | 949 return; |
912 | 950 |
913 int disable_reasons = extension_prefs_->GetDisableReasons(extension_id); | 951 int disable_reasons = extension_prefs_->GetDisableReasons(extension_id); |
914 extension_prefs_->SetExtensionState(extension_id, Extension::ENABLED); | 952 extension_prefs_->SetExtensionState(extension_id, Extension::ENABLED); |
915 extension_prefs_->ClearDisableReasons(extension_id); | 953 extension_prefs_->ClearDisableReasons(extension_id); |
916 | 954 |
917 const Extension* extension = GetExtensionByIdInternal(extension_id, | 955 const Extension* extension = disabled_extensions_.GetByID(extension_id); |
918 INCLUDE_DISABLED); | |
919 // This can happen if sync enables an extension that is not | 956 // This can happen if sync enables an extension that is not |
920 // installed yet. | 957 // installed yet. |
921 if (!extension) | 958 if (!extension) |
922 return; | 959 return; |
923 | 960 |
924 if (IsUnacknowledgedExternalExtension(extension)) { | 961 if (IsUnacknowledgedExternalExtension(extension)) { |
925 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEvent", | 962 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEvent", |
926 EXTERNAL_EXTENSION_REENABLED, | 963 EXTERNAL_EXTENSION_REENABLED, |
927 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); | 964 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); |
928 AcknowledgeExternalExtension(extension->id()); | 965 AcknowledgeExternalExtension(extension->id()); |
(...skipping 30 matching lines...) Expand all Loading... |
959 // |extension| can be NULL if sync disables an extension that is not | 996 // |extension| can be NULL if sync disables an extension that is not |
960 // installed yet. | 997 // installed yet. |
961 if (extension && | 998 if (extension && |
962 !system_->management_policy()->UserMayModifySettings(extension, NULL)) { | 999 !system_->management_policy()->UserMayModifySettings(extension, NULL)) { |
963 return; | 1000 return; |
964 } | 1001 } |
965 | 1002 |
966 extension_prefs_->SetExtensionState(extension_id, Extension::DISABLED); | 1003 extension_prefs_->SetExtensionState(extension_id, Extension::DISABLED); |
967 extension_prefs_->AddDisableReason(extension_id, disable_reason); | 1004 extension_prefs_->AddDisableReason(extension_id, disable_reason); |
968 | 1005 |
969 int include_mask = INCLUDE_ENABLED | INCLUDE_TERMINATED; | 1006 int include_mask = INCLUDE_EVERYTHING & ~INCLUDE_DISABLED; |
970 extension = GetExtensionByIdInternal(extension_id, include_mask); | 1007 extension = GetExtensionById(extension_id, include_mask); |
971 if (!extension) | 1008 if (!extension) |
972 return; | 1009 return; |
973 | 1010 |
974 // Move it over to the disabled list. Don't send a second unload notification | 1011 // Move it over to the disabled list. Don't send a second unload notification |
975 // for terminated extensions being disabled. | 1012 // for terminated extensions being disabled. |
976 disabled_extensions_.Insert(make_scoped_refptr(extension)); | 1013 disabled_extensions_.Insert(make_scoped_refptr(extension)); |
977 if (extensions_.Contains(extension->id())) { | 1014 if (extensions_.Contains(extension->id())) { |
978 extensions_.Remove(extension->id()); | 1015 extensions_.Remove(extension->id()); |
979 NotifyExtensionUnloaded(extension, extension_misc::UNLOAD_REASON_DISABLE); | 1016 NotifyExtensionUnloaded(extension, extension_misc::UNLOAD_REASON_DISABLE); |
980 } else { | 1017 } else { |
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1256 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); | 1293 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); |
1257 return file_task_runner_; | 1294 return file_task_runner_; |
1258 } | 1295 } |
1259 | 1296 |
1260 extensions::ExtensionUpdater* ExtensionService::updater() { | 1297 extensions::ExtensionUpdater* ExtensionService::updater() { |
1261 return updater_.get(); | 1298 return updater_.get(); |
1262 } | 1299 } |
1263 | 1300 |
1264 void ExtensionService::CheckManagementPolicy() { | 1301 void ExtensionService::CheckManagementPolicy() { |
1265 std::vector<std::string> to_be_removed; | 1302 std::vector<std::string> to_be_removed; |
| 1303 |
1266 // Loop through extensions list, unload installed extensions. | 1304 // Loop through extensions list, unload installed extensions. |
1267 for (ExtensionSet::const_iterator iter = extensions_.begin(); | 1305 for (ExtensionSet::const_iterator iter = extensions_.begin(); |
1268 iter != extensions_.end(); ++iter) { | 1306 iter != extensions_.end(); ++iter) { |
1269 const Extension* extension = (*iter); | 1307 const Extension* extension = (*iter); |
1270 if (!system_->management_policy()->UserMayLoad(extension, NULL)) | 1308 if (!system_->management_policy()->UserMayLoad(extension, NULL)) |
1271 to_be_removed.push_back(extension->id()); | 1309 to_be_removed.push_back(extension->id()); |
1272 } | 1310 } |
1273 | 1311 |
1274 // UnloadExtension will change the extensions_ list. So, we should | 1312 // UnloadExtension will change the extensions_ list. So, we should |
1275 // call it outside the iterator loop. | 1313 // call it outside the iterator loop. |
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1819 | 1857 |
1820 UpdateExternalExtensionAlert(); | 1858 UpdateExternalExtensionAlert(); |
1821 | 1859 |
1822 if (!did_show_alert) | 1860 if (!did_show_alert) |
1823 extension_error_ui_.reset(); | 1861 extension_error_ui_.reset(); |
1824 } | 1862 } |
1825 | 1863 |
1826 bool ExtensionService::PopulateExtensionErrorUI( | 1864 bool ExtensionService::PopulateExtensionErrorUI( |
1827 ExtensionErrorUI* extension_error_ui) { | 1865 ExtensionErrorUI* extension_error_ui) { |
1828 bool needs_alert = false; | 1866 bool needs_alert = false; |
| 1867 |
| 1868 // Extensions that are blacklisted. |
| 1869 for (ExtensionSet::const_iterator it = blacklisted_extensions_.begin(); |
| 1870 it != blacklisted_extensions_.end(); ++it) { |
| 1871 std::string id = (*it)->id(); |
| 1872 if (!extension_prefs_->IsBlacklistedExtensionAcknowledged(id)) { |
| 1873 extension_error_ui->AddBlacklistedExtension(id); |
| 1874 needs_alert = true; |
| 1875 } |
| 1876 } |
| 1877 |
1829 for (ExtensionSet::const_iterator iter = extensions_.begin(); | 1878 for (ExtensionSet::const_iterator iter = extensions_.begin(); |
1830 iter != extensions_.end(); ++iter) { | 1879 iter != extensions_.end(); ++iter) { |
1831 const Extension* e = *iter; | 1880 const Extension* e = *iter; |
| 1881 |
| 1882 // Extensions disabled by policy. Note: this no longer includes blacklisted |
| 1883 // extensions, though we still show the same UI. |
1832 if (!system_->management_policy()->UserMayLoad(e, NULL)) { | 1884 if (!system_->management_policy()->UserMayLoad(e, NULL)) { |
1833 if (!extension_prefs_->IsBlacklistedExtensionAcknowledged(e->id())) { | 1885 if (!extension_prefs_->IsBlacklistedExtensionAcknowledged(e->id())) { |
1834 extension_error_ui->AddBlacklistedExtension(e->id()); | 1886 extension_error_ui->AddBlacklistedExtension(e->id()); |
1835 needs_alert = true; | 1887 needs_alert = true; |
1836 } | 1888 } |
1837 } | 1889 } |
| 1890 |
| 1891 // Orphaned extensions. |
1838 if (extension_prefs_->IsExtensionOrphaned(e->id())) { | 1892 if (extension_prefs_->IsExtensionOrphaned(e->id())) { |
1839 if (!extension_prefs_->IsOrphanedExtensionAcknowledged(e->id())) { | 1893 if (!extension_prefs_->IsOrphanedExtensionAcknowledged(e->id())) { |
1840 extension_error_ui->AddOrphanedExtension(e->id()); | 1894 extension_error_ui->AddOrphanedExtension(e->id()); |
1841 needs_alert = true; | 1895 needs_alert = true; |
1842 } | 1896 } |
1843 } | 1897 } |
1844 } | 1898 } |
| 1899 |
1845 return needs_alert; | 1900 return needs_alert; |
1846 } | 1901 } |
1847 | 1902 |
1848 void ExtensionService::HandleExtensionAlertClosed() { | 1903 void ExtensionService::HandleExtensionAlertClosed() { |
1849 extension_error_ui_.reset(); | 1904 extension_error_ui_.reset(); |
1850 } | 1905 } |
1851 | 1906 |
1852 void ExtensionService::HandleExtensionAlertAccept() { | 1907 void ExtensionService::HandleExtensionAlertAccept() { |
1853 const ExtensionIdSet* extension_ids = | 1908 const ExtensionIdSet* extension_ids = |
1854 extension_error_ui_->get_blacklisted_extension_ids(); | 1909 extension_error_ui_->get_blacklisted_extension_ids(); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1914 } | 1969 } |
1915 } else { | 1970 } else { |
1916 extensions::RemoveExternalInstallError(this); | 1971 extensions::RemoveExternalInstallError(this); |
1917 } | 1972 } |
1918 } | 1973 } |
1919 | 1974 |
1920 void ExtensionService::UnloadExtension( | 1975 void ExtensionService::UnloadExtension( |
1921 const std::string& extension_id, | 1976 const std::string& extension_id, |
1922 extension_misc::UnloadedExtensionReason reason) { | 1977 extension_misc::UnloadedExtensionReason reason) { |
1923 // Make sure the extension gets deleted after we return from this function. | 1978 // Make sure the extension gets deleted after we return from this function. |
1924 int include_mask = INCLUDE_ENABLED | INCLUDE_DISABLED; | 1979 int include_mask = INCLUDE_EVERYTHING & ~INCLUDE_TERMINATED; |
1925 scoped_refptr<const Extension> extension( | 1980 scoped_refptr<const Extension> extension( |
1926 GetExtensionByIdInternal(extension_id, include_mask)); | 1981 GetExtensionById(extension_id, include_mask)); |
1927 | 1982 |
1928 // This method can be called via PostTask, so the extension may have been | 1983 // This method can be called via PostTask, so the extension may have been |
1929 // unloaded by the time this runs. | 1984 // unloaded by the time this runs. |
1930 if (!extension) { | 1985 if (!extension) { |
1931 // In case the extension may have crashed/uninstalled. Allow the profile to | 1986 // In case the extension may have crashed/uninstalled. Allow the profile to |
1932 // clean up its RequestContexts. | 1987 // clean up its RequestContexts. |
1933 system_->UnregisterExtensionWithRequestContexts(extension_id, reason); | 1988 system_->UnregisterExtensionWithRequestContexts(extension_id, reason); |
1934 return; | 1989 return; |
1935 } | 1990 } |
1936 | 1991 |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2074 EnableExtension(extension->id()); | 2129 EnableExtension(extension->id()); |
2075 | 2130 |
2076 // Check if the extension's privileges have changed and disable the | 2131 // Check if the extension's privileges have changed and disable the |
2077 // extension if necessary. | 2132 // extension if necessary. |
2078 InitializePermissions(extension); | 2133 InitializePermissions(extension); |
2079 | 2134 |
2080 // If this extension is a sideloaded extension and we've not performed a | 2135 // If this extension is a sideloaded extension and we've not performed a |
2081 // wipeout before, we might disable this extension here. | 2136 // wipeout before, we might disable this extension here. |
2082 MaybeWipeout(extension); | 2137 MaybeWipeout(extension); |
2083 | 2138 |
2084 if (extension_prefs_->IsExtensionDisabled(extension->id())) { | 2139 // Communicated to the Blacklist. |
| 2140 std::set<std::string> already_in_blacklist; |
| 2141 |
| 2142 if (extension_prefs_->IsExtensionBlacklisted(extension->id())) { |
| 2143 // Don't check the Blacklist yet because it's asynchronous (we do it at |
| 2144 // the end). This pre-emptive check is because we will always store the |
| 2145 // blacklisted state of *installed* extensions in prefs, and it's important |
| 2146 // not to re-enable blacklisted extensions. |
| 2147 blacklisted_extensions_.Insert(extension); |
| 2148 already_in_blacklist.insert(extension->id()); |
| 2149 } else if (extension_prefs_->IsExtensionDisabled(extension->id())) { |
2085 disabled_extensions_.Insert(extension); | 2150 disabled_extensions_.Insert(extension); |
2086 SyncExtensionChangeIfNeeded(*extension); | 2151 SyncExtensionChangeIfNeeded(*extension); |
2087 content::NotificationService::current()->Notify( | 2152 content::NotificationService::current()->Notify( |
2088 chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED, | 2153 chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED, |
2089 content::Source<Profile>(profile_), | 2154 content::Source<Profile>(profile_), |
2090 content::Details<const Extension>(extension)); | 2155 content::Details<const Extension>(extension)); |
2091 | 2156 |
2092 if (extension_prefs_->GetDisableReasons(extension->id()) & | 2157 if (extension_prefs_->GetDisableReasons(extension->id()) & |
2093 Extension::DISABLE_PERMISSIONS_INCREASE) { | 2158 Extension::DISABLE_PERMISSIONS_INCREASE) { |
2094 extensions::AddExtensionDisabledError(this, extension); | 2159 extensions::AddExtensionDisabledError(this, extension); |
2095 } | 2160 } |
2096 return; | 2161 } else { |
| 2162 // All apps that are displayed in the launcher are ordered by their ordinals |
| 2163 // so we must ensure they have valid ordinals. |
| 2164 if (extension->RequiresSortOrdinal()) { |
| 2165 extension_prefs_->extension_sorting()->EnsureValidOrdinals( |
| 2166 extension->id(), syncer::StringOrdinal()); |
| 2167 } |
| 2168 |
| 2169 extensions_.Insert(extension); |
| 2170 SyncExtensionChangeIfNeeded(*extension); |
| 2171 NotifyExtensionLoaded(extension); |
| 2172 DoPostLoadTasks(extension); |
| 2173 |
| 2174 #if defined(ENABLE_THEMES) |
| 2175 if (extension->is_theme()) { |
| 2176 // Now that the theme extension is visible from outside the |
| 2177 // ExtensionService, notify the ThemeService about the |
| 2178 // newly-installed theme. |
| 2179 ThemeServiceFactory::GetForProfile(profile_)->SetTheme(extension); |
| 2180 } |
| 2181 #endif |
2097 } | 2182 } |
2098 | 2183 |
2099 // All apps that are displayed in the launcher are ordered by their ordinals | 2184 // Lastly, begin the process for checking the blacklist status of extensions. |
2100 // so we must ensure they have valid ordinals. | 2185 // This may need to go to other threads so is asynchronous. |
2101 if (extension->RequiresSortOrdinal()) { | 2186 std::set<std::string> id_set; |
2102 extension_prefs_->extension_sorting()->EnsureValidOrdinals( | 2187 id_set.insert(extension->id()); |
2103 extension->id(), syncer::StringOrdinal()); | 2188 blacklist_->GetBlacklistedIDs( |
2104 } | 2189 id_set, |
2105 | 2190 base::Bind(&ExtensionService::ManageBlacklist, |
2106 extensions_.Insert(extension); | 2191 AsWeakPtr(), |
2107 SyncExtensionChangeIfNeeded(*extension); | 2192 already_in_blacklist)); |
2108 NotifyExtensionLoaded(extension); | |
2109 DoPostLoadTasks(extension); | |
2110 | |
2111 #if defined(ENABLE_THEMES) | |
2112 if (extension->is_theme()) { | |
2113 // Now that the theme extension is visible from outside the | |
2114 // ExtensionService, notify the ThemeService about the | |
2115 // newly-installed theme. | |
2116 ThemeServiceFactory::GetForProfile(profile_)->SetTheme(extension); | |
2117 } | |
2118 #endif | |
2119 } | 2193 } |
2120 | 2194 |
2121 void ExtensionService::AddComponentExtension(const Extension* extension) { | 2195 void ExtensionService::AddComponentExtension(const Extension* extension) { |
2122 const std::string old_version_string( | 2196 const std::string old_version_string( |
2123 extension_prefs_->GetVersionString(extension->id())); | 2197 extension_prefs_->GetVersionString(extension->id())); |
2124 const Version old_version(old_version_string); | 2198 const Version old_version(old_version_string); |
2125 | 2199 |
2126 if (!old_version.IsValid() || !old_version.Equals(*extension->version())) { | 2200 if (!old_version.IsValid() || !old_version.Equals(*extension->version())) { |
2127 VLOG(1) << "Component extension " << extension->name() << " (" | 2201 VLOG(1) << "Component extension " << extension->name() << " (" |
2128 << extension->id() << ") installing/upgrading from '" | 2202 << extension->id() << ") installing/upgrading from '" |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2181 // maintain backwards compatibility while still having "omnibox" in the | 2255 // maintain backwards compatibility while still having "omnibox" in the |
2182 // manifest. If a user installs the extension on Chrome 9, the browser | 2256 // manifest. If a user installs the extension on Chrome 9, the browser |
2183 // will record the permissions it recognized, not including "omnibox." | 2257 // will record the permissions it recognized, not including "omnibox." |
2184 // When upgrading to Chrome 10, "omnibox" will be recognized and Chrome | 2258 // When upgrading to Chrome 10, "omnibox" will be recognized and Chrome |
2185 // will disable the extension and prompt the user to approve the increase | 2259 // will disable the extension and prompt the user to approve the increase |
2186 // in privileges. The extension could then release a new version that | 2260 // in privileges. The extension could then release a new version that |
2187 // removes the "omnibox" permission. When the user upgrades, Chrome will | 2261 // removes the "omnibox" permission. When the user upgrades, Chrome will |
2188 // still remember that "omnibox" had been granted, so that if the | 2262 // still remember that "omnibox" had been granted, so that if the |
2189 // extension once again includes "omnibox" in an upgrade, the extension | 2263 // extension once again includes "omnibox" in an upgrade, the extension |
2190 // can upgrade without requiring this user's approval. | 2264 // can upgrade without requiring this user's approval. |
2191 int include_mask = INCLUDE_ENABLED | INCLUDE_DISABLED; | 2265 const Extension* old = GetInstalledExtension(extension->id()); |
2192 const Extension* old = | |
2193 GetExtensionByIdInternal(extension->id(), include_mask); | |
2194 bool is_extension_upgrade = old != NULL; | 2266 bool is_extension_upgrade = old != NULL; |
2195 bool is_privilege_increase = false; | 2267 bool is_privilege_increase = false; |
2196 bool previously_disabled = false; | 2268 bool previously_disabled = false; |
2197 int disable_reasons = extension_prefs_->GetDisableReasons(extension->id()); | 2269 int disable_reasons = extension_prefs_->GetDisableReasons(extension->id()); |
2198 | 2270 |
2199 // We only need to compare the granted permissions to the current permissions | 2271 // We only need to compare the granted permissions to the current permissions |
2200 // if the extension is not allowed to silently increase its permissions. | 2272 // if the extension is not allowed to silently increase its permissions. |
2201 bool is_default_app_install = | 2273 bool is_default_app_install = |
2202 (!is_extension_upgrade && extension->was_installed_by_default()); | 2274 (!is_extension_upgrade && extension->was_installed_by_default()); |
2203 if (!(extension->CanSilentlyIncreasePermissions() | 2275 if (!(extension->CanSilentlyIncreasePermissions() |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2364 id, Extension::DISABLE_UNSUPPORTED_REQUIREMENT); | 2436 id, Extension::DISABLE_UNSUPPORTED_REQUIREMENT); |
2365 // If the extension was disabled because of unsupported requirements but | 2437 // If the extension was disabled because of unsupported requirements but |
2366 // now supports all requirements after an update and there are not other | 2438 // now supports all requirements after an update and there are not other |
2367 // disable reasons, enable it. | 2439 // disable reasons, enable it. |
2368 } else if (extension_prefs_->GetDisableReasons(id) == | 2440 } else if (extension_prefs_->GetDisableReasons(id) == |
2369 Extension::DISABLE_UNSUPPORTED_REQUIREMENT) { | 2441 Extension::DISABLE_UNSUPPORTED_REQUIREMENT) { |
2370 initial_enable = true; | 2442 initial_enable = true; |
2371 extension_prefs_->ClearDisableReasons(id); | 2443 extension_prefs_->ClearDisableReasons(id); |
2372 } | 2444 } |
2373 | 2445 |
2374 int include_mask = INCLUDE_ENABLED | INCLUDE_DISABLED; | 2446 if (!GetInstalledExtension(extension->id())) { |
2375 if (!GetExtensionByIdInternal(extension->id(), include_mask)) { | |
2376 UMA_HISTOGRAM_ENUMERATION("Extensions.InstallType", | 2447 UMA_HISTOGRAM_ENUMERATION("Extensions.InstallType", |
2377 extension->GetType(), 100); | 2448 extension->GetType(), 100); |
2378 UMA_HISTOGRAM_ENUMERATION("Extensions.InstallSource", | 2449 UMA_HISTOGRAM_ENUMERATION("Extensions.InstallSource", |
2379 extension->location(), Extension::NUM_LOCATIONS); | 2450 extension->location(), Extension::NUM_LOCATIONS); |
2380 RecordPermissionMessagesHistogram( | 2451 RecordPermissionMessagesHistogram( |
2381 extension, "Extensions.Permissions_Install"); | 2452 extension, "Extensions.Permissions_Install"); |
2382 } else { | 2453 } else { |
2383 UMA_HISTOGRAM_ENUMERATION("Extensions.UpdateType", | 2454 UMA_HISTOGRAM_ENUMERATION("Extensions.UpdateType", |
2384 extension->GetType(), 100); | 2455 extension->GetType(), 100); |
2385 UMA_HISTOGRAM_ENUMERATION("Extensions.UpdateSource", | 2456 UMA_HISTOGRAM_ENUMERATION("Extensions.UpdateSource", |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2477 EXTERNAL_EXTENSION_INSTALLED, | 2548 EXTERNAL_EXTENSION_INSTALLED, |
2478 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); | 2549 EXTERNAL_EXTENSION_BUCKET_BOUNDARY); |
2479 } | 2550 } |
2480 } | 2551 } |
2481 | 2552 |
2482 const Extension* ExtensionService::GetPendingExtensionUpdate( | 2553 const Extension* ExtensionService::GetPendingExtensionUpdate( |
2483 const std::string& id) const { | 2554 const std::string& id) const { |
2484 return pending_extension_updates_.GetByID(id); | 2555 return pending_extension_updates_.GetByID(id); |
2485 } | 2556 } |
2486 | 2557 |
2487 const Extension* ExtensionService::GetExtensionByIdInternal( | |
2488 const std::string& id, int include_mask) const { | |
2489 std::string lowercase_id = StringToLowerASCII(id); | |
2490 if (include_mask & INCLUDE_ENABLED) { | |
2491 const Extension* extension = extensions_.GetByID(lowercase_id); | |
2492 if (extension) | |
2493 return extension; | |
2494 } | |
2495 if (include_mask & INCLUDE_DISABLED) { | |
2496 const Extension* extension = disabled_extensions_.GetByID(lowercase_id); | |
2497 if (extension) | |
2498 return extension; | |
2499 } | |
2500 if (include_mask & INCLUDE_TERMINATED) { | |
2501 const Extension* extension = terminated_extensions_.GetByID(lowercase_id); | |
2502 if (extension) | |
2503 return extension; | |
2504 } | |
2505 return NULL; | |
2506 } | |
2507 | |
2508 void ExtensionService::TrackTerminatedExtension(const Extension* extension) { | 2558 void ExtensionService::TrackTerminatedExtension(const Extension* extension) { |
2509 if (!terminated_extensions_.Contains(extension->id())) | 2559 if (!terminated_extensions_.Contains(extension->id())) |
2510 terminated_extensions_.Insert(make_scoped_refptr(extension)); | 2560 terminated_extensions_.Insert(make_scoped_refptr(extension)); |
2511 | 2561 |
2512 UnloadExtension(extension->id(), extension_misc::UNLOAD_REASON_TERMINATE); | 2562 UnloadExtension(extension->id(), extension_misc::UNLOAD_REASON_TERMINATE); |
2513 } | 2563 } |
2514 | 2564 |
2515 void ExtensionService::UntrackTerminatedExtension(const std::string& id) { | 2565 void ExtensionService::UntrackTerminatedExtension(const std::string& id) { |
2516 std::string lowercase_id = StringToLowerASCII(id); | 2566 std::string lowercase_id = StringToLowerASCII(id); |
2517 terminated_extensions_.Remove(lowercase_id); | 2567 terminated_extensions_.Remove(lowercase_id); |
2518 } | 2568 } |
2519 | 2569 |
2520 const Extension* ExtensionService::GetTerminatedExtension( | 2570 const Extension* ExtensionService::GetTerminatedExtension( |
2521 const std::string& id) const { | 2571 const std::string& id) const { |
2522 return GetExtensionByIdInternal(id, INCLUDE_TERMINATED); | 2572 return GetExtensionById(id, INCLUDE_TERMINATED); |
2523 } | 2573 } |
2524 | 2574 |
2525 const Extension* ExtensionService::GetInstalledExtension( | 2575 const Extension* ExtensionService::GetInstalledExtension( |
2526 const std::string& id) const { | 2576 const std::string& id) const { |
2527 int include_mask = INCLUDE_ENABLED | INCLUDE_DISABLED | INCLUDE_TERMINATED; | 2577 int include_mask = INCLUDE_ENABLED | |
2528 return GetExtensionByIdInternal(id, include_mask); | 2578 INCLUDE_DISABLED | |
| 2579 INCLUDE_TERMINATED | |
| 2580 INCLUDE_BLACKLISTED; |
| 2581 return GetExtensionById(id, include_mask); |
2529 } | 2582 } |
2530 | 2583 |
2531 bool ExtensionService::ExtensionBindingsAllowed(const GURL& url) { | 2584 bool ExtensionService::ExtensionBindingsAllowed(const GURL& url) { |
2532 // Allow bindings for all packaged extensions and component hosted apps. | 2585 // Allow bindings for all packaged extensions and component hosted apps. |
2533 const Extension* extension = extensions_.GetExtensionOrAppByURL( | 2586 const Extension* extension = extensions_.GetExtensionOrAppByURL( |
2534 ExtensionURLInfo(url)); | 2587 ExtensionURLInfo(url)); |
2535 return extension && (!extension->is_hosted_app() || | 2588 return extension && (!extension->is_hosted_app() || |
2536 extension->location() == Extension::COMPONENT); | 2589 extension->location() == Extension::COMPONENT); |
2537 } | 2590 } |
2538 | 2591 |
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3010 bool ExtensionService::ShouldDelayExtensionUpdate( | 3063 bool ExtensionService::ShouldDelayExtensionUpdate( |
3011 const std::string& extension_id, | 3064 const std::string& extension_id, |
3012 bool wait_for_idle) const { | 3065 bool wait_for_idle) const { |
3013 const char kOnUpdateAvailableEvent[] = "runtime.onUpdateAvailable"; | 3066 const char kOnUpdateAvailableEvent[] = "runtime.onUpdateAvailable"; |
3014 | 3067 |
3015 // If delayed updates are globally disabled, or just for this extension, | 3068 // If delayed updates are globally disabled, or just for this extension, |
3016 // don't delay. | 3069 // don't delay. |
3017 if (!install_updates_when_idle_ || !wait_for_idle) | 3070 if (!install_updates_when_idle_ || !wait_for_idle) |
3018 return false; | 3071 return false; |
3019 | 3072 |
3020 int include_mask = INCLUDE_ENABLED | INCLUDE_DISABLED; | 3073 const Extension* old = GetInstalledExtension(extension_id); |
3021 const Extension* old = | |
3022 GetExtensionByIdInternal(extension_id, include_mask); | |
3023 // If there is no old extension, this is not an update, so don't delay. | 3074 // If there is no old extension, this is not an update, so don't delay. |
3024 if (!old) | 3075 if (!old) |
3025 return false; | 3076 return false; |
3026 | 3077 |
3027 if (old->has_persistent_background_page()) { | 3078 if (old->has_persistent_background_page()) { |
3028 // Delay installation if the extension listens for the onUpdateAvailable | 3079 // Delay installation if the extension listens for the onUpdateAvailable |
3029 // event. | 3080 // event. |
3030 return system_->event_router()->ExtensionHasEventListener( | 3081 return system_->event_router()->ExtensionHasEventListener( |
3031 extension_id, kOnUpdateAvailableEvent); | 3082 extension_id, kOnUpdateAvailableEvent); |
3032 } else { | 3083 } else { |
3033 // Delay installation if the extension is not idle. | 3084 // Delay installation if the extension is not idle. |
3034 return !IsExtensionIdle(extension_id); | 3085 return !IsExtensionIdle(extension_id); |
3035 } | 3086 } |
3036 } | 3087 } |
3037 | 3088 |
3038 void ExtensionService::OnBlacklistUpdated() { | 3089 void ExtensionService::OnBlacklistUpdated() { |
3039 CheckManagementPolicy(); | 3090 blacklist_->GetBlacklistedIDs( |
| 3091 GenerateInstalledExtensionsSet()->GetIDs(), |
| 3092 base::Bind(&ExtensionService::ManageBlacklist, |
| 3093 AsWeakPtr(), |
| 3094 blacklisted_extensions_.GetIDs())); |
3040 } | 3095 } |
| 3096 |
| 3097 void ExtensionService::ManageBlacklist( |
| 3098 const std::set<std::string>& old_blacklisted_ids, |
| 3099 const std::set<std::string>& new_blacklisted_ids) { |
| 3100 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 3101 |
| 3102 std::set<std::string> no_longer_blacklisted; |
| 3103 std::set_difference(old_blacklisted_ids.begin(), old_blacklisted_ids.end(), |
| 3104 new_blacklisted_ids.begin(), new_blacklisted_ids.end(), |
| 3105 std::inserter(no_longer_blacklisted, |
| 3106 no_longer_blacklisted.begin())); |
| 3107 std::set<std::string> not_yet_blacklisted; |
| 3108 std::set_difference(new_blacklisted_ids.begin(), new_blacklisted_ids.end(), |
| 3109 old_blacklisted_ids.begin(), old_blacklisted_ids.end(), |
| 3110 std::inserter(not_yet_blacklisted, |
| 3111 not_yet_blacklisted.begin())); |
| 3112 |
| 3113 for (std::set<std::string>::iterator it = no_longer_blacklisted.begin(); |
| 3114 it != no_longer_blacklisted.end(); ++it) { |
| 3115 scoped_refptr<const Extension> extension = |
| 3116 blacklisted_extensions_.GetByID(*it); |
| 3117 DCHECK(extension); |
| 3118 if (!extension) |
| 3119 continue; |
| 3120 blacklisted_extensions_.Remove(*it); |
| 3121 AddExtension(extension); |
| 3122 } |
| 3123 |
| 3124 for (std::set<std::string>::iterator it = not_yet_blacklisted.begin(); |
| 3125 it != not_yet_blacklisted.end(); ++it) { |
| 3126 scoped_refptr<const Extension> extension = GetInstalledExtension(*it); |
| 3127 DCHECK(extension); |
| 3128 if (!extension) |
| 3129 continue; |
| 3130 blacklisted_extensions_.Insert(extension); |
| 3131 UnloadExtension(*it, extension_misc::UNLOAD_REASON_BLACKLIST); |
| 3132 } |
| 3133 |
| 3134 IdentifyAlertableExtensions(); |
| 3135 } |
OLD | NEW |