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