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