Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 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_util.h" | 5 #include "chrome/browser/extensions/extension_util.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/values.h" | 9 #include "base/values.h" |
| 10 #include "chrome/browser/extensions/extension_service.h" | 10 #include "chrome/browser/extensions/extension_service.h" |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 27 #include "extensions/common/manifest.h" | 27 #include "extensions/common/manifest.h" |
| 28 #include "extensions/common/manifest_handlers/incognito_info.h" | 28 #include "extensions/common/manifest_handlers/incognito_info.h" |
| 29 #include "extensions/common/permissions/permissions_data.h" | 29 #include "extensions/common/permissions/permissions_data.h" |
| 30 #include "grit/theme_resources.h" | 30 #include "grit/theme_resources.h" |
| 31 #include "ui/base/resource/resource_bundle.h" | 31 #include "ui/base/resource/resource_bundle.h" |
| 32 | 32 |
| 33 namespace extensions { | 33 namespace extensions { |
| 34 namespace util { | 34 namespace util { |
| 35 | 35 |
| 36 namespace { | 36 namespace { |
| 37 | |
| 37 // The entry into the ExtensionPrefs for allowing an extension to script on | 38 // The entry into the ExtensionPrefs for allowing an extension to script on |
| 38 // all urls without explicit permission. | 39 // all urls without explicit permission. |
| 39 const char kExtensionAllowedOnAllUrlsPrefName[] = | 40 const char kExtensionAllowedOnAllUrlsPrefName[] = |
| 40 "extension_can_script_all_urls"; | 41 "extension_can_script_all_urls"; |
| 41 | 42 |
| 42 // Returns true if |extension_id| for an external component extension should | 43 // Returns true if |extension_id| for an external component extension should |
| 43 // always be enabled in incognito windows. | 44 // always be enabled in incognito windows. |
| 44 bool IsWhitelistedForIncognito(const std::string& extension_id) { | 45 bool IsWhitelistedForIncognito(const std::string& extension_id) { |
| 45 static const char* kExtensionWhitelist[] = { | 46 static const char* kExtensionWhitelist[] = { |
| 46 "D5736E4B5CF695CB93A2FB57E4FDC6E5AFAB6FE2", // http://crbug.com/312900 | 47 "D5736E4B5CF695CB93A2FB57E4FDC6E5AFAB6FE2", // http://crbug.com/312900 |
| 47 "D57DE394F36DC1C3220E7604C575D29C51A6C495", // http://crbug.com/319444 | 48 "D57DE394F36DC1C3220E7604C575D29C51A6C495", // http://crbug.com/319444 |
| 48 "3F65507A3B39259B38C8173C6FFA3D12DF64CCE9" // http://crbug.com/371562 | 49 "3F65507A3B39259B38C8173C6FFA3D12DF64CCE9" // http://crbug.com/371562 |
| 49 }; | 50 }; |
| 50 | 51 |
| 51 return extensions::SimpleFeature::IsIdInList( | 52 return extensions::SimpleFeature::IsIdInList( |
| 52 extension_id, | 53 extension_id, |
| 53 std::set<std::string>( | 54 std::set<std::string>( |
| 54 kExtensionWhitelist, | 55 kExtensionWhitelist, |
| 55 kExtensionWhitelist + arraysize(kExtensionWhitelist))); | 56 kExtensionWhitelist + arraysize(kExtensionWhitelist))); |
| 56 } | 57 } |
| 58 | |
| 59 // Returns |extension_id|. See note below. | |
| 60 std::string ReloadExtensionIfEnabled(const std::string& extension_id, | |
| 61 content::BrowserContext* context) { | |
| 62 ExtensionRegistry* registry = ExtensionRegistry::Get(context); | |
| 63 bool extension_is_enabled = | |
| 64 registry->enabled_extensions().Contains(extension_id); | |
| 65 | |
| 66 if (extension_is_enabled) | |
| 67 return extension_id; | |
|
Devlin
2014/09/04 20:50:00
This line means that this is "ReloadExtensionIfNot
Lei Zhang
2014/09/05 06:07:45
I meant if (!extension_is_enabled) ...
| |
| 68 | |
| 69 // When we reload the extension the ID may be invalidated if we've passed it | |
| 70 // by const ref everywhere. Make a copy to be safe. http://crbug.com/103762 | |
| 71 std::string id = extension_id; | |
| 72 ExtensionService* service = | |
| 73 ExtensionSystem::Get(context)->extension_service(); | |
| 74 CHECK(service); | |
| 75 service->ReloadExtension(id); | |
| 76 return id; | |
| 77 } | |
| 78 | |
| 57 } // namespace | 79 } // namespace |
| 58 | 80 |
| 59 bool IsIncognitoEnabled(const std::string& extension_id, | 81 bool IsIncognitoEnabled(const std::string& extension_id, |
| 60 content::BrowserContext* context) { | 82 content::BrowserContext* context) { |
| 61 const Extension* extension = ExtensionRegistry::Get(context)-> | 83 const Extension* extension = ExtensionRegistry::Get(context)-> |
| 62 GetExtensionById(extension_id, ExtensionRegistry::ENABLED); | 84 GetExtensionById(extension_id, ExtensionRegistry::ENABLED); |
| 63 if (extension) { | 85 if (extension) { |
| 64 if (!extension->can_be_incognito_enabled()) | 86 if (!extension->can_be_incognito_enabled()) |
| 65 return false; | 87 return false; |
| 66 // If this is an existing component extension we always allow it to | 88 // If this is an existing component extension we always allow it to |
| 67 // work in incognito mode. | 89 // work in incognito mode. |
| 68 if (extension->location() == Manifest::COMPONENT) | 90 if (extension->location() == Manifest::COMPONENT) |
| 69 return true; | 91 return true; |
| 70 if (extension->location() == Manifest::EXTERNAL_COMPONENT && | 92 if (extension->location() == Manifest::EXTERNAL_COMPONENT && |
| 71 IsWhitelistedForIncognito(extension_id)) { | 93 IsWhitelistedForIncognito(extension_id)) { |
| 72 return true; | 94 return true; |
| 73 } | 95 } |
| 74 } | 96 } |
| 75 | 97 |
| 76 return ExtensionPrefs::Get(context)->IsIncognitoEnabled(extension_id); | 98 return ExtensionPrefs::Get(context)->IsIncognitoEnabled(extension_id); |
| 77 } | 99 } |
| 78 | 100 |
| 79 void SetIsIncognitoEnabled(const std::string& extension_id, | 101 void SetIsIncognitoEnabled(const std::string& extension_id, |
| 80 content::BrowserContext* context, | 102 content::BrowserContext* context, |
| 81 bool enabled) { | 103 bool enabled) { |
| 82 ExtensionService* service = | 104 ExtensionRegistry* registry = ExtensionRegistry::Get(context); |
| 83 ExtensionSystem::Get(context)->extension_service(); | 105 const Extension* extension = |
| 84 CHECK(service); | 106 registry->enabled_extensions().GetByID(extension_id); |
|
Devlin
2014/09/04 20:50:00
I think this should probably be registry->GetExten
Lei Zhang
2014/09/05 06:07:45
Bleh, I looked up the GetExtensionById() conversio
| |
| 85 const Extension* extension = service->GetInstalledExtension(extension_id); | |
| 86 | 107 |
| 87 if (extension) { | 108 if (extension) { |
| 88 if (!extension->can_be_incognito_enabled()) | 109 if (!extension->can_be_incognito_enabled()) |
| 89 return; | 110 return; |
| 90 | 111 |
| 91 if (extension->location() == Manifest::COMPONENT) { | 112 if (extension->location() == Manifest::COMPONENT) { |
| 92 // This shouldn't be called for component extensions unless it is called | 113 // This shouldn't be called for component extensions unless it is called |
| 93 // by sync, for syncable component extensions. | 114 // by sync, for syncable component extensions. |
| 94 // See http://crbug.com/112290 and associated CLs for the sordid history. | 115 // See http://crbug.com/112290 and associated CLs for the sordid history. |
| 95 DCHECK(sync_helper::IsSyncable(extension)); | 116 DCHECK(sync_helper::IsSyncable(extension)); |
| 96 | 117 |
| 97 // If we are here, make sure the we aren't trying to change the value. | 118 // If we are here, make sure the we aren't trying to change the value. |
| 98 DCHECK_EQ(enabled, IsIncognitoEnabled(extension_id, service->profile())); | 119 DCHECK_EQ(enabled, IsIncognitoEnabled(extension_id, context)); |
| 99 return; | 120 return; |
| 100 } | 121 } |
| 101 } | 122 } |
| 102 | 123 |
| 103 ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(service->profile()); | 124 ExtensionPrefs* extension_prefs = ExtensionPrefs::Get(context); |
| 104 // Broadcast unloaded and loaded events to update browser state. Only bother | 125 // Broadcast unloaded and loaded events to update browser state. Only bother |
| 105 // if the value changed and the extension is actually enabled, since there is | 126 // if the value changed and the extension is actually enabled, since there is |
| 106 // no UI otherwise. | 127 // no UI otherwise. |
| 107 bool old_enabled = extension_prefs->IsIncognitoEnabled(extension_id); | 128 bool old_enabled = extension_prefs->IsIncognitoEnabled(extension_id); |
| 108 if (enabled == old_enabled) | 129 if (enabled == old_enabled) |
| 109 return; | 130 return; |
| 110 | 131 |
| 111 extension_prefs->SetIsIncognitoEnabled(extension_id, enabled); | 132 extension_prefs->SetIsIncognitoEnabled(extension_id, enabled); |
| 112 | 133 |
| 113 bool extension_is_enabled = service->extensions()->Contains(extension_id); | 134 std::string id = ReloadExtensionIfEnabled(extension_id, context); |
| 114 | |
| 115 // When we reload the extension the ID may be invalidated if we've passed it | |
| 116 // by const ref everywhere. Make a copy to be safe. | |
| 117 std::string id = extension_id; | |
| 118 if (extension_is_enabled) | |
| 119 service->ReloadExtension(id); | |
| 120 | 135 |
| 121 // Reloading the extension invalidates the |extension| pointer. | 136 // Reloading the extension invalidates the |extension| pointer. |
| 122 extension = service->GetInstalledExtension(id); | 137 extension = registry->GetExtensionById(id, ExtensionRegistry::EVERYTHING); |
|
Devlin
2014/09/04 20:50:00
Maybe have ReloadExtensionIfEnabled return a valid
Lei Zhang
2014/09/05 06:07:45
In the SetAllowFileAccess() use case, the returned
Devlin
2014/09/05 15:38:09
Fair. I think what would be best would actually b
| |
| 123 if (extension) { | 138 if (extension) { |
| 124 ExtensionSyncService::Get(service->profile())-> | 139 Profile* profile = Profile::FromBrowserContext(context); |
| 125 SyncExtensionChangeIfNeeded(*extension); | 140 ExtensionSyncService::Get(profile)->SyncExtensionChangeIfNeeded(*extension); |
| 126 } | 141 } |
| 127 } | 142 } |
| 128 | 143 |
| 129 bool CanCrossIncognito(const Extension* extension, | 144 bool CanCrossIncognito(const Extension* extension, |
| 130 content::BrowserContext* context) { | 145 content::BrowserContext* context) { |
| 131 // We allow the extension to see events and data from another profile iff it | 146 // We allow the extension to see events and data from another profile iff it |
| 132 // uses "spanning" behavior and it has incognito access. "split" mode | 147 // uses "spanning" behavior and it has incognito access. "split" mode |
| 133 // extensions only see events for a matching profile. | 148 // extensions only see events for a matching profile. |
| 134 CHECK(extension); | 149 CHECK(extension); |
| 135 return IsIncognitoEnabled(extension->id(), context) && | 150 return IsIncognitoEnabled(extension->id(), context) && |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 150 bool AllowFileAccess(const std::string& extension_id, | 165 bool AllowFileAccess(const std::string& extension_id, |
| 151 content::BrowserContext* context) { | 166 content::BrowserContext* context) { |
| 152 return CommandLine::ForCurrentProcess()->HasSwitch( | 167 return CommandLine::ForCurrentProcess()->HasSwitch( |
| 153 switches::kDisableExtensionsFileAccessCheck) || | 168 switches::kDisableExtensionsFileAccessCheck) || |
| 154 ExtensionPrefs::Get(context)->AllowFileAccess(extension_id); | 169 ExtensionPrefs::Get(context)->AllowFileAccess(extension_id); |
| 155 } | 170 } |
| 156 | 171 |
| 157 void SetAllowFileAccess(const std::string& extension_id, | 172 void SetAllowFileAccess(const std::string& extension_id, |
| 158 content::BrowserContext* context, | 173 content::BrowserContext* context, |
| 159 bool allow) { | 174 bool allow) { |
| 160 ExtensionService* service = | |
| 161 ExtensionSystem::Get(context)->extension_service(); | |
| 162 CHECK(service); | |
| 163 | |
| 164 // Reload to update browser state. Only bother if the value changed and the | 175 // Reload to update browser state. Only bother if the value changed and the |
| 165 // extension is actually enabled, since there is no UI otherwise. | 176 // extension is actually enabled, since there is no UI otherwise. |
| 166 if (allow == AllowFileAccess(extension_id, context)) | 177 if (allow == AllowFileAccess(extension_id, context)) |
| 167 return; | 178 return; |
| 168 | 179 |
| 169 ExtensionPrefs::Get(context)->SetAllowFileAccess(extension_id, allow); | 180 ExtensionPrefs::Get(context)->SetAllowFileAccess(extension_id, allow); |
| 170 | 181 |
| 171 bool extension_is_enabled = service->extensions()->Contains(extension_id); | 182 ReloadExtensionIfEnabled(extension_id, context); |
| 172 if (extension_is_enabled) | |
| 173 service->ReloadExtension(extension_id); | |
| 174 } | 183 } |
| 175 | 184 |
| 176 bool AllowedScriptingOnAllUrls(const std::string& extension_id, | 185 bool AllowedScriptingOnAllUrls(const std::string& extension_id, |
| 177 content::BrowserContext* context) { | 186 content::BrowserContext* context) { |
| 178 bool allowed = false; | 187 bool allowed = false; |
| 179 return ExtensionPrefs::Get(context)->ReadPrefAsBoolean( | 188 return ExtensionPrefs::Get(context)->ReadPrefAsBoolean( |
| 180 extension_id, | 189 extension_id, |
| 181 kExtensionAllowedOnAllUrlsPrefName, | 190 kExtensionAllowedOnAllUrlsPrefName, |
| 182 &allowed) && | 191 &allowed) && |
| 183 allowed; | 192 allowed; |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 323 IDR_EXTENSION_DEFAULT_ICON); | 332 IDR_EXTENSION_DEFAULT_ICON); |
| 324 } | 333 } |
| 325 | 334 |
| 326 bool IsStreamlinedHostedAppsEnabled() { | 335 bool IsStreamlinedHostedAppsEnabled() { |
| 327 return CommandLine::ForCurrentProcess()->HasSwitch( | 336 return CommandLine::ForCurrentProcess()->HasSwitch( |
| 328 switches::kEnableStreamlinedHostedApps); | 337 switches::kEnableStreamlinedHostedApps); |
| 329 } | 338 } |
| 330 | 339 |
| 331 } // namespace util | 340 } // namespace util |
| 332 } // namespace extensions | 341 } // namespace extensions |
| OLD | NEW |