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