OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/active_script_controller.h" | 5 #include "chrome/browser/extensions/active_script_controller.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 8 #include "base/bind_helpers.h" |
9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 extension->permissions_data() | 53 extension->permissions_data() |
54 ->active_permissions() | 54 ->active_permissions() |
55 ->ShouldWarnAllHosts(); | 55 ->ShouldWarnAllHosts(); |
56 } | 56 } |
57 | 57 |
58 } // namespace | 58 } // namespace |
59 | 59 |
60 ActiveScriptController::ActiveScriptController( | 60 ActiveScriptController::ActiveScriptController( |
61 content::WebContents* web_contents) | 61 content::WebContents* web_contents) |
62 : content::WebContentsObserver(web_contents), | 62 : content::WebContentsObserver(web_contents), |
| 63 browser_context_(web_contents->GetBrowserContext()), |
63 enabled_(FeatureSwitch::scripts_require_action()->IsEnabled()), | 64 enabled_(FeatureSwitch::scripts_require_action()->IsEnabled()), |
64 extension_registry_observer_(this) { | 65 extension_registry_observer_(this) { |
65 CHECK(web_contents); | 66 CHECK(web_contents); |
66 extension_registry_observer_.Add( | 67 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context_)); |
67 ExtensionRegistry::Get(web_contents->GetBrowserContext())); | |
68 } | 68 } |
69 | 69 |
70 ActiveScriptController::~ActiveScriptController() { | 70 ActiveScriptController::~ActiveScriptController() { |
71 LogUMA(); | 71 LogUMA(); |
72 } | 72 } |
73 | 73 |
74 // static | 74 // static |
75 ActiveScriptController* ActiveScriptController::GetForWebContents( | 75 ActiveScriptController* ActiveScriptController::GetForWebContents( |
76 content::WebContents* web_contents) { | 76 content::WebContents* web_contents) { |
77 if (!web_contents) | 77 if (!web_contents) |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 scoped_refptr<PermissionSet> new_permissions = | 123 scoped_refptr<PermissionSet> new_permissions = |
124 new PermissionSet(APIPermissionSet(), | 124 new PermissionSet(APIPermissionSet(), |
125 ManifestPermissionSet(), | 125 ManifestPermissionSet(), |
126 new_explicit_hosts, | 126 new_explicit_hosts, |
127 new_scriptable_hosts); | 127 new_scriptable_hosts); |
128 | 128 |
129 // Update permissions for the session. This adds |new_permissions| to active | 129 // Update permissions for the session. This adds |new_permissions| to active |
130 // permissions and granted permissions. | 130 // permissions and granted permissions. |
131 // TODO(devlin): Make sure that the permission is removed from | 131 // TODO(devlin): Make sure that the permission is removed from |
132 // withheld_permissions if appropriate. | 132 // withheld_permissions if appropriate. |
133 PermissionsUpdater(web_contents()->GetBrowserContext()) | 133 PermissionsUpdater(browser_context_).AddPermissions(extension, |
134 .AddPermissions(extension, new_permissions.get()); | 134 new_permissions.get()); |
135 | 135 |
136 // Allow current tab to run injection. | 136 // Allow current tab to run injection. |
137 OnClicked(extension); | 137 OnClicked(extension); |
138 } | 138 } |
139 | 139 |
140 void ActiveScriptController::OnClicked(const Extension* extension) { | 140 void ActiveScriptController::OnClicked(const Extension* extension) { |
141 DCHECK(ContainsKey(pending_requests_, extension->id())); | 141 DCHECK(ContainsKey(pending_requests_, extension->id())); |
142 RunPendingForExtension(extension); | 142 RunPendingForExtension(extension); |
143 } | 143 } |
144 | 144 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 return PermissionsData::ACCESS_DENIED; | 176 return PermissionsData::ACCESS_DENIED; |
177 } | 177 } |
178 | 178 |
179 void ActiveScriptController::RequestScriptInjection( | 179 void ActiveScriptController::RequestScriptInjection( |
180 const Extension* extension, | 180 const Extension* extension, |
181 const base::Closure& callback) { | 181 const base::Closure& callback) { |
182 CHECK(extension); | 182 CHECK(extension); |
183 PendingRequestList& list = pending_requests_[extension->id()]; | 183 PendingRequestList& list = pending_requests_[extension->id()]; |
184 list.push_back(callback); | 184 list.push_back(callback); |
185 | 185 |
186 // If this was the first entry, notify the location bar that there's a new | 186 // If this was the first entry, we need to notify that a new extension wants |
187 // icon. | 187 // to run. |
188 if (list.size() == 1u) { | 188 if (list.size() == 1u) |
189 ExtensionActionAPI::Get(web_contents()->GetBrowserContext())-> | 189 NotifyChange(extension); |
190 NotifyPageActionsChanged(web_contents()); | |
191 } | |
192 } | 190 } |
193 | 191 |
194 void ActiveScriptController::RunPendingForExtension( | 192 void ActiveScriptController::RunPendingForExtension( |
195 const Extension* extension) { | 193 const Extension* extension) { |
196 DCHECK(extension); | 194 DCHECK(extension); |
197 | 195 |
198 content::NavigationEntry* visible_entry = | 196 content::NavigationEntry* visible_entry = |
199 web_contents()->GetController().GetVisibleEntry(); | 197 web_contents()->GetController().GetVisibleEntry(); |
200 // Refuse to run if there's no visible entry, because we have no idea of | 198 // Refuse to run if there's no visible entry, because we have no idea of |
201 // determining if it's the proper page. This should rarely, if ever, happen. | 199 // determining if it's the proper page. This should rarely, if ever, happen. |
(...skipping 20 matching lines...) Expand all Loading... |
222 TabHelper::FromWebContents(web_contents())-> | 220 TabHelper::FromWebContents(web_contents())-> |
223 active_tab_permission_granter()->GrantIfRequested(extension); | 221 active_tab_permission_granter()->GrantIfRequested(extension); |
224 | 222 |
225 // Run all pending injections for the given extension. | 223 // Run all pending injections for the given extension. |
226 for (PendingRequestList::iterator request = requests.begin(); | 224 for (PendingRequestList::iterator request = requests.begin(); |
227 request != requests.end(); | 225 request != requests.end(); |
228 ++request) { | 226 ++request) { |
229 request->Run(); | 227 request->Run(); |
230 } | 228 } |
231 | 229 |
232 // Inform the location bar that the action is now gone. | 230 // The extension ran, so we need to update the ExtensionActionAPI that we no |
233 ExtensionActionAPI::Get(web_contents()->GetBrowserContext())-> | 231 // longer want to act. |
234 NotifyPageActionsChanged(web_contents()); | 232 NotifyChange(extension); |
235 } | 233 } |
236 | 234 |
237 void ActiveScriptController::OnRequestScriptInjectionPermission( | 235 void ActiveScriptController::OnRequestScriptInjectionPermission( |
238 const std::string& extension_id, | 236 const std::string& extension_id, |
239 UserScript::InjectionType script_type, | 237 UserScript::InjectionType script_type, |
240 int64 request_id) { | 238 int64 request_id) { |
241 if (!crx_file::id_util::IdIsValid(extension_id)) { | 239 if (!crx_file::id_util::IdIsValid(extension_id)) { |
242 NOTREACHED() << "'" << extension_id << "' is not a valid id."; | 240 NOTREACHED() << "'" << extension_id << "' is not a valid id."; |
243 return; | 241 return; |
244 } | 242 } |
245 | 243 |
246 const Extension* extension = | 244 const Extension* extension = |
247 ExtensionRegistry::Get(web_contents()->GetBrowserContext()) | 245 ExtensionRegistry::Get(browser_context_) |
248 ->enabled_extensions().GetByID(extension_id); | 246 ->enabled_extensions().GetByID(extension_id); |
249 // We shouldn't allow extensions which are no longer enabled to run any | 247 // We shouldn't allow extensions which are no longer enabled to run any |
250 // scripts. Ignore the request. | 248 // scripts. Ignore the request. |
251 if (!extension) | 249 if (!extension) |
252 return; | 250 return; |
253 | 251 |
254 // If the request id is -1, that signals that the content script has already | 252 // If the request id is -1, that signals that the content script has already |
255 // ran (because this feature is not enabled). Add the extension to the list of | 253 // ran (because this feature is not enabled). Add the extension to the list of |
256 // permitted extensions (for metrics), and return immediately. | 254 // permitted extensions (for metrics), and return immediately. |
257 if (request_id == -1) { | 255 if (request_id == -1) { |
(...skipping 29 matching lines...) Expand all Loading... |
287 // This only sends the response to the renderer - the process of adding the | 285 // This only sends the response to the renderer - the process of adding the |
288 // extension to the list of |permitted_extensions_| is done elsewhere. | 286 // extension to the list of |permitted_extensions_| is done elsewhere. |
289 content::RenderViewHost* render_view_host = | 287 content::RenderViewHost* render_view_host = |
290 web_contents()->GetRenderViewHost(); | 288 web_contents()->GetRenderViewHost(); |
291 if (render_view_host) { | 289 if (render_view_host) { |
292 render_view_host->Send(new ExtensionMsg_PermitScriptInjection( | 290 render_view_host->Send(new ExtensionMsg_PermitScriptInjection( |
293 render_view_host->GetRoutingID(), request_id)); | 291 render_view_host->GetRoutingID(), request_id)); |
294 } | 292 } |
295 } | 293 } |
296 | 294 |
| 295 void ActiveScriptController::NotifyChange(const Extension* extension) { |
| 296 ExtensionActionAPI* extension_action_api = |
| 297 ExtensionActionAPI::Get(browser_context_); |
| 298 ExtensionAction* extension_action = |
| 299 ExtensionActionManager::Get(browser_context_)-> |
| 300 GetExtensionAction(*extension); |
| 301 // If the extension has an action, we need to notify that it's updated. |
| 302 if (extension_action) { |
| 303 extension_action_api->NotifyChange( |
| 304 extension_action, web_contents(), browser_context_); |
| 305 } |
| 306 |
| 307 // We also notify that page actions may have changed. |
| 308 extension_action_api->NotifyPageActionsChanged(web_contents()); |
| 309 } |
| 310 |
297 void ActiveScriptController::LogUMA() const { | 311 void ActiveScriptController::LogUMA() const { |
298 UMA_HISTOGRAM_COUNTS_100( | 312 UMA_HISTOGRAM_COUNTS_100( |
299 "Extensions.ActiveScriptController.ShownActiveScriptsOnPage", | 313 "Extensions.ActiveScriptController.ShownActiveScriptsOnPage", |
300 pending_requests_.size()); | 314 pending_requests_.size()); |
301 | 315 |
302 // We only log the permitted extensions metric if the feature is enabled, | 316 // We only log the permitted extensions metric if the feature is enabled, |
303 // because otherwise the data will be boring (100% allowed). | 317 // because otherwise the data will be boring (100% allowed). |
304 if (enabled_) { | 318 if (enabled_) { |
305 UMA_HISTOGRAM_COUNTS_100( | 319 UMA_HISTOGRAM_COUNTS_100( |
306 "Extensions.ActiveScriptController.PermittedExtensions", | 320 "Extensions.ActiveScriptController.PermittedExtensions", |
(...skipping 25 matching lines...) Expand all Loading... |
332 pending_requests_.clear(); | 346 pending_requests_.clear(); |
333 } | 347 } |
334 | 348 |
335 void ActiveScriptController::OnExtensionUnloaded( | 349 void ActiveScriptController::OnExtensionUnloaded( |
336 content::BrowserContext* browser_context, | 350 content::BrowserContext* browser_context, |
337 const Extension* extension, | 351 const Extension* extension, |
338 UnloadedExtensionInfo::Reason reason) { | 352 UnloadedExtensionInfo::Reason reason) { |
339 PendingRequestMap::iterator iter = pending_requests_.find(extension->id()); | 353 PendingRequestMap::iterator iter = pending_requests_.find(extension->id()); |
340 if (iter != pending_requests_.end()) { | 354 if (iter != pending_requests_.end()) { |
341 pending_requests_.erase(iter); | 355 pending_requests_.erase(iter); |
342 ExtensionActionAPI::Get(web_contents()->GetBrowserContext())-> | 356 ExtensionActionAPI::Get(browser_context_)-> |
343 NotifyPageActionsChanged(web_contents()); | 357 NotifyPageActionsChanged(web_contents()); |
344 } | 358 } |
345 } | 359 } |
346 | 360 |
347 } // namespace extensions | 361 } // namespace extensions |
OLD | NEW |