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

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: 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 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698