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

Side by Side Diff: chrome/browser/extensions/extension_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: Rebase and review changes. Created 8 years, 5 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/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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698