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

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

Issue 695133005: Temporarily disable extensions and sync while a profile is locked - Profiles Approach (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: extension service's block_all bit set on Profile reload Created 6 years, 1 month 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
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 <iterator>
9 #include <set> 9 #include <set>
10 10
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 pending_extension_manager_(profile), 263 pending_extension_manager_(profile),
264 install_directory_(install_directory), 264 install_directory_(install_directory),
265 extensions_enabled_(extensions_enabled), 265 extensions_enabled_(extensions_enabled),
266 show_extensions_prompts_(true), 266 show_extensions_prompts_(true),
267 install_updates_when_idle_(true), 267 install_updates_when_idle_(true),
268 ready_(ready), 268 ready_(ready),
269 update_once_all_providers_are_ready_(false), 269 update_once_all_providers_are_ready_(false),
270 browser_terminating_(false), 270 browser_terminating_(false),
271 installs_delayed_for_gc_(false), 271 installs_delayed_for_gc_(false),
272 is_first_run_(false), 272 is_first_run_(false),
273 block_extensions_(false),
273 shared_module_service_(new extensions::SharedModuleService(profile_)) { 274 shared_module_service_(new extensions::SharedModuleService(profile_)) {
274 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 275 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
275 276
276 // Figure out if extension installation should be enabled. 277 // Figure out if extension installation should be enabled.
277 if (extensions::ExtensionsBrowserClient::Get()->AreExtensionsDisabled( 278 if (extensions::ExtensionsBrowserClient::Get()->AreExtensionsDisabled(
278 *command_line, profile)) 279 *command_line, profile))
279 extensions_enabled_ = false; 280 extensions_enabled_ = false;
280 281
281 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, 282 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING,
282 content::NotificationService::AllBrowserContextsAndSources()); 283 content::NotificationService::AllBrowserContextsAndSources());
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 ->GetForBrowserContext(profile()) 368 ->GetForBrowserContext(profile())
368 ->RemoveObserver(this); 369 ->RemoveObserver(this);
369 system_->management_policy()->UnregisterProvider( 370 system_->management_policy()->UnregisterProvider(
370 shared_module_policy_provider_.get()); 371 shared_module_policy_provider_.get());
371 } 372 }
372 373
373 const Extension* ExtensionService::GetExtensionById( 374 const Extension* ExtensionService::GetExtensionById(
374 const std::string& id, bool include_disabled) const { 375 const std::string& id, bool include_disabled) const {
375 int include_mask = ExtensionRegistry::ENABLED; 376 int include_mask = ExtensionRegistry::ENABLED;
376 if (include_disabled) { 377 if (include_disabled) {
377 // Include blacklisted extensions here because there are hundreds of 378 // Include blacklisted and blocked extensions here because there are
378 // callers of this function, and many might assume that this includes those 379 // hundreds of callers of this function, and many might assume that this
379 // that have been disabled due to blacklisting. 380 // includes those that have been disabled due to blacklisting or blocking.
380 include_mask |= ExtensionRegistry::DISABLED | 381 include_mask |= ExtensionRegistry::DISABLED |
381 ExtensionRegistry::BLACKLISTED; 382 ExtensionRegistry::BLACKLISTED |
383 ExtensionRegistry::BLOCKED;
382 } 384 }
383 return registry_->GetExtensionById(id, include_mask); 385 return registry_->GetExtensionById(id, include_mask);
384 } 386 }
385 387
386 void ExtensionService::Init() { 388 void ExtensionService::Init() {
387 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 389 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
388 390
389 base::Time begin_time = base::Time::Now(); 391 base::Time begin_time = base::Time::Now();
390 392
391 DCHECK(!is_ready()); // Can't redo init. 393 DCHECK(!is_ready()); // Can't redo init.
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
572 const std::string& transient_extension_id, 574 const std::string& transient_extension_id,
573 bool be_noisy) { 575 bool be_noisy) {
574 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 576 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
575 577
576 // If the extension is already reloading, don't reload again. 578 // If the extension is already reloading, don't reload again.
577 if (extension_prefs_->GetDisableReasons(transient_extension_id) & 579 if (extension_prefs_->GetDisableReasons(transient_extension_id) &
578 Extension::DISABLE_RELOAD) { 580 Extension::DISABLE_RELOAD) {
579 return; 581 return;
580 } 582 }
581 583
582 // Ignore attempts to reload a blacklisted extension. Sometimes this can 584 // Ignore attempts to reload a blacklisted or blocked extension. Sometimes
583 // happen in a convoluted reload sequence triggered by the termination of a 585 // this can happen in a convoluted reload sequence triggered by the
584 // blacklisted extension and a naive attempt to reload it. For an example see 586 // termination of a blacklisted or blocked extension and a naive attempt to
585 // http://crbug.com/373842. 587 // reload it. For an example see http://crbug.com/373842.
586 if (registry_->blacklisted_extensions().Contains(transient_extension_id)) 588 if (registry_->blacklisted_extensions().Contains(transient_extension_id) ||
589 registry_->blocked_extensions().Contains(transient_extension_id)) {
587 return; 590 return;
591 }
588 592
589 base::FilePath path; 593 base::FilePath path;
590 594
591 std::string extension_id = transient_extension_id; 595 std::string extension_id = transient_extension_id;
592 const Extension* transient_current_extension = 596 const Extension* transient_current_extension =
593 GetExtensionById(extension_id, false); 597 GetExtensionById(extension_id, false);
594 598
595 // Disable the extension if it's loaded. It might not be loaded if it crashed. 599 // Disable the extension if it's loaded. It might not be loaded if it crashed.
596 if (transient_current_extension) { 600 if (transient_current_extension) {
597 // If the extension has an inspector open for its background page, detach 601 // If the extension has an inspector open for its background page, detach
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 } 786 }
783 787
784 bool ExtensionService::IsExtensionEnabled( 788 bool ExtensionService::IsExtensionEnabled(
785 const std::string& extension_id) const { 789 const std::string& extension_id) const {
786 if (registry_->enabled_extensions().Contains(extension_id) || 790 if (registry_->enabled_extensions().Contains(extension_id) ||
787 registry_->terminated_extensions().Contains(extension_id)) { 791 registry_->terminated_extensions().Contains(extension_id)) {
788 return true; 792 return true;
789 } 793 }
790 794
791 if (registry_->disabled_extensions().Contains(extension_id) || 795 if (registry_->disabled_extensions().Contains(extension_id) ||
792 registry_->blacklisted_extensions().Contains(extension_id)) { 796 registry_->blacklisted_extensions().Contains(extension_id) ||
797 registry_->blocked_extensions().Contains(extension_id)) {
793 return false; 798 return false;
794 } 799 }
795 800
796 // If the extension hasn't been loaded yet, check the prefs for it. Assume 801 // If the extension hasn't been loaded yet, check the prefs for it. Assume
797 // enabled unless otherwise noted. 802 // enabled unless otherwise noted.
798 return !extension_prefs_->IsExtensionDisabled(extension_id) && 803 return !extension_prefs_->IsExtensionDisabled(extension_id) &&
799 !extension_prefs_->IsExtensionBlacklisted(extension_id) && 804 !extension_prefs_->IsExtensionBlacklisted(extension_id) &&
805 !extension_prefs_->IsExtensionBlocked(extension_id) &&
800 !extension_prefs_->IsExternalExtensionUninstalled(extension_id); 806 !extension_prefs_->IsExternalExtensionUninstalled(extension_id);
801 } 807 }
802 808
803 void ExtensionService::EnableExtension(const std::string& extension_id) { 809 void ExtensionService::EnableExtension(const std::string& extension_id) {
804 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 810 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
805 811
806 if (IsExtensionEnabled(extension_id)) 812 if (IsExtensionEnabled(extension_id))
807 return; 813 return;
808 const Extension* extension = 814 const Extension* extension =
809 registry_->disabled_extensions().GetByID(extension_id); 815 registry_->disabled_extensions().GetByID(extension_id);
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
913 if ((*extension)->was_installed_by_default() && 919 if ((*extension)->was_installed_by_default() &&
914 extension_urls::IsWebstoreUpdateUrl( 920 extension_urls::IsWebstoreUpdateUrl(
915 extensions::ManifestURL::GetUpdateURL(extension->get()))) 921 extensions::ManifestURL::GetUpdateURL(extension->get())))
916 continue; 922 continue;
917 const std::string& id = (*extension)->id(); 923 const std::string& id = (*extension)->id();
918 if (except_ids.end() == std::find(except_ids.begin(), except_ids.end(), id)) 924 if (except_ids.end() == std::find(except_ids.begin(), except_ids.end(), id))
919 DisableExtension(id, extensions::Extension::DISABLE_USER_ACTION); 925 DisableExtension(id, extensions::Extension::DISABLE_USER_ACTION);
920 } 926 }
921 } 927 }
922 928
929 // Extensions that are not locked, components or forced by policy should be
930 // locked. Extensions are no longer considered enabled or disabled. Blacklisted
931 // extensions are now considered both blacklisted and locked.
932 void ExtensionService::BlockAllExtensions() {
not at google - send to devlin 2014/11/12 23:41:43 Oh, you might want to check that it's not already
Mike Lerman 2014/11/13 15:30:05 There's no reason this method couldn't be called m
933 block_extensions_ = true;
934 scoped_ptr<ExtensionSet> extensions =
935 registry_->GenerateInstalledExtensionsSet();
936
937 ExtensionIdSet to_lock;
not at google - send to devlin 2014/11/12 23:41:43 You can delete this now.
Mike Lerman 2014/11/13 15:30:05 Bye bye!
938 for (const scoped_refptr<const Extension> extension : *extensions.get()) {
939 const std::string& id = extension.get()->id();
not at google - send to devlin 2014/11/12 23:41:43 just extension->id();
Mike Lerman 2014/11/13 15:30:04 Done.
940
941 if (!CanBlockExtension(extension.get()))
942 continue;
943
944 // Blacklisted extensions remain in the blacklisted list.
945 registry_->RemoveEnabled(id);
946 registry_->RemoveDisabled(id);
947 registry_->RemoveTerminated(id);
948
not at google - send to devlin 2014/11/12 23:41:43 Come to think of it it's probably also wise/safer
Mike Lerman 2014/11/13 15:30:05 I'm concerned about removing things from the black
not at google - send to devlin 2014/11/13 18:09:47 I'm not suggesting removing it from the blacklist.
Mike Lerman 2014/11/13 21:42:32 Done.
949 registry_->AddBlocked(extension.get());
950 extension_prefs_->SetExtensionState(id, Extension::BLOCKED);
not at google - send to devlin 2014/11/12 23:41:43 Actually - why do you need to change prefs at all?
Mike Lerman 2014/11/13 15:30:04 The goal was the keep the ExtensionState sync-ed w
not at google - send to devlin 2014/11/13 18:09:47 I don't think so. For example we keep terminated e
Mike Lerman 2014/11/13 21:42:32 Done.
951 UnloadExtension(
952 id, extensions::UnloadedExtensionInfo::REASON_LOCK_ALL);
953 }
954 }
955
956 // All locked extensions should revert to being either enabled or disabled
957 // as appropriate.
958 void ExtensionService::UnblockAllBlockedExtensions() {
959 ExtensionIdSet to_unblock = registry_->blocked_extensions().GetIDs();
not at google - send to devlin 2014/11/12 23:41:43 (see previous point about just copying the whole e
Mike Lerman 2014/11/13 15:30:04 Which one? Is making a copy of the set better tha
not at google - send to devlin 2014/11/13 18:09:47 Maybe they should copy the set as well. Needing 7
Mike Lerman 2014/11/13 21:42:32 Copied as well. Done.
960
961 block_extensions_ = false;
962 for (ExtensionIdSet::iterator it = to_unblock.begin();
not at google - send to devlin 2014/11/12 23:41:43 (and use : syntax here too)
Mike Lerman 2014/11/13 15:30:04 Done.
963 it != to_unblock.end(); ++it) {
964 scoped_refptr<const Extension> extension = GetInstalledExtension(*it);
965 if (!extension.get()) {
966 NOTREACHED() << "Extension " << *it << " needs to be "
967 << "unblocked, but it's not installed.";
968 continue;
969 }
970
971 registry_->RemoveBlocked(*it);
972 if (extensions_being_terminated_.find(extension->id()) !=
not at google - send to devlin 2014/11/12 23:41:43 Mm, maybe this isn't actually useful. I doubt this
Mike Lerman 2014/11/13 15:30:05 Done.
973 extensions_being_terminated_.end()) {
974 registry_->AddTerminated(extension.get());
975 } else {
976 if (extension_prefs_->GetDisableReasons(*it)) {
not at google - send to devlin 2014/11/12 23:41:43 GetDisableReasons returns a bitmask, so it's a lit
Mike Lerman 2014/11/13 15:30:04 I agree about using IsExtensionDisabled, if we hav
977 extension_prefs_->SetExtensionState(*it, Extension::DISABLED);
978 } else {
979 extension_prefs_->SetExtensionState(*it, Extension::ENABLED);
980 }
981 AddExtension(extension.get());
982 }
983 }
984 }
985
923 void ExtensionService::GrantPermissionsAndEnableExtension( 986 void ExtensionService::GrantPermissionsAndEnableExtension(
924 const Extension* extension) { 987 const Extension* extension) {
925 GrantPermissions(extension); 988 GrantPermissions(extension);
926 RecordPermissionMessagesHistogram(extension, 989 RecordPermissionMessagesHistogram(extension,
927 "Extensions.Permissions_ReEnable2"); 990 "Extensions.Permissions_ReEnable2");
928 extension_prefs_->SetDidExtensionEscalatePermissions(extension, false); 991 extension_prefs_->SetDidExtensionEscalatePermissions(extension, false);
929 EnableExtension(extension->id()); 992 EnableExtension(extension->id());
930 } 993 }
931 994
932 void ExtensionService::GrantPermissions(const Extension* extension) { 995 void ExtensionService::GrantPermissions(const Extension* extension) {
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
1366 // new one. ReloadExtension disables the extension, which is sufficient. 1429 // new one. ReloadExtension disables the extension, which is sufficient.
1367 UnloadExtension(extension->id(), UnloadedExtensionInfo::REASON_UPDATE); 1430 UnloadExtension(extension->id(), UnloadedExtensionInfo::REASON_UPDATE);
1368 } 1431 }
1369 1432
1370 if (extension_prefs_->IsExtensionBlacklisted(extension->id())) { 1433 if (extension_prefs_->IsExtensionBlacklisted(extension->id())) {
1371 // Only prefs is checked for the blacklist. We rely on callers to check the 1434 // Only prefs is checked for the blacklist. We rely on callers to check the
1372 // blacklist before calling into here, e.g. CrxInstaller checks before 1435 // blacklist before calling into here, e.g. CrxInstaller checks before
1373 // installation then threads through the install and pending install flow 1436 // installation then threads through the install and pending install flow
1374 // of this class, and we check when loading installed extensions. 1437 // of this class, and we check when loading installed extensions.
1375 registry_->AddBlacklisted(extension); 1438 registry_->AddBlacklisted(extension);
1439 } else if (extension_prefs_->IsExtensionBlocked(extension->id()) ||
1440 (block_extensions_ && CanBlockExtension(extension))) {
1441 registry_->AddBlocked(extension);
1376 } else if (!reloading && 1442 } else if (!reloading &&
1377 extension_prefs_->IsExtensionDisabled(extension->id())) { 1443 extension_prefs_->IsExtensionDisabled(extension->id())) {
1378 registry_->AddDisabled(extension); 1444 registry_->AddDisabled(extension);
1379 if (extension_sync_service_) 1445 if (extension_sync_service_)
1380 extension_sync_service_->SyncExtensionChangeIfNeeded(*extension); 1446 extension_sync_service_->SyncExtensionChangeIfNeeded(*extension);
1381 content::NotificationService::current()->Notify( 1447 content::NotificationService::current()->Notify(
1382 extensions::NOTIFICATION_EXTENSION_UPDATE_DISABLED, 1448 extensions::NOTIFICATION_EXTENSION_UPDATE_DISABLED,
1383 content::Source<Profile>(profile_), 1449 content::Source<Profile>(profile_),
1384 content::Details<const Extension>(extension)); 1450 content::Details<const Extension>(extension));
1385 1451
(...skipping 782 matching lines...) Expand 10 before | Expand all | Expand 10 after
2168 if (extension->GetType() != Manifest::TYPE_HOSTED_APP && 2234 if (extension->GetType() != Manifest::TYPE_HOSTED_APP &&
2169 Manifest::IsExternalLocation(extension->location()) && 2235 Manifest::IsExternalLocation(extension->location()) &&
2170 !extension_prefs_->IsExternalExtensionAcknowledged(extension->id())) { 2236 !extension_prefs_->IsExternalExtensionAcknowledged(extension->id())) {
2171 return false; 2237 return false;
2172 } 2238 }
2173 } 2239 }
2174 2240
2175 return true; 2241 return true;
2176 } 2242 }
2177 2243
2244 // Helper method to determine if an extension can be blocked.
2245 bool ExtensionService::CanBlockExtension(const Extension* extension) {
2246 return (extension->location() != Manifest::COMPONENT &&
not at google - send to devlin 2014/11/12 23:41:43 Outer parens are unnecessary.
Mike Lerman 2014/11/13 15:30:04 Done.
2247 extension->location() != Manifest::EXTERNAL_COMPONENT &&
2248 !system_->management_policy()->MustRemainEnabled(extension, NULL));
2249 }
2250
2178 bool ExtensionService::ShouldDelayExtensionUpdate( 2251 bool ExtensionService::ShouldDelayExtensionUpdate(
2179 const std::string& extension_id, 2252 const std::string& extension_id,
2180 bool install_immediately) const { 2253 bool install_immediately) const {
2181 const char kOnUpdateAvailableEvent[] = "runtime.onUpdateAvailable"; 2254 const char kOnUpdateAvailableEvent[] = "runtime.onUpdateAvailable";
2182 2255
2183 // If delayed updates are globally disabled, or just for this extension, 2256 // If delayed updates are globally disabled, or just for this extension,
2184 // don't delay. 2257 // don't delay.
2185 if (!install_updates_when_idle_ || install_immediately) 2258 if (!install_updates_when_idle_ || install_immediately)
2186 return false; 2259 return false;
2187 2260
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
2256 case extensions::BLACKLISTED_POTENTIALLY_UNWANTED: 2329 case extensions::BLACKLISTED_POTENTIALLY_UNWANTED:
2257 greylist.insert(it->first); 2330 greylist.insert(it->first);
2258 break; 2331 break;
2259 2332
2260 case extensions::BLACKLISTED_UNKNOWN: 2333 case extensions::BLACKLISTED_UNKNOWN:
2261 unchanged.insert(it->first); 2334 unchanged.insert(it->first);
2262 break; 2335 break;
2263 } 2336 }
2264 } 2337 }
2265 2338
2266 UpdateBlockedExtensions(blocked, unchanged); 2339 UpdateBlockedExtensions(blocked, unchanged);
not at google - send to devlin 2014/11/12 23:41:43 Looks like the "blocked" term is already used, but
Mike Lerman 2014/11/13 15:30:04 Done.
2267 UpdateGreylistedExtensions(greylist, unchanged, state_map); 2340 UpdateGreylistedExtensions(greylist, unchanged, state_map);
2268 2341
2269 error_controller_->ShowErrorIfNeeded(); 2342 error_controller_->ShowErrorIfNeeded();
2270 } 2343 }
2271 2344
2272 namespace { 2345 namespace {
2273 void Partition(const ExtensionIdSet& before, 2346 void Partition(const ExtensionIdSet& before,
2274 const ExtensionIdSet& after, 2347 const ExtensionIdSet& after,
2275 const ExtensionIdSet& unchanged, 2348 const ExtensionIdSet& unchanged,
2276 ExtensionIdSet* no_longer, 2349 ExtensionIdSet* no_longer,
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
2388 } 2461 }
2389 2462
2390 void ExtensionService::OnProfileDestructionStarted() { 2463 void ExtensionService::OnProfileDestructionStarted() {
2391 ExtensionIdSet ids_to_unload = registry_->enabled_extensions().GetIDs(); 2464 ExtensionIdSet ids_to_unload = registry_->enabled_extensions().GetIDs();
2392 for (ExtensionIdSet::iterator it = ids_to_unload.begin(); 2465 for (ExtensionIdSet::iterator it = ids_to_unload.begin();
2393 it != ids_to_unload.end(); 2466 it != ids_to_unload.end();
2394 ++it) { 2467 ++it) {
2395 UnloadExtension(*it, UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN); 2468 UnloadExtension(*it, UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN);
2396 } 2469 }
2397 } 2470 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698