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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 if (list.size() == 1u) | 103 if (list.size() == 1u) |
104 LocationBarController::NotifyChange(web_contents()); | 104 LocationBarController::NotifyChange(web_contents()); |
105 } | 105 } |
106 | 106 |
107 void ActiveScriptController::OnActiveTabPermissionGranted( | 107 void ActiveScriptController::OnActiveTabPermissionGranted( |
108 const Extension* extension) { | 108 const Extension* extension) { |
109 RunPendingForExtension(extension); | 109 RunPendingForExtension(extension); |
110 } | 110 } |
111 | 111 |
112 void ActiveScriptController::OnAdInjectionDetected( | 112 void ActiveScriptController::OnAdInjectionDetected( |
113 const std::set<std::string> ad_injectors) { | 113 const std::set<std::string>& ad_injectors) { |
114 // We're only interested in data if there are ad injectors detected. | 114 // We're only interested in data if there are ad injectors detected. |
115 if (ad_injectors.empty()) | 115 if (ad_injectors.empty()) |
116 return; | 116 return; |
117 | 117 |
118 size_t num_preventable_ad_injectors = | 118 size_t num_preventable_ad_injectors = |
119 base::STLSetIntersection<std::set<std::string> >( | 119 base::STLSetIntersection<std::set<std::string> >( |
120 ad_injectors, permitted_extensions_).size(); | 120 ad_injectors, permitted_extensions_).size(); |
121 | 121 |
122 UMA_HISTOGRAM_COUNTS_100( | 122 UMA_HISTOGRAM_COUNTS_100( |
123 "Extensions.ActiveScriptController.PreventableAdInjectors", | 123 "Extensions.ActiveScriptController.PreventableAdInjectors", |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 RunPendingForExtension(extension); | 161 RunPendingForExtension(extension); |
162 return LocationBarController::ACTION_NONE; | 162 return LocationBarController::ACTION_NONE; |
163 } | 163 } |
164 | 164 |
165 void ActiveScriptController::OnNavigated() { | 165 void ActiveScriptController::OnNavigated() { |
166 LogUMA(); | 166 LogUMA(); |
167 permitted_extensions_.clear(); | 167 permitted_extensions_.clear(); |
168 pending_requests_.clear(); | 168 pending_requests_.clear(); |
169 } | 169 } |
170 | 170 |
| 171 void ActiveScriptController::OnExtensionUnloaded(const Extension* extension) { |
| 172 PendingRequestMap::iterator iter = pending_requests_.find(extension->id()); |
| 173 if (iter != pending_requests_.end()) |
| 174 pending_requests_.erase(iter); |
| 175 } |
| 176 |
171 void ActiveScriptController::RunPendingForExtension( | 177 void ActiveScriptController::RunPendingForExtension( |
172 const Extension* extension) { | 178 const Extension* extension) { |
173 DCHECK(extension); | 179 DCHECK(extension); |
174 PendingRequestMap::iterator iter = | 180 PendingRequestMap::iterator iter = |
175 pending_requests_.find(extension->id()); | 181 pending_requests_.find(extension->id()); |
176 if (iter == pending_requests_.end()) | 182 if (iter == pending_requests_.end()) |
177 return; | 183 return; |
178 | 184 |
179 content::NavigationEntry* visible_entry = | 185 content::NavigationEntry* visible_entry = |
180 web_contents()->GetController().GetVisibleEntry(); | 186 web_contents()->GetController().GetVisibleEntry(); |
(...skipping 25 matching lines...) Expand all Loading... |
206 ++request) { | 212 ++request) { |
207 // Only run if it's on the proper page. | 213 // Only run if it's on the proper page. |
208 if (request->page_id == page_id) | 214 if (request->page_id == page_id) |
209 request->closure.Run(); | 215 request->closure.Run(); |
210 } | 216 } |
211 | 217 |
212 // Inform the location bar that the action is now gone. | 218 // Inform the location bar that the action is now gone. |
213 LocationBarController::NotifyChange(web_contents()); | 219 LocationBarController::NotifyChange(web_contents()); |
214 } | 220 } |
215 | 221 |
216 void ActiveScriptController::OnNotifyExtensionScriptExecution( | 222 void ActiveScriptController::OnRequestContentScriptPermission( |
217 const std::string& extension_id, | 223 const std::string& extension_id, |
218 int page_id) { | 224 int page_id, |
| 225 int request_id) { |
219 if (!Extension::IdIsValid(extension_id)) { | 226 if (!Extension::IdIsValid(extension_id)) { |
220 NOTREACHED() << "'" << extension_id << "' is not a valid id."; | 227 NOTREACHED() << "'" << extension_id << "' is not a valid id."; |
221 return; | 228 return; |
222 } | 229 } |
223 | 230 |
224 const Extension* extension = | 231 const Extension* extension = |
225 ExtensionRegistry::Get(web_contents()->GetBrowserContext()) | 232 ExtensionRegistry::Get(web_contents()->GetBrowserContext()) |
226 ->enabled_extensions().GetByID(extension_id); | 233 ->enabled_extensions().GetByID(extension_id); |
227 // We shouldn't allow extensions which are no longer enabled to run any | 234 // We shouldn't allow extensions which are no longer enabled to run any |
228 // scripts. Ignore the request. | 235 // scripts. Ignore the request. |
229 if (!extension) | 236 if (!extension) |
230 return; | 237 return; |
231 | 238 |
232 // Right now, we allow all content scripts to execute, but notify the | 239 // If the request id is -1, that signals that the content script has already |
233 // controller of them. | 240 // ran (because this feature is not enabled). Add the extension to the list of |
234 // TODO(rdevlin.cronin): Fix this in a future CL. | 241 // permitted extensions (for metrics), and return immediately. |
235 if (RequiresUserConsentForScriptInjection(extension)) | 242 if (request_id == -1) { |
236 RequestScriptInjection(extension, page_id, base::Bind(&base::DoNothing)); | 243 DCHECK(!enabled_); |
| 244 permitted_extensions_.insert(extension->id()); |
| 245 return; |
| 246 } |
| 247 |
| 248 if (RequiresUserConsentForScriptInjection(extension)) { |
| 249 // This base::Unretained() is safe, because the callback is only invoked by |
| 250 // this object. |
| 251 RequestScriptInjection( |
| 252 extension, |
| 253 page_id, |
| 254 base::Bind(&ActiveScriptController::GrantContentScriptPermission, |
| 255 base::Unretained(this), |
| 256 request_id)); |
| 257 } else { |
| 258 GrantContentScriptPermission(request_id); |
| 259 } |
| 260 } |
| 261 |
| 262 void ActiveScriptController::GrantContentScriptPermission(int request_id) { |
| 263 content::RenderViewHost* render_view_host = |
| 264 web_contents()->GetRenderViewHost(); |
| 265 if (render_view_host) { |
| 266 render_view_host->Send(new ExtensionMsg_GrantContentScriptPermission( |
| 267 render_view_host->GetRoutingID(), |
| 268 request_id)); |
| 269 } |
237 } | 270 } |
238 | 271 |
239 bool ActiveScriptController::OnMessageReceived(const IPC::Message& message) { | 272 bool ActiveScriptController::OnMessageReceived(const IPC::Message& message) { |
240 bool handled = true; | 273 bool handled = true; |
241 IPC_BEGIN_MESSAGE_MAP(ActiveScriptController, message) | 274 IPC_BEGIN_MESSAGE_MAP(ActiveScriptController, message) |
242 IPC_MESSAGE_HANDLER(ExtensionHostMsg_NotifyExtensionScriptExecution, | 275 IPC_MESSAGE_HANDLER(ExtensionHostMsg_RequestContentScriptPermission, |
243 OnNotifyExtensionScriptExecution) | 276 OnRequestContentScriptPermission) |
244 IPC_MESSAGE_UNHANDLED(handled = false) | 277 IPC_MESSAGE_UNHANDLED(handled = false) |
245 IPC_END_MESSAGE_MAP() | 278 IPC_END_MESSAGE_MAP() |
246 return handled; | 279 return handled; |
247 } | 280 } |
248 | 281 |
249 void ActiveScriptController::LogUMA() const { | 282 void ActiveScriptController::LogUMA() const { |
250 UMA_HISTOGRAM_COUNTS_100( | 283 UMA_HISTOGRAM_COUNTS_100( |
251 "Extensions.ActiveScriptController.ShownActiveScriptsOnPage", | 284 "Extensions.ActiveScriptController.ShownActiveScriptsOnPage", |
252 pending_requests_.size()); | 285 pending_requests_.size()); |
253 | 286 |
254 // We only log the permitted extensions metric if the feature is enabled, | 287 // We only log the permitted extensions metric if the feature is enabled, |
255 // because otherwise the data will be boring (100% allowed). | 288 // because otherwise the data will be boring (100% allowed). |
256 if (enabled_) { | 289 if (enabled_) { |
257 UMA_HISTOGRAM_COUNTS_100( | 290 UMA_HISTOGRAM_COUNTS_100( |
258 "Extensions.ActiveScriptController.PermittedExtensions", | 291 "Extensions.ActiveScriptController.PermittedExtensions", |
259 permitted_extensions_.size()); | 292 permitted_extensions_.size()); |
260 UMA_HISTOGRAM_COUNTS_100( | 293 UMA_HISTOGRAM_COUNTS_100( |
261 "Extensions.ActiveScriptController.DeniedExtensions", | 294 "Extensions.ActiveScriptController.DeniedExtensions", |
262 pending_requests_.size()); | 295 pending_requests_.size()); |
263 } | 296 } |
264 } | 297 } |
265 | 298 |
266 } // namespace extensions | 299 } // namespace extensions |
OLD | NEW |