Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / extensions / browser / event_listener_map.h
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_