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; |
| 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->GetExtensionById(extension_id, ExtensionRegistry::EVERYTHING); |
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); |
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 |