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 "extensions/renderer/dispatcher.h" | 5 #include "extensions/renderer/dispatcher.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/callback.h" | 8 #include "base/callback.h" |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/debug/alias.h" | 10 #include "base/debug/alias.h" |
11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
12 #include "base/metrics/histogram_macros.h" | 12 #include "base/metrics/histogram_macros.h" |
13 #include "base/metrics/user_metrics_action.h" | 13 #include "base/metrics/user_metrics_action.h" |
14 #include "base/strings/string_piece.h" | 14 #include "base/strings/string_piece.h" |
15 #include "base/strings/string_split.h" | 15 #include "base/strings/string_split.h" |
16 #include "base/strings/string_util.h" | 16 #include "base/strings/string_util.h" |
17 #include "base/time/time.h" | 17 #include "base/time/time.h" |
18 #include "base/values.h" | 18 #include "base/values.h" |
19 #include "content/grit/content_resources.h" | 19 #include "content/grit/content_resources.h" |
20 #include "content/public/child/v8_value_converter.h" | 20 #include "content/public/child/v8_value_converter.h" |
21 #include "content/public/common/content_switches.h" | 21 #include "content/public/common/content_switches.h" |
22 #include "content/public/common/url_constants.h" | 22 #include "content/public/common/url_constants.h" |
23 #include "content/public/renderer/render_thread.h" | 23 #include "content/public/renderer/render_thread.h" |
24 #include "content/public/renderer/render_view.h" | 24 #include "content/public/renderer/render_view.h" |
25 #include "extensions/common/api/messaging/message.h" | 25 #include "extensions/common/api/messaging/message.h" |
26 #include "extensions/common/constants.h" | 26 #include "extensions/common/constants.h" |
| 27 #include "extensions/common/extension.h" |
27 #include "extensions/common/extension_api.h" | 28 #include "extensions/common/extension_api.h" |
28 #include "extensions/common/extension_messages.h" | 29 #include "extensions/common/extension_messages.h" |
29 #include "extensions/common/extension_urls.h" | 30 #include "extensions/common/extension_urls.h" |
30 #include "extensions/common/feature_switch.h" | 31 #include "extensions/common/feature_switch.h" |
31 #include "extensions/common/features/feature.h" | 32 #include "extensions/common/features/feature.h" |
32 #include "extensions/common/features/feature_provider.h" | 33 #include "extensions/common/features/feature_provider.h" |
33 #include "extensions/common/manifest.h" | 34 #include "extensions/common/manifest.h" |
34 #include "extensions/common/manifest_constants.h" | 35 #include "extensions/common/manifest_constants.h" |
35 #include "extensions/common/manifest_handlers/background_info.h" | 36 #include "extensions/common/manifest_handlers/background_info.h" |
36 #include "extensions/common/manifest_handlers/content_capabilities_handler.h" | 37 #include "extensions/common/manifest_handlers/content_capabilities_handler.h" |
37 #include "extensions/common/manifest_handlers/externally_connectable.h" | 38 #include "extensions/common/manifest_handlers/externally_connectable.h" |
38 #include "extensions/common/manifest_handlers/options_page_info.h" | 39 #include "extensions/common/manifest_handlers/options_page_info.h" |
| 40 #include "extensions/common/manifest_handlers/sandboxed_page_info.h" |
39 #include "extensions/common/message_bundle.h" | 41 #include "extensions/common/message_bundle.h" |
40 #include "extensions/common/permissions/permission_set.h" | 42 #include "extensions/common/permissions/permission_set.h" |
41 #include "extensions/common/permissions/permissions_data.h" | 43 #include "extensions/common/permissions/permissions_data.h" |
42 #include "extensions/common/switches.h" | 44 #include "extensions/common/switches.h" |
43 #include "extensions/common/view_type.h" | 45 #include "extensions/common/view_type.h" |
44 #include "extensions/renderer/api_activity_logger.h" | 46 #include "extensions/renderer/api_activity_logger.h" |
45 #include "extensions/renderer/api_definitions_natives.h" | 47 #include "extensions/renderer/api_definitions_natives.h" |
46 #include "extensions/renderer/app_runtime_custom_bindings.h" | 48 #include "extensions/renderer/app_runtime_custom_bindings.h" |
47 #include "extensions/renderer/app_window_custom_bindings.h" | 49 #include "extensions/renderer/app_window_custom_bindings.h" |
48 #include "extensions/renderer/binding_generating_native_handler.h" | 50 #include "extensions/renderer/binding_generating_native_handler.h" |
49 #include "extensions/renderer/blob_native_handler.h" | 51 #include "extensions/renderer/blob_native_handler.h" |
50 #include "extensions/renderer/content_watcher.h" | 52 #include "extensions/renderer/content_watcher.h" |
51 #include "extensions/renderer/context_menus_custom_bindings.h" | 53 #include "extensions/renderer/context_menus_custom_bindings.h" |
52 #include "extensions/renderer/css_native_handler.h" | 54 #include "extensions/renderer/css_native_handler.h" |
53 #include "extensions/renderer/dispatcher_delegate.h" | 55 #include "extensions/renderer/dispatcher_delegate.h" |
54 #include "extensions/renderer/document_custom_bindings.h" | 56 #include "extensions/renderer/document_custom_bindings.h" |
55 #include "extensions/renderer/dom_activity_logger.h" | 57 #include "extensions/renderer/dom_activity_logger.h" |
56 #include "extensions/renderer/event_bindings.h" | 58 #include "extensions/renderer/event_bindings.h" |
| 59 #include "extensions/renderer/extension_groups.h" |
57 #include "extensions/renderer/extension_helper.h" | 60 #include "extensions/renderer/extension_helper.h" |
58 #include "extensions/renderer/extensions_renderer_client.h" | 61 #include "extensions/renderer/extensions_renderer_client.h" |
59 #include "extensions/renderer/file_system_natives.h" | 62 #include "extensions/renderer/file_system_natives.h" |
60 #include "extensions/renderer/guest_view/guest_view_internal_custom_bindings.h" | 63 #include "extensions/renderer/guest_view/guest_view_internal_custom_bindings.h" |
61 #include "extensions/renderer/i18n_custom_bindings.h" | 64 #include "extensions/renderer/i18n_custom_bindings.h" |
62 #include "extensions/renderer/id_generator_custom_bindings.h" | 65 #include "extensions/renderer/id_generator_custom_bindings.h" |
63 #include "extensions/renderer/lazy_background_page_native_handler.h" | 66 #include "extensions/renderer/lazy_background_page_native_handler.h" |
64 #include "extensions/renderer/logging_native_handler.h" | 67 #include "extensions/renderer/logging_native_handler.h" |
65 #include "extensions/renderer/messaging_bindings.h" | 68 #include "extensions/renderer/messaging_bindings.h" |
66 #include "extensions/renderer/module_system.h" | 69 #include "extensions/renderer/module_system.h" |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 command_line.HasSwitch(switches::kExtensionProcess) || | 198 command_line.HasSwitch(switches::kExtensionProcess) || |
196 command_line.HasSwitch(::switches::kSingleProcess); | 199 command_line.HasSwitch(::switches::kSingleProcess); |
197 | 200 |
198 if (set_idle_notifications_) { | 201 if (set_idle_notifications_) { |
199 RenderThread::Get()->SetIdleNotificationDelayInMs( | 202 RenderThread::Get()->SetIdleNotificationDelayInMs( |
200 kInitialExtensionIdleHandlerDelayMs); | 203 kInitialExtensionIdleHandlerDelayMs); |
201 } | 204 } |
202 | 205 |
203 RenderThread::Get()->RegisterExtension(SafeBuiltins::CreateV8Extension()); | 206 RenderThread::Get()->RegisterExtension(SafeBuiltins::CreateV8Extension()); |
204 | 207 |
205 script_context_set_.reset( | |
206 new ScriptContextSet(&extensions_, &active_extension_ids_)); | |
207 user_script_set_manager_.reset(new UserScriptSetManager(&extensions_)); | 208 user_script_set_manager_.reset(new UserScriptSetManager(&extensions_)); |
208 script_injection_manager_.reset( | 209 script_injection_manager_.reset( |
209 new ScriptInjectionManager(&extensions_, user_script_set_manager_.get())); | 210 new ScriptInjectionManager(&extensions_, user_script_set_manager_.get())); |
210 user_script_set_manager_observer_.Add(user_script_set_manager_.get()); | 211 user_script_set_manager_observer_.Add(user_script_set_manager_.get()); |
211 request_sender_.reset(new RequestSender(this)); | 212 request_sender_.reset(new RequestSender(this)); |
212 PopulateSourceMap(); | 213 PopulateSourceMap(); |
213 } | 214 } |
214 | 215 |
215 Dispatcher::~Dispatcher() { | 216 Dispatcher::~Dispatcher() { |
216 } | 217 } |
217 | 218 |
218 void Dispatcher::OnRenderViewCreated(content::RenderView* render_view) { | 219 void Dispatcher::OnRenderViewCreated(content::RenderView* render_view) { |
219 script_injection_manager_->OnRenderViewCreated(render_view); | 220 script_injection_manager_->OnRenderViewCreated(render_view); |
220 } | 221 } |
221 | 222 |
222 bool Dispatcher::IsExtensionActive(const std::string& extension_id) const { | 223 bool Dispatcher::IsExtensionActive(const std::string& extension_id) const { |
223 bool is_active = | 224 bool is_active = |
224 active_extension_ids_.find(extension_id) != active_extension_ids_.end(); | 225 active_extension_ids_.find(extension_id) != active_extension_ids_.end(); |
225 if (is_active) | 226 if (is_active) |
226 CHECK(extensions_.Contains(extension_id)); | 227 CHECK(extensions_.Contains(extension_id)); |
227 return is_active; | 228 return is_active; |
228 } | 229 } |
229 | 230 |
| 231 const Extension* Dispatcher::GetExtensionFromFrameAndWorld( |
| 232 const blink::WebFrame* frame, |
| 233 int world_id, |
| 234 bool use_effective_url) { |
| 235 std::string extension_id; |
| 236 if (world_id != 0) { |
| 237 // Isolated worlds (content script). |
| 238 extension_id = ScriptInjection::GetHostIdForIsolatedWorld(world_id); |
| 239 } else if (!frame->document().securityOrigin().isUnique()) { |
| 240 // TODO(kalman): Delete the above check. |
| 241 |
| 242 // Extension pages (chrome-extension:// URLs). |
| 243 GURL frame_url = ScriptContext::GetDataSourceURLForFrame(frame); |
| 244 frame_url = ScriptContext::GetEffectiveDocumentURL( |
| 245 frame, frame_url, use_effective_url); |
| 246 extension_id = extensions_.GetExtensionOrAppIDByURL(frame_url); |
| 247 } |
| 248 |
| 249 const Extension* extension = extensions_.GetByID(extension_id); |
| 250 if (!extension && !extension_id.empty()) { |
| 251 // There are conditions where despite a context being associated with an |
| 252 // extension, no extension actually gets found. Ignore "invalid" because |
| 253 // CSP blocks extension page loading by switching the extension ID to |
| 254 // "invalid". This isn't interesting. |
| 255 if (extension_id != "invalid") { |
| 256 LOG(ERROR) << "Extension \"" << extension_id << "\" not found"; |
| 257 RenderThread::Get()->RecordAction( |
| 258 UserMetricsAction("ExtensionNotFound_ED")); |
| 259 } |
| 260 } |
| 261 return extension; |
| 262 } |
| 263 |
230 void Dispatcher::DidCreateScriptContext( | 264 void Dispatcher::DidCreateScriptContext( |
231 blink::WebLocalFrame* frame, | 265 blink::WebLocalFrame* frame, |
232 const v8::Handle<v8::Context>& v8_context, | 266 const v8::Handle<v8::Context>& v8_context, |
233 int extension_group, | 267 int extension_group, |
234 int world_id) { | 268 int world_id) { |
235 const base::TimeTicks start_time = base::TimeTicks::Now(); | 269 const base::TimeTicks start_time = base::TimeTicks::Now(); |
236 | 270 |
237 ScriptContext* context = script_context_set_->Register( | 271 const Extension* extension = |
238 frame, v8_context, extension_group, world_id); | 272 GetExtensionFromFrameAndWorld(frame, world_id, false); |
| 273 const Extension* effective_extension = |
| 274 GetExtensionFromFrameAndWorld(frame, world_id, true); |
| 275 |
| 276 GURL frame_url = ScriptContext::GetDataSourceURLForFrame(frame); |
| 277 Feature::Context context_type = |
| 278 ClassifyJavaScriptContext(extension, |
| 279 extension_group, |
| 280 frame_url, |
| 281 frame->document().securityOrigin()); |
| 282 Feature::Context effective_context_type = ClassifyJavaScriptContext( |
| 283 effective_extension, |
| 284 extension_group, |
| 285 ScriptContext::GetEffectiveDocumentURL(frame, frame_url, true), |
| 286 frame->document().securityOrigin()); |
| 287 |
| 288 ScriptContext* context = |
| 289 new ScriptContext(v8_context, frame, extension, context_type, |
| 290 effective_extension, effective_context_type); |
| 291 script_context_set_.Add(context); |
239 | 292 |
240 // Initialize origin permissions for content scripts, which can't be | 293 // Initialize origin permissions for content scripts, which can't be |
241 // initialized in |OnActivateExtension|. | 294 // initialized in |OnActivateExtension|. |
242 if (context->context_type() == Feature::CONTENT_SCRIPT_CONTEXT) | 295 if (context_type == Feature::CONTENT_SCRIPT_CONTEXT) |
243 InitOriginPermissions(context->extension()); | 296 InitOriginPermissions(extension); |
244 | 297 |
245 { | 298 { |
246 scoped_ptr<ModuleSystem> module_system( | 299 scoped_ptr<ModuleSystem> module_system( |
247 new ModuleSystem(context, &source_map_)); | 300 new ModuleSystem(context, &source_map_)); |
248 context->set_module_system(module_system.Pass()); | 301 context->set_module_system(module_system.Pass()); |
249 } | 302 } |
250 ModuleSystem* module_system = context->module_system(); | 303 ModuleSystem* module_system = context->module_system(); |
251 | 304 |
252 // Enable natives in startup. | 305 // Enable natives in startup. |
253 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system); | 306 ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system); |
(...skipping 14 matching lines...) Expand all Loading... |
268 bool is_within_platform_app = IsWithinPlatformApp(); | 321 bool is_within_platform_app = IsWithinPlatformApp(); |
269 // Inject custom JS into the platform app context. | 322 // Inject custom JS into the platform app context. |
270 if (is_within_platform_app) { | 323 if (is_within_platform_app) { |
271 module_system->Require("platformApp"); | 324 module_system->Require("platformApp"); |
272 } | 325 } |
273 | 326 |
274 RequireGuestViewModules(context); | 327 RequireGuestViewModules(context); |
275 delegate_->RequireAdditionalModules(context, is_within_platform_app); | 328 delegate_->RequireAdditionalModules(context, is_within_platform_app); |
276 | 329 |
277 const base::TimeDelta elapsed = base::TimeTicks::Now() - start_time; | 330 const base::TimeDelta elapsed = base::TimeTicks::Now() - start_time; |
278 switch (context->context_type()) { | 331 switch (context_type) { |
279 case Feature::UNSPECIFIED_CONTEXT: | 332 case Feature::UNSPECIFIED_CONTEXT: |
280 UMA_HISTOGRAM_TIMES("Extensions.DidCreateScriptContext_Unspecified", | 333 UMA_HISTOGRAM_TIMES("Extensions.DidCreateScriptContext_Unspecified", |
281 elapsed); | 334 elapsed); |
282 break; | 335 break; |
283 case Feature::BLESSED_EXTENSION_CONTEXT: | 336 case Feature::BLESSED_EXTENSION_CONTEXT: |
284 UMA_HISTOGRAM_TIMES("Extensions.DidCreateScriptContext_Blessed", elapsed); | 337 UMA_HISTOGRAM_TIMES("Extensions.DidCreateScriptContext_Blessed", elapsed); |
285 break; | 338 break; |
286 case Feature::UNBLESSED_EXTENSION_CONTEXT: | 339 case Feature::UNBLESSED_EXTENSION_CONTEXT: |
287 UMA_HISTOGRAM_TIMES("Extensions.DidCreateScriptContext_Unblessed", | 340 UMA_HISTOGRAM_TIMES("Extensions.DidCreateScriptContext_Unblessed", |
288 elapsed); | 341 elapsed); |
289 break; | 342 break; |
290 case Feature::CONTENT_SCRIPT_CONTEXT: | 343 case Feature::CONTENT_SCRIPT_CONTEXT: |
291 UMA_HISTOGRAM_TIMES("Extensions.DidCreateScriptContext_ContentScript", | 344 UMA_HISTOGRAM_TIMES("Extensions.DidCreateScriptContext_ContentScript", |
292 elapsed); | 345 elapsed); |
293 break; | 346 break; |
294 case Feature::WEB_PAGE_CONTEXT: | 347 case Feature::WEB_PAGE_CONTEXT: |
295 UMA_HISTOGRAM_TIMES("Extensions.DidCreateScriptContext_WebPage", elapsed); | 348 UMA_HISTOGRAM_TIMES("Extensions.DidCreateScriptContext_WebPage", elapsed); |
296 break; | 349 break; |
297 case Feature::BLESSED_WEB_PAGE_CONTEXT: | 350 case Feature::BLESSED_WEB_PAGE_CONTEXT: |
298 UMA_HISTOGRAM_TIMES("Extensions.DidCreateScriptContext_BlessedWebPage", | 351 UMA_HISTOGRAM_TIMES("Extensions.DidCreateScriptContext_BlessedWebPage", |
299 elapsed); | 352 elapsed); |
300 break; | 353 break; |
301 case Feature::WEBUI_CONTEXT: | 354 case Feature::WEBUI_CONTEXT: |
302 UMA_HISTOGRAM_TIMES("Extensions.DidCreateScriptContext_WebUI", elapsed); | 355 UMA_HISTOGRAM_TIMES("Extensions.DidCreateScriptContext_WebUI", elapsed); |
303 break; | 356 break; |
304 } | 357 } |
305 | 358 |
306 VLOG(1) << "Num tracked contexts: " << script_context_set_->size(); | 359 VLOG(1) << "Num tracked contexts: " << script_context_set_.size(); |
307 } | 360 } |
308 | 361 |
309 void Dispatcher::WillReleaseScriptContext( | 362 void Dispatcher::WillReleaseScriptContext( |
310 blink::WebLocalFrame* frame, | 363 blink::WebLocalFrame* frame, |
311 const v8::Handle<v8::Context>& v8_context, | 364 const v8::Handle<v8::Context>& v8_context, |
312 int world_id) { | 365 int world_id) { |
313 ScriptContext* context = script_context_set_->GetByV8Context(v8_context); | 366 ScriptContext* context = script_context_set_.GetByV8Context(v8_context); |
314 if (!context) | 367 if (!context) |
315 return; | 368 return; |
316 | 369 |
317 context->DispatchOnUnloadEvent(); | 370 context->DispatchOnUnloadEvent(); |
318 // TODO(kalman): add an invalidation observer interface to ScriptContext. | 371 // TODO(kalman): add an invalidation observer interface to ScriptContext. |
319 request_sender_->InvalidateSource(context); | 372 request_sender_->InvalidateSource(context); |
320 | 373 |
321 script_context_set_->Remove(context); | 374 script_context_set_.Remove(context); |
322 VLOG(1) << "Num tracked contexts: " << script_context_set_->size(); | 375 VLOG(1) << "Num tracked contexts: " << script_context_set_.size(); |
323 } | 376 } |
324 | 377 |
325 void Dispatcher::DidCreateDocumentElement(blink::WebFrame* frame) { | 378 void Dispatcher::DidCreateDocumentElement(blink::WebFrame* frame) { |
326 // Note: use GetEffectiveDocumentURL not just frame->document()->url() | 379 // Note: use GetEffectiveDocumentURL not just frame->document()->url() |
327 // so that this also injects the stylesheet on about:blank frames that | 380 // so that this also injects the stylesheet on about:blank frames that |
328 // are hosted in the extension process. | 381 // are hosted in the extension process. |
329 GURL effective_document_url = ScriptContext::GetEffectiveDocumentURL( | 382 GURL effective_document_url = ScriptContext::GetEffectiveDocumentURL( |
330 frame, frame->document().url(), true /* match_about_blank */); | 383 frame, frame->document().url(), true /* match_about_blank */); |
331 | 384 |
332 const Extension* extension = | 385 const Extension* extension = |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 const std::string& function_name, | 436 const std::string& function_name, |
384 ScriptContext* context) const { | 437 ScriptContext* context) const { |
385 if (!context) { | 438 if (!context) { |
386 DLOG(ERROR) << "Not in a v8::Context"; | 439 DLOG(ERROR) << "Not in a v8::Context"; |
387 return false; | 440 return false; |
388 } | 441 } |
389 | 442 |
390 // Theoretically we could end up with bindings being injected into sandboxed | 443 // Theoretically we could end up with bindings being injected into sandboxed |
391 // frames, for example content scripts. Don't let them execute API functions. | 444 // frames, for example content scripts. Don't let them execute API functions. |
392 blink::WebFrame* frame = context->web_frame(); | 445 blink::WebFrame* frame = context->web_frame(); |
393 if (ScriptContext::IsSandboxedPage( | 446 if (IsSandboxedPage(ScriptContext::GetDataSourceURLForFrame(frame))) { |
394 extensions_, ScriptContext::GetDataSourceURLForFrame(frame))) { | |
395 static const char kMessage[] = | 447 static const char kMessage[] = |
396 "%s cannot be used within a sandboxed frame."; | 448 "%s cannot be used within a sandboxed frame."; |
397 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str()); | 449 std::string error_msg = base::StringPrintf(kMessage, function_name.c_str()); |
398 context->isolate()->ThrowException(v8::Exception::Error( | 450 context->isolate()->ThrowException(v8::Exception::Error( |
399 v8::String::NewFromUtf8(context->isolate(), error_msg.c_str()))); | 451 v8::String::NewFromUtf8(context->isolate(), error_msg.c_str()))); |
400 return false; | 452 return false; |
401 } | 453 } |
402 | 454 |
403 Feature::Availability availability = context->GetAvailability(function_name); | 455 Feature::Availability availability = context->GetAvailability(function_name); |
404 if (!availability.is_available()) { | 456 if (!availability.is_available()) { |
405 context->isolate()->ThrowException( | 457 context->isolate()->ThrowException( |
406 v8::Exception::Error(v8::String::NewFromUtf8( | 458 v8::Exception::Error(v8::String::NewFromUtf8( |
407 context->isolate(), availability.message().c_str()))); | 459 context->isolate(), availability.message().c_str()))); |
408 } | 460 } |
409 | 461 |
410 return availability.is_available(); | 462 return availability.is_available(); |
411 } | 463 } |
412 | 464 |
413 void Dispatcher::DispatchEvent(const std::string& extension_id, | 465 void Dispatcher::DispatchEvent(const std::string& extension_id, |
414 const std::string& event_name) const { | 466 const std::string& event_name) const { |
415 base::ListValue args; | 467 base::ListValue args; |
416 args.Set(0, new base::StringValue(event_name)); | 468 args.Set(0, new base::StringValue(event_name)); |
417 args.Set(1, new base::ListValue()); | 469 args.Set(1, new base::ListValue()); |
418 | 470 |
419 // Needed for Windows compilation, since kEventBindings is declared extern. | 471 // Needed for Windows compilation, since kEventBindings is declared extern. |
420 const char* local_event_bindings = kEventBindings; | 472 const char* local_event_bindings = kEventBindings; |
421 script_context_set_->ForEach( | 473 script_context_set_.ForEach(extension_id, |
422 extension_id, base::Bind(&CallModuleMethod, local_event_bindings, | 474 base::Bind(&CallModuleMethod, |
423 kEventDispatchFunction, &args)); | 475 local_event_bindings, |
| 476 kEventDispatchFunction, |
| 477 &args)); |
424 } | 478 } |
425 | 479 |
426 void Dispatcher::InvokeModuleSystemMethod(content::RenderView* render_view, | 480 void Dispatcher::InvokeModuleSystemMethod(content::RenderView* render_view, |
427 const std::string& extension_id, | 481 const std::string& extension_id, |
428 const std::string& module_name, | 482 const std::string& module_name, |
429 const std::string& function_name, | 483 const std::string& function_name, |
430 const base::ListValue& args, | 484 const base::ListValue& args, |
431 bool user_gesture) { | 485 bool user_gesture) { |
432 scoped_ptr<WebScopedUserGesture> web_user_gesture; | 486 scoped_ptr<WebScopedUserGesture> web_user_gesture; |
433 if (user_gesture) | 487 if (user_gesture) |
434 web_user_gesture.reset(new WebScopedUserGesture); | 488 web_user_gesture.reset(new WebScopedUserGesture); |
435 | 489 |
436 script_context_set_->ForEach( | 490 script_context_set_.ForEach( |
437 extension_id, render_view, | 491 extension_id, |
| 492 render_view, |
438 base::Bind(&CallModuleMethod, module_name, function_name, &args)); | 493 base::Bind(&CallModuleMethod, module_name, function_name, &args)); |
439 | 494 |
440 // Reset the idle handler each time there's any activity like event or message | 495 // Reset the idle handler each time there's any activity like event or message |
441 // dispatch, for which Invoke is the chokepoint. | 496 // dispatch, for which Invoke is the chokepoint. |
442 if (set_idle_notifications_) { | 497 if (set_idle_notifications_) { |
443 RenderThread::Get()->ScheduleIdleHandler( | 498 RenderThread::Get()->ScheduleIdleHandler( |
444 kInitialExtensionIdleHandlerDelayMs); | 499 kInitialExtensionIdleHandlerDelayMs); |
445 } | 500 } |
446 | 501 |
447 // Tell the browser process when an event has been dispatched with a lazy | 502 // Tell the browser process when an event has been dispatched with a lazy |
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
832 | 887 |
833 void Dispatcher::OnDeliverMessage(int target_port_id, const Message& message) { | 888 void Dispatcher::OnDeliverMessage(int target_port_id, const Message& message) { |
834 scoped_ptr<RequestSender::ScopedTabID> scoped_tab_id; | 889 scoped_ptr<RequestSender::ScopedTabID> scoped_tab_id; |
835 std::map<int, int>::const_iterator it = | 890 std::map<int, int>::const_iterator it = |
836 port_to_tab_id_map_.find(target_port_id); | 891 port_to_tab_id_map_.find(target_port_id); |
837 if (it != port_to_tab_id_map_.end()) { | 892 if (it != port_to_tab_id_map_.end()) { |
838 scoped_tab_id.reset( | 893 scoped_tab_id.reset( |
839 new RequestSender::ScopedTabID(request_sender(), it->second)); | 894 new RequestSender::ScopedTabID(request_sender(), it->second)); |
840 } | 895 } |
841 | 896 |
842 MessagingBindings::DeliverMessage(*script_context_set_, target_port_id, | 897 MessagingBindings::DeliverMessage(script_context_set_, |
| 898 target_port_id, |
843 message, | 899 message, |
844 NULL); // All render frames. | 900 NULL); // All render frames. |
845 } | 901 } |
846 | 902 |
847 void Dispatcher::OnDispatchOnConnect( | 903 void Dispatcher::OnDispatchOnConnect( |
848 int target_port_id, | 904 int target_port_id, |
849 const std::string& channel_name, | 905 const std::string& channel_name, |
850 const ExtensionMsg_TabConnectionInfo& source, | 906 const ExtensionMsg_TabConnectionInfo& source, |
851 const ExtensionMsg_ExternalConnectionInfo& info, | 907 const ExtensionMsg_ExternalConnectionInfo& info, |
852 const std::string& tls_channel_id) { | 908 const std::string& tls_channel_id) { |
853 DCHECK(!ContainsKey(port_to_tab_id_map_, target_port_id)); | 909 DCHECK(!ContainsKey(port_to_tab_id_map_, target_port_id)); |
854 DCHECK_EQ(1, target_port_id % 2); // target renderer ports have odd IDs. | 910 DCHECK_EQ(1, target_port_id % 2); // target renderer ports have odd IDs. |
855 int sender_tab_id = -1; | 911 int sender_tab_id = -1; |
856 source.tab.GetInteger("id", &sender_tab_id); | 912 source.tab.GetInteger("id", &sender_tab_id); |
857 port_to_tab_id_map_[target_port_id] = sender_tab_id; | 913 port_to_tab_id_map_[target_port_id] = sender_tab_id; |
858 | 914 |
859 MessagingBindings::DispatchOnConnect(*script_context_set_, target_port_id, | 915 MessagingBindings::DispatchOnConnect(script_context_set_, |
860 channel_name, source, info, | 916 target_port_id, |
| 917 channel_name, |
| 918 source, |
| 919 info, |
861 tls_channel_id, | 920 tls_channel_id, |
862 NULL); // All render frames. | 921 NULL); // All render frames. |
863 } | 922 } |
864 | 923 |
865 void Dispatcher::OnDispatchOnDisconnect(int port_id, | 924 void Dispatcher::OnDispatchOnDisconnect(int port_id, |
866 const std::string& error_message) { | 925 const std::string& error_message) { |
867 MessagingBindings::DispatchOnDisconnect(*script_context_set_, port_id, | 926 MessagingBindings::DispatchOnDisconnect(script_context_set_, |
| 927 port_id, |
868 error_message, | 928 error_message, |
869 NULL); // All render frames. | 929 NULL); // All render frames. |
870 } | 930 } |
871 | 931 |
872 void Dispatcher::OnLoaded( | 932 void Dispatcher::OnLoaded( |
873 const std::vector<ExtensionMsg_Loaded_Params>& loaded_extensions) { | 933 const std::vector<ExtensionMsg_Loaded_Params>& loaded_extensions) { |
874 std::vector<ExtensionMsg_Loaded_Params>::const_iterator i; | 934 std::vector<ExtensionMsg_Loaded_Params>::const_iterator i; |
875 for (i = loaded_extensions.begin(); i != loaded_extensions.end(); ++i) { | 935 for (i = loaded_extensions.begin(); i != loaded_extensions.end(); ++i) { |
876 std::string error; | 936 std::string error; |
877 scoped_refptr<const Extension> extension = i->ConvertToExtension(&error); | 937 scoped_refptr<const Extension> extension = i->ConvertToExtension(&error); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
947 | 1007 |
948 script_injection_manager_->OnExtensionUnloaded(id); | 1008 script_injection_manager_->OnExtensionUnloaded(id); |
949 | 1009 |
950 // If the extension is later reloaded with a different set of permissions, | 1010 // If the extension is later reloaded with a different set of permissions, |
951 // we'd like it to get a new isolated world ID, so that it can pick up the | 1011 // we'd like it to get a new isolated world ID, so that it can pick up the |
952 // changed origin whitelist. | 1012 // changed origin whitelist. |
953 ScriptInjection::RemoveIsolatedWorld(id); | 1013 ScriptInjection::RemoveIsolatedWorld(id); |
954 | 1014 |
955 // Invalidate all of the contexts that were removed. | 1015 // Invalidate all of the contexts that were removed. |
956 // TODO(kalman): add an invalidation observer interface to ScriptContext. | 1016 // TODO(kalman): add an invalidation observer interface to ScriptContext. |
957 std::set<ScriptContext*> removed_contexts = | 1017 ScriptContextSet::ContextSet removed_contexts = |
958 script_context_set_->OnExtensionUnloaded(id); | 1018 script_context_set_.OnExtensionUnloaded(id); |
959 for (ScriptContext* context : removed_contexts) { | 1019 for (ScriptContextSet::ContextSet::iterator it = removed_contexts.begin(); |
960 request_sender_->InvalidateSource(context); | 1020 it != removed_contexts.end(); |
| 1021 ++it) { |
| 1022 request_sender_->InvalidateSource(*it); |
961 } | 1023 } |
962 | 1024 |
963 // Update the available bindings for the remaining contexts. These may have | 1025 // Update the available bindings for the remaining contexts. These may have |
964 // changed if an externally_connectable extension is unloaded and a webpage | 1026 // changed if an externally_connectable extension is unloaded and a webpage |
965 // is no longer accessible. | 1027 // is no longer accessible. |
966 UpdateBindings(""); | 1028 UpdateBindings(""); |
967 | 1029 |
968 // Invalidates the messages map for the extension in case the extension is | 1030 // Invalidates the messages map for the extension in case the extension is |
969 // reloaded with a new messages map. | 1031 // reloaded with a new messages map. |
970 EraseL10nMessagesMap(id); | 1032 EraseL10nMessagesMap(id); |
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1315 for (std::set<std::string>::iterator iter = active_extension_ids_.begin(); | 1377 for (std::set<std::string>::iterator iter = active_extension_ids_.begin(); |
1316 iter != active_extension_ids_.end(); | 1378 iter != active_extension_ids_.end(); |
1317 ++iter) { | 1379 ++iter) { |
1318 const Extension* extension = extensions_.GetByID(*iter); | 1380 const Extension* extension = extensions_.GetByID(*iter); |
1319 if (extension && extension->is_platform_app()) | 1381 if (extension && extension->is_platform_app()) |
1320 return true; | 1382 return true; |
1321 } | 1383 } |
1322 return false; | 1384 return false; |
1323 } | 1385 } |
1324 | 1386 |
| 1387 // TODO(kalman): This is checking for the wrong thing, it should be checking if |
| 1388 // the frame's security origin is unique. The extension sandbox directive is |
| 1389 // checked for in extensions/common/manifest_handlers/csp_info.cc. |
| 1390 bool Dispatcher::IsSandboxedPage(const GURL& url) const { |
| 1391 if (url.SchemeIs(kExtensionScheme)) { |
| 1392 const Extension* extension = extensions_.GetByID(url.host()); |
| 1393 if (extension) { |
| 1394 return SandboxedPageInfo::IsSandboxedPage(extension, url.path()); |
| 1395 } |
| 1396 } |
| 1397 return false; |
| 1398 } |
| 1399 |
| 1400 Feature::Context Dispatcher::ClassifyJavaScriptContext( |
| 1401 const Extension* extension, |
| 1402 int extension_group, |
| 1403 const GURL& url, |
| 1404 const blink::WebSecurityOrigin& origin) { |
| 1405 // WARNING: This logic must match ProcessMap::GetContextType, as much as |
| 1406 // possible. |
| 1407 |
| 1408 DCHECK_GE(extension_group, 0); |
| 1409 if (extension_group == EXTENSION_GROUP_CONTENT_SCRIPTS) { |
| 1410 return extension ? // TODO(kalman): when does this happen? |
| 1411 Feature::CONTENT_SCRIPT_CONTEXT |
| 1412 : Feature::UNSPECIFIED_CONTEXT; |
| 1413 } |
| 1414 |
| 1415 // We have an explicit check for sandboxed pages before checking whether the |
| 1416 // extension is active in this process because: |
| 1417 // 1. Sandboxed pages run in the same process as regular extension pages, so |
| 1418 // the extension is considered active. |
| 1419 // 2. ScriptContext creation (which triggers bindings injection) happens |
| 1420 // before the SecurityContext is updated with the sandbox flags (after |
| 1421 // reading the CSP header), so the caller can't check if the context's |
| 1422 // security origin is unique yet. |
| 1423 if (IsSandboxedPage(url)) |
| 1424 return Feature::WEB_PAGE_CONTEXT; |
| 1425 |
| 1426 if (extension && IsExtensionActive(extension->id())) { |
| 1427 // |extension| is active in this process, but it could be either a true |
| 1428 // extension process or within the extent of a hosted app. In the latter |
| 1429 // case this would usually be considered a (blessed) web page context, |
| 1430 // unless the extension in question is a component extension, in which case |
| 1431 // we cheat and call it blessed. |
| 1432 return (extension->is_hosted_app() && |
| 1433 extension->location() != Manifest::COMPONENT) |
| 1434 ? Feature::BLESSED_WEB_PAGE_CONTEXT |
| 1435 : Feature::BLESSED_EXTENSION_CONTEXT; |
| 1436 } |
| 1437 |
| 1438 // TODO(kalman): This isUnique() check is wrong, it should be performed as |
| 1439 // part of IsSandboxedPage(). |
| 1440 if (!origin.isUnique() && extensions_.ExtensionBindingsAllowed(url)) { |
| 1441 if (!extension) // TODO(kalman): when does this happen? |
| 1442 return Feature::UNSPECIFIED_CONTEXT; |
| 1443 return extension->is_hosted_app() ? Feature::BLESSED_WEB_PAGE_CONTEXT |
| 1444 : Feature::UNBLESSED_EXTENSION_CONTEXT; |
| 1445 } |
| 1446 |
| 1447 if (!url.is_valid()) |
| 1448 return Feature::UNSPECIFIED_CONTEXT; |
| 1449 |
| 1450 if (url.SchemeIs(content::kChromeUIScheme)) |
| 1451 return Feature::WEBUI_CONTEXT; |
| 1452 |
| 1453 return Feature::WEB_PAGE_CONTEXT; |
| 1454 } |
| 1455 |
1325 v8::Handle<v8::Object> Dispatcher::GetOrCreateObject( | 1456 v8::Handle<v8::Object> Dispatcher::GetOrCreateObject( |
1326 const v8::Handle<v8::Object>& object, | 1457 const v8::Handle<v8::Object>& object, |
1327 const std::string& field, | 1458 const std::string& field, |
1328 v8::Isolate* isolate) { | 1459 v8::Isolate* isolate) { |
1329 v8::Handle<v8::String> key = v8::String::NewFromUtf8(isolate, field.c_str()); | 1460 v8::Handle<v8::String> key = v8::String::NewFromUtf8(isolate, field.c_str()); |
1330 // If the object has a callback property, it is assumed it is an unavailable | 1461 // If the object has a callback property, it is assumed it is an unavailable |
1331 // API, so it is safe to delete. This is checked before GetOrCreateObject is | 1462 // API, so it is safe to delete. This is checked before GetOrCreateObject is |
1332 // called. | 1463 // called. |
1333 if (object->HasRealNamedCallbackProperty(key)) { | 1464 if (object->HasRealNamedCallbackProperty(key)) { |
1334 object->Delete(key); | 1465 object->Delete(key); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1431 // The "guestViewDeny" module must always be loaded last. It registers | 1562 // The "guestViewDeny" module must always be loaded last. It registers |
1432 // error-providing custom elements for the GuestView types that are not | 1563 // error-providing custom elements for the GuestView types that are not |
1433 // available, and thus all of those types must have been checked and loaded | 1564 // available, and thus all of those types must have been checked and loaded |
1434 // (or not loaded) beforehand. | 1565 // (or not loaded) beforehand. |
1435 if (context_type == Feature::BLESSED_EXTENSION_CONTEXT) { | 1566 if (context_type == Feature::BLESSED_EXTENSION_CONTEXT) { |
1436 module_system->Require("guestViewDeny"); | 1567 module_system->Require("guestViewDeny"); |
1437 } | 1568 } |
1438 } | 1569 } |
1439 | 1570 |
1440 } // namespace extensions | 1571 } // namespace extensions |
OLD | NEW |