Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(277)

Side by Side Diff: chrome/browser/extensions/extension_service.cc

Issue 11415216: Make Blacklist::IsBlacklist asynchronous (it will need to be for safe (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase past conflict #2 Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698