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 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 const CommandLine* command_line, | 359 const CommandLine* command_line, |
359 const FilePath& install_directory, | 360 const FilePath& install_directory, |
360 extensions::ExtensionPrefs* extension_prefs, | 361 extensions::ExtensionPrefs* extension_prefs, |
361 extensions::Blacklist* blacklist, | 362 extensions::Blacklist* blacklist, |
362 bool autoupdate_enabled, | 363 bool autoupdate_enabled, |
363 bool extensions_enabled) | 364 bool extensions_enabled) |
364 : extensions::Blacklist::Observer(blacklist), | 365 : extensions::Blacklist::Observer(blacklist), |
365 profile_(profile), | 366 profile_(profile), |
366 system_(extensions::ExtensionSystem::Get(profile)), | 367 system_(extensions::ExtensionSystem::Get(profile)), |
367 extension_prefs_(extension_prefs), | 368 extension_prefs_(extension_prefs), |
| 369 blacklist_(blacklist), |
368 settings_frontend_(extensions::SettingsFrontend::Create(profile)), | 370 settings_frontend_(extensions::SettingsFrontend::Create(profile)), |
369 pending_extension_manager_(*ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 371 pending_extension_manager_(*ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
370 install_directory_(install_directory), | 372 install_directory_(install_directory), |
371 extensions_enabled_(extensions_enabled), | 373 extensions_enabled_(extensions_enabled), |
372 show_extensions_prompts_(true), | 374 show_extensions_prompts_(true), |
373 install_updates_when_idle_(true), | 375 install_updates_when_idle_(true), |
374 ready_(false), | 376 ready_(false), |
375 toolbar_model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 377 toolbar_model_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
376 menu_manager_(profile), | 378 menu_manager_(profile), |
377 app_notification_manager_( | 379 app_notification_manager_( |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 } | 465 } |
464 | 466 |
465 const ExtensionSet* ExtensionService::disabled_extensions() const { | 467 const ExtensionSet* ExtensionService::disabled_extensions() const { |
466 return &disabled_extensions_; | 468 return &disabled_extensions_; |
467 } | 469 } |
468 | 470 |
469 const ExtensionSet* ExtensionService::terminated_extensions() const { | 471 const ExtensionSet* ExtensionService::terminated_extensions() const { |
470 return &terminated_extensions_; | 472 return &terminated_extensions_; |
471 } | 473 } |
472 | 474 |
473 const ExtensionSet* ExtensionService::GenerateInstalledExtensionsSet() const { | 475 const ExtensionSet* ExtensionService::blacklisted_extensions() const { |
474 ExtensionSet* installed_extensions = new ExtensionSet(); | 476 return &blacklisted_extensions_; |
| 477 } |
| 478 |
| 479 scoped_ptr<const ExtensionSet> |
| 480 ExtensionService::GenerateInstalledExtensionsSet() const { |
| 481 scoped_ptr<ExtensionSet> installed_extensions(new ExtensionSet()); |
475 installed_extensions->InsertAll(extensions_); | 482 installed_extensions->InsertAll(extensions_); |
476 installed_extensions->InsertAll(disabled_extensions_); | 483 installed_extensions->InsertAll(disabled_extensions_); |
477 installed_extensions->InsertAll(terminated_extensions_); | 484 installed_extensions->InsertAll(terminated_extensions_); |
478 return installed_extensions; | 485 return installed_extensions.PassAs<const ExtensionSet>(); |
479 } | 486 } |
480 | 487 |
481 const ExtensionSet* ExtensionService::GetWipedOutExtensions() const { | 488 scoped_ptr<const ExtensionSet> ExtensionService::GetWipedOutExtensions() const { |
482 ExtensionSet* extension_set = new ExtensionSet(); | 489 scoped_ptr<ExtensionSet> extension_set(new ExtensionSet()); |
483 for (ExtensionSet::const_iterator iter = disabled_extensions_.begin(); | 490 for (ExtensionSet::const_iterator iter = disabled_extensions_.begin(); |
484 iter != disabled_extensions_.end(); ++iter) { | 491 iter != disabled_extensions_.end(); ++iter) { |
485 int disabled_reason = extension_prefs_->GetDisableReasons((*iter)->id()); | 492 int disabled_reason = extension_prefs_->GetDisableReasons((*iter)->id()); |
486 if ((disabled_reason & Extension::DISABLE_SIDELOAD_WIPEOUT) != 0) | 493 if ((disabled_reason & Extension::DISABLE_SIDELOAD_WIPEOUT) != 0) |
487 extension_set->Insert(*iter); | 494 extension_set->Insert(*iter); |
488 } | 495 } |
489 return extension_set; | 496 return extension_set.PassAs<const ExtensionSet>(); |
490 } | 497 } |
491 | 498 |
492 extensions::PendingExtensionManager* | 499 extensions::PendingExtensionManager* |
493 ExtensionService::pending_extension_manager() { | 500 ExtensionService::pending_extension_manager() { |
494 return &pending_extension_manager_; | 501 return &pending_extension_manager_; |
495 } | 502 } |
496 | 503 |
497 ExtensionService::~ExtensionService() { | 504 ExtensionService::~ExtensionService() { |
498 // No need to unload extensions here because they are profile-scoped, and the | 505 // No need to unload extensions here because they are profile-scoped, and the |
499 // profile is in the process of being deleted. | 506 // profile is in the process of being deleted. |
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
886 return true; | 893 return true; |
887 } | 894 } |
888 | 895 |
889 bool ExtensionService::IsExtensionEnabled( | 896 bool ExtensionService::IsExtensionEnabled( |
890 const std::string& extension_id) const { | 897 const std::string& extension_id) const { |
891 if (extensions_.Contains(extension_id) || | 898 if (extensions_.Contains(extension_id) || |
892 terminated_extensions_.Contains(extension_id)) { | 899 terminated_extensions_.Contains(extension_id)) { |
893 return true; | 900 return true; |
894 } | 901 } |
895 | 902 |
896 if (disabled_extensions_.Contains(extension_id)) | 903 if (disabled_extensions_.Contains(extension_id) || |
| 904 blacklisted_extensions_.Contains(extension_id)) { |
897 return false; | 905 return false; |
| 906 } |
898 | 907 |
899 // If the extension hasn't been loaded yet, check the prefs for it. Assume | 908 // If the extension hasn't been loaded yet, check the prefs for it. Assume |
900 // enabled unless otherwise noted. | 909 // enabled unless otherwise noted. |
901 return !extension_prefs_->IsExtensionDisabled(extension_id) && | 910 return !extension_prefs_->IsExtensionDisabled(extension_id) && |
902 !extension_prefs_->IsExternalExtensionUninstalled(extension_id); | 911 !extension_prefs_->IsExternalExtensionUninstalled(extension_id); |
903 } | 912 } |
904 | 913 |
905 bool ExtensionService::IsExternalExtensionUninstalled( | 914 bool ExtensionService::IsExternalExtensionUninstalled( |
906 const std::string& extension_id) const { | 915 const std::string& extension_id) const { |
907 return extension_prefs_->IsExternalExtensionUninstalled(extension_id); | 916 return extension_prefs_->IsExternalExtensionUninstalled(extension_id); |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1259 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); | 1268 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); |
1260 return file_task_runner_; | 1269 return file_task_runner_; |
1261 } | 1270 } |
1262 | 1271 |
1263 extensions::ExtensionUpdater* ExtensionService::updater() { | 1272 extensions::ExtensionUpdater* ExtensionService::updater() { |
1264 return updater_.get(); | 1273 return updater_.get(); |
1265 } | 1274 } |
1266 | 1275 |
1267 void ExtensionService::CheckManagementPolicy() { | 1276 void ExtensionService::CheckManagementPolicy() { |
1268 std::vector<std::string> to_be_removed; | 1277 std::vector<std::string> to_be_removed; |
| 1278 |
1269 // Loop through extensions list, unload installed extensions. | 1279 // Loop through extensions list, unload installed extensions. |
1270 for (ExtensionSet::const_iterator iter = extensions_.begin(); | 1280 for (ExtensionSet::const_iterator iter = extensions_.begin(); |
1271 iter != extensions_.end(); ++iter) { | 1281 iter != extensions_.end(); ++iter) { |
1272 const Extension* extension = (*iter); | 1282 const Extension* extension = (*iter); |
1273 if (!system_->management_policy()->UserMayLoad(extension, NULL)) | 1283 if (!system_->management_policy()->UserMayLoad(extension, NULL)) |
1274 to_be_removed.push_back(extension->id()); | 1284 to_be_removed.push_back(extension->id()); |
1275 } | 1285 } |
1276 | 1286 |
1277 // UnloadExtension will change the extensions_ list. So, we should | 1287 // UnloadExtension will change the extensions_ list. So, we should |
1278 // call it outside the iterator loop. | 1288 // call it outside the iterator loop. |
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1822 | 1832 |
1823 UpdateExternalExtensionAlert(); | 1833 UpdateExternalExtensionAlert(); |
1824 | 1834 |
1825 if (!did_show_alert) | 1835 if (!did_show_alert) |
1826 extension_error_ui_.reset(); | 1836 extension_error_ui_.reset(); |
1827 } | 1837 } |
1828 | 1838 |
1829 bool ExtensionService::PopulateExtensionErrorUI( | 1839 bool ExtensionService::PopulateExtensionErrorUI( |
1830 ExtensionErrorUI* extension_error_ui) { | 1840 ExtensionErrorUI* extension_error_ui) { |
1831 bool needs_alert = false; | 1841 bool needs_alert = false; |
| 1842 |
| 1843 // Extensions that are blacklisted. |
| 1844 for (ExtensionSet::const_iterator it = blacklisted_extensions_.begin(); |
| 1845 it != blacklisted_extensions_.end(); ++it) { |
| 1846 std::string id = (*it)->id(); |
| 1847 if (!extension_prefs_->IsBlacklistedExtensionAcknowledged(id)) { |
| 1848 extension_error_ui->AddBlacklistedExtension(id); |
| 1849 needs_alert = true; |
| 1850 } |
| 1851 } |
| 1852 |
1832 for (ExtensionSet::const_iterator iter = extensions_.begin(); | 1853 for (ExtensionSet::const_iterator iter = extensions_.begin(); |
1833 iter != extensions_.end(); ++iter) { | 1854 iter != extensions_.end(); ++iter) { |
1834 const Extension* e = *iter; | 1855 const Extension* e = *iter; |
| 1856 |
| 1857 // Extensions disabled by policy. Note: this no longer includes blacklisted |
| 1858 // extensions, though we still show the same UI. |
1835 if (!system_->management_policy()->UserMayLoad(e, NULL)) { | 1859 if (!system_->management_policy()->UserMayLoad(e, NULL)) { |
1836 if (!extension_prefs_->IsBlacklistedExtensionAcknowledged(e->id())) { | 1860 if (!extension_prefs_->IsBlacklistedExtensionAcknowledged(e->id())) { |
1837 extension_error_ui->AddBlacklistedExtension(e->id()); | 1861 extension_error_ui->AddBlacklistedExtension(e->id()); |
1838 needs_alert = true; | 1862 needs_alert = true; |
1839 } | 1863 } |
1840 } | 1864 } |
| 1865 |
| 1866 // Orphaned extensions. |
1841 if (extension_prefs_->IsExtensionOrphaned(e->id())) { | 1867 if (extension_prefs_->IsExtensionOrphaned(e->id())) { |
1842 if (!extension_prefs_->IsOrphanedExtensionAcknowledged(e->id())) { | 1868 if (!extension_prefs_->IsOrphanedExtensionAcknowledged(e->id())) { |
1843 extension_error_ui->AddOrphanedExtension(e->id()); | 1869 extension_error_ui->AddOrphanedExtension(e->id()); |
1844 needs_alert = true; | 1870 needs_alert = true; |
1845 } | 1871 } |
1846 } | 1872 } |
1847 } | 1873 } |
| 1874 |
1848 return needs_alert; | 1875 return needs_alert; |
1849 } | 1876 } |
1850 | 1877 |
1851 void ExtensionService::HandleExtensionAlertClosed() { | 1878 void ExtensionService::HandleExtensionAlertClosed() { |
1852 extension_error_ui_.reset(); | 1879 extension_error_ui_.reset(); |
1853 } | 1880 } |
1854 | 1881 |
1855 void ExtensionService::HandleExtensionAlertAccept() { | 1882 void ExtensionService::HandleExtensionAlertAccept() { |
1856 const ExtensionIdSet* extension_ids = | 1883 const ExtensionIdSet* extension_ids = |
1857 extension_error_ui_->get_blacklisted_extension_ids(); | 1884 extension_error_ui_->get_blacklisted_extension_ids(); |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2077 EnableExtension(extension->id()); | 2104 EnableExtension(extension->id()); |
2078 | 2105 |
2079 // Check if the extension's privileges have changed and disable the | 2106 // Check if the extension's privileges have changed and disable the |
2080 // extension if necessary. | 2107 // extension if necessary. |
2081 InitializePermissions(extension); | 2108 InitializePermissions(extension); |
2082 | 2109 |
2083 // If this extension is a sideloaded extension and we've not performed a | 2110 // If this extension is a sideloaded extension and we've not performed a |
2084 // wipeout before, we might disable this extension here. | 2111 // wipeout before, we might disable this extension here. |
2085 MaybeWipeout(extension); | 2112 MaybeWipeout(extension); |
2086 | 2113 |
2087 if (extension_prefs_->IsExtensionDisabled(extension->id())) { | 2114 // Communicated to the Blacklist. |
| 2115 std::set<std::string> already_in_blacklist; |
| 2116 |
| 2117 if (extension_prefs_->IsExtensionBlacklisted(extension->id())) { |
| 2118 // Don't check the Blacklist yet because it's asynchronous (we do it at |
| 2119 // the end). This pre-emptive check is because we will always store the |
| 2120 // blacklisted state of *installed* extensions in prefs, and it's important |
| 2121 // not to re-enable blacklisted extensions. |
| 2122 blacklisted_extensions_.Insert(extension); |
| 2123 already_in_blacklist.insert(extension->id()); |
| 2124 } else if (extension_prefs_->IsExtensionDisabled(extension->id())) { |
2088 disabled_extensions_.Insert(extension); | 2125 disabled_extensions_.Insert(extension); |
2089 SyncExtensionChangeIfNeeded(*extension); | 2126 SyncExtensionChangeIfNeeded(*extension); |
2090 content::NotificationService::current()->Notify( | 2127 content::NotificationService::current()->Notify( |
2091 chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED, | 2128 chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED, |
2092 content::Source<Profile>(profile_), | 2129 content::Source<Profile>(profile_), |
2093 content::Details<const Extension>(extension)); | 2130 content::Details<const Extension>(extension)); |
2094 | 2131 |
2095 if (extension_prefs_->GetDisableReasons(extension->id()) & | 2132 if (extension_prefs_->GetDisableReasons(extension->id()) & |
2096 Extension::DISABLE_PERMISSIONS_INCREASE) { | 2133 Extension::DISABLE_PERMISSIONS_INCREASE) { |
2097 extensions::AddExtensionDisabledError(this, extension); | 2134 extensions::AddExtensionDisabledError(this, extension); |
2098 } | 2135 } |
2099 return; | 2136 } else { |
| 2137 // All apps that are displayed in the launcher are ordered by their ordinals |
| 2138 // so we must ensure they have valid ordinals. |
| 2139 if (extension->RequiresSortOrdinal()) { |
| 2140 extension_prefs_->extension_sorting()->EnsureValidOrdinals( |
| 2141 extension->id(), syncer::StringOrdinal()); |
| 2142 } |
| 2143 |
| 2144 extensions_.Insert(extension); |
| 2145 SyncExtensionChangeIfNeeded(*extension); |
| 2146 NotifyExtensionLoaded(extension); |
| 2147 DoPostLoadTasks(extension); |
| 2148 |
| 2149 #if defined(ENABLE_THEMES) |
| 2150 if (extension->is_theme()) { |
| 2151 // Notify the ThemeService about the newly-installed theme. |
| 2152 ThemeServiceFactory::SetThemeForProfile(profile_, extension); |
| 2153 } |
| 2154 #endif |
2100 } | 2155 } |
2101 | 2156 |
2102 // All apps that are displayed in the launcher are ordered by their ordinals | 2157 // Lastly, begin the process for checking the blacklist status of extensions. |
2103 // so we must ensure they have valid ordinals. | 2158 // This may need to go to other threads so is asynchronous. |
2104 if (extension->RequiresSortOrdinal()) { | 2159 std::set<std::string> id_set; |
2105 extension_prefs_->extension_sorting()->EnsureValidOrdinals( | 2160 id_set.insert(extension->id()); |
2106 extension->id(), syncer::StringOrdinal()); | 2161 blacklist_->GetBlacklistedIDs( |
2107 } | 2162 id_set, |
2108 | 2163 base::Bind(&ExtensionService::ManageBlacklist, |
2109 extensions_.Insert(extension); | 2164 AsWeakPtr(), |
2110 SyncExtensionChangeIfNeeded(*extension); | 2165 already_in_blacklist)); |
2111 NotifyExtensionLoaded(extension); | |
2112 DoPostLoadTasks(extension); | |
2113 | |
2114 #if defined(ENABLE_THEMES) | |
2115 if (extension->is_theme()) { | |
2116 // Notify the ThemeService about the newly-installed theme. | |
2117 ThemeServiceFactory::SetThemeForProfile(profile_, extension); | |
2118 } | |
2119 #endif | |
2120 } | 2166 } |
2121 | 2167 |
2122 void ExtensionService::AddComponentExtension(const Extension* extension) { | 2168 void ExtensionService::AddComponentExtension(const Extension* extension) { |
2123 const std::string old_version_string( | 2169 const std::string old_version_string( |
2124 extension_prefs_->GetVersionString(extension->id())); | 2170 extension_prefs_->GetVersionString(extension->id())); |
2125 const Version old_version(old_version_string); | 2171 const Version old_version(old_version_string); |
2126 | 2172 |
2127 if (!old_version.IsValid() || !old_version.Equals(*extension->version())) { | 2173 if (!old_version.IsValid() || !old_version.Equals(*extension->version())) { |
2128 VLOG(1) << "Component extension " << extension->name() << " (" | 2174 VLOG(1) << "Component extension " << extension->name() << " (" |
2129 << extension->id() << ") installing/upgrading from '" | 2175 << extension->id() << ") installing/upgrading from '" |
(...skipping 900 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3030 // event. | 3076 // event. |
3031 return system_->event_router()->ExtensionHasEventListener( | 3077 return system_->event_router()->ExtensionHasEventListener( |
3032 extension_id, kOnUpdateAvailableEvent); | 3078 extension_id, kOnUpdateAvailableEvent); |
3033 } else { | 3079 } else { |
3034 // Delay installation if the extension is not idle. | 3080 // Delay installation if the extension is not idle. |
3035 return !IsExtensionIdle(extension_id); | 3081 return !IsExtensionIdle(extension_id); |
3036 } | 3082 } |
3037 } | 3083 } |
3038 | 3084 |
3039 void ExtensionService::OnBlacklistUpdated() { | 3085 void ExtensionService::OnBlacklistUpdated() { |
3040 CheckManagementPolicy(); | 3086 blacklist_->GetBlacklistedIDs( |
| 3087 GenerateInstalledExtensionsSet()->GetIDs(), |
| 3088 base::Bind(&ExtensionService::ManageBlacklist, |
| 3089 AsWeakPtr(), |
| 3090 blacklisted_extensions_.GetIDs())); |
3041 } | 3091 } |
| 3092 |
| 3093 void ExtensionService::ManageBlacklist( |
| 3094 const std::set<std::string>& old_blacklisted_ids, |
| 3095 const std::set<std::string>& new_blacklisted_ids) { |
| 3096 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 3097 |
| 3098 std::set<std::string> no_longer_blacklisted; |
| 3099 std::set_difference(old_blacklisted_ids.begin(), old_blacklisted_ids.end(), |
| 3100 new_blacklisted_ids.begin(), new_blacklisted_ids.end(), |
| 3101 std::inserter(no_longer_blacklisted, |
| 3102 no_longer_blacklisted.begin())); |
| 3103 std::set<std::string> not_yet_blacklisted; |
| 3104 std::set_difference(new_blacklisted_ids.begin(), new_blacklisted_ids.end(), |
| 3105 old_blacklisted_ids.begin(), old_blacklisted_ids.end(), |
| 3106 std::inserter(not_yet_blacklisted, |
| 3107 not_yet_blacklisted.begin())); |
| 3108 |
| 3109 for (std::set<std::string>::iterator it = no_longer_blacklisted.begin(); |
| 3110 it != no_longer_blacklisted.end(); ++it) { |
| 3111 scoped_refptr<const Extension> extension = |
| 3112 blacklisted_extensions_.GetByID(*it); |
| 3113 if (!extension) |
| 3114 continue; |
| 3115 blacklisted_extensions_.Remove(*it); |
| 3116 AddExtension(extension); |
| 3117 } |
| 3118 |
| 3119 for (std::set<std::string>::iterator it = not_yet_blacklisted.begin(); |
| 3120 it != not_yet_blacklisted.end(); ++it) { |
| 3121 scoped_refptr<const Extension> extension = GetInstalledExtension(*it); |
| 3122 if (!extension) |
| 3123 continue; |
| 3124 blacklisted_extensions_.Insert(extension); |
| 3125 UnloadExtension(*it, extension_misc::UNLOAD_REASON_BLACKLIST); |
| 3126 } |
| 3127 |
| 3128 IdentifyAlertableExtensions(); |
| 3129 } |
OLD | NEW |