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/extension_event_router.h" | 5 #include "chrome/browser/extensions/extension_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 18 matching lines...) Expand all Loading... | |
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 using extensions::Extension; | 34 using extensions::Extension; |
35 using extensions::ExtensionAPI; | 35 using extensions::ExtensionAPI; |
36 | 36 |
37 namespace { | 37 namespace { |
38 | 38 |
39 const char kDispatchEvent[] = "Event.dispatchJSON"; | 39 const char kDispatchEvent[] = "Event.dispatch"; |
40 | 40 |
41 void NotifyEventListenerRemovedOnIOThread( | 41 void NotifyEventListenerRemovedOnIOThread( |
42 void* profile, | 42 void* profile, |
43 const std::string& extension_id, | 43 const std::string& extension_id, |
44 const std::string& sub_event_name) { | 44 const std::string& sub_event_name) { |
45 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( | 45 ExtensionWebRequestEventRouter::GetInstance()->RemoveEventListener( |
46 profile, extension_id, sub_event_name); | 46 profile, extension_id, sub_event_name); |
47 } | 47 } |
48 | 48 |
49 } // namespace | 49 } // namespace |
(...skipping 13 matching lines...) Expand all Loading... | |
63 return true; | 63 return true; |
64 return false; | 64 return false; |
65 } | 65 } |
66 }; | 66 }; |
67 | 67 |
68 // static | 68 // static |
69 void ExtensionEventRouter::DispatchEvent( | 69 void ExtensionEventRouter::DispatchEvent( |
70 IPC::Sender* ipc_sender, | 70 IPC::Sender* ipc_sender, |
71 const std::string& extension_id, | 71 const std::string& extension_id, |
72 const std::string& event_name, | 72 const std::string& event_name, |
73 const Value& event_args, | 73 ListValue* event_args, |
74 const GURL& event_url, | 74 const GURL& event_url, |
75 UserGestureState user_gesture, | 75 UserGestureState user_gesture, |
76 const extensions::EventFilteringInfo& info) { | 76 const extensions::EventFilteringInfo& info) { |
77 // TODO(gdk): Reduce number of DeepCopy() calls throughout the event dispatch | |
78 // chain, starting by replacing the event_args with a Value*. | |
79 ListValue args; | 77 ListValue args; |
80 args.Set(0, Value::CreateStringValue(event_name)); | 78 args.Set(0, Value::CreateStringValue(event_name)); |
81 args.Set(1, event_args.DeepCopy()); | 79 args.Set(1, event_args); |
82 args.Set(2, info.AsValue().release()); | 80 args.Set(2, info.AsValue().release()); |
83 | |
84 ipc_sender->Send(new ExtensionMsg_MessageInvoke(MSG_ROUTING_CONTROL, | 81 ipc_sender->Send(new ExtensionMsg_MessageInvoke(MSG_ROUTING_CONTROL, |
85 extension_id, kDispatchEvent, args, event_url, | 82 extension_id, kDispatchEvent, args, event_url, |
86 user_gesture == USER_GESTURE_ENABLED)); | 83 user_gesture == USER_GESTURE_ENABLED)); |
87 } | |
88 | 84 |
89 // static | 85 // The event_args for this dispatch are possibly going to be re-used by |
90 void ExtensionEventRouter::DispatchEvent( | 86 // dispatches to other listeners (to avoid copying them), therefore we need to |
91 IPC::Sender* ipc_sender, | 87 // ensure that args' destruction doesn't result in event_args' deletion. |
asargent_no_longer_on_chrome
2012/07/09 18:51:50
In the header documentation you specify that this
| |
92 const std::string& extension_id, | 88 Value* removed_event_args = NULL; |
93 const std::string& event_name, | 89 args.Remove(1, &removed_event_args); |
94 const std::string& event_args, | |
95 const GURL& event_url, | |
96 UserGestureState user_gesture, | |
97 const extensions::EventFilteringInfo& info) { | |
98 scoped_ptr<Value> event_args_value(Value::CreateStringValue(event_args)); | |
99 DispatchEvent(ipc_sender, extension_id, event_name, *event_args_value.get(), | |
100 event_url, user_gesture, info); | |
101 } | 90 } |
102 | 91 |
103 ExtensionEventRouter::ExtensionEventRouter(Profile* profile) | 92 ExtensionEventRouter::ExtensionEventRouter(Profile* profile) |
104 : profile_(profile), | 93 : profile_(profile), |
105 extension_devtools_manager_( | 94 extension_devtools_manager_( |
106 ExtensionSystem::Get(profile)->devtools_manager()), | 95 ExtensionSystem::Get(profile)->devtools_manager()), |
107 listeners_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | 96 listeners_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
108 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, | 97 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
109 content::NotificationService::AllSources()); | 98 content::NotificationService::AllSources()); |
110 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, | 99 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
281 for (std::set<ListenerProcess>::const_iterator listener = listeners.begin(); | 270 for (std::set<ListenerProcess>::const_iterator listener = listeners.begin(); |
282 listener != listeners.end(); ++listener) { | 271 listener != listeners.end(); ++listener) { |
283 if (listener->extension_id == extension_id) | 272 if (listener->extension_id == extension_id) |
284 return true; | 273 return true; |
285 } | 274 } |
286 return false; | 275 return false; |
287 } | 276 } |
288 | 277 |
289 void ExtensionEventRouter::DispatchEventToRenderers( | 278 void ExtensionEventRouter::DispatchEventToRenderers( |
290 const std::string& event_name, | 279 const std::string& event_name, |
291 const std::string& event_args, | 280 ListValue* event_args, |
292 Profile* restrict_to_profile, | 281 Profile* restrict_to_profile, |
293 const GURL& event_url, | 282 const GURL& event_url, |
294 extensions::EventFilteringInfo info) { | 283 extensions::EventFilteringInfo info) { |
295 DCHECK(!event_args.empty()); | |
296 StringValue event_args_value(event_args); | |
297 linked_ptr<ExtensionEvent> event( | 284 linked_ptr<ExtensionEvent> event( |
298 new ExtensionEvent(event_name, event_args_value, event_url, | 285 new ExtensionEvent(event_name, event_args, event_url, restrict_to_profile, |
299 restrict_to_profile, USER_GESTURE_UNKNOWN, info)); | 286 NULL, USER_GESTURE_UNKNOWN, |
287 info)); | |
300 DispatchEventImpl("", event); | 288 DispatchEventImpl("", event); |
301 } | 289 } |
302 | 290 |
303 void ExtensionEventRouter::DispatchEventToRenderers( | 291 void ExtensionEventRouter::DispatchEventToRenderers( |
304 const std::string& event_name, | 292 const std::string& event_name, |
305 const std::string& event_args, | 293 ListValue* event_args, |
306 Profile* restrict_to_profile, | 294 Profile* restrict_to_profile, |
307 const GURL& event_url) { | 295 const GURL& event_url) { |
308 DispatchEventToRenderers(event_name, event_args, restrict_to_profile, | 296 DispatchEventToRenderers(event_name, event_args, restrict_to_profile, |
309 event_url, extensions::EventFilteringInfo()); | 297 event_url, extensions::EventFilteringInfo()); |
310 } | 298 } |
311 | 299 |
312 void ExtensionEventRouter::DispatchEventToExtension( | 300 void ExtensionEventRouter::DispatchEventToExtension( |
313 const std::string& extension_id, | 301 const std::string& extension_id, |
314 const std::string& event_name, | 302 const std::string& event_name, |
315 const Value& event_args, | 303 ListValue* event_args, |
316 Profile* restrict_to_profile, | 304 Profile* restrict_to_profile, |
317 const GURL& event_url) { | 305 const GURL& event_url) { |
318 DCHECK(!extension_id.empty()); | 306 DCHECK(!extension_id.empty()); |
319 linked_ptr<ExtensionEvent> event( | 307 linked_ptr<ExtensionEvent> event( |
320 new ExtensionEvent(event_name, event_args, event_url, | 308 new ExtensionEvent(event_name, event_args, event_url, restrict_to_profile, |
321 restrict_to_profile, USER_GESTURE_UNKNOWN, | 309 NULL, USER_GESTURE_UNKNOWN, EventFilteringInfo())); |
322 EventFilteringInfo())); | |
323 DispatchEventImpl(extension_id, event); | 310 DispatchEventImpl(extension_id, event); |
324 } | 311 } |
325 | 312 |
326 void ExtensionEventRouter::DispatchEventToExtension( | 313 void ExtensionEventRouter::DispatchEventToExtension( |
327 const std::string& extension_id, | 314 const std::string& extension_id, |
328 const std::string& event_name, | 315 const std::string& event_name, |
329 const std::string& event_args, | 316 ListValue* event_args, |
330 Profile* restrict_to_profile, | |
331 const GURL& event_url) { | |
332 StringValue event_args_value(event_args); | |
333 DispatchEventToExtension(extension_id, event_name, event_args_value, | |
334 restrict_to_profile, event_url); | |
335 } | |
336 | |
337 void ExtensionEventRouter::DispatchEventToExtension( | |
338 const std::string& extension_id, | |
339 const std::string& event_name, | |
340 const std::string& event_args, | |
341 Profile* restrict_to_profile, | 317 Profile* restrict_to_profile, |
342 const GURL& event_url, | 318 const GURL& event_url, |
343 UserGestureState user_gesture) { | 319 UserGestureState user_gesture) { |
344 DCHECK(!extension_id.empty()); | 320 DCHECK(!extension_id.empty()); |
345 StringValue event_args_value(event_args); | |
346 linked_ptr<ExtensionEvent> event( | 321 linked_ptr<ExtensionEvent> event( |
347 new ExtensionEvent(event_name, event_args_value, event_url, | 322 new ExtensionEvent(event_name, event_args, event_url, restrict_to_profile, |
348 restrict_to_profile, user_gesture, | 323 NULL, user_gesture, EventFilteringInfo())); |
349 EventFilteringInfo())); | |
350 DispatchEventImpl(extension_id, event); | 324 DispatchEventImpl(extension_id, event); |
351 } | 325 } |
352 | 326 |
353 void ExtensionEventRouter::DispatchEventsToRenderersAcrossIncognito( | 327 void ExtensionEventRouter::DispatchEventsToRenderersAcrossIncognito( |
354 const std::string& event_name, | 328 const std::string& event_name, |
355 const std::string& event_args, | 329 ListValue* event_args, |
356 Profile* restrict_to_profile, | 330 Profile* restrict_to_profile, |
357 const std::string& cross_incognito_args, | 331 ListValue* cross_incognito_args, |
358 const GURL& event_url) { | 332 const GURL& event_url) { |
359 linked_ptr<ExtensionEvent> event( | 333 linked_ptr<ExtensionEvent> event( |
360 new ExtensionEvent(event_name, event_args, event_url, | 334 new ExtensionEvent(event_name, event_args, event_url, |
361 restrict_to_profile, cross_incognito_args, | 335 restrict_to_profile, cross_incognito_args, |
362 USER_GESTURE_UNKNOWN, EventFilteringInfo())); | 336 USER_GESTURE_UNKNOWN, EventFilteringInfo())); |
363 DispatchEventImpl("", event); | 337 DispatchEventImpl("", event); |
364 } | 338 } |
365 | 339 |
366 void ExtensionEventRouter::DispatchEventImpl( | 340 void ExtensionEventRouter::DispatchEventImpl( |
367 const std::string& restrict_to_extension_id, | 341 const std::string& restrict_to_extension_id, |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
420 process->GetBrowserContext()); | 394 process->GetBrowserContext()); |
421 extensions::ProcessMap* process_map = | 395 extensions::ProcessMap* process_map = |
422 listener_profile->GetExtensionService()->process_map(); | 396 listener_profile->GetExtensionService()->process_map(); |
423 // If the event is privileged, only send to extension processes. Otherwise, | 397 // If the event is privileged, only send to extension processes. Otherwise, |
424 // it's OK to send to normal renderers (e.g., for content scripts). | 398 // it's OK to send to normal renderers (e.g., for content scripts). |
425 if (ExtensionAPI::GetSharedInstance()->IsPrivileged(event->event_name) && | 399 if (ExtensionAPI::GetSharedInstance()->IsPrivileged(event->event_name) && |
426 !process_map->Contains(extension->id(), process->GetID())) { | 400 !process_map->Contains(extension->id(), process->GetID())) { |
427 return; | 401 return; |
428 } | 402 } |
429 | 403 |
430 const Value* event_args = NULL; | 404 ListValue* event_args = NULL; |
431 if (!CanDispatchEventToProfile(listener_profile, extension, | 405 if (!CanDispatchEventToProfile(listener_profile, extension, |
432 event, &event_args)) { | 406 event, &event_args)) { |
433 return; | 407 return; |
434 } | 408 } |
435 | 409 |
436 DispatchEvent(process, extension_id, | 410 DispatchEvent(process, extension_id, |
437 event->event_name, *event_args, | 411 event->event_name, event_args, |
438 event->event_url, event->user_gesture, | 412 event->event_url, event->user_gesture, |
439 event->info); | 413 event->info); |
440 IncrementInFlightEvents(listener_profile, extension); | 414 IncrementInFlightEvents(listener_profile, extension); |
441 } | 415 } |
442 | 416 |
443 bool ExtensionEventRouter::CanDispatchEventToProfile( | 417 bool ExtensionEventRouter::CanDispatchEventToProfile( |
444 Profile* profile, | 418 Profile* profile, |
445 const Extension* extension, | 419 const Extension* extension, |
446 const linked_ptr<ExtensionEvent>& event, | 420 const linked_ptr<ExtensionEvent>& event, |
447 const Value** event_args) { | 421 ListValue** event_args) { |
448 *event_args = event->event_args.get(); | 422 if (event_args) |
423 *event_args = event->event_args.get(); | |
449 | 424 |
450 // Is this event from a different profile than the renderer (ie, an | 425 // Is this event from a different profile than the renderer (ie, an |
451 // incognito tab event sent to a normal process, or vice versa). | 426 // incognito tab event sent to a normal process, or vice versa). |
452 bool cross_incognito = event->restrict_to_profile && | 427 bool cross_incognito = event->restrict_to_profile && |
453 profile != event->restrict_to_profile; | 428 profile != event->restrict_to_profile; |
454 if (cross_incognito && | 429 if (cross_incognito && |
455 !profile->GetExtensionService()->CanCrossIncognito(extension)) { | 430 !profile->GetExtensionService()->CanCrossIncognito(extension)) { |
456 if (!event->cross_incognito_args.get()) | 431 if (!event->cross_incognito_args.get()) |
457 return false; | 432 return false; |
458 // Send the event with different arguments to extensions that can't | 433 // Send the event with different arguments to extensions that can't |
459 // cross incognito. | 434 // cross incognito. |
460 *event_args = event->cross_incognito_args.get(); | 435 if (event_args) { |
436 *event_args = event->cross_incognito_args.get(); | |
437 } | |
461 } | 438 } |
462 | 439 |
463 return true; | 440 return true; |
464 } | 441 } |
465 | 442 |
466 void ExtensionEventRouter::MaybeLoadLazyBackgroundPageToDispatchEvent( | 443 void ExtensionEventRouter::MaybeLoadLazyBackgroundPageToDispatchEvent( |
467 Profile* profile, | 444 Profile* profile, |
468 const Extension* extension, | 445 const Extension* extension, |
469 const linked_ptr<ExtensionEvent>& event) { | 446 const linked_ptr<ExtensionEvent>& event) { |
470 const Value* event_args = NULL; | 447 if (!CanDispatchEventToProfile(profile, extension, event, NULL)) |
471 if (!CanDispatchEventToProfile(profile, extension, event, &event_args)) | |
472 return; | 448 return; |
473 | 449 |
474 extensions::LazyBackgroundTaskQueue* queue = | 450 extensions::LazyBackgroundTaskQueue* queue = |
475 ExtensionSystem::Get(profile)->lazy_background_task_queue(); | 451 ExtensionSystem::Get(profile)->lazy_background_task_queue(); |
476 if (queue->ShouldEnqueueTask(profile, extension)) { | 452 if (queue->ShouldEnqueueTask(profile, extension)) { |
477 queue->AddPendingTask( | 453 queue->AddPendingTask( |
478 profile, extension->id(), | 454 profile, extension->id(), |
479 base::Bind(&ExtensionEventRouter::DispatchPendingEvent, | 455 base::Bind(&ExtensionEventRouter::DispatchPendingEvent, |
480 base::Unretained(this), event)); | 456 base::Unretained(this), event)); |
481 } | 457 } |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
566 break; | 542 break; |
567 } | 543 } |
568 default: | 544 default: |
569 NOTREACHED(); | 545 NOTREACHED(); |
570 return; | 546 return; |
571 } | 547 } |
572 } | 548 } |
573 | 549 |
574 ExtensionEvent::ExtensionEvent( | 550 ExtensionEvent::ExtensionEvent( |
575 const std::string& event_name, | 551 const std::string& event_name, |
576 const Value& event_args, | 552 ListValue* event_args, |
577 const GURL& event_url, | 553 const GURL& event_url, |
578 Profile* restrict_to_profile, | 554 Profile* restrict_to_profile, |
579 const Value& cross_incognito_args, | 555 ListValue* cross_incognito_args, |
580 ExtensionEventRouter::UserGestureState user_gesture, | 556 ExtensionEventRouter::UserGestureState user_gesture, |
581 const extensions::EventFilteringInfo& info) | 557 const extensions::EventFilteringInfo& info) |
582 : event_name(event_name), | 558 : event_name(event_name), |
583 event_args(event_args.DeepCopy()), | 559 event_args(event_args), |
584 event_url(event_url), | 560 event_url(event_url), |
585 restrict_to_profile(restrict_to_profile), | 561 restrict_to_profile(restrict_to_profile), |
586 cross_incognito_args(cross_incognito_args.DeepCopy()), | 562 cross_incognito_args(cross_incognito_args), |
587 user_gesture(user_gesture), | 563 user_gesture(user_gesture), |
588 info(info) { | 564 info(info) { |
565 if (!event_args) | |
566 this->event_args.reset(new ListValue()); | |
589 } | 567 } |
590 | 568 |
591 ExtensionEvent::ExtensionEvent( | 569 ExtensionEvent::~ExtensionEvent() {} |
592 const std::string& event_name, | |
593 const std::string& event_args, | |
594 const GURL& event_url, | |
595 Profile* restrict_to_profile, | |
596 const std::string& cross_incognito_args, | |
597 ExtensionEventRouter::UserGestureState user_gesture, | |
598 const extensions::EventFilteringInfo& info) | |
599 : event_name(event_name), | |
600 event_args(Value::CreateStringValue(event_args)), | |
601 event_url(event_url), | |
602 restrict_to_profile(restrict_to_profile), | |
603 cross_incognito_args(Value::CreateStringValue(cross_incognito_args)), | |
604 user_gesture(user_gesture), | |
605 info(info) { | |
606 } | |
607 | |
608 ExtensionEvent::ExtensionEvent( | |
609 const std::string& event_name, | |
610 const Value& event_args, | |
611 const GURL& event_url, | |
612 Profile* restrict_to_profile, | |
613 ExtensionEventRouter::UserGestureState user_gesture, | |
614 const extensions::EventFilteringInfo& info) | |
615 : event_name(event_name), | |
616 event_args(event_args.DeepCopy()), | |
617 event_url(event_url), | |
618 restrict_to_profile(restrict_to_profile), | |
619 cross_incognito_args(NULL), | |
620 user_gesture(user_gesture), | |
621 info(info) { | |
622 } | |
623 | |
624 ExtensionEvent::~ExtensionEvent() { | |
625 } | |
OLD | NEW |