| 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 |