Revert 264226 "Reduce dependency of TiclInvalidationService on P..."
[chromium-blink-merge.git] / extensions / browser / event_router.h
blob79a0c944d4eb06ddb3e43aebab6cb913e2d7f10f
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.
5 #ifndef EXTENSIONS_BROWSER_EVENT_ROUTER_H_
6 #define EXTENSIONS_BROWSER_EVENT_ROUTER_H_
8 #include <map>
9 #include <set>
10 #include <string>
11 #include <utility>
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"
26 class GURL;
27 class PrefService;
29 namespace content {
30 class BrowserContext;
31 class RenderProcessHost;
34 namespace extensions {
35 class ActivityLog;
36 class Extension;
37 class ExtensionHost;
38 class ExtensionPrefs;
40 struct Event;
41 struct EventDispatchInfo;
42 struct EventListenerInfo;
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,
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[];
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) {}
71 // Gets the EventRouter for |browser_context|.
72 // Shorthand for ExtensionSystem::Get(browser_context)->event_router(); it's
73 // a very common operation.
74 static EventRouter* Get(content::BrowserContext* browser_context);
76 // Converts event names like "foo.onBar/123" into "foo.onBar". Event names
77 // without a "/" are returned unchanged.
78 static std::string GetBaseEventName(const std::string& full_event_name);
80 // Sends an event via ipc_sender to the given extension. Can be called on any
81 // thread.
82 static void DispatchEvent(IPC::Sender* ipc_sender,
83 void* browser_context_id,
84 const std::string& extension_id,
85 const std::string& event_name,
86 scoped_ptr<base::ListValue> event_args,
87 UserGestureState user_gesture,
88 const EventFilteringInfo& info);
90 // An EventRouter is shared between |browser_context| and its associated
91 // incognito context. |extension_prefs| may be NULL in tests.
92 EventRouter(content::BrowserContext* browser_context,
93 ExtensionPrefs* extension_prefs);
94 virtual ~EventRouter();
96 // Add or remove the process/extension pair as a listener for |event_name|.
97 // Note that multiple extensions can share a process due to process
98 // collapsing. Also, a single extension can have 2 processes if it is a split
99 // mode extension.
100 void AddEventListener(const std::string& event_name,
101 content::RenderProcessHost* process,
102 const std::string& extension_id);
103 void RemoveEventListener(const std::string& event_name,
104 content::RenderProcessHost* process,
105 const std::string& extension_id);
107 EventListenerMap& listeners() { return listeners_; }
109 // Registers an observer to be notified when an event listener for
110 // |event_name| is added or removed. There can currently be only one observer
111 // for each distinct |event_name|.
112 void RegisterObserver(Observer* observer,
113 const std::string& event_name);
115 // Unregisters an observer from all events.
116 void UnregisterObserver(Observer* observer);
118 // Add or remove the extension as having a lazy background page that listens
119 // to the event. The difference from the above methods is that these will be
120 // remembered even after the process goes away. We use this list to decide
121 // which extension pages to load when dispatching an event.
122 void AddLazyEventListener(const std::string& event_name,
123 const std::string& extension_id);
124 void RemoveLazyEventListener(const std::string& event_name,
125 const std::string& extension_id);
127 // If |add_lazy_listener| is true also add the lazy version of this listener.
128 void AddFilteredEventListener(const std::string& event_name,
129 content::RenderProcessHost* process,
130 const std::string& extension_id,
131 const base::DictionaryValue& filter,
132 bool add_lazy_listener);
134 // If |remove_lazy_listener| is true also remove the lazy version of this
135 // listener.
136 void RemoveFilteredEventListener(const std::string& event_name,
137 content::RenderProcessHost* process,
138 const std::string& extension_id,
139 const base::DictionaryValue& filter,
140 bool remove_lazy_listener);
142 // Returns true if there is at least one listener for the given event.
143 bool HasEventListener(const std::string& event_name);
145 // Returns true if the extension is listening to the given event.
146 bool ExtensionHasEventListener(const std::string& extension_id,
147 const std::string& event_name);
149 // Return or set the list of events for which the given extension has
150 // registered.
151 std::set<std::string> GetRegisteredEvents(const std::string& extension_id);
152 void SetRegisteredEvents(const std::string& extension_id,
153 const std::set<std::string>& events);
155 // Broadcasts an event to every listener registered for that event.
156 virtual void BroadcastEvent(scoped_ptr<Event> event);
158 // Dispatches an event to the given extension.
159 virtual void DispatchEventToExtension(const std::string& extension_id,
160 scoped_ptr<Event> event);
162 // Dispatches |event| to the given extension as if the extension has a lazy
163 // listener for it. NOTE: This should be used rarely, for dispatching events
164 // to extensions that haven't had a chance to add their own listeners yet, eg:
165 // newly installed extensions.
166 void DispatchEventWithLazyListener(const std::string& extension_id,
167 scoped_ptr<Event> event);
169 // Record the Event Ack from the renderer. (One less event in-flight.)
170 void OnEventAck(content::BrowserContext* context,
171 const std::string& extension_id);
173 private:
174 FRIEND_TEST_ALL_PREFIXES(EventRouterTest, EventRouterObserver);
176 // The extension and process that contains the event listener for a given
177 // event.
178 struct ListenerProcess;
180 // A map between an event name and a set of extensions that are listening
181 // to that event.
182 typedef std::map<std::string, std::set<ListenerProcess> > ListenerMap;
184 // An identifier for an event dispatch that is used to prevent double dispatch
185 // due to race conditions between the direct and lazy dispatch paths.
186 typedef std::pair<const content::BrowserContext*, std::string>
187 EventDispatchIdentifier;
189 // TODO(gdk): Document this.
190 static void DispatchExtensionMessage(
191 IPC::Sender* ipc_sender,
192 void* browser_context_id,
193 const std::string& extension_id,
194 const std::string& event_name,
195 base::ListValue* event_args,
196 UserGestureState user_gesture,
197 const extensions::EventFilteringInfo& info);
199 virtual void Observe(int type,
200 const content::NotificationSource& source,
201 const content::NotificationDetails& details) OVERRIDE;
203 // Returns true if the given listener map contains a event listeners for
204 // the given event. If |extension_id| is non-empty, we also check that that
205 // extension is one of the listeners.
206 bool HasEventListenerImpl(const ListenerMap& listeners,
207 const std::string& extension_id,
208 const std::string& event_name);
210 // Shared by DispatchEvent*. If |restrict_to_extension_id| is empty, the
211 // event is broadcast.
212 // An event that just came off the pending list may not be delayed again.
213 void DispatchEventImpl(const std::string& restrict_to_extension_id,
214 const linked_ptr<Event>& event);
216 // Ensures that all lazy background pages that are interested in the given
217 // event are loaded, and queues the event if the page is not ready yet.
218 // Inserts an EventDispatchIdentifier into |already_dispatched| for each lazy
219 // event dispatch that is queued.
220 void DispatchLazyEvent(const std::string& extension_id,
221 const linked_ptr<Event>& event,
222 std::set<EventDispatchIdentifier>* already_dispatched);
224 // Dispatches the event to the specified extension running in |process|.
225 void DispatchEventToProcess(const std::string& extension_id,
226 content::RenderProcessHost* process,
227 const linked_ptr<Event>& event);
229 // Returns false when the event is scoped to a context and the listening
230 // extension does not have access to events from that context. Also fills
231 // |event_args| with the proper arguments to send, which may differ if
232 // the event crosses the incognito boundary.
233 bool CanDispatchEventToBrowserContext(content::BrowserContext* context,
234 const Extension* extension,
235 const linked_ptr<Event>& event);
237 // Possibly loads given extension's background page in preparation to
238 // dispatch an event. Returns true if the event was queued for subsequent
239 // dispatch, false otherwise.
240 bool MaybeLoadLazyBackgroundPageToDispatchEvent(
241 content::BrowserContext* context,
242 const Extension* extension,
243 const linked_ptr<Event>& event);
245 // Adds a filter to an event.
246 void AddFilterToEvent(const std::string& event_name,
247 const std::string& extension_id,
248 const base::DictionaryValue* filter);
250 // Removes a filter from an event.
251 void RemoveFilterFromEvent(const std::string& event_name,
252 const std::string& extension_id,
253 const base::DictionaryValue* filter);
255 // Returns the dictionary of event filters that the given extension has
256 // registered.
257 const base::DictionaryValue* GetFilteredEvents(
258 const std::string& extension_id);
260 // Track of the number of dispatched events that have not yet sent an
261 // ACK from the renderer.
262 void IncrementInFlightEvents(content::BrowserContext* context,
263 const Extension* extension);
265 // static
266 static void IncrementInFlightEventsOnUI(
267 void* browser_context_id,
268 const std::string& extension_id);
270 void DispatchPendingEvent(const linked_ptr<Event>& event,
271 ExtensionHost* host);
273 // Implementation of EventListenerMap::Delegate.
274 virtual void OnListenerAdded(const EventListener* listener) OVERRIDE;
275 virtual void OnListenerRemoved(const EventListener* listener) OVERRIDE;
277 content::BrowserContext* browser_context_;
279 // The ExtensionPrefs associated with |browser_context_|. May be NULL in
280 // tests.
281 ExtensionPrefs* extension_prefs_;
283 content::NotificationRegistrar registrar_;
285 EventListenerMap listeners_;
287 // Map from base event name to observer.
288 typedef base::hash_map<std::string, Observer*> ObserverMap;
289 ObserverMap observers_;
291 DISALLOW_COPY_AND_ASSIGN(EventRouter);
294 struct Event {
295 typedef base::Callback<void(content::BrowserContext*,
296 const Extension*,
297 base::ListValue*)> WillDispatchCallback;
299 // The event to dispatch.
300 std::string event_name;
302 // Arguments to send to the event listener.
303 scoped_ptr<base::ListValue> event_args;
305 // If non-NULL, then the event will not be sent to other BrowserContexts
306 // unless the extension has permission (e.g. incognito tab update -> normal
307 // tab only works if extension is allowed incognito access).
308 content::BrowserContext* restrict_to_browser_context;
310 // If not empty, the event is only sent to extensions with host permissions
311 // for this url.
312 GURL event_url;
314 // Whether a user gesture triggered the event.
315 EventRouter::UserGestureState user_gesture;
317 // Extra information used to filter which events are sent to the listener.
318 EventFilteringInfo filter_info;
320 // If specified, this is called before dispatching an event to each
321 // extension. The third argument is a mutable reference to event_args,
322 // allowing the caller to provide different arguments depending on the
323 // extension and profile. This is guaranteed to be called synchronously with
324 // DispatchEvent, so callers don't need to worry about lifetime.
325 WillDispatchCallback will_dispatch_callback;
327 // If true, this event will always be dispatched to ephemeral apps, regardless
328 // of whether they are running or inactive. Defaults to false.
329 // Most events can only be dispatched to ephemeral apps that are already
330 // running. Cached ephemeral apps are inactive until launched by the user.
331 bool can_load_ephemeral_apps;
333 Event(const std::string& event_name,
334 scoped_ptr<base::ListValue> event_args);
336 Event(const std::string& event_name,
337 scoped_ptr<base::ListValue> event_args,
338 content::BrowserContext* restrict_to_browser_context);
340 Event(const std::string& event_name,
341 scoped_ptr<base::ListValue> event_args,
342 content::BrowserContext* restrict_to_browser_context,
343 const GURL& event_url,
344 EventRouter::UserGestureState user_gesture,
345 const EventFilteringInfo& info);
347 ~Event();
349 // Makes a deep copy of this instance. Ownership is transferred to the
350 // caller.
351 Event* DeepCopy();
354 struct EventListenerInfo {
355 EventListenerInfo(const std::string& event_name,
356 const std::string& extension_id,
357 content::BrowserContext* browser_context);
358 // The event name including any sub-event, e.g. "runtime.onStartup" or
359 // "webRequest.onCompleted/123".
360 const std::string event_name;
362 const std::string extension_id;
363 content::BrowserContext* browser_context;
366 } // namespace extensions
368 #endif // EXTENSIONS_BROWSER_EVENT_ROUTER_H_