OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/event_router.h" | 5 #include "chrome/browser/extensions/event_router.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/values.h" | 10 #include "base/values.h" |
(...skipping 16 matching lines...) Expand all Loading... |
27 #include "chrome/common/extensions/api/extension_api.h" | 27 #include "chrome/common/extensions/api/extension_api.h" |
28 #include "chrome/common/view_type.h" | 28 #include "chrome/common/view_type.h" |
29 #include "content/public/browser/notification_service.h" | 29 #include "content/public/browser/notification_service.h" |
30 #include "content/public/browser/render_process_host.h" | 30 #include "content/public/browser/render_process_host.h" |
31 | 31 |
32 using base::Value; | 32 using base::Value; |
33 using content::BrowserThread; | 33 using content::BrowserThread; |
34 | 34 |
35 namespace { | 35 namespace { |
36 | 36 |
37 const char kDispatchEvent[] = "Event.dispatchJSON"; | 37 const char kDispatchEvent[] = "Event.dispatchEvent"; |
38 | 38 |
39 void NotifyEventListenerRemovedOnIOThread( | 39 void NotifyEventListenerRemovedOnIOThread( |
40 void* profile, | 40 void* profile, |
41 const std::string& extension_id, | 41 const std::string& extension_id, |
42 const std::string& sub_event_name) { | 42 const std::string& sub_event_name) { |
43 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( | 43 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( |
44 profile, extension_id, sub_event_name); | 44 profile, extension_id, sub_event_name); |
45 } | 45 } |
46 | 46 |
47 } // namespace | 47 } // namespace |
(...skipping 11 matching lines...) Expand all Loading... |
59 bool operator<(const ListenerProcess& that) const { | 59 bool operator<(const ListenerProcess& that) const { |
60 if (process < that.process) | 60 if (process < that.process) |
61 return true; | 61 return true; |
62 if (process == that.process && extension_id < that.extension_id) | 62 if (process == that.process && extension_id < that.extension_id) |
63 return true; | 63 return true; |
64 return false; | 64 return false; |
65 } | 65 } |
66 }; | 66 }; |
67 | 67 |
68 // static | 68 // static |
69 void EventRouter::DispatchEvent(IPC::Sender* ipc_sender, | 69 void EventRouter::DispatchExtensionMessage(IPC::Sender* ipc_sender, |
70 const std::string& extension_id, | 70 const std::string& extension_id, |
71 const std::string& event_name, | 71 const std::string& event_name, |
72 const Value& event_args, | 72 ListValue* event_args, |
73 const GURL& event_url, | 73 const GURL& event_url, |
74 UserGestureState user_gesture, | 74 UserGestureState user_gesture, |
75 const EventFilteringInfo& info) { | 75 const EventFilteringInfo& info) { |
76 // TODO(gdk): Reduce number of DeepCopy() calls throughout the event dispatch | |
77 // chain, starting by replacing the event_args with a Value*. | |
78 ListValue args; | 76 ListValue args; |
79 args.Set(0, Value::CreateStringValue(event_name)); | 77 args.Set(0, Value::CreateStringValue(event_name)); |
80 args.Set(1, event_args.DeepCopy()); | 78 args.Set(1, event_args); |
81 args.Set(2, info.AsValue().release()); | 79 args.Set(2, info.AsValue().release()); |
82 | |
83 ipc_sender->Send(new ExtensionMsg_MessageInvoke(MSG_ROUTING_CONTROL, | 80 ipc_sender->Send(new ExtensionMsg_MessageInvoke(MSG_ROUTING_CONTROL, |
84 extension_id, kDispatchEvent, args, event_url, | 81 extension_id, kDispatchEvent, args, event_url, |
85 user_gesture == USER_GESTURE_ENABLED)); | 82 user_gesture == USER_GESTURE_ENABLED)); |
| 83 |
| 84 // DispatchExtensionMessage does _not_ take ownership of event_args, so we |
| 85 // must ensure that the destruction of args does not attempt to free it. |
| 86 Value* removed_event_args = NULL; |
| 87 args.Remove(1, &removed_event_args); |
86 } | 88 } |
87 | 89 |
88 // static | 90 // static |
89 void EventRouter::DispatchEvent(IPC::Sender* ipc_sender, | 91 void EventRouter::DispatchEvent(IPC::Sender* ipc_sender, |
90 const std::string& extension_id, | 92 const std::string& extension_id, |
91 const std::string& event_name, | 93 const std::string& event_name, |
92 const std::string& event_args, | 94 scoped_ptr<ListValue> event_args, |
93 const GURL& event_url, | 95 const GURL& event_url, |
94 UserGestureState user_gesture, | 96 UserGestureState user_gesture, |
95 const EventFilteringInfo& info) { | 97 const EventFilteringInfo& info) { |
96 scoped_ptr<Value> event_args_value(Value::CreateStringValue(event_args)); | 98 DispatchExtensionMessage(ipc_sender, extension_id, event_name, |
97 DispatchEvent(ipc_sender, extension_id, event_name, *event_args_value.get(), | 99 event_args.get(), event_url, user_gesture, info); |
98 event_url, user_gesture, info); | |
99 } | 100 } |
100 | 101 |
101 EventRouter::EventRouter(Profile* profile) | 102 EventRouter::EventRouter(Profile* profile) |
102 : profile_(profile), | 103 : profile_(profile), |
103 extension_devtools_manager_( | 104 extension_devtools_manager_( |
104 ExtensionSystem::Get(profile)->devtools_manager()), | 105 ExtensionSystem::Get(profile)->devtools_manager()), |
105 listeners_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | 106 listeners_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
106 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, | 107 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
107 content::NotificationService::AllSources()); | 108 content::NotificationService::AllSources()); |
108 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, | 109 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 | 274 |
274 for (std::set<ListenerProcess>::const_iterator listener = listeners.begin(); | 275 for (std::set<ListenerProcess>::const_iterator listener = listeners.begin(); |
275 listener != listeners.end(); ++listener) { | 276 listener != listeners.end(); ++listener) { |
276 if (listener->extension_id == extension_id) | 277 if (listener->extension_id == extension_id) |
277 return true; | 278 return true; |
278 } | 279 } |
279 return false; | 280 return false; |
280 } | 281 } |
281 | 282 |
282 void EventRouter::DispatchEventToRenderers(const std::string& event_name, | 283 void EventRouter::DispatchEventToRenderers(const std::string& event_name, |
283 const std::string& event_args, | 284 scoped_ptr<ListValue> event_args, |
284 Profile* restrict_to_profile, | 285 Profile* restrict_to_profile, |
285 const GURL& event_url, | 286 const GURL& event_url, |
286 EventFilteringInfo info) { | 287 EventFilteringInfo info) { |
287 DCHECK(!event_args.empty()); | 288 linked_ptr<Event> event(new Event(event_name, event_args.Pass(), |
288 StringValue event_args_value(event_args); | |
289 linked_ptr<Event> event(new Event(event_name, event_args_value, | |
290 event_url, restrict_to_profile, | 289 event_url, restrict_to_profile, |
291 USER_GESTURE_UNKNOWN, info)); | 290 USER_GESTURE_UNKNOWN, info)); |
292 DispatchEventImpl("", event); | 291 DispatchEventImpl("", event); |
293 } | 292 } |
294 | 293 |
295 void EventRouter::DispatchEventToRenderers(const std::string& event_name, | 294 void EventRouter::DispatchEventToRenderers(const std::string& event_name, |
296 const std::string& event_args, | 295 scoped_ptr<ListValue> event_args, |
297 Profile* restrict_to_profile, | 296 Profile* restrict_to_profile, |
298 const GURL& event_url) { | 297 const GURL& event_url) { |
299 DispatchEventToRenderers(event_name, event_args, restrict_to_profile, | 298 DispatchEventToRenderers(event_name, event_args.Pass(), restrict_to_profile, |
300 event_url, EventFilteringInfo()); | 299 event_url, EventFilteringInfo()); |
301 } | 300 } |
302 | 301 |
303 void EventRouter::DispatchEventToRenderers(const std::string& event_name, | 302 void EventRouter::DispatchEventToRenderers(const std::string& event_name, |
304 const std::string& event_args, | 303 scoped_ptr<ListValue> event_args, |
305 Profile* restrict_to_profile, | 304 Profile* restrict_to_profile, |
306 const GURL& event_url, | 305 const GURL& event_url, |
307 UserGestureState user_gesture) { | 306 UserGestureState user_gesture) { |
308 DCHECK(!event_args.empty()); | |
309 StringValue event_args_value(event_args); | |
310 EventFilteringInfo info; | 307 EventFilteringInfo info; |
311 linked_ptr<Event> event(new Event(event_name, event_args_value, | 308 linked_ptr<Event> event(new Event(event_name, event_args.Pass(), |
312 event_url, restrict_to_profile, | 309 event_url, restrict_to_profile, |
313 user_gesture, info)); | 310 user_gesture, info)); |
314 DispatchEventImpl("", event); | 311 DispatchEventImpl("", event); |
315 } | 312 } |
316 | 313 |
317 void EventRouter::DispatchEventToExtension(const std::string& extension_id, | 314 void EventRouter::DispatchEventToExtension(const std::string& extension_id, |
318 const std::string& event_name, | 315 const std::string& event_name, |
319 const Value& event_args, | 316 scoped_ptr<ListValue> event_args, |
320 Profile* restrict_to_profile, | 317 Profile* restrict_to_profile, |
321 const GURL& event_url) { | 318 const GURL& event_url) { |
322 DCHECK(!extension_id.empty()); | 319 DCHECK(!extension_id.empty()); |
323 linked_ptr<Event> event(new Event(event_name, event_args, event_url, | 320 linked_ptr<Event> event(new Event(event_name, event_args.Pass(), event_url, |
324 restrict_to_profile, USER_GESTURE_UNKNOWN, | 321 restrict_to_profile, USER_GESTURE_UNKNOWN, |
325 EventFilteringInfo())); | 322 EventFilteringInfo())); |
326 DispatchEventImpl(extension_id, event); | 323 DispatchEventImpl(extension_id, event); |
327 } | 324 } |
328 | 325 |
329 void EventRouter::DispatchEventToExtension(const std::string& extension_id, | 326 void EventRouter::DispatchEventToExtension(const std::string& extension_id, |
330 const std::string& event_name, | 327 const std::string& event_name, |
331 const std::string& event_args, | 328 scoped_ptr<ListValue> event_args, |
332 Profile* restrict_to_profile, | |
333 const GURL& event_url) { | |
334 StringValue event_args_value(event_args); | |
335 DispatchEventToExtension(extension_id, event_name, event_args_value, | |
336 restrict_to_profile, event_url); | |
337 } | |
338 | |
339 void EventRouter::DispatchEventToExtension(const std::string& extension_id, | |
340 const std::string& event_name, | |
341 const std::string& event_args, | |
342 Profile* restrict_to_profile, | 329 Profile* restrict_to_profile, |
343 const GURL& event_url, | 330 const GURL& event_url, |
344 UserGestureState user_gesture) { | 331 UserGestureState user_gesture) { |
345 DCHECK(!extension_id.empty()); | 332 DCHECK(!extension_id.empty()); |
346 StringValue event_args_value(event_args); | 333 linked_ptr<Event> event(new Event(event_name, event_args.Pass(), event_url, |
347 linked_ptr<Event> event(new Event(event_name, event_args_value, event_url, | |
348 restrict_to_profile, user_gesture, | 334 restrict_to_profile, user_gesture, |
349 EventFilteringInfo())); | 335 EventFilteringInfo())); |
350 DispatchEventImpl(extension_id, event); | 336 DispatchEventImpl(extension_id, event); |
351 } | 337 } |
352 | 338 |
353 void EventRouter::DispatchEventsToRenderersAcrossIncognito( | 339 void EventRouter::DispatchEventsToRenderersAcrossIncognito( |
354 const std::string& event_name, | 340 const std::string& event_name, |
355 const std::string& event_args, | 341 scoped_ptr<ListValue> event_args, |
356 Profile* restrict_to_profile, | 342 Profile* restrict_to_profile, |
357 const std::string& cross_incognito_args, | 343 scoped_ptr<ListValue> cross_incognito_args, |
358 const GURL& event_url) { | 344 const GURL& event_url) { |
359 linked_ptr<Event> event(new Event(event_name, event_args, | 345 linked_ptr<Event> event(new Event(event_name, event_args.Pass(), event_url, |
360 event_url, restrict_to_profile, | 346 restrict_to_profile, |
361 cross_incognito_args, USER_GESTURE_UNKNOWN, | 347 cross_incognito_args.Pass(), |
| 348 USER_GESTURE_UNKNOWN, |
362 EventFilteringInfo())); | 349 EventFilteringInfo())); |
363 DispatchEventImpl("", event); | 350 DispatchEventImpl("", event); |
364 } | 351 } |
365 | 352 |
366 void EventRouter::DispatchEventImpl(const std::string& restrict_to_extension_id, | 353 void EventRouter::DispatchEventImpl(const std::string& restrict_to_extension_id, |
367 const linked_ptr<Event>& event) { | 354 const linked_ptr<Event>& event) { |
368 // We don't expect to get events from a completely different profile. | 355 // We don't expect to get events from a completely different profile. |
369 DCHECK(!event->restrict_to_profile || | 356 DCHECK(!event->restrict_to_profile || |
370 profile_->IsSameProfile(event->restrict_to_profile)); | 357 profile_->IsSameProfile(event->restrict_to_profile)); |
371 | 358 |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
433 process->GetBrowserContext()); | 420 process->GetBrowserContext()); |
434 ProcessMap* process_map = | 421 ProcessMap* process_map = |
435 listener_profile->GetExtensionService()->process_map(); | 422 listener_profile->GetExtensionService()->process_map(); |
436 // If the event is privileged, only send to extension processes. Otherwise, | 423 // If the event is privileged, only send to extension processes. Otherwise, |
437 // it's OK to send to normal renderers (e.g., for content scripts). | 424 // it's OK to send to normal renderers (e.g., for content scripts). |
438 if (ExtensionAPI::GetSharedInstance()->IsPrivileged(event->event_name) && | 425 if (ExtensionAPI::GetSharedInstance()->IsPrivileged(event->event_name) && |
439 !process_map->Contains(extension->id(), process->GetID())) { | 426 !process_map->Contains(extension->id(), process->GetID())) { |
440 return; | 427 return; |
441 } | 428 } |
442 | 429 |
443 const Value* event_args = NULL; | 430 ListValue* event_args = NULL; |
444 if (!CanDispatchEventToProfile(listener_profile, extension, | 431 if (!CanDispatchEventToProfile(listener_profile, extension, |
445 event, &event_args)) { | 432 event, &event_args)) { |
446 return; | 433 return; |
447 } | 434 } |
448 | 435 |
449 DispatchEvent(process, extension_id, | 436 DispatchExtensionMessage(process, extension_id, |
450 event->event_name, *event_args, | 437 event->event_name, event_args, |
451 event->event_url, event->user_gesture, | 438 event->event_url, event->user_gesture, |
452 event->info); | 439 event->info); |
453 IncrementInFlightEvents(listener_profile, extension); | 440 IncrementInFlightEvents(listener_profile, extension); |
454 } | 441 } |
455 | 442 |
456 bool EventRouter::CanDispatchEventToProfile(Profile* profile, | 443 bool EventRouter::CanDispatchEventToProfile(Profile* profile, |
457 const Extension* extension, | 444 const Extension* extension, |
458 const linked_ptr<Event>& event, | 445 const linked_ptr<Event>& event, |
459 const Value** event_args) { | 446 ListValue** event_args) { |
460 *event_args = event->event_args.get(); | 447 if (event_args) |
| 448 *event_args = event->event_args.get(); |
461 | 449 |
462 // Is this event from a different profile than the renderer (ie, an | 450 // Is this event from a different profile than the renderer (ie, an |
463 // incognito tab event sent to a normal process, or vice versa). | 451 // incognito tab event sent to a normal process, or vice versa). |
464 bool cross_incognito = | 452 bool cross_incognito = |
465 event->restrict_to_profile && profile != event->restrict_to_profile; | 453 event->restrict_to_profile && profile != event->restrict_to_profile; |
466 if (cross_incognito && | 454 if (cross_incognito && |
467 !profile->GetExtensionService()->CanCrossIncognito(extension)) { | 455 !profile->GetExtensionService()->CanCrossIncognito(extension)) { |
468 if (!event->cross_incognito_args.get()) | 456 if (!event->cross_incognito_args.get()) |
469 return false; | 457 return false; |
470 // Send the event with different arguments to extensions that can't | 458 // Send the event with different arguments to extensions that can't |
471 // cross incognito. | 459 // cross incognito. |
472 *event_args = event->cross_incognito_args.get(); | 460 if (event_args) |
| 461 *event_args = event->cross_incognito_args.get(); |
473 } | 462 } |
474 | 463 |
475 return true; | 464 return true; |
476 } | 465 } |
477 | 466 |
478 void EventRouter::MaybeLoadLazyBackgroundPageToDispatchEvent( | 467 void EventRouter::MaybeLoadLazyBackgroundPageToDispatchEvent( |
479 Profile* profile, | 468 Profile* profile, |
480 const Extension* extension, | 469 const Extension* extension, |
481 const linked_ptr<Event>& event) { | 470 const linked_ptr<Event>& event) { |
482 const Value* event_args = NULL; | 471 if (!CanDispatchEventToProfile(profile, extension, event, NULL)) |
483 if (!CanDispatchEventToProfile(profile, extension, event, &event_args)) | |
484 return; | 472 return; |
485 | 473 |
486 LazyBackgroundTaskQueue* queue = | 474 LazyBackgroundTaskQueue* queue = |
487 ExtensionSystem::Get(profile)->lazy_background_task_queue(); | 475 ExtensionSystem::Get(profile)->lazy_background_task_queue(); |
488 if (queue->ShouldEnqueueTask(profile, extension)) { | 476 if (queue->ShouldEnqueueTask(profile, extension)) { |
489 queue->AddPendingTask(profile, extension->id(), | 477 queue->AddPendingTask(profile, extension->id(), |
490 base::Bind(&EventRouter::DispatchPendingEvent, | 478 base::Bind(&EventRouter::DispatchPendingEvent, |
491 base::Unretained(this), event)); | 479 base::Unretained(this), event)); |
492 } | 480 } |
493 } | 481 } |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
574 profile_, extension->id())); | 562 profile_, extension->id())); |
575 break; | 563 break; |
576 } | 564 } |
577 default: | 565 default: |
578 NOTREACHED(); | 566 NOTREACHED(); |
579 return; | 567 return; |
580 } | 568 } |
581 } | 569 } |
582 | 570 |
583 Event::Event(const std::string& event_name, | 571 Event::Event(const std::string& event_name, |
584 const Value& event_args, | 572 scoped_ptr<ListValue> event_args, |
585 const GURL& event_url, | 573 const GURL& event_url, |
586 Profile* restrict_to_profile, | 574 Profile* restrict_to_profile, |
587 const Value& cross_incognito_args, | 575 scoped_ptr<ListValue> cross_incognito_args, |
588 EventRouter::UserGestureState user_gesture, | 576 EventRouter::UserGestureState user_gesture, |
589 const EventFilteringInfo& info) | 577 const EventFilteringInfo& info) |
590 : event_name(event_name), | 578 : event_name(event_name), |
591 event_args(event_args.DeepCopy()), | 579 event_args(event_args.Pass()), |
592 event_url(event_url), | 580 event_url(event_url), |
593 restrict_to_profile(restrict_to_profile), | 581 restrict_to_profile(restrict_to_profile), |
594 cross_incognito_args(cross_incognito_args.DeepCopy()), | 582 cross_incognito_args(cross_incognito_args.Pass()), |
595 user_gesture(user_gesture), | 583 user_gesture(user_gesture), |
596 info(info) { | 584 info(info) {} |
597 } | |
598 | 585 |
599 Event::Event(const std::string& event_name, | 586 Event::Event(const std::string& event_name, |
600 const std::string& event_args, | 587 scoped_ptr<ListValue> event_args, |
601 const GURL& event_url, | |
602 Profile* restrict_to_profile, | |
603 const std::string& cross_incognito_args, | |
604 EventRouter::UserGestureState user_gesture, | |
605 const EventFilteringInfo& info) | |
606 : event_name(event_name), | |
607 event_args(Value::CreateStringValue(event_args)), | |
608 event_url(event_url), | |
609 restrict_to_profile(restrict_to_profile), | |
610 cross_incognito_args(Value::CreateStringValue(cross_incognito_args)), | |
611 user_gesture(user_gesture), | |
612 info(info) { | |
613 } | |
614 | |
615 Event::Event(const std::string& event_name, | |
616 const Value& event_args, | |
617 const GURL& event_url, | 588 const GURL& event_url, |
618 Profile* restrict_to_profile, | 589 Profile* restrict_to_profile, |
619 EventRouter::UserGestureState user_gesture, | 590 EventRouter::UserGestureState user_gesture, |
620 const EventFilteringInfo& info) | 591 const EventFilteringInfo& info) |
621 : event_name(event_name), | 592 : event_name(event_name), |
622 event_args(event_args.DeepCopy()), | 593 event_args(event_args.Pass()), |
623 event_url(event_url), | 594 event_url(event_url), |
624 restrict_to_profile(restrict_to_profile), | 595 restrict_to_profile(restrict_to_profile), |
625 cross_incognito_args(NULL), | 596 cross_incognito_args(NULL), |
626 user_gesture(user_gesture), | 597 user_gesture(user_gesture), |
627 info(info) { | 598 info(info) {} |
628 } | |
629 | 599 |
630 Event::~Event() { | 600 Event::~Event() {} |
631 } | |
632 | 601 |
633 } // namespace extensions | 602 } // namespace extensions |
OLD | NEW |