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 <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
11 #include "base/atomic_sequence_num.h" | 11 #include "base/atomic_sequence_num.h" |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
13 #include "base/command_line.h" | |
14 #include "base/lazy_instance.h" | |
15 #include "base/memory/ptr_util.h" | 13 #include "base/memory/ptr_util.h" |
16 #include "base/message_loop/message_loop.h" | 14 #include "base/message_loop/message_loop.h" |
17 #include "base/metrics/histogram_macros.h" | 15 #include "base/metrics/histogram_macros.h" |
18 #include "base/stl_util.h" | 16 #include "base/stl_util.h" |
19 #include "base/values.h" | 17 #include "base/values.h" |
20 #include "content/public/browser/notification_service.h" | 18 #include "content/public/browser/notification_service.h" |
21 #include "content/public/browser/render_process_host.h" | 19 #include "content/public/browser/render_process_host.h" |
22 #include "extensions/browser/api_activity_monitor.h" | 20 #include "extensions/browser/api_activity_monitor.h" |
23 #include "extensions/browser/event_router_factory.h" | 21 #include "extensions/browser/event_router_factory.h" |
24 #include "extensions/browser/extension_host.h" | 22 #include "extensions/browser/extension_host.h" |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 } | 185 } |
188 | 186 |
189 void EventRouter::RegisterObserver(Observer* observer, | 187 void EventRouter::RegisterObserver(Observer* observer, |
190 const std::string& event_name) { | 188 const std::string& event_name) { |
191 // Observing sub-event names like "foo.onBar/123" is not allowed. | 189 // Observing sub-event names like "foo.onBar/123" is not allowed. |
192 DCHECK(event_name.find('/') == std::string::npos); | 190 DCHECK(event_name.find('/') == std::string::npos); |
193 observers_[event_name] = observer; | 191 observers_[event_name] = observer; |
194 } | 192 } |
195 | 193 |
196 void EventRouter::UnregisterObserver(Observer* observer) { | 194 void EventRouter::UnregisterObserver(Observer* observer) { |
197 std::vector<ObserverMap::iterator> iters_to_remove; | 195 for (ObserverMap::iterator it = observers_.begin(); it != observers_.end();) { |
198 for (ObserverMap::iterator iter = observers_.begin(); | 196 if (it->second == observer) |
199 iter != observers_.end(); ++iter) { | 197 it = observers_.erase(it); |
200 if (iter->second == observer) | 198 else |
201 iters_to_remove.push_back(iter); | 199 ++it; |
202 } | 200 } |
203 for (size_t i = 0; i < iters_to_remove.size(); ++i) | |
204 observers_.erase(iters_to_remove[i]); | |
205 } | 201 } |
206 | 202 |
207 void EventRouter::OnListenerAdded(const EventListener* listener) { | 203 void EventRouter::OnListenerAdded(const EventListener* listener) { |
208 const EventListenerInfo details(listener->event_name(), | 204 const EventListenerInfo details(listener->event_name(), |
209 listener->extension_id(), | 205 listener->extension_id(), |
210 listener->listener_url(), | 206 listener->listener_url(), |
211 listener->GetBrowserContext()); | 207 listener->GetBrowserContext()); |
212 std::string base_event_name = GetBaseEventName(listener->event_name()); | 208 std::string base_event_name = GetBaseEventName(listener->event_name()); |
213 ObserverMap::iterator observer = observers_.find(base_event_name); | 209 ObserverMap::iterator observer = observers_.find(base_event_name); |
214 if (observer != observers_.end()) | 210 if (observer != observers_.end()) |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
276 | 272 |
277 void EventRouter::AddFilteredEventListener(const std::string& event_name, | 273 void EventRouter::AddFilteredEventListener(const std::string& event_name, |
278 content::RenderProcessHost* process, | 274 content::RenderProcessHost* process, |
279 const std::string& extension_id, | 275 const std::string& extension_id, |
280 const base::DictionaryValue& filter, | 276 const base::DictionaryValue& filter, |
281 bool add_lazy_listener) { | 277 bool add_lazy_listener) { |
282 listeners_.AddListener(EventListener::ForExtension( | 278 listeners_.AddListener(EventListener::ForExtension( |
283 event_name, extension_id, process, | 279 event_name, extension_id, process, |
284 std::unique_ptr<DictionaryValue>(filter.DeepCopy()))); | 280 std::unique_ptr<DictionaryValue>(filter.DeepCopy()))); |
285 | 281 |
286 if (add_lazy_listener) { | 282 if (!add_lazy_listener) |
287 bool added = listeners_.AddListener(EventListener::ForExtension( | 283 return; |
288 event_name, extension_id, NULL, | |
289 std::unique_ptr<DictionaryValue>(filter.DeepCopy()))); | |
290 | 284 |
291 if (added) | 285 bool added = listeners_.AddListener(EventListener::ForExtension( |
292 AddFilterToEvent(event_name, extension_id, &filter); | 286 event_name, extension_id, nullptr, |
293 } | 287 std::unique_ptr<DictionaryValue>(filter.DeepCopy()))); |
| 288 if (added) |
| 289 AddFilterToEvent(event_name, extension_id, &filter); |
294 } | 290 } |
295 | 291 |
296 void EventRouter::RemoveFilteredEventListener( | 292 void EventRouter::RemoveFilteredEventListener( |
297 const std::string& event_name, | 293 const std::string& event_name, |
298 content::RenderProcessHost* process, | 294 content::RenderProcessHost* process, |
299 const std::string& extension_id, | 295 const std::string& extension_id, |
300 const base::DictionaryValue& filter, | 296 const base::DictionaryValue& filter, |
301 bool remove_lazy_listener) { | 297 bool remove_lazy_listener) { |
302 std::unique_ptr<EventListener> listener = EventListener::ForExtension( | 298 std::unique_ptr<EventListener> listener = EventListener::ForExtension( |
303 event_name, extension_id, process, | 299 event_name, extension_id, process, |
304 std::unique_ptr<DictionaryValue>(filter.DeepCopy())); | 300 std::unique_ptr<DictionaryValue>(filter.DeepCopy())); |
305 | 301 |
306 listeners_.RemoveListener(listener.get()); | 302 listeners_.RemoveListener(listener.get()); |
307 | 303 |
308 if (remove_lazy_listener) { | 304 if (remove_lazy_listener) { |
309 listener->MakeLazy(); | 305 listener->MakeLazy(); |
310 bool removed = listeners_.RemoveListener(listener.get()); | 306 bool removed = listeners_.RemoveListener(listener.get()); |
311 | 307 |
312 if (removed) | 308 if (removed) |
313 RemoveFilterFromEvent(event_name, extension_id, &filter); | 309 RemoveFilterFromEvent(event_name, extension_id, &filter); |
314 } | 310 } |
315 } | 311 } |
316 | 312 |
317 bool EventRouter::HasEventListener(const std::string& event_name) { | 313 bool EventRouter::HasEventListener(const std::string& event_name) const { |
318 return listeners_.HasListenerForEvent(event_name); | 314 return listeners_.HasListenerForEvent(event_name); |
319 } | 315 } |
320 | 316 |
321 bool EventRouter::ExtensionHasEventListener(const std::string& extension_id, | 317 bool EventRouter::ExtensionHasEventListener( |
322 const std::string& event_name) { | 318 const std::string& extension_id, |
| 319 const std::string& event_name) const { |
323 return listeners_.HasListenerForExtension(extension_id, event_name); | 320 return listeners_.HasListenerForExtension(extension_id, event_name); |
324 } | 321 } |
325 | 322 |
326 std::set<std::string> EventRouter::GetRegisteredEvents( | 323 std::set<std::string> EventRouter::GetRegisteredEvents( |
327 const std::string& extension_id) const { | 324 const std::string& extension_id) const { |
328 std::set<std::string> events; | 325 std::set<std::string> events; |
329 const ListValue* events_value = NULL; | 326 const ListValue* events_value = NULL; |
330 | 327 |
331 if (!extension_prefs_ || | 328 if (!extension_prefs_ || |
332 !extension_prefs_->ReadPrefAsList( | 329 !extension_prefs_->ReadPrefAsList( |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
569 | 566 |
570 bool EventRouter::MaybeLoadLazyBackgroundPageToDispatchEvent( | 567 bool EventRouter::MaybeLoadLazyBackgroundPageToDispatchEvent( |
571 BrowserContext* context, | 568 BrowserContext* context, |
572 const Extension* extension, | 569 const Extension* extension, |
573 const linked_ptr<Event>& event, | 570 const linked_ptr<Event>& event, |
574 const base::DictionaryValue* listener_filter) { | 571 const base::DictionaryValue* listener_filter) { |
575 if (!CanDispatchEventToBrowserContext(context, extension, event)) | 572 if (!CanDispatchEventToBrowserContext(context, extension, event)) |
576 return false; | 573 return false; |
577 | 574 |
578 LazyBackgroundTaskQueue* queue = LazyBackgroundTaskQueue::Get(context); | 575 LazyBackgroundTaskQueue* queue = LazyBackgroundTaskQueue::Get(context); |
579 if (queue->ShouldEnqueueTask(context, extension)) { | 576 if (!queue->ShouldEnqueueTask(context, extension)) |
580 linked_ptr<Event> dispatched_event(event); | 577 return false; |
581 | 578 |
582 // If there's a dispatch callback, call it now (rather than dispatch time) | 579 linked_ptr<Event> dispatched_event(event); |
583 // to avoid lifetime issues. Use a separate copy of the event args, so they | 580 |
584 // last until the event is dispatched. | 581 // If there's a dispatch callback, call it now (rather than dispatch time) |
585 if (!event->will_dispatch_callback.is_null()) { | 582 // to avoid lifetime issues. Use a separate copy of the event args, so they |
586 dispatched_event.reset(event->DeepCopy()); | 583 // last until the event is dispatched. |
587 if (!dispatched_event->will_dispatch_callback.Run( | 584 if (!event->will_dispatch_callback.is_null()) { |
588 context, extension, dispatched_event.get(), listener_filter)) { | 585 dispatched_event.reset(event->DeepCopy()); |
589 // The event has been canceled. | 586 if (!dispatched_event->will_dispatch_callback.Run( |
590 return true; | 587 context, extension, dispatched_event.get(), listener_filter)) { |
591 } | 588 // The event has been canceled. |
592 // Ensure we don't call it again at dispatch time. | 589 return true; |
593 dispatched_event->will_dispatch_callback.Reset(); | |
594 } | 590 } |
595 | 591 // Ensure we don't call it again at dispatch time. |
596 queue->AddPendingTask(context, extension->id(), | 592 dispatched_event->will_dispatch_callback.Reset(); |
597 base::Bind(&EventRouter::DispatchPendingEvent, | |
598 base::Unretained(this), dispatched_event)); | |
599 return true; | |
600 } | 593 } |
601 | 594 |
602 return false; | 595 queue->AddPendingTask(context, extension->id(), |
| 596 base::Bind(&EventRouter::DispatchPendingEvent, |
| 597 base::Unretained(this), dispatched_event)); |
| 598 return true; |
603 } | 599 } |
604 | 600 |
605 // static | 601 // static |
606 void EventRouter::DoDispatchEventToSenderBookkeepingOnUI( | 602 void EventRouter::DoDispatchEventToSenderBookkeepingOnUI( |
607 void* browser_context_id, | 603 void* browser_context_id, |
608 const std::string& extension_id, | 604 const std::string& extension_id, |
609 int event_id, | 605 int event_id, |
610 events::HistogramValue histogram_value, | 606 events::HistogramValue histogram_value, |
611 const std::string& event_name) { | 607 const std::string& event_name) { |
612 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 608 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
749 filtered_events->SetWithoutPathExpansion(event_name, | 745 filtered_events->SetWithoutPathExpansion(event_name, |
750 base::WrapUnique(filter_list)); | 746 base::WrapUnique(filter_list)); |
751 } | 747 } |
752 | 748 |
753 filter_list->Append(filter->CreateDeepCopy()); | 749 filter_list->Append(filter->CreateDeepCopy()); |
754 } | 750 } |
755 | 751 |
756 void EventRouter::Observe(int type, | 752 void EventRouter::Observe(int type, |
757 const content::NotificationSource& source, | 753 const content::NotificationSource& source, |
758 const content::NotificationDetails& details) { | 754 const content::NotificationDetails& details) { |
759 switch (type) { | 755 DCHECK_EQ(extensions::NOTIFICATION_EXTENSION_ENABLED, type); |
760 case extensions::NOTIFICATION_EXTENSION_ENABLED: { | 756 // If the extension has a lazy background page, make sure it gets loaded |
761 // If the extension has a lazy background page, make sure it gets loaded | 757 // to register the events the extension is interested in. |
762 // to register the events the extension is interested in. | 758 const Extension* extension = content::Details<const Extension>(details).ptr(); |
763 const Extension* extension = | 759 if (BackgroundInfo::HasLazyBackgroundPage(extension)) { |
764 content::Details<const Extension>(details).ptr(); | 760 LazyBackgroundTaskQueue* queue = |
765 if (BackgroundInfo::HasLazyBackgroundPage(extension)) { | 761 LazyBackgroundTaskQueue::Get(browser_context_); |
766 LazyBackgroundTaskQueue* queue = | 762 queue->AddPendingTask(browser_context_, extension->id(), |
767 LazyBackgroundTaskQueue::Get(browser_context_); | 763 base::Bind(&DoNothing)); |
768 queue->AddPendingTask(browser_context_, extension->id(), | |
769 base::Bind(&DoNothing)); | |
770 } | |
771 break; | |
772 } | |
773 default: | |
774 NOTREACHED(); | |
775 } | 764 } |
776 } | 765 } |
777 | 766 |
778 void EventRouter::OnExtensionLoaded(content::BrowserContext* browser_context, | 767 void EventRouter::OnExtensionLoaded(content::BrowserContext* browser_context, |
779 const Extension* extension) { | 768 const Extension* extension) { |
780 // Add all registered lazy listeners to our cache. | 769 // Add all registered lazy listeners to our cache. |
781 std::set<std::string> registered_events = | 770 std::set<std::string> registered_events = |
782 GetRegisteredEvents(extension->id()); | 771 GetRegisteredEvents(extension->id()); |
783 listeners_.LoadUnfilteredLazyListeners(extension->id(), registered_events); | 772 listeners_.LoadUnfilteredLazyListeners(extension->id(), registered_events); |
784 const DictionaryValue* filtered_events = GetFilteredEvents(extension->id()); | 773 const DictionaryValue* filtered_events = GetFilteredEvents(extension->id()); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
848 const std::string& extension_id, | 837 const std::string& extension_id, |
849 const GURL& listener_url, | 838 const GURL& listener_url, |
850 content::BrowserContext* browser_context) | 839 content::BrowserContext* browser_context) |
851 : event_name(event_name), | 840 : event_name(event_name), |
852 extension_id(extension_id), | 841 extension_id(extension_id), |
853 listener_url(listener_url), | 842 listener_url(listener_url), |
854 browser_context(browser_context) { | 843 browser_context(browser_context) { |
855 } | 844 } |
856 | 845 |
857 } // namespace extensions | 846 } // namespace extensions |
OLD | NEW |