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 10 matching lines...) Expand all Loading... | |
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 struct ExtensionEventRouter::ExtensionEvent { | 68 struct ExtensionEventRouter::ExtensionEvent { |
69 std::string event_name; | 69 std::string event_name; |
70 scoped_ptr<Value> event_args; | 70 ListValue* event_args; |
71 GURL event_url; | 71 GURL event_url; |
72 Profile* restrict_to_profile; | 72 Profile* restrict_to_profile; |
73 scoped_ptr<Value> cross_incognito_args; | 73 ListValue* cross_incognito_args; |
74 UserGestureState user_gesture; | 74 UserGestureState user_gesture; |
75 | 75 |
76 ExtensionEvent(const std::string& event_name, | 76 ExtensionEvent(const std::string& event_name, |
77 const Value& event_args, | 77 ListValue* event_args, |
78 const GURL& event_url, | 78 const GURL& event_url, |
79 Profile* restrict_to_profile, | 79 Profile* restrict_to_profile, |
80 const Value& cross_incognito_args, | 80 ListValue* cross_incognito_args, |
81 UserGestureState user_gesture) | 81 UserGestureState user_gesture) |
82 : event_name(event_name), | 82 : event_name(event_name), |
83 event_args(event_args.DeepCopy()), | 83 event_args(event_args), |
84 event_url(event_url), | 84 event_url(event_url), |
85 restrict_to_profile(restrict_to_profile), | 85 restrict_to_profile(restrict_to_profile), |
86 cross_incognito_args(cross_incognito_args.DeepCopy()), | 86 cross_incognito_args(cross_incognito_args), |
87 user_gesture(user_gesture) {} | |
88 | |
89 ExtensionEvent(const std::string& event_name, | |
90 const Value& event_args, | |
91 const GURL& event_url, | |
92 Profile* restrict_to_profile, | |
93 UserGestureState user_gesture) | |
94 : event_name(event_name), | |
95 event_args(event_args.DeepCopy()), | |
96 event_url(event_url), | |
97 restrict_to_profile(restrict_to_profile), | |
98 cross_incognito_args(NULL), | |
99 user_gesture(user_gesture) {} | |
100 | |
101 // TODO(gdk): This variant should be retired once the callers are switched to | |
102 // providing Values instead of just strings. | |
103 ExtensionEvent(const std::string& event_name, | |
104 const std::string& event_args, | |
105 const GURL& event_url, | |
106 Profile* restrict_to_profile, | |
107 const std::string& cross_incognito_args, | |
108 UserGestureState user_gesture) | |
109 : event_name(event_name), | |
110 event_args(Value::CreateStringValue(event_args)), | |
111 event_url(event_url), | |
112 restrict_to_profile(restrict_to_profile), | |
113 cross_incognito_args(Value::CreateStringValue(cross_incognito_args)), | |
114 user_gesture(user_gesture) {} | 87 user_gesture(user_gesture) {} |
115 }; | 88 }; |
116 | 89 |
117 // static | 90 // static |
118 void ExtensionEventRouter::DispatchEvent(IPC::Sender* ipc_sender, | 91 void ExtensionEventRouter::DispatchEvent(IPC::Sender* ipc_sender, |
119 const std::string& extension_id, | 92 const std::string& extension_id, |
120 const std::string& event_name, | 93 const std::string& event_name, |
121 const Value& event_args, | 94 ListValue* event_args, |
122 const GURL& event_url, | 95 const GURL& event_url, |
123 UserGestureState user_gesture) { | 96 UserGestureState user_gesture) { |
124 // TODO(gdk): Reduce number of DeepCopy() calls throughout the event dispatch | 97 // TODO(gdk): Reduce number of DeepCopy() calls throughout the event dispatch |
bryeung
2012/07/09 15:12:08
should this get removed now?
Garret Kelly
2012/07/09 15:32:29
Done.
| |
125 // chain, starting by replacing the event_args with a Value*. | 98 // chain, starting by replacing the event_args with a Value*. |
126 ListValue args; | 99 ListValue args; |
127 args.Set(0, Value::CreateStringValue(event_name)); | 100 args.Set(0, Value::CreateStringValue(event_name)); |
128 args.Set(1, event_args.DeepCopy()); | 101 args.Set(1, event_args); |
129 ipc_sender->Send(new ExtensionMsg_MessageInvoke(MSG_ROUTING_CONTROL, | 102 ipc_sender->Send(new ExtensionMsg_MessageInvoke(MSG_ROUTING_CONTROL, |
130 extension_id, kDispatchEvent, args, event_url, | 103 extension_id, kDispatchEvent, args, event_url, |
131 user_gesture == USER_GESTURE_ENABLED)); | 104 user_gesture == USER_GESTURE_ENABLED)); |
132 } | 105 } |
133 | 106 |
134 // static | |
135 void ExtensionEventRouter::DispatchEvent(IPC::Sender* ipc_sender, | |
136 const std::string& extension_id, | |
137 const std::string& event_name, | |
138 const std::string& event_args, | |
139 const GURL& event_url, | |
140 UserGestureState user_gesture) { | |
141 scoped_ptr<Value> event_args_value(Value::CreateStringValue(event_args)); | |
142 DispatchEvent(ipc_sender, extension_id, event_name, *event_args_value.get(), | |
143 event_url, user_gesture); | |
144 } | |
145 | |
146 ExtensionEventRouter::ExtensionEventRouter(Profile* profile) | 107 ExtensionEventRouter::ExtensionEventRouter(Profile* profile) |
147 : profile_(profile), | 108 : profile_(profile), |
148 extension_devtools_manager_( | 109 extension_devtools_manager_( |
149 ExtensionSystem::Get(profile)->devtools_manager()) { | 110 ExtensionSystem::Get(profile)->devtools_manager()) { |
150 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, | 111 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
151 content::NotificationService::AllSources()); | 112 content::NotificationService::AllSources()); |
152 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, | 113 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, |
153 content::NotificationService::AllSources()); | 114 content::NotificationService::AllSources()); |
154 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, | 115 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED, |
155 content::Source<Profile>(profile_)); | 116 content::Source<Profile>(profile_)); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
266 for (std::set<ListenerProcess>::const_iterator listener = listeners.begin(); | 227 for (std::set<ListenerProcess>::const_iterator listener = listeners.begin(); |
267 listener != listeners.end(); ++listener) { | 228 listener != listeners.end(); ++listener) { |
268 if (listener->extension_id == extension_id) | 229 if (listener->extension_id == extension_id) |
269 return true; | 230 return true; |
270 } | 231 } |
271 return false; | 232 return false; |
272 } | 233 } |
273 | 234 |
274 void ExtensionEventRouter::DispatchEventToRenderers( | 235 void ExtensionEventRouter::DispatchEventToRenderers( |
275 const std::string& event_name, | 236 const std::string& event_name, |
276 const std::string& event_args, | 237 ListValue* event_args, |
277 Profile* restrict_to_profile, | 238 Profile* restrict_to_profile, |
278 const GURL& event_url) { | 239 const GURL& event_url) { |
279 linked_ptr<ExtensionEvent> event( | 240 linked_ptr<ExtensionEvent> event( |
280 new ExtensionEvent(event_name, event_args, event_url, | 241 new ExtensionEvent(event_name, event_args, event_url, restrict_to_profile, |
281 restrict_to_profile, "", USER_GESTURE_UNKNOWN)); | 242 NULL, USER_GESTURE_UNKNOWN)); |
282 DispatchEventImpl("", event); | 243 DispatchEventImpl("", event); |
283 } | 244 } |
284 | 245 |
285 void ExtensionEventRouter::DispatchEventToExtension( | 246 void ExtensionEventRouter::DispatchEventToExtension( |
286 const std::string& extension_id, | 247 const std::string& extension_id, |
287 const std::string& event_name, | 248 const std::string& event_name, |
288 const Value& event_args, | 249 ListValue* event_args, |
289 Profile* restrict_to_profile, | 250 Profile* restrict_to_profile, |
290 const GURL& event_url) { | 251 const GURL& event_url) { |
291 DCHECK(!extension_id.empty()); | 252 DCHECK(!extension_id.empty()); |
292 linked_ptr<ExtensionEvent> event( | 253 linked_ptr<ExtensionEvent> event( |
293 new ExtensionEvent(event_name, event_args, event_url, | 254 new ExtensionEvent(event_name, event_args, event_url, restrict_to_profile, |
294 restrict_to_profile, USER_GESTURE_UNKNOWN)); | 255 NULL, USER_GESTURE_UNKNOWN)); |
295 DispatchEventImpl(extension_id, event); | 256 DispatchEventImpl(extension_id, event); |
296 } | 257 } |
297 | 258 |
298 void ExtensionEventRouter::DispatchEventToExtension( | 259 void ExtensionEventRouter::DispatchEventToExtension( |
299 const std::string& extension_id, | 260 const std::string& extension_id, |
300 const std::string& event_name, | 261 const std::string& event_name, |
301 const std::string& event_args, | 262 ListValue* event_args, |
302 Profile* restrict_to_profile, | |
303 const GURL& event_url) { | |
304 scoped_ptr<Value> event_args_value(Value::CreateStringValue(event_args)); | |
305 DispatchEventToExtension(extension_id, event_name, *event_args_value.get(), | |
306 restrict_to_profile, event_url); | |
307 } | |
308 | |
309 void ExtensionEventRouter::DispatchEventToExtension( | |
310 const std::string& extension_id, | |
311 const std::string& event_name, | |
312 const std::string& event_args, | |
313 Profile* restrict_to_profile, | 263 Profile* restrict_to_profile, |
314 const GURL& event_url, | 264 const GURL& event_url, |
315 UserGestureState user_gesture) { | 265 UserGestureState user_gesture) { |
316 DCHECK(!extension_id.empty()); | 266 DCHECK(!extension_id.empty()); |
317 linked_ptr<ExtensionEvent> event( | 267 linked_ptr<ExtensionEvent> event( |
318 new ExtensionEvent(event_name, event_args, event_url, | 268 new ExtensionEvent(event_name, event_args, event_url, restrict_to_profile, |
319 restrict_to_profile, "", user_gesture)); | 269 NULL, user_gesture)); |
320 DispatchEventImpl(extension_id, event); | 270 DispatchEventImpl(extension_id, event); |
321 } | 271 } |
322 | 272 |
323 void ExtensionEventRouter::DispatchEventsToRenderersAcrossIncognito( | 273 void ExtensionEventRouter::DispatchEventsToRenderersAcrossIncognito( |
324 const std::string& event_name, | 274 const std::string& event_name, |
325 const std::string& event_args, | 275 ListValue* event_args, |
326 Profile* restrict_to_profile, | 276 Profile* restrict_to_profile, |
327 const std::string& cross_incognito_args, | 277 ListValue* cross_incognito_args, |
328 const GURL& event_url) { | 278 const GURL& event_url) { |
329 linked_ptr<ExtensionEvent> event( | 279 linked_ptr<ExtensionEvent> event( |
330 new ExtensionEvent(event_name, event_args, event_url, | 280 new ExtensionEvent(event_name, event_args, event_url, |
331 restrict_to_profile, cross_incognito_args, | 281 restrict_to_profile, cross_incognito_args, |
332 USER_GESTURE_UNKNOWN)); | 282 USER_GESTURE_UNKNOWN)); |
333 DispatchEventImpl("", event); | 283 DispatchEventImpl("", event); |
334 } | 284 } |
335 | 285 |
336 void ExtensionEventRouter::DispatchEventImpl( | 286 void ExtensionEventRouter::DispatchEventImpl( |
337 const std::string& extension_id, | 287 const std::string& extension_id, |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
372 listener.process->GetBrowserContext()); | 322 listener.process->GetBrowserContext()); |
373 extensions::ProcessMap* process_map = | 323 extensions::ProcessMap* process_map = |
374 listener_profile->GetExtensionService()->process_map(); | 324 listener_profile->GetExtensionService()->process_map(); |
375 // If the event is privileged, only send to extension processes. Otherwise, | 325 // If the event is privileged, only send to extension processes. Otherwise, |
376 // it's OK to send to normal renderers (e.g., for content scripts). | 326 // it's OK to send to normal renderers (e.g., for content scripts). |
377 if (ExtensionAPI::GetSharedInstance()->IsPrivileged(event->event_name) && | 327 if (ExtensionAPI::GetSharedInstance()->IsPrivileged(event->event_name) && |
378 !process_map->Contains(extension->id(), listener.process->GetID())) { | 328 !process_map->Contains(extension->id(), listener.process->GetID())) { |
379 return; | 329 return; |
380 } | 330 } |
381 | 331 |
382 const Value* event_args = NULL; | 332 ListValue* event_args = NULL; |
383 if (!CanDispatchEventToProfile(listener_profile, extension, | 333 if (!CanDispatchEventToProfile(listener_profile, extension, |
384 event, &event_args)) { | 334 event, &event_args)) { |
385 return; | 335 return; |
386 } | 336 } |
387 | 337 |
388 DispatchEvent(listener.process, listener.extension_id, | 338 DispatchEvent(listener.process, listener.extension_id, |
389 event->event_name, *event_args, | 339 event->event_name, event_args, |
390 event->event_url, event->user_gesture); | 340 event->event_url, event->user_gesture); |
391 IncrementInFlightEvents(listener_profile, extension); | 341 IncrementInFlightEvents(listener_profile, extension); |
392 } | 342 } |
393 | 343 |
394 bool ExtensionEventRouter::CanDispatchEventToProfile( | 344 bool ExtensionEventRouter::CanDispatchEventToProfile( |
395 Profile* profile, | 345 Profile* profile, |
396 const Extension* extension, | 346 const Extension* extension, |
397 const linked_ptr<ExtensionEvent>& event, | 347 const linked_ptr<ExtensionEvent>& event, |
398 const Value** event_args) { | 348 ListValue** event_args) { |
399 *event_args = event->event_args.get(); | 349 if (event_args) { |
bryeung
2012/07/09 15:12:08
nit: no braces
Garret Kelly
2012/07/09 15:32:29
Done.
| |
350 *event_args = event->event_args; | |
351 } | |
400 | 352 |
401 // Is this event from a different profile than the renderer (ie, an | 353 // Is this event from a different profile than the renderer (ie, an |
402 // incognito tab event sent to a normal process, or vice versa). | 354 // incognito tab event sent to a normal process, or vice versa). |
403 bool cross_incognito = event->restrict_to_profile && | 355 bool cross_incognito = event->restrict_to_profile && |
404 profile != event->restrict_to_profile; | 356 profile != event->restrict_to_profile; |
405 if (cross_incognito && | 357 if (cross_incognito && |
406 !profile->GetExtensionService()->CanCrossIncognito(extension)) { | 358 !profile->GetExtensionService()->CanCrossIncognito(extension)) { |
407 if (!event->cross_incognito_args.get()) | 359 if (!event->cross_incognito_args) |
408 return false; | 360 return false; |
409 // Send the event with different arguments to extensions that can't | 361 // Send the event with different arguments to extensions that can't |
410 // cross incognito. | 362 // cross incognito. |
411 *event_args = event->cross_incognito_args.get(); | 363 if (event_args) { |
364 delete *event_args; | |
365 *event_args = event->cross_incognito_args; | |
366 } | |
412 } | 367 } |
413 | 368 |
414 return true; | 369 return true; |
415 } | 370 } |
416 | 371 |
417 void ExtensionEventRouter::LoadLazyBackgroundPagesForEvent( | 372 void ExtensionEventRouter::LoadLazyBackgroundPagesForEvent( |
418 const std::string& extension_id, | 373 const std::string& extension_id, |
419 const linked_ptr<ExtensionEvent>& event) { | 374 const linked_ptr<ExtensionEvent>& event) { |
420 ExtensionService* service = profile_->GetExtensionService(); | 375 ExtensionService* service = profile_->GetExtensionService(); |
421 | 376 |
(...skipping 20 matching lines...) Expand all Loading... | |
442 profile_->GetOffTheRecordProfile(), extension, event); | 397 profile_->GetOffTheRecordProfile(), extension, event); |
443 } | 398 } |
444 } | 399 } |
445 } | 400 } |
446 } | 401 } |
447 | 402 |
448 void ExtensionEventRouter::MaybeLoadLazyBackgroundPage( | 403 void ExtensionEventRouter::MaybeLoadLazyBackgroundPage( |
449 Profile* profile, | 404 Profile* profile, |
450 const Extension* extension, | 405 const Extension* extension, |
451 const linked_ptr<ExtensionEvent>& event) { | 406 const linked_ptr<ExtensionEvent>& event) { |
452 const Value* event_args = NULL; | 407 if (!CanDispatchEventToProfile(profile, extension, event, NULL)) |
453 if (!CanDispatchEventToProfile(profile, extension, event, &event_args)) | |
454 return; | 408 return; |
455 | 409 |
456 extensions::LazyBackgroundTaskQueue* queue = | 410 extensions::LazyBackgroundTaskQueue* queue = |
457 ExtensionSystem::Get(profile)->lazy_background_task_queue(); | 411 ExtensionSystem::Get(profile)->lazy_background_task_queue(); |
458 if (queue->ShouldEnqueueTask(profile, extension)) { | 412 if (queue->ShouldEnqueueTask(profile, extension)) { |
459 queue->AddPendingTask( | 413 queue->AddPendingTask( |
460 profile, extension->id(), | 414 profile, extension->id(), |
461 base::Bind(&ExtensionEventRouter::DispatchPendingEvent, | 415 base::Bind(&ExtensionEventRouter::DispatchPendingEvent, |
462 base::Unretained(this), event)); | 416 base::Unretained(this), event)); |
463 } | 417 } |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
559 MessageLoop::current()->PostTask(FROM_HERE, | 513 MessageLoop::current()->PostTask(FROM_HERE, |
560 base::Bind(&extensions::RuntimeEventRouter::DispatchOnInstalledEvent, | 514 base::Bind(&extensions::RuntimeEventRouter::DispatchOnInstalledEvent, |
561 profile_, extension->id())); | 515 profile_, extension->id())); |
562 break; | 516 break; |
563 } | 517 } |
564 default: | 518 default: |
565 NOTREACHED(); | 519 NOTREACHED(); |
566 return; | 520 return; |
567 } | 521 } |
568 } | 522 } |
OLD | NEW |