Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / extensions / browser / event_router.h
1 // Copyright (c) 2012 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_ROUTER_H_
6 #define EXTENSIONS_BROWSER_EVENT_ROUTER_H_
7
8 #include <map>
9 #include <set>
10 #include <string>
11 #include <utility>
12
13 #include "base/callback.h"
14 #include "base/compiler_specific.h"
15 #include "base/containers/hash_tables.h"
16 #include "base/gtest_prod_util.h"
17 #include "base/memory/linked_ptr.h"
18 #include "base/memory/ref_counted.h"
19 #include "base/values.h"
20 #include "content/public/browser/notification_observer.h"
21 #include "content/public/browser/notification_registrar.h"
22 #include "extensions/browser/event_listener_map.h"
23 #include "extensions/common/event_filtering_info.h"
24 #include "ipc/ipc_sender.h"
25
26 class GURL;
27 class PrefService;
28
29 namespace content {
30 class BrowserContext;
31 class RenderProcessHost;
32 }
33
34 namespace extensions {
35 class ActivityLog;
36 class Extension;
37 class ExtensionHost;
38 class ExtensionPrefs;
39
40 struct Event;
41 struct EventDispatchInfo;
42 struct EventListenerInfo;
43
44 class EventRouter : public content::NotificationObserver,
45                     public EventListenerMap::Delegate {
46  public:
47   // These constants convey the state of our knowledge of whether we're in
48   // a user-caused gesture as part of DispatchEvent.
49   enum UserGestureState {
50     USER_GESTURE_UNKNOWN = 0,
51     USER_GESTURE_ENABLED = 1,
52     USER_GESTURE_NOT_ENABLED = 2,
53   };
54
55   // The pref key for the list of event names for which an extension has
56   // registered from its lazy background page.
57   static const char kRegisteredEvents[];
58
59   // Observers register interest in events with a particular name and are
60   // notified when a listener is added or removed. Observers are matched by
61   // the base name of the event (e.g. adding an event listener for event name
62   // "foo.onBar/123" will trigger observers registered for "foo.onBar").
63   class Observer {
64    public:
65     // Called when a listener is added.
66     virtual void OnListenerAdded(const EventListenerInfo& details) {}
67     // Called when a listener is removed.
68     virtual void OnListenerRemoved(const EventListenerInfo& details) {}
69   };
70
71   // Converts event names like "foo.onBar/123" into "foo.onBar". Event names
72   // without a "/" are returned unchanged.
73   static std::string GetBaseEventName(const std::string& full_event_name);
74
75   // Sends an event via ipc_sender to the given extension. Can be called on any
76   // thread.
77   static void DispatchEvent(IPC::Sender* ipc_sender,
78                             void* browser_context_id,
79                             const std::string& extension_id,
80                             const std::string& event_name,
81                             scoped_ptr<base::ListValue> event_args,
82                             UserGestureState user_gesture,
83                             const EventFilteringInfo& info);
84
85   // An EventRouter is shared between |browser_context| and its associated
86   // incognito context. |extension_prefs| may be NULL in tests.
87   EventRouter(content::BrowserContext* browser_context,
88               ExtensionPrefs* extension_prefs);
89   virtual ~EventRouter();
90
91   // Add or remove the process/extension pair as a listener for |event_name|.
92   // Note that multiple extensions can share a process due to process
93   // collapsing. Also, a single extension can have 2 processes if it is a split
94   // mode extension.
95   void AddEventListener(const std::string& event_name,
96                         content::RenderProcessHost* process,
97                         const std::string& extension_id);
98   void RemoveEventListener(const std::string& event_name,
99                            content::RenderProcessHost* process,
100                            const std::string& extension_id);
101
102   EventListenerMap& listeners() { return listeners_; }
103
104   // Registers an observer to be notified when an event listener for
105   // |event_name| is added or removed. There can currently be only one observer
106   // for each distinct |event_name|.
107   void RegisterObserver(Observer* observer,
108                         const std::string& event_name);
109
110   // Unregisters an observer from all events.
111   void UnregisterObserver(Observer* observer);
112
113   // Add or remove the extension as having a lazy background page that listens
114   // to the event. The difference from the above methods is that these will be
115   // remembered even after the process goes away. We use this list to decide
116   // which extension pages to load when dispatching an event.
117   void AddLazyEventListener(const std::string& event_name,
118                             const std::string& extension_id);
119   void RemoveLazyEventListener(const std::string& event_name,
120                                const std::string& extension_id);
121
122   // If |add_lazy_listener| is true also add the lazy version of this listener.
123   void AddFilteredEventListener(const std::string& event_name,
124                                 content::RenderProcessHost* process,
125                                 const std::string& extension_id,
126                                 const base::DictionaryValue& filter,
127                                 bool add_lazy_listener);
128
129   // If |remove_lazy_listener| is true also remove the lazy version of this
130   // listener.
131   void RemoveFilteredEventListener(const std::string& event_name,
132                                    content::RenderProcessHost* process,
133                                    const std::string& extension_id,
134                                    const base::DictionaryValue& filter,
135                                    bool remove_lazy_listener);
136
137   // Returns true if there is at least one listener for the given event.
138   bool HasEventListener(const std::string& event_name);
139
140   // Returns true if the extension is listening to the given event.
141   bool ExtensionHasEventListener(const std::string& extension_id,
142                                  const std::string& event_name);
143
144   // Return or set the list of events for which the given extension has
145   // registered.
146   std::set<std::string> GetRegisteredEvents(const std::string& extension_id);
147   void SetRegisteredEvents(const std::string& extension_id,
148                            const std::set<std::string>& events);
149
150   // Broadcasts an event to every listener registered for that event.
151   virtual void BroadcastEvent(scoped_ptr<Event> event);
152
153   // Dispatches an event to the given extension.
154   virtual void DispatchEventToExtension(const std::string& extension_id,
155                                         scoped_ptr<Event> event);
156
157   // Dispatches |event| to the given extension as if the extension has a lazy
158   // listener for it. NOTE: This should be used rarely, for dispatching events
159   // to extensions that haven't had a chance to add their own listeners yet, eg:
160   // newly installed extensions.
161   void DispatchEventWithLazyListener(const std::string& extension_id,
162                                      scoped_ptr<Event> event);
163
164   // Record the Event Ack from the renderer. (One less event in-flight.)
165   void OnEventAck(content::BrowserContext* context,
166                   const std::string& extension_id);
167
168  private:
169   FRIEND_TEST_ALL_PREFIXES(EventRouterTest, EventRouterObserver);
170
171   // The extension and process that contains the event listener for a given
172   // event.
173   struct ListenerProcess;
174
175   // A map between an event name and a set of extensions that are listening
176   // to that event.
177   typedef std::map<std::string, std::set<ListenerProcess> > ListenerMap;
178
179   // An identifier for an event dispatch that is used to prevent double dispatch
180   // due to race conditions between the direct and lazy dispatch paths.
181   typedef std::pair<const content::BrowserContext*, std::string>
182       EventDispatchIdentifier;
183
184   // TODO(gdk): Document this.
185   static void DispatchExtensionMessage(
186       IPC::Sender* ipc_sender,
187       void* browser_context_id,
188       const std::string& extension_id,
189       const std::string& event_name,
190       base::ListValue* event_args,
191       UserGestureState user_gesture,
192       const extensions::EventFilteringInfo& info);
193
194   virtual void Observe(int type,
195                        const content::NotificationSource& source,
196                        const content::NotificationDetails& details) OVERRIDE;
197
198   // Returns true if the given listener map contains a event listeners for
199   // the given event. If |extension_id| is non-empty, we also check that that
200   // extension is one of the listeners.
201   bool HasEventListenerImpl(const ListenerMap& listeners,
202                             const std::string& extension_id,
203                             const std::string& event_name);
204
205   // Shared by DispatchEvent*. If |restrict_to_extension_id| is empty, the
206   // event is broadcast.
207   // An event that just came off the pending list may not be delayed again.
208   void DispatchEventImpl(const std::string& restrict_to_extension_id,
209                          const linked_ptr<Event>& event);
210
211   // Ensures that all lazy background pages that are interested in the given
212   // event are loaded, and queues the event if the page is not ready yet.
213   // Inserts an EventDispatchIdentifier into |already_dispatched| for each lazy
214   // event dispatch that is queued.
215   void DispatchLazyEvent(const std::string& extension_id,
216                          const linked_ptr<Event>& event,
217                          std::set<EventDispatchIdentifier>* already_dispatched);
218
219   // Dispatches the event to the specified extension running in |process|.
220   void DispatchEventToProcess(const std::string& extension_id,
221                               content::RenderProcessHost* process,
222                               const linked_ptr<Event>& event);
223
224   // Returns false when the event is scoped to a context and the listening
225   // extension does not have access to events from that context. Also fills
226   // |event_args| with the proper arguments to send, which may differ if
227   // the event crosses the incognito boundary.
228   bool CanDispatchEventToBrowserContext(content::BrowserContext* context,
229                                         const Extension* extension,
230                                         const linked_ptr<Event>& event);
231
232   // Possibly loads given extension's background page in preparation to
233   // dispatch an event.  Returns true if the event was queued for subsequent
234   // dispatch, false otherwise.
235   bool MaybeLoadLazyBackgroundPageToDispatchEvent(
236       content::BrowserContext* context,
237       const Extension* extension,
238       const linked_ptr<Event>& event);
239
240   // Adds a filter to an event.
241   void AddFilterToEvent(const std::string& event_name,
242                         const std::string& extension_id,
243                         const base::DictionaryValue* filter);
244
245   // Removes a filter from an event.
246   void RemoveFilterFromEvent(const std::string& event_name,
247                              const std::string& extension_id,
248                              const base::DictionaryValue* filter);
249
250   // Returns the dictionary of event filters that the given extension has
251   // registered.
252   const base::DictionaryValue* GetFilteredEvents(
253       const std::string& extension_id);
254
255   // Track of the number of dispatched events that have not yet sent an
256   // ACK from the renderer.
257   void IncrementInFlightEvents(content::BrowserContext* context,
258                                const Extension* extension);
259
260   // static
261   static void IncrementInFlightEventsOnUI(
262       void* browser_context_id,
263       const std::string& extension_id);
264
265   void DispatchPendingEvent(const linked_ptr<Event>& event,
266                             ExtensionHost* host);
267
268   // Implementation of EventListenerMap::Delegate.
269   virtual void OnListenerAdded(const EventListener* listener) OVERRIDE;
270   virtual void OnListenerRemoved(const EventListener* listener) OVERRIDE;
271
272   content::BrowserContext* browser_context_;
273
274   // The ExtensionPrefs associated with |browser_context_|. May be NULL in
275   // tests.
276   ExtensionPrefs* extension_prefs_;
277
278   content::NotificationRegistrar registrar_;
279
280   EventListenerMap listeners_;
281
282   // Map from base event name to observer.
283   typedef base::hash_map<std::string, Observer*> ObserverMap;
284   ObserverMap observers_;
285
286   DISALLOW_COPY_AND_ASSIGN(EventRouter);
287 };
288
289 struct Event {
290   typedef base::Callback<void(content::BrowserContext*,
291                               const Extension*,
292                               base::ListValue*)> WillDispatchCallback;
293
294   // The event to dispatch.
295   std::string event_name;
296
297   // Arguments to send to the event listener.
298   scoped_ptr<base::ListValue> event_args;
299
300   // If non-NULL, then the event will not be sent to other BrowserContexts
301   // unless the extension has permission (e.g. incognito tab update -> normal
302   // tab only works if extension is allowed incognito access).
303   content::BrowserContext* restrict_to_browser_context;
304
305   // If not empty, the event is only sent to extensions with host permissions
306   // for this url.
307   GURL event_url;
308
309   // Whether a user gesture triggered the event.
310   EventRouter::UserGestureState user_gesture;
311
312   // Extra information used to filter which events are sent to the listener.
313   EventFilteringInfo filter_info;
314
315   // If specified, this is called before dispatching an event to each
316   // extension. The third argument is a mutable reference to event_args,
317   // allowing the caller to provide different arguments depending on the
318   // extension and profile. This is guaranteed to be called synchronously with
319   // DispatchEvent, so callers don't need to worry about lifetime.
320   WillDispatchCallback will_dispatch_callback;
321
322   // If true, this event will always be dispatched to ephemeral apps, regardless
323   // of whether they are running or inactive. Defaults to false.
324   // Most events can only be dispatched to ephemeral apps that are already
325   // running. Cached ephemeral apps are inactive until launched by the user.
326   bool can_load_ephemeral_apps;
327
328   Event(const std::string& event_name,
329         scoped_ptr<base::ListValue> event_args);
330
331   Event(const std::string& event_name,
332         scoped_ptr<base::ListValue> event_args,
333         content::BrowserContext* restrict_to_browser_context);
334
335   Event(const std::string& event_name,
336         scoped_ptr<base::ListValue> event_args,
337         content::BrowserContext* restrict_to_browser_context,
338         const GURL& event_url,
339         EventRouter::UserGestureState user_gesture,
340         const EventFilteringInfo& info);
341
342   ~Event();
343
344   // Makes a deep copy of this instance. Ownership is transferred to the
345   // caller.
346   Event* DeepCopy();
347 };
348
349 struct EventListenerInfo {
350   EventListenerInfo(const std::string& event_name,
351                     const std::string& extension_id,
352                     content::BrowserContext* browser_context);
353   // The event name including any sub-event, e.g. "runtime.onStartup" or
354   // "webRequest.onCompleted/123".
355   const std::string event_name;
356
357   const std::string extension_id;
358   content::BrowserContext* browser_context;
359 };
360
361 }  // namespace extensions
362
363 #endif  // EXTENSIONS_BROWSER_EVENT_ROUTER_H_