Upstream version 7.36.149.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
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_