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 "extensions/browser/event_router.h" | 5 #include "extensions/browser/event_router.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 content::Source<BrowserContext>(browser_context_)); | 181 content::Source<BrowserContext>(browser_context_)); |
182 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED, | 182 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED, |
183 content::Source<BrowserContext>(browser_context_)); | 183 content::Source<BrowserContext>(browser_context_)); |
184 } | 184 } |
185 | 185 |
186 EventRouter::~EventRouter() {} | 186 EventRouter::~EventRouter() {} |
187 | 187 |
188 void EventRouter::AddEventListener(const std::string& event_name, | 188 void EventRouter::AddEventListener(const std::string& event_name, |
189 content::RenderProcessHost* process, | 189 content::RenderProcessHost* process, |
190 const std::string& extension_id) { | 190 const std::string& extension_id) { |
191 listeners_.AddListener(scoped_ptr<EventListener>(new EventListener( | 191 listeners_.AddListener(scoped_ptr<EventListener>( |
192 event_name, extension_id, process, scoped_ptr<DictionaryValue>()))); | 192 new EventListener(event_name, |
| 193 extension_id, |
| 194 GURL(), // listener_url |
| 195 process, |
| 196 scoped_ptr<DictionaryValue>()))); |
193 } | 197 } |
194 | 198 |
195 void EventRouter::RemoveEventListener(const std::string& event_name, | 199 void EventRouter::RemoveEventListener(const std::string& event_name, |
196 content::RenderProcessHost* process, | 200 content::RenderProcessHost* process, |
197 const std::string& extension_id) { | 201 const std::string& extension_id) { |
198 EventListener listener(event_name, extension_id, process, | 202 EventListener listener(event_name, |
| 203 extension_id, |
| 204 GURL(), // listener_url |
| 205 process, |
199 scoped_ptr<DictionaryValue>()); | 206 scoped_ptr<DictionaryValue>()); |
200 listeners_.RemoveListener(&listener); | 207 listeners_.RemoveListener(&listener); |
201 } | 208 } |
| 209 |
| 210 void EventRouter::AddEventListenerForURL(const std::string& event_name, |
| 211 content::RenderProcessHost* process, |
| 212 const GURL& listener_url) { |
| 213 listeners_.AddListener(scoped_ptr<EventListener>( |
| 214 new EventListener(event_name, |
| 215 "", // extension_id |
| 216 listener_url, |
| 217 process, |
| 218 scoped_ptr<DictionaryValue>()))); |
| 219 } |
| 220 |
| 221 void EventRouter::RemoveEventListenerForURL(const std::string& event_name, |
| 222 content::RenderProcessHost* process, |
| 223 const GURL& listener_url) { |
| 224 EventListener listener(event_name, |
| 225 "", // extension_id |
| 226 listener_url, |
| 227 process, |
| 228 scoped_ptr<DictionaryValue>()); |
| 229 listeners_.RemoveListener(&listener); |
| 230 } |
202 | 231 |
203 void EventRouter::RegisterObserver(Observer* observer, | 232 void EventRouter::RegisterObserver(Observer* observer, |
204 const std::string& event_name) { | 233 const std::string& event_name) { |
205 // Observing sub-event names like "foo.onBar/123" is not allowed. | 234 // Observing sub-event names like "foo.onBar/123" is not allowed. |
206 DCHECK(event_name.find('/') == std::string::npos); | 235 DCHECK(event_name.find('/') == std::string::npos); |
207 observers_[event_name] = observer; | 236 observers_[event_name] = observer; |
208 } | 237 } |
209 | 238 |
210 void EventRouter::UnregisterObserver(Observer* observer) { | 239 void EventRouter::UnregisterObserver(Observer* observer) { |
211 std::vector<ObserverMap::iterator> iters_to_remove; | 240 std::vector<ObserverMap::iterator> iters_to_remove; |
212 for (ObserverMap::iterator iter = observers_.begin(); | 241 for (ObserverMap::iterator iter = observers_.begin(); |
213 iter != observers_.end(); ++iter) { | 242 iter != observers_.end(); ++iter) { |
214 if (iter->second == observer) | 243 if (iter->second == observer) |
215 iters_to_remove.push_back(iter); | 244 iters_to_remove.push_back(iter); |
216 } | 245 } |
217 for (size_t i = 0; i < iters_to_remove.size(); ++i) | 246 for (size_t i = 0; i < iters_to_remove.size(); ++i) |
218 observers_.erase(iters_to_remove[i]); | 247 observers_.erase(iters_to_remove[i]); |
219 } | 248 } |
220 | 249 |
221 void EventRouter::OnListenerAdded(const EventListener* listener) { | 250 void EventRouter::OnListenerAdded(const EventListener* listener) { |
222 const EventListenerInfo details(listener->event_name(), | 251 const EventListenerInfo details(listener->event_name(), |
223 listener->extension_id(), | 252 listener->extension_id(), |
| 253 listener->listener_url(), |
224 listener->GetBrowserContext()); | 254 listener->GetBrowserContext()); |
225 std::string base_event_name = GetBaseEventName(listener->event_name()); | 255 std::string base_event_name = GetBaseEventName(listener->event_name()); |
226 ObserverMap::iterator observer = observers_.find(base_event_name); | 256 ObserverMap::iterator observer = observers_.find(base_event_name); |
227 if (observer != observers_.end()) | 257 if (observer != observers_.end()) |
228 observer->second->OnListenerAdded(details); | 258 observer->second->OnListenerAdded(details); |
229 } | 259 } |
230 | 260 |
231 void EventRouter::OnListenerRemoved(const EventListener* listener) { | 261 void EventRouter::OnListenerRemoved(const EventListener* listener) { |
232 const EventListenerInfo details(listener->event_name(), | 262 const EventListenerInfo details(listener->event_name(), |
233 listener->extension_id(), | 263 listener->extension_id(), |
| 264 listener->listener_url(), |
234 listener->GetBrowserContext()); | 265 listener->GetBrowserContext()); |
235 std::string base_event_name = GetBaseEventName(listener->event_name()); | 266 std::string base_event_name = GetBaseEventName(listener->event_name()); |
236 ObserverMap::iterator observer = observers_.find(base_event_name); | 267 ObserverMap::iterator observer = observers_.find(base_event_name); |
237 if (observer != observers_.end()) | 268 if (observer != observers_.end()) |
238 observer->second->OnListenerRemoved(details); | 269 observer->second->OnListenerRemoved(details); |
239 } | 270 } |
240 | 271 |
241 void EventRouter::AddLazyEventListener(const std::string& event_name, | 272 void EventRouter::AddLazyEventListener(const std::string& event_name, |
242 const std::string& extension_id) { | 273 const std::string& extension_id) { |
243 scoped_ptr<EventListener> listener(new EventListener( | 274 scoped_ptr<EventListener> listener(new EventListener( |
244 event_name, extension_id, NULL, scoped_ptr<DictionaryValue>())); | 275 event_name, extension_id, GURL(), NULL, scoped_ptr<DictionaryValue>())); |
245 bool is_new = listeners_.AddListener(listener.Pass()); | 276 bool is_new = listeners_.AddListener(listener.Pass()); |
246 | 277 |
247 if (is_new) { | 278 if (is_new) { |
248 std::set<std::string> events = GetRegisteredEvents(extension_id); | 279 std::set<std::string> events = GetRegisteredEvents(extension_id); |
249 bool prefs_is_new = events.insert(event_name).second; | 280 bool prefs_is_new = events.insert(event_name).second; |
250 if (prefs_is_new) | 281 if (prefs_is_new) |
251 SetRegisteredEvents(extension_id, events); | 282 SetRegisteredEvents(extension_id, events); |
252 } | 283 } |
253 } | 284 } |
254 | 285 |
255 void EventRouter::RemoveLazyEventListener(const std::string& event_name, | 286 void EventRouter::RemoveLazyEventListener(const std::string& event_name, |
256 const std::string& extension_id) { | 287 const std::string& extension_id) { |
257 EventListener listener(event_name, extension_id, NULL, | 288 EventListener listener( |
258 scoped_ptr<DictionaryValue>()); | 289 event_name, extension_id, GURL(), NULL, scoped_ptr<DictionaryValue>()); |
259 bool did_exist = listeners_.RemoveListener(&listener); | 290 bool did_exist = listeners_.RemoveListener(&listener); |
260 | 291 |
261 if (did_exist) { | 292 if (did_exist) { |
262 std::set<std::string> events = GetRegisteredEvents(extension_id); | 293 std::set<std::string> events = GetRegisteredEvents(extension_id); |
263 bool prefs_did_exist = events.erase(event_name) > 0; | 294 bool prefs_did_exist = events.erase(event_name) > 0; |
264 DCHECK(prefs_did_exist); | 295 DCHECK(prefs_did_exist); |
265 SetRegisteredEvents(extension_id, events); | 296 SetRegisteredEvents(extension_id, events); |
266 } | 297 } |
267 } | 298 } |
268 | 299 |
269 void EventRouter::AddFilteredEventListener(const std::string& event_name, | 300 void EventRouter::AddFilteredEventListener(const std::string& event_name, |
270 content::RenderProcessHost* process, | 301 content::RenderProcessHost* process, |
271 const std::string& extension_id, | 302 const std::string& extension_id, |
272 const base::DictionaryValue& filter, | 303 const base::DictionaryValue& filter, |
273 bool add_lazy_listener) { | 304 bool add_lazy_listener) { |
274 listeners_.AddListener(scoped_ptr<EventListener>(new EventListener( | 305 listeners_.AddListener(scoped_ptr<EventListener>(new EventListener( |
275 event_name, extension_id, process, | 306 event_name, |
| 307 extension_id, |
| 308 GURL(), // TODO(kalman): pass through URL from filtered events |
| 309 process, |
276 scoped_ptr<DictionaryValue>(filter.DeepCopy())))); | 310 scoped_ptr<DictionaryValue>(filter.DeepCopy())))); |
277 | 311 |
278 if (add_lazy_listener) { | 312 if (add_lazy_listener) { |
279 bool added = listeners_.AddListener(scoped_ptr<EventListener>( | 313 bool added = listeners_.AddListener(scoped_ptr<EventListener>( |
280 new EventListener(event_name, extension_id, NULL, | 314 new EventListener(event_name, |
281 scoped_ptr<DictionaryValue>(filter.DeepCopy())))); | 315 extension_id, |
| 316 GURL(), // URL is irrelevant for lazy listeners. |
| 317 NULL, |
| 318 scoped_ptr<DictionaryValue>(filter.DeepCopy())))); |
282 | 319 |
283 if (added) | 320 if (added) |
284 AddFilterToEvent(event_name, extension_id, &filter); | 321 AddFilterToEvent(event_name, extension_id, &filter); |
285 } | 322 } |
286 } | 323 } |
287 | 324 |
288 void EventRouter::RemoveFilteredEventListener( | 325 void EventRouter::RemoveFilteredEventListener( |
289 const std::string& event_name, | 326 const std::string& event_name, |
290 content::RenderProcessHost* process, | 327 content::RenderProcessHost* process, |
291 const std::string& extension_id, | 328 const std::string& extension_id, |
292 const base::DictionaryValue& filter, | 329 const base::DictionaryValue& filter, |
293 bool remove_lazy_listener) { | 330 bool remove_lazy_listener) { |
294 EventListener listener(event_name, extension_id, process, | 331 EventListener listener(event_name, |
| 332 extension_id, |
| 333 GURL(), // TODO(kalman): URLs for filtered events |
| 334 process, |
295 scoped_ptr<DictionaryValue>(filter.DeepCopy())); | 335 scoped_ptr<DictionaryValue>(filter.DeepCopy())); |
296 | 336 |
297 listeners_.RemoveListener(&listener); | 337 listeners_.RemoveListener(&listener); |
298 | 338 |
299 if (remove_lazy_listener) { | 339 if (remove_lazy_listener) { |
300 listener.MakeLazy(); | 340 listener.MakeLazy(); |
301 bool removed = listeners_.RemoveListener(&listener); | 341 bool removed = listeners_.RemoveListener(&listener); |
302 | 342 |
303 if (removed) | 343 if (removed) |
304 RemoveFilterFromEvent(event_name, extension_id, &filter); | 344 RemoveFilterFromEvent(event_name, extension_id, &filter); |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
464 | 504 |
465 for (std::set<const EventListener*>::iterator it = listeners.begin(); | 505 for (std::set<const EventListener*>::iterator it = listeners.begin(); |
466 it != listeners.end(); it++) { | 506 it != listeners.end(); it++) { |
467 const EventListener* listener = *it; | 507 const EventListener* listener = *it; |
468 if (restrict_to_extension_id.empty() || | 508 if (restrict_to_extension_id.empty() || |
469 restrict_to_extension_id == listener->extension_id()) { | 509 restrict_to_extension_id == listener->extension_id()) { |
470 if (listener->process()) { | 510 if (listener->process()) { |
471 EventDispatchIdentifier dispatch_id(listener->GetBrowserContext(), | 511 EventDispatchIdentifier dispatch_id(listener->GetBrowserContext(), |
472 listener->extension_id()); | 512 listener->extension_id()); |
473 if (!ContainsKey(already_dispatched, dispatch_id)) { | 513 if (!ContainsKey(already_dispatched, dispatch_id)) { |
474 DispatchEventToProcess( | 514 DispatchEventToProcess(listener->extension_id(), |
475 listener->extension_id(), listener->process(), event); | 515 listener->listener_url(), |
| 516 listener->process(), |
| 517 event); |
476 } | 518 } |
477 } | 519 } |
478 } | 520 } |
479 } | 521 } |
480 } | 522 } |
481 | 523 |
482 void EventRouter::DispatchLazyEvent( | 524 void EventRouter::DispatchLazyEvent( |
483 const std::string& extension_id, | 525 const std::string& extension_id, |
484 const linked_ptr<Event>& event, | 526 const linked_ptr<Event>& event, |
485 std::set<EventDispatchIdentifier>* already_dispatched) { | 527 std::set<EventDispatchIdentifier>* already_dispatched) { |
(...skipping 18 matching lines...) Expand all Loading... |
504 browser_client->GetOffTheRecordContext(browser_context_); | 546 browser_client->GetOffTheRecordContext(browser_context_); |
505 if (MaybeLoadLazyBackgroundPageToDispatchEvent( | 547 if (MaybeLoadLazyBackgroundPageToDispatchEvent( |
506 incognito_context, extension, event)) { | 548 incognito_context, extension, event)) { |
507 already_dispatched->insert( | 549 already_dispatched->insert( |
508 std::make_pair(incognito_context, extension_id)); | 550 std::make_pair(incognito_context, extension_id)); |
509 } | 551 } |
510 } | 552 } |
511 } | 553 } |
512 | 554 |
513 void EventRouter::DispatchEventToProcess(const std::string& extension_id, | 555 void EventRouter::DispatchEventToProcess(const std::string& extension_id, |
| 556 const GURL& listener_url, |
514 content::RenderProcessHost* process, | 557 content::RenderProcessHost* process, |
515 const linked_ptr<Event>& event) { | 558 const linked_ptr<Event>& event) { |
516 BrowserContext* listener_context = process->GetBrowserContext(); | 559 BrowserContext* listener_context = process->GetBrowserContext(); |
517 ProcessMap* process_map = ProcessMap::Get(listener_context); | 560 ProcessMap* process_map = ProcessMap::Get(listener_context); |
518 | 561 |
519 const Extension* extension = | 562 const Extension* extension = |
520 ExtensionRegistry::Get(browser_context_)->enabled_extensions().GetByID( | 563 ExtensionRegistry::Get(browser_context_)->enabled_extensions().GetByID( |
521 extension_id); | 564 extension_id); |
522 // NOTE: |extension| being NULL does not necessarily imply that this event | 565 // NOTE: |extension| being NULL does not necessarily imply that this event |
523 // shouldn't be dispatched. Events can be dispatched to WebUI as well. | 566 // shouldn't be dispatched. Events can be dispatched to WebUI as well. |
(...skipping 25 matching lines...) Expand all Loading... |
549 return; | 592 return; |
550 } | 593 } |
551 | 594 |
552 if (!CanDispatchEventToBrowserContext(listener_context, extension, event)) { | 595 if (!CanDispatchEventToBrowserContext(listener_context, extension, event)) { |
553 return; | 596 return; |
554 } | 597 } |
555 } else if (content::ChildProcessSecurityPolicy::GetInstance() | 598 } else if (content::ChildProcessSecurityPolicy::GetInstance() |
556 ->HasWebUIBindings(process->GetID())) { | 599 ->HasWebUIBindings(process->GetID())) { |
557 // Dispatching event to WebUI. | 600 // Dispatching event to WebUI. |
558 if (!ExtensionAPI::GetSharedInstance()->IsAvailableToWebUI( | 601 if (!ExtensionAPI::GetSharedInstance()->IsAvailableToWebUI( |
559 event->event_name)) { | 602 event->event_name, listener_url)) { |
560 return; | 603 return; |
561 } | 604 } |
562 } else { | 605 } else { |
563 // Dispatching event to a webpage - however, all such events (e.g. | 606 // Dispatching event to a webpage - however, all such events (e.g. |
564 // messaging) don't go through EventRouter so this should be impossible. | 607 // messaging) don't go through EventRouter so this should be impossible. |
565 return; | 608 return; |
566 } | 609 } |
567 | 610 |
568 if (!event->will_dispatch_callback.is_null()) { | 611 if (!event->will_dispatch_callback.is_null()) { |
569 event->will_dispatch_callback.Run( | 612 event->will_dispatch_callback.Run( |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
683 pm->DecrementLazyKeepaliveCount(host->extension()); | 726 pm->DecrementLazyKeepaliveCount(host->extension()); |
684 } | 727 } |
685 | 728 |
686 void EventRouter::DispatchPendingEvent(const linked_ptr<Event>& event, | 729 void EventRouter::DispatchPendingEvent(const linked_ptr<Event>& event, |
687 ExtensionHost* host) { | 730 ExtensionHost* host) { |
688 if (!host) | 731 if (!host) |
689 return; | 732 return; |
690 | 733 |
691 if (listeners_.HasProcessListener(host->render_process_host(), | 734 if (listeners_.HasProcessListener(host->render_process_host(), |
692 host->extension()->id())) { | 735 host->extension()->id())) { |
693 DispatchEventToProcess(host->extension()->id(), | 736 DispatchEventToProcess( |
694 host->render_process_host(), event); | 737 host->extension()->id(), GURL(), host->render_process_host(), event); |
695 } | 738 } |
696 } | 739 } |
697 | 740 |
698 void EventRouter::Observe(int type, | 741 void EventRouter::Observe(int type, |
699 const content::NotificationSource& source, | 742 const content::NotificationSource& source, |
700 const content::NotificationDetails& details) { | 743 const content::NotificationDetails& details) { |
701 switch (type) { | 744 switch (type) { |
702 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: | 745 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: |
703 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { | 746 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { |
704 content::RenderProcessHost* renderer = | 747 content::RenderProcessHost* renderer = |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
792 restrict_to_browser_context, | 835 restrict_to_browser_context, |
793 event_url, | 836 event_url, |
794 user_gesture, | 837 user_gesture, |
795 filter_info); | 838 filter_info); |
796 copy->will_dispatch_callback = will_dispatch_callback; | 839 copy->will_dispatch_callback = will_dispatch_callback; |
797 return copy; | 840 return copy; |
798 } | 841 } |
799 | 842 |
800 EventListenerInfo::EventListenerInfo(const std::string& event_name, | 843 EventListenerInfo::EventListenerInfo(const std::string& event_name, |
801 const std::string& extension_id, | 844 const std::string& extension_id, |
| 845 const GURL& listener_url, |
802 content::BrowserContext* browser_context) | 846 content::BrowserContext* browser_context) |
803 : event_name(event_name), | 847 : event_name(event_name), |
804 extension_id(extension_id), | 848 extension_id(extension_id), |
805 browser_context(browser_context) {} | 849 listener_url(listener_url), |
| 850 browser_context(browser_context) { |
| 851 } |
806 | 852 |
807 } // namespace extensions | 853 } // namespace extensions |
OLD | NEW |