Chromium Code Reviews| Index: chrome/browser/extensions/extension_service.cc |
| diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc |
| index d8e601beb50ac115f6528daf73bf231b02b4ae96..7cf147dec19c9f19e8cb0b786c2b9aba24dcda3e 100644 |
| --- a/chrome/browser/extensions/extension_service.cc |
| +++ b/chrome/browser/extensions/extension_service.cc |
| @@ -270,6 +270,7 @@ ExtensionService::ExtensionService(Profile* profile, |
| browser_terminating_(false), |
| installs_delayed_for_gc_(false), |
| is_first_run_(false), |
| + block_extensions_(false), |
| shared_module_service_(new extensions::SharedModuleService(profile_)) { |
| CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| @@ -374,11 +375,12 @@ const Extension* ExtensionService::GetExtensionById( |
| const std::string& id, bool include_disabled) const { |
| int include_mask = ExtensionRegistry::ENABLED; |
| if (include_disabled) { |
| - // Include blacklisted extensions here because there are hundreds of |
| - // callers of this function, and many might assume that this includes those |
| - // that have been disabled due to blacklisting. |
| + // Include blacklisted and blocked extensions here because there are |
| + // hundreds of callers of this function, and many might assume that this |
| + // includes those that have been disabled due to blacklisting or blocking. |
| include_mask |= ExtensionRegistry::DISABLED | |
| - ExtensionRegistry::BLACKLISTED; |
| + ExtensionRegistry::BLACKLISTED | |
| + ExtensionRegistry::BLOCKED; |
| } |
| return registry_->GetExtensionById(id, include_mask); |
| } |
| @@ -579,12 +581,14 @@ void ExtensionService::ReloadExtensionImpl( |
| return; |
| } |
| - // Ignore attempts to reload a blacklisted extension. Sometimes this can |
| - // happen in a convoluted reload sequence triggered by the termination of a |
| - // blacklisted extension and a naive attempt to reload it. For an example see |
| - // http://crbug.com/373842. |
| - if (registry_->blacklisted_extensions().Contains(transient_extension_id)) |
| + // Ignore attempts to reload a blacklisted or blocked extension. Sometimes |
| + // this can happen in a convoluted reload sequence triggered by the |
| + // termination of a blacklisted or blocked extension and a naive attempt to |
| + // reload it. For an example see http://crbug.com/373842. |
| + if (registry_->blacklisted_extensions().Contains(transient_extension_id) || |
| + registry_->blocked_extensions().Contains(transient_extension_id)) { |
| return; |
| + } |
| base::FilePath path; |
| @@ -789,7 +793,8 @@ bool ExtensionService::IsExtensionEnabled( |
| } |
| if (registry_->disabled_extensions().Contains(extension_id) || |
| - registry_->blacklisted_extensions().Contains(extension_id)) { |
| + registry_->blacklisted_extensions().Contains(extension_id) || |
| + registry_->blocked_extensions().Contains(extension_id)) { |
| return false; |
| } |
| @@ -797,6 +802,7 @@ bool ExtensionService::IsExtensionEnabled( |
| // enabled unless otherwise noted. |
| return !extension_prefs_->IsExtensionDisabled(extension_id) && |
| !extension_prefs_->IsExtensionBlacklisted(extension_id) && |
| + !extension_prefs_->IsExtensionBlocked(extension_id) && |
| !extension_prefs_->IsExternalExtensionUninstalled(extension_id); |
| } |
| @@ -920,6 +926,63 @@ void ExtensionService::DisableUserExtensions( |
| } |
| } |
| +// Extensions that are not locked, components or forced by policy should be |
| +// locked. Extensions are no longer considered enabled or disabled. Blacklisted |
| +// extensions are now considered both blacklisted and locked. |
| +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
|
| + block_extensions_ = true; |
| + scoped_ptr<ExtensionSet> extensions = |
| + registry_->GenerateInstalledExtensionsSet(); |
| + |
| + 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!
|
| + for (const scoped_refptr<const Extension> extension : *extensions.get()) { |
| + 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.
|
| + |
| + if (!CanBlockExtension(extension.get())) |
| + continue; |
| + |
| + // Blacklisted extensions remain in the blacklisted list. |
| + registry_->RemoveEnabled(id); |
| + registry_->RemoveDisabled(id); |
| + registry_->RemoveTerminated(id); |
| + |
|
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.
|
| + registry_->AddBlocked(extension.get()); |
| + 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.
|
| + UnloadExtension( |
| + id, extensions::UnloadedExtensionInfo::REASON_LOCK_ALL); |
| + } |
| +} |
| + |
| +// All locked extensions should revert to being either enabled or disabled |
| +// as appropriate. |
| +void ExtensionService::UnblockAllBlockedExtensions() { |
| + 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.
|
| + |
| + block_extensions_ = false; |
| + 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.
|
| + it != to_unblock.end(); ++it) { |
| + scoped_refptr<const Extension> extension = GetInstalledExtension(*it); |
| + if (!extension.get()) { |
| + NOTREACHED() << "Extension " << *it << " needs to be " |
| + << "unblocked, but it's not installed."; |
| + continue; |
| + } |
| + |
| + registry_->RemoveBlocked(*it); |
| + 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.
|
| + extensions_being_terminated_.end()) { |
| + registry_->AddTerminated(extension.get()); |
| + } else { |
| + 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
|
| + extension_prefs_->SetExtensionState(*it, Extension::DISABLED); |
| + } else { |
| + extension_prefs_->SetExtensionState(*it, Extension::ENABLED); |
| + } |
| + AddExtension(extension.get()); |
| + } |
| + } |
| +} |
| + |
| void ExtensionService::GrantPermissionsAndEnableExtension( |
| const Extension* extension) { |
| GrantPermissions(extension); |
| @@ -1373,6 +1436,9 @@ void ExtensionService::AddExtension(const Extension* extension) { |
| // installation then threads through the install and pending install flow |
| // of this class, and we check when loading installed extensions. |
| registry_->AddBlacklisted(extension); |
| + } else if (extension_prefs_->IsExtensionBlocked(extension->id()) || |
| + (block_extensions_ && CanBlockExtension(extension))) { |
| + registry_->AddBlocked(extension); |
| } else if (!reloading && |
| extension_prefs_->IsExtensionDisabled(extension->id())) { |
| registry_->AddDisabled(extension); |
| @@ -2175,6 +2241,13 @@ bool ExtensionService::ShouldEnableOnInstall(const Extension* extension) { |
| return true; |
| } |
| +// Helper method to determine if an extension can be blocked. |
| +bool ExtensionService::CanBlockExtension(const Extension* extension) { |
| + 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.
|
| + extension->location() != Manifest::EXTERNAL_COMPONENT && |
| + !system_->management_policy()->MustRemainEnabled(extension, NULL)); |
| +} |
| + |
| bool ExtensionService::ShouldDelayExtensionUpdate( |
| const std::string& extension_id, |
| bool install_immediately) const { |