Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(186)

Side by Side Diff: chrome/browser/extensions/event_router.cc

Issue 10694085: Refactor extension event distribution to use Values instead of JSON strings. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixing memory leak in a test. Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « chrome/browser/extensions/event_router.h ('k') | chrome/browser/extensions/event_router_forwarder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698