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 std::vector<ObserverMap::iterator> iters_to_remove; |
Devlin
2017/05/20 00:49:16
It seems a shame to construct a vector just for th
Lei Zhang
2017/05/20 01:04:14
Sure.
I see people do it both ways and I don't ha
| |
198 for (ObserverMap::iterator iter = observers_.begin(); | 196 for (ObserverMap::iterator iter = observers_.begin(); |
199 iter != observers_.end(); ++iter) { | 197 iter != observers_.end(); ++iter) { |
200 if (iter->second == observer) | 198 if (iter->second == observer) |
201 iters_to_remove.push_back(iter); | 199 iters_to_remove.push_back(iter); |
202 } | 200 } |
203 for (size_t i = 0; i < iters_to_remove.size(); ++i) | 201 for (auto& iter : iters_to_remove) |
204 observers_.erase(iters_to_remove[i]); | 202 observers_.erase(iter); |
205 } | 203 } |
206 | 204 |
207 void EventRouter::OnListenerAdded(const EventListener* listener) { | 205 void EventRouter::OnListenerAdded(const EventListener* listener) { |
208 const EventListenerInfo details(listener->event_name(), | 206 const EventListenerInfo details(listener->event_name(), |
209 listener->extension_id(), | 207 listener->extension_id(), |
210 listener->listener_url(), | 208 listener->listener_url(), |
211 listener->GetBrowserContext()); | 209 listener->GetBrowserContext()); |
212 std::string base_event_name = GetBaseEventName(listener->event_name()); | 210 std::string base_event_name = GetBaseEventName(listener->event_name()); |
213 ObserverMap::iterator observer = observers_.find(base_event_name); | 211 ObserverMap::iterator observer = observers_.find(base_event_name); |
214 if (observer != observers_.end()) | 212 if (observer != observers_.end()) |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
276 | 274 |
277 void EventRouter::AddFilteredEventListener(const std::string& event_name, | 275 void EventRouter::AddFilteredEventListener(const std::string& event_name, |
278 content::RenderProcessHost* process, | 276 content::RenderProcessHost* process, |
279 const std::string& extension_id, | 277 const std::string& extension_id, |
280 const base::DictionaryValue& filter, | 278 const base::DictionaryValue& filter, |
281 bool add_lazy_listener) { | 279 bool add_lazy_listener) { |
282 listeners_.AddListener(EventListener::ForExtension( | 280 listeners_.AddListener(EventListener::ForExtension( |
283 event_name, extension_id, process, | 281 event_name, extension_id, process, |
284 std::unique_ptr<DictionaryValue>(filter.DeepCopy()))); | 282 std::unique_ptr<DictionaryValue>(filter.DeepCopy()))); |
285 | 283 |
286 if (add_lazy_listener) { | 284 if (!add_lazy_listener) |
287 bool added = listeners_.AddListener(EventListener::ForExtension( | 285 return; |
288 event_name, extension_id, NULL, | |
289 std::unique_ptr<DictionaryValue>(filter.DeepCopy()))); | |
290 | 286 |
291 if (added) | 287 bool added = listeners_.AddListener(EventListener::ForExtension( |
292 AddFilterToEvent(event_name, extension_id, &filter); | 288 event_name, extension_id, nullptr, |
293 } | 289 std::unique_ptr<DictionaryValue>(filter.DeepCopy()))); |
290 if (added) | |
291 AddFilterToEvent(event_name, extension_id, &filter); | |
294 } | 292 } |
295 | 293 |
296 void EventRouter::RemoveFilteredEventListener( | 294 void EventRouter::RemoveFilteredEventListener( |
297 const std::string& event_name, | 295 const std::string& event_name, |
298 content::RenderProcessHost* process, | 296 content::RenderProcessHost* process, |
299 const std::string& extension_id, | 297 const std::string& extension_id, |
300 const base::DictionaryValue& filter, | 298 const base::DictionaryValue& filter, |
301 bool remove_lazy_listener) { | 299 bool remove_lazy_listener) { |
302 std::unique_ptr<EventListener> listener = EventListener::ForExtension( | 300 std::unique_ptr<EventListener> listener = EventListener::ForExtension( |
303 event_name, extension_id, process, | 301 event_name, extension_id, process, |
304 std::unique_ptr<DictionaryValue>(filter.DeepCopy())); | 302 std::unique_ptr<DictionaryValue>(filter.DeepCopy())); |
305 | 303 |
306 listeners_.RemoveListener(listener.get()); | 304 listeners_.RemoveListener(listener.get()); |
307 | 305 |
308 if (remove_lazy_listener) { | 306 if (remove_lazy_listener) { |
309 listener->MakeLazy(); | 307 listener->MakeLazy(); |
310 bool removed = listeners_.RemoveListener(listener.get()); | 308 bool removed = listeners_.RemoveListener(listener.get()); |
311 | 309 |
312 if (removed) | 310 if (removed) |
313 RemoveFilterFromEvent(event_name, extension_id, &filter); | 311 RemoveFilterFromEvent(event_name, extension_id, &filter); |
314 } | 312 } |
315 } | 313 } |
316 | 314 |
317 bool EventRouter::HasEventListener(const std::string& event_name) { | 315 bool EventRouter::HasEventListener(const std::string& event_name) const { |
318 return listeners_.HasListenerForEvent(event_name); | 316 return listeners_.HasListenerForEvent(event_name); |
319 } | 317 } |
320 | 318 |
321 bool EventRouter::ExtensionHasEventListener(const std::string& extension_id, | 319 bool EventRouter::ExtensionHasEventListener( |
322 const std::string& event_name) { | 320 const std::string& extension_id, |
321 const std::string& event_name) const { | |
323 return listeners_.HasListenerForExtension(extension_id, event_name); | 322 return listeners_.HasListenerForExtension(extension_id, event_name); |
324 } | 323 } |
325 | 324 |
326 std::set<std::string> EventRouter::GetRegisteredEvents( | 325 std::set<std::string> EventRouter::GetRegisteredEvents( |
327 const std::string& extension_id) const { | 326 const std::string& extension_id) const { |
328 std::set<std::string> events; | 327 std::set<std::string> events; |
329 const ListValue* events_value = NULL; | 328 const ListValue* events_value = NULL; |
330 | 329 |
331 if (!extension_prefs_ || | 330 if (!extension_prefs_ || |
332 !extension_prefs_->ReadPrefAsList( | 331 !extension_prefs_->ReadPrefAsList( |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
569 | 568 |
570 bool EventRouter::MaybeLoadLazyBackgroundPageToDispatchEvent( | 569 bool EventRouter::MaybeLoadLazyBackgroundPageToDispatchEvent( |
571 BrowserContext* context, | 570 BrowserContext* context, |
572 const Extension* extension, | 571 const Extension* extension, |
573 const linked_ptr<Event>& event, | 572 const linked_ptr<Event>& event, |
574 const base::DictionaryValue* listener_filter) { | 573 const base::DictionaryValue* listener_filter) { |
575 if (!CanDispatchEventToBrowserContext(context, extension, event)) | 574 if (!CanDispatchEventToBrowserContext(context, extension, event)) |
576 return false; | 575 return false; |
577 | 576 |
578 LazyBackgroundTaskQueue* queue = LazyBackgroundTaskQueue::Get(context); | 577 LazyBackgroundTaskQueue* queue = LazyBackgroundTaskQueue::Get(context); |
579 if (queue->ShouldEnqueueTask(context, extension)) { | 578 if (!queue->ShouldEnqueueTask(context, extension)) |
580 linked_ptr<Event> dispatched_event(event); | 579 return false; |
581 | 580 |
582 // If there's a dispatch callback, call it now (rather than dispatch time) | 581 linked_ptr<Event> dispatched_event(event); |
583 // to avoid lifetime issues. Use a separate copy of the event args, so they | 582 |
584 // last until the event is dispatched. | 583 // If there's a dispatch callback, call it now (rather than dispatch time) |
585 if (!event->will_dispatch_callback.is_null()) { | 584 // to avoid lifetime issues. Use a separate copy of the event args, so they |
586 dispatched_event.reset(event->DeepCopy()); | 585 // last until the event is dispatched. |
587 if (!dispatched_event->will_dispatch_callback.Run( | 586 if (!event->will_dispatch_callback.is_null()) { |
588 context, extension, dispatched_event.get(), listener_filter)) { | 587 dispatched_event.reset(event->DeepCopy()); |
589 // The event has been canceled. | 588 if (!dispatched_event->will_dispatch_callback.Run( |
590 return true; | 589 context, extension, dispatched_event.get(), listener_filter)) { |
591 } | 590 // The event has been canceled. |
592 // Ensure we don't call it again at dispatch time. | 591 return true; |
593 dispatched_event->will_dispatch_callback.Reset(); | |
594 } | 592 } |
595 | 593 // Ensure we don't call it again at dispatch time. |
596 queue->AddPendingTask(context, extension->id(), | 594 dispatched_event->will_dispatch_callback.Reset(); |
597 base::Bind(&EventRouter::DispatchPendingEvent, | |
598 base::Unretained(this), dispatched_event)); | |
599 return true; | |
600 } | 595 } |
601 | 596 |
602 return false; | 597 queue->AddPendingTask(context, extension->id(), |
598 base::Bind(&EventRouter::DispatchPendingEvent, | |
599 base::Unretained(this), dispatched_event)); | |
600 return true; | |
603 } | 601 } |
604 | 602 |
605 // static | 603 // static |
606 void EventRouter::DoDispatchEventToSenderBookkeepingOnUI( | 604 void EventRouter::DoDispatchEventToSenderBookkeepingOnUI( |
607 void* browser_context_id, | 605 void* browser_context_id, |
608 const std::string& extension_id, | 606 const std::string& extension_id, |
609 int event_id, | 607 int event_id, |
610 events::HistogramValue histogram_value, | 608 events::HistogramValue histogram_value, |
611 const std::string& event_name) { | 609 const std::string& event_name) { |
612 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 610 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
749 filtered_events->SetWithoutPathExpansion(event_name, | 747 filtered_events->SetWithoutPathExpansion(event_name, |
750 base::WrapUnique(filter_list)); | 748 base::WrapUnique(filter_list)); |
751 } | 749 } |
752 | 750 |
753 filter_list->Append(filter->CreateDeepCopy()); | 751 filter_list->Append(filter->CreateDeepCopy()); |
754 } | 752 } |
755 | 753 |
756 void EventRouter::Observe(int type, | 754 void EventRouter::Observe(int type, |
757 const content::NotificationSource& source, | 755 const content::NotificationSource& source, |
758 const content::NotificationDetails& details) { | 756 const content::NotificationDetails& details) { |
759 switch (type) { | 757 DCHECK_EQ(extensions::NOTIFICATION_EXTENSION_ENABLED, type); |
760 case extensions::NOTIFICATION_EXTENSION_ENABLED: { | 758 // 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 | 759 // to register the events the extension is interested in. |
762 // to register the events the extension is interested in. | 760 const Extension* extension = content::Details<const Extension>(details).ptr(); |
763 const Extension* extension = | 761 if (BackgroundInfo::HasLazyBackgroundPage(extension)) { |
764 content::Details<const Extension>(details).ptr(); | 762 LazyBackgroundTaskQueue* queue = |
765 if (BackgroundInfo::HasLazyBackgroundPage(extension)) { | 763 LazyBackgroundTaskQueue::Get(browser_context_); |
766 LazyBackgroundTaskQueue* queue = | 764 queue->AddPendingTask(browser_context_, extension->id(), |
767 LazyBackgroundTaskQueue::Get(browser_context_); | 765 base::Bind(&DoNothing)); |
768 queue->AddPendingTask(browser_context_, extension->id(), | |
769 base::Bind(&DoNothing)); | |
770 } | |
771 break; | |
772 } | |
773 default: | |
774 NOTREACHED(); | |
775 } | 766 } |
776 } | 767 } |
777 | 768 |
778 void EventRouter::OnExtensionLoaded(content::BrowserContext* browser_context, | 769 void EventRouter::OnExtensionLoaded(content::BrowserContext* browser_context, |
779 const Extension* extension) { | 770 const Extension* extension) { |
780 // Add all registered lazy listeners to our cache. | 771 // Add all registered lazy listeners to our cache. |
781 std::set<std::string> registered_events = | 772 std::set<std::string> registered_events = |
782 GetRegisteredEvents(extension->id()); | 773 GetRegisteredEvents(extension->id()); |
783 listeners_.LoadUnfilteredLazyListeners(extension->id(), registered_events); | 774 listeners_.LoadUnfilteredLazyListeners(extension->id(), registered_events); |
784 const DictionaryValue* filtered_events = GetFilteredEvents(extension->id()); | 775 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, | 839 const std::string& extension_id, |
849 const GURL& listener_url, | 840 const GURL& listener_url, |
850 content::BrowserContext* browser_context) | 841 content::BrowserContext* browser_context) |
851 : event_name(event_name), | 842 : event_name(event_name), |
852 extension_id(extension_id), | 843 extension_id(extension_id), |
853 listener_url(listener_url), | 844 listener_url(listener_url), |
854 browser_context(browser_context) { | 845 browser_context(browser_context) { |
855 } | 846 } |
856 | 847 |
857 } // namespace extensions | 848 } // namespace extensions |
OLD | NEW |