1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef EXTENSIONS_BROWSER_EVENT_LISTENER_MAP_H_ 6 #define EXTENSIONS_BROWSER_EVENT_LISTENER_MAP_H_ 7 8 #include <map> 9 #include <set> 10 #include <string> 11 #include <vector> 12 13 #include "base/memory/scoped_ptr.h" 14 #include "extensions/common/event_filter.h" 15 16 namespace base { 17 class DictionaryValue; 18 } 19 20 namespace content { 21 class RenderProcessHost; 22 } 23 24 class ListenerRemovalListener; 25 26 namespace extensions { 27 struct Event; 28 29 // A listener for an extension event. A listener is essentially an endpoint 30 // that an event can be dispatched to. This is a lazy listener if |process| is 31 // NULL and a filtered listener if |filter| is defined. 32 // 33 // A lazy listener is added to an event to indicate that a lazy background page 34 // is listening to the event. It is associated with no process, so to dispatch 35 // an event to a lazy listener one must start a process running the associated 36 // extension and dispatch the event to that. 37 // 38 struct EventListener { 39 // |filter| represents a generic filter structure that EventFilter knows how 40 // to filter events with. A typical filter instance will look like 41 // 42 // { 43 // url: [{hostSuffix: 'google.com'}], 44 // tabId: 5 45 // } 46 EventListener(const std::string& event_name, 47 const std::string& extension_id, 48 content::RenderProcessHost* process, 49 scoped_ptr<base::DictionaryValue> filter); 50 ~EventListener(); 51 52 bool Equals(const EventListener* other) const; 53 54 scoped_ptr<EventListener> Copy() const; 55 56 const std::string event_name; 57 const std::string extension_id; 58 content::RenderProcessHost* process; 59 scoped_ptr<base::DictionaryValue> filter; 60 EventFilter::MatcherID matcher_id; 61 62 private: 63 DISALLOW_COPY_AND_ASSIGN(EventListener); 64 }; 65 66 // Holds listeners for extension events and can answer questions about which 67 // listeners are interested in what events. 68 class EventListenerMap { 69 public: 70 typedef std::vector<linked_ptr<EventListener> > ListenerList; 71 72 class Delegate { 73 public: 74 virtual ~Delegate() {} 75 virtual void OnListenerAdded(const EventListener* listener) = 0; 76 virtual void OnListenerRemoved(const EventListener* listener) = 0; 77 }; 78 79 explicit EventListenerMap(Delegate* delegate); 80 ~EventListenerMap(); 81 82 // Add a listener for a particular event. GetEventListeners() will include a 83 // weak pointer to |listener| in its results if passed a relevant 84 // extensions::Event. 85 // Returns true if the listener was added (in the case that it has never been 86 // seen before). 87 bool AddListener(scoped_ptr<EventListener> listener); 88 89 // Remove a listener that .Equals() |listener|. 90 // Returns true if the listener was removed . 91 bool RemoveListener(const EventListener* listener); 92 93 // Returns the set of listeners that want to be notified of |event|. 94 std::set<const EventListener*> GetEventListeners(const Event& event); 95 96 const ListenerList& GetEventListenersByName(const std::string& event_name) { 97 return listeners_[event_name]; 98 } 99 100 // Removes all listeners with process equal to |process|. 101 void RemoveListenersForProcess(const content::RenderProcessHost* process); 102 103 // Returns true if there are any listeners on the event named |event_name|. 104 bool HasListenerForEvent(const std::string& event_name); 105 106 // Returns true if there are any listeners on |event_name| from 107 // |extension_id|. 108 bool HasListenerForExtension(const std::string& extension_id, 109 const std::string& event_name); 110 111 // Returns true if this map contains an EventListener that .Equals() 112 // |listener|. 113 bool HasListener(const EventListener* listener); 114 115 // Returns true if there is a listener for |extension_id| in |process|. 116 bool HasProcessListener(content::RenderProcessHost* process, 117 const std::string& extension_id); 118 119 // Removes any lazy listeners that |extension_id| has added. 120 void RemoveLazyListenersForExtension(const std::string& extension_id); 121 122 // Adds unfiltered lazy listeners as described their serialised descriptions. 123 // |event_names| the names of the lazy events. 124 // Note that we can only load lazy listeners in this fashion, because there 125 // is no way to serialise a RenderProcessHost*. 126 void LoadUnfilteredLazyListeners(const std::string& extension_id, 127 const std::set<std::string>& event_names); 128 129 // Adds filtered lazy listeners as described their serialised descriptions. 130 // |filtered| contains a map from event names to filters, each pairing 131 // defining a lazy filtered listener. 132 void LoadFilteredLazyListeners( 133 const std::string& extension_id, 134 const base::DictionaryValue& filtered); 135 136 private: 137 // The key here is an event name. 138 typedef std::map<std::string, ListenerList> ListenerMap; 139 140 void CleanupListener(EventListener* listener); 141 bool IsFilteredEvent(const Event& event) const; 142 scoped_ptr<EventMatcher> ParseEventMatcher( 143 base::DictionaryValue* filter_dict); 144 145 // Listens for removals from this map. 146 Delegate* delegate_; 147 148 std::set<std::string> filtered_events_; 149 ListenerMap listeners_; 150 151 std::map<EventFilter::MatcherID, EventListener*> listeners_by_matcher_id_; 152 153 EventFilter event_filter_; 154 155 DISALLOW_COPY_AND_ASSIGN(EventListenerMap); 156 }; 157 158 } // namespace extensions 159 160 #endif // EXTENSIONS_BROWSER_EVENT_LISTENER_MAP_H_ 161