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 29 matching lines...) Expand all Loading... | |
40 : closure(closure), | 40 : closure(closure), |
41 page_id(page_id) { | 41 page_id(page_id) { |
42 } | 42 } |
43 | 43 |
44 ActiveScriptController::PendingRequest::~PendingRequest() { | 44 ActiveScriptController::PendingRequest::~PendingRequest() { |
45 } | 45 } |
46 | 46 |
47 ActiveScriptController::ActiveScriptController( | 47 ActiveScriptController::ActiveScriptController( |
48 content::WebContents* web_contents) | 48 content::WebContents* web_contents) |
49 : content::WebContentsObserver(web_contents), | 49 : content::WebContentsObserver(web_contents), |
50 enabled_(FeatureSwitch::scripts_require_action()->IsEnabled()) { | 50 enabled_(FeatureSwitch::scripts_require_action()->IsEnabled()), |
51 extension_registry_observer_(this) { | |
51 CHECK(web_contents); | 52 CHECK(web_contents); |
53 extension_registry_observer_.Add( | |
54 ExtensionRegistry::Get(web_contents->GetBrowserContext())); | |
52 } | 55 } |
53 | 56 |
54 ActiveScriptController::~ActiveScriptController() { | 57 ActiveScriptController::~ActiveScriptController() { |
55 LogUMA(); | 58 LogUMA(); |
56 } | 59 } |
57 | 60 |
58 // static | 61 // static |
59 ActiveScriptController* ActiveScriptController::GetForWebContents( | 62 ActiveScriptController* ActiveScriptController::GetForWebContents( |
60 content::WebContents* web_contents) { | 63 content::WebContents* web_contents) { |
61 if (!web_contents) | 64 if (!web_contents) |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
103 if (list.size() == 1u) | 106 if (list.size() == 1u) |
104 LocationBarController::NotifyChange(web_contents()); | 107 LocationBarController::NotifyChange(web_contents()); |
105 } | 108 } |
106 | 109 |
107 void ActiveScriptController::OnActiveTabPermissionGranted( | 110 void ActiveScriptController::OnActiveTabPermissionGranted( |
108 const Extension* extension) { | 111 const Extension* extension) { |
109 RunPendingForExtension(extension); | 112 RunPendingForExtension(extension); |
110 } | 113 } |
111 | 114 |
112 void ActiveScriptController::OnAdInjectionDetected( | 115 void ActiveScriptController::OnAdInjectionDetected( |
113 const std::set<std::string> ad_injectors) { | 116 const std::set<std::string>& ad_injectors) { |
114 // We're only interested in data if there are ad injectors detected. | 117 // We're only interested in data if there are ad injectors detected. |
115 if (ad_injectors.empty()) | 118 if (ad_injectors.empty()) |
116 return; | 119 return; |
117 | 120 |
118 size_t num_preventable_ad_injectors = | 121 size_t num_preventable_ad_injectors = |
119 base::STLSetIntersection<std::set<std::string> >( | 122 base::STLSetIntersection<std::set<std::string> >( |
120 ad_injectors, permitted_extensions_).size(); | 123 ad_injectors, permitted_extensions_).size(); |
121 | 124 |
122 UMA_HISTOGRAM_COUNTS_100( | 125 UMA_HISTOGRAM_COUNTS_100( |
123 "Extensions.ActiveScriptController.PreventableAdInjectors", | 126 "Extensions.ActiveScriptController.PreventableAdInjectors", |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
206 ++request) { | 209 ++request) { |
207 // Only run if it's on the proper page. | 210 // Only run if it's on the proper page. |
208 if (request->page_id == page_id) | 211 if (request->page_id == page_id) |
209 request->closure.Run(); | 212 request->closure.Run(); |
210 } | 213 } |
211 | 214 |
212 // Inform the location bar that the action is now gone. | 215 // Inform the location bar that the action is now gone. |
213 LocationBarController::NotifyChange(web_contents()); | 216 LocationBarController::NotifyChange(web_contents()); |
214 } | 217 } |
215 | 218 |
216 void ActiveScriptController::OnNotifyExtensionScriptExecution( | 219 void ActiveScriptController::OnRequestContentScriptPermission( |
217 const std::string& extension_id, | 220 const std::string& extension_id, |
218 int page_id) { | 221 int page_id, |
222 int request_id) { | |
219 if (!Extension::IdIsValid(extension_id)) { | 223 if (!Extension::IdIsValid(extension_id)) { |
220 NOTREACHED() << "'" << extension_id << "' is not a valid id."; | 224 NOTREACHED() << "'" << extension_id << "' is not a valid id."; |
221 return; | 225 return; |
222 } | 226 } |
223 | 227 |
224 const Extension* extension = | 228 const Extension* extension = |
225 ExtensionRegistry::Get(web_contents()->GetBrowserContext()) | 229 ExtensionRegistry::Get(web_contents()->GetBrowserContext()) |
226 ->enabled_extensions().GetByID(extension_id); | 230 ->enabled_extensions().GetByID(extension_id); |
227 // We shouldn't allow extensions which are no longer enabled to run any | 231 // We shouldn't allow extensions which are no longer enabled to run any |
228 // scripts. Ignore the request. | 232 // scripts. Ignore the request. |
229 if (!extension) | 233 if (!extension) |
230 return; | 234 return; |
231 | 235 |
232 // Right now, we allow all content scripts to execute, but notify the | 236 // If the request id is -1, that signals that the content script has already |
233 // controller of them. | 237 // ran (because this feature is not enabled). Add the extension to the list of |
234 // TODO(rdevlin.cronin): Fix this in a future CL. | 238 // permitted extensions (for metrics), and return immediately. |
235 if (RequiresUserConsentForScriptInjection(extension)) | 239 if (request_id == -1) { |
236 RequestScriptInjection(extension, page_id, base::Bind(&base::DoNothing)); | 240 DCHECK(!enabled_); |
241 permitted_extensions_.insert(extension->id()); | |
242 return; | |
243 } | |
244 | |
245 if (RequiresUserConsentForScriptInjection(extension)) { | |
246 // This base::Unretained() is safe, because the callback is only invoked by | |
247 // this object. | |
248 RequestScriptInjection( | |
249 extension, | |
250 page_id, | |
251 base::Bind(&ActiveScriptController::GrantContentScriptPermission, | |
252 base::Unretained(this), | |
253 request_id)); | |
254 } else { | |
255 GrantContentScriptPermission(request_id); | |
256 } | |
257 } | |
258 | |
259 void ActiveScriptController::GrantContentScriptPermission(int request_id) { | |
260 content::RenderViewHost* render_view_host = | |
261 web_contents()->GetRenderViewHost(); | |
262 if (render_view_host) { | |
263 render_view_host->Send(new ExtensionMsg_GrantContentScriptPermission( | |
264 render_view_host->GetRoutingID(), | |
265 request_id)); | |
266 } | |
237 } | 267 } |
238 | 268 |
239 bool ActiveScriptController::OnMessageReceived(const IPC::Message& message) { | 269 bool ActiveScriptController::OnMessageReceived(const IPC::Message& message) { |
240 bool handled = true; | 270 bool handled = true; |
241 IPC_BEGIN_MESSAGE_MAP(ActiveScriptController, message) | 271 IPC_BEGIN_MESSAGE_MAP(ActiveScriptController, message) |
242 IPC_MESSAGE_HANDLER(ExtensionHostMsg_NotifyExtensionScriptExecution, | 272 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RequestContentScriptPermission, |
243 OnNotifyExtensionScriptExecution) | 273 OnRequestContentScriptPermission) |
244 IPC_MESSAGE_UNHANDLED(handled = false) | 274 IPC_MESSAGE_UNHANDLED(handled = false) |
245 IPC_END_MESSAGE_MAP() | 275 IPC_END_MESSAGE_MAP() |
246 return handled; | 276 return handled; |
247 } | 277 } |
248 | 278 |
279 void ActiveScriptController::OnExtensionUnloaded( | |
280 content::BrowserContext* browser_context, | |
281 const Extension* extension, | |
282 UnloadedExtensionInfo::Reason reason) { | |
283 PendingRequestMap::iterator iter = pending_requests_.find(extension->id()); | |
284 if (iter != pending_requests_.end()) { | |
285 pending_requests_.erase(iter); | |
not at google - send to devlin
2014/06/02 21:28:17
seems like you could delete the entry from pending
Devlin
2014/06/02 23:07:52
Done.
| |
286 LocationBarController::NotifyChange(web_contents()); | |
287 } | |
288 } | |
289 | |
249 void ActiveScriptController::LogUMA() const { | 290 void ActiveScriptController::LogUMA() const { |
250 UMA_HISTOGRAM_COUNTS_100( | 291 UMA_HISTOGRAM_COUNTS_100( |
251 "Extensions.ActiveScriptController.ShownActiveScriptsOnPage", | 292 "Extensions.ActiveScriptController.ShownActiveScriptsOnPage", |
252 pending_requests_.size()); | 293 pending_requests_.size()); |
253 | 294 |
254 // We only log the permitted extensions metric if the feature is enabled, | 295 // We only log the permitted extensions metric if the feature is enabled, |
255 // because otherwise the data will be boring (100% allowed). | 296 // because otherwise the data will be boring (100% allowed). |
256 if (enabled_) { | 297 if (enabled_) { |
257 UMA_HISTOGRAM_COUNTS_100( | 298 UMA_HISTOGRAM_COUNTS_100( |
258 "Extensions.ActiveScriptController.PermittedExtensions", | 299 "Extensions.ActiveScriptController.PermittedExtensions", |
259 permitted_extensions_.size()); | 300 permitted_extensions_.size()); |
260 UMA_HISTOGRAM_COUNTS_100( | 301 UMA_HISTOGRAM_COUNTS_100( |
261 "Extensions.ActiveScriptController.DeniedExtensions", | 302 "Extensions.ActiveScriptController.DeniedExtensions", |
262 pending_requests_.size()); | 303 pending_requests_.size()); |
263 } | 304 } |
264 } | 305 } |
265 | 306 |
266 } // namespace extensions | 307 } // namespace extensions |
OLD | NEW |