blob: 4afc4a265f26dbb501029ad6d4d4d2483c84852c [file] [log] [blame]
[email protected]9e6720a2012-01-24 02:30:561// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]2c699652010-10-15 18:22:412// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_EVENT_ROUTER_H_
6#define CHROME_BROWSER_EXTENSIONS_EXTENSION_EVENT_ROUTER_H_
7#pragma once
8
9#include <map>
10#include <set>
11#include <string>
12
[email protected]17902752011-08-31 22:52:5413#include "base/compiler_specific.h"
[email protected]f72d0c62011-08-31 16:27:4414#include "base/memory/linked_ptr.h"
[email protected]3b63f8f42011-03-28 01:54:1515#include "base/memory/ref_counted.h"
[email protected]8a16a032012-06-18 19:37:3116#include "base/values.h"
[email protected]d9e559d2012-07-05 01:04:5717#include "chrome/browser/extensions/event_listener_map.h"
18#include "chrome/common/extensions/event_filtering_info.h"
[email protected]6c2381d2011-10-19 02:52:5319#include "content/public/browser/notification_observer.h"
20#include "content/public/browser/notification_registrar.h"
[email protected]b44f8ad2012-06-15 20:52:5821#include "ipc/ipc_sender.h"
[email protected]2c699652010-10-15 18:22:4122
23class GURL;
[email protected]b6536df2012-03-16 18:55:2324class ExtensionHost;
[email protected]2c699652010-10-15 18:22:4125class ExtensionDevToolsManager;
26class Profile;
[email protected]f3b1a082011-11-18 00:34:3027
28namespace content {
[email protected]2c699652010-10-15 18:22:4129class RenderProcessHost;
[email protected]f3b1a082011-11-18 00:34:3030}
[email protected]2c699652010-10-15 18:22:4131
[email protected]1c321ee52012-05-21 03:02:3432namespace extensions {
33class Extension;
34}
35
[email protected]d9e559d2012-07-05 01:04:5736struct ExtensionEvent;
37
38using extensions::EventFilteringInfo;
39using extensions::EventListener;
40using extensions::EventListenerMap;
41
42class ExtensionEventRouter : public content::NotificationObserver,
43 public extensions::EventListenerMap::Delegate {
[email protected]2c699652010-10-15 18:22:4144 public:
[email protected]b085856f2012-03-02 04:37:2545 // These constants convey the state of our knowledge of whether we're in
46 // a user-caused gesture as part of DispatchEvent.
47 enum UserGestureState {
48 USER_GESTURE_UNKNOWN = 0,
49 USER_GESTURE_ENABLED = 1,
50 USER_GESTURE_NOT_ENABLED = 2,
51 };
52
[email protected]c357acb42011-06-09 20:52:4253 // Sends an event via ipc_sender to the given extension. Can be called on
54 // any thread.
[email protected]b44f8ad2012-06-15 20:52:5855 static void DispatchEvent(IPC::Sender* ipc_sender,
[email protected]c357acb42011-06-09 20:52:4256 const std::string& extension_id,
57 const std::string& event_name,
[email protected]8a16a032012-06-18 19:37:3158 const base::Value& event_args,
59 const GURL& event_url,
[email protected]d9e559d2012-07-05 01:04:5760 UserGestureState user_gesture,
61 const extensions::EventFilteringInfo& info);
[email protected]8a16a032012-06-18 19:37:3162
63 // This invocation is deprecated. All future consumers of this API should be
64 // sending Values as event arguments, using the above version.
65 static void DispatchEvent(IPC::Sender* ipc_sender,
66 const std::string& extension_id,
67 const std::string& event_name,
[email protected]c357acb42011-06-09 20:52:4268 const std::string& event_args,
[email protected]b085856f2012-03-02 04:37:2569 const GURL& event_url,
[email protected]d9e559d2012-07-05 01:04:5770 UserGestureState user_gesture,
71 const extensions::EventFilteringInfo& info);
[email protected]5a7b5eaf2010-11-02 20:52:1972
[email protected]2c699652010-10-15 18:22:4173 explicit ExtensionEventRouter(Profile* profile);
[email protected]3690ebe02011-05-25 09:08:1974 virtual ~ExtensionEventRouter();
[email protected]2c699652010-10-15 18:22:4175
[email protected]a7ab1b782010-10-21 23:24:1676 // Add or remove the process/extension pair as a listener for |event_name|.
77 // Note that multiple extensions can share a process due to process
78 // collapsing. Also, a single extension can have 2 processes if it is a split
79 // mode extension.
[email protected]2c699652010-10-15 18:22:4180 void AddEventListener(const std::string& event_name,
[email protected]f3b1a082011-11-18 00:34:3081 content::RenderProcessHost* process,
[email protected]a7ab1b782010-10-21 23:24:1682 const std::string& extension_id);
[email protected]2c699652010-10-15 18:22:4183 void RemoveEventListener(const std::string& event_name,
[email protected]f3b1a082011-11-18 00:34:3084 content::RenderProcessHost* process,
[email protected]a7ab1b782010-10-21 23:24:1685 const std::string& extension_id);
[email protected]2c699652010-10-15 18:22:4186
[email protected]36531222012-02-07 19:41:2787 // Add or remove the extension as having a lazy background page that listens
88 // to the event. The difference from the above methods is that these will be
89 // remembered even after the process goes away. We use this list to decide
90 // which extension pages to load when dispatching an event.
91 void AddLazyEventListener(const std::string& event_name,
92 const std::string& extension_id);
93 void RemoveLazyEventListener(const std::string& event_name,
94 const std::string& extension_id);
95
[email protected]d9e559d2012-07-05 01:04:5796 // If |add_lazy_listener| is true also add the lazy version of this listener.
97 void AddFilteredEventListener(const std::string& event_name,
98 content::RenderProcessHost* process,
99 const std::string& extension_id,
100 const base::DictionaryValue& filter,
101 bool add_lazy_listener);
102
103 // If |remove_lazy_listener| is true also remove the lazy version of this
104 // listener.
105 void RemoveFilteredEventListener(const std::string& event_name,
106 content::RenderProcessHost* process,
107 const std::string& extension_id,
108 const base::DictionaryValue& filter,
109 bool remove_lazy_listener);
110
[email protected]2c699652010-10-15 18:22:41111 // Returns true if there is at least one listener for the given event.
112 bool HasEventListener(const std::string& event_name);
113
[email protected]a7ab1b782010-10-21 23:24:16114 // Returns true if the extension is listening to the given event.
115 bool ExtensionHasEventListener(const std::string& extension_id,
116 const std::string& event_name);
117
[email protected]2c699652010-10-15 18:22:41118 // Send an event to every registered extension renderer. If
119 // |restrict_to_profile| is non-NULL, then the event will not be sent to other
120 // profiles unless the extension has permission (e.g. incognito tab update ->
121 // normal profile only works if extension is allowed incognito access). If
122 // |event_url| is not empty, the event is only sent to extension with host
123 // permissions for this url.
[email protected]a7ab1b782010-10-21 23:24:16124 void DispatchEventToRenderers(
[email protected]0a184b52011-06-23 00:41:13125 const std::string& event_name,
126 const std::string& event_args,
127 Profile* restrict_to_profile,
[email protected]d9e559d2012-07-05 01:04:57128 const GURL& event_url,
129 extensions::EventFilteringInfo info);
130
131 // As above, but defaults |info| to EventFilteringInfo().
132 void DispatchEventToRenderers(
133 const std::string& event_name,
134 const std::string& event_args,
135 Profile* restrict_to_profile,
[email protected]0a184b52011-06-23 00:41:13136 const GURL& event_url);
[email protected]2c699652010-10-15 18:22:41137
[email protected]a7ab1b782010-10-21 23:24:16138 // Same as above, except only send the event to the given extension.
[email protected]f72d0c62011-08-31 16:27:44139 virtual void DispatchEventToExtension(
[email protected]2c699652010-10-15 18:22:41140 const std::string& extension_id,
[email protected]0a184b52011-06-23 00:41:13141 const std::string& event_name,
[email protected]8a16a032012-06-18 19:37:31142 const base::Value& event_args,
143 Profile* restrict_to_profile,
144 const GURL& event_url);
145
146 // This invocation is deprecated. The above variant which uses a Value for
147 // event_args is to be used instead.
148 virtual void DispatchEventToExtension(
149 const std::string& extension_id,
150 const std::string& event_name,
[email protected]0a184b52011-06-23 00:41:13151 const std::string& event_args,
152 Profile* restrict_to_profile,
153 const GURL& event_url);
154
[email protected]b085856f2012-03-02 04:37:25155 // Dispatch an event to particular extension. Also include an
156 // explicit user gesture indicator.
157 virtual void DispatchEventToExtension(
158 const std::string& extension_id,
159 const std::string& event_name,
160 const std::string& event_args,
161 Profile* restrict_to_profile,
162 const GURL& event_url,
163 UserGestureState user_gesture);
164
[email protected]0a184b52011-06-23 00:41:13165 // Send different versions of an event to extensions in different profiles.
166 // This is used in the case of sending one event to extensions that have
167 // incognito access, and another event to extensions that don't (here),
168 // in order to avoid sending 2 events to "spanning" extensions.
169 // If |cross_incognito_profile| is non-NULL and different from
170 // restrict_to_profile, send the event with cross_incognito_args to the
171 // extensions in that profile that can't cross incognito.
172 void DispatchEventsToRenderersAcrossIncognito(
173 const std::string& event_name,
174 const std::string& event_args,
175 Profile* restrict_to_profile,
176 const std::string& cross_incognito_args,
177 const GURL& event_url);
[email protected]2c699652010-10-15 18:22:41178
[email protected]89102012011-11-01 21:23:56179 // Record the Event Ack from the renderer. (One less event in-flight.)
[email protected]7042b682012-04-19 22:57:51180 void OnEventAck(Profile* profile, const std::string& extension_id);
[email protected]89102012011-11-01 21:23:56181
[email protected]fb6ff23b2012-03-13 23:13:42182 private:
[email protected]61f5fc82012-02-15 20:10:45183 // The extension and process that contains the event listener for a given
184 // event.
185 struct ListenerProcess;
186
187 // A map between an event name and a set of extensions that are listening
188 // to that event.
189 typedef std::map<std::string, std::set<ListenerProcess> > ListenerMap;
[email protected]a7ab1b782010-10-21 23:24:16190
[email protected]432115822011-07-10 15:52:27191 virtual void Observe(int type,
[email protected]6c2381d2011-10-19 02:52:53192 const content::NotificationSource& source,
193 const content::NotificationDetails& details) OVERRIDE;
[email protected]2c699652010-10-15 18:22:41194
[email protected]61f5fc82012-02-15 20:10:45195 // Returns true if the given listener map contains a event listeners for
196 // the given event. If |extension_id| is non-empty, we also check that that
197 // extension is one of the listeners.
198 bool HasEventListenerImpl(const ListenerMap& listeners,
199 const std::string& extension_id,
200 const std::string& event_name);
201
[email protected]d9e559d2012-07-05 01:04:57202 // Shared by DispatchEvent*. If |restrict_to_extension_id| is empty, the
203 // event is broadcast.
[email protected]fb6ff23b2012-03-13 23:13:42204 // An event that just came off the pending list may not be delayed again.
[email protected]d9e559d2012-07-05 01:04:57205 void DispatchEventImpl(const std::string& restrict_to_extension_id,
[email protected]fb6ff23b2012-03-13 23:13:42206 const linked_ptr<ExtensionEvent>& event);
207
[email protected]d9e559d2012-07-05 01:04:57208 // Ensures that all lazy background pages that are interested in the given
209 // event are loaded, and queues the event if the page is not ready yet.
210 void DispatchLazyEvent(const std::string& extension_id,
211 const linked_ptr<ExtensionEvent>& event);
212
213 // Dispatches the event to the specified extension running in |process|.
214 void DispatchEventToProcess(const std::string& extension_id,
215 content::RenderProcessHost* process,
216 const linked_ptr<ExtensionEvent>& event);
[email protected]fb6ff23b2012-03-13 23:13:42217
218 // Returns false when the event is scoped to a profile and the listening
219 // extension does not have access to events from that profile. Also fills
220 // |event_args| with the proper arguments to send, which may differ if
221 // the event crosses the incognito boundary.
222 bool CanDispatchEventToProfile(
223 Profile* profile,
[email protected]1c321ee52012-05-21 03:02:34224 const extensions::Extension* extension,
[email protected]fb6ff23b2012-03-13 23:13:42225 const linked_ptr<ExtensionEvent>& event,
[email protected]8a16a032012-06-18 19:37:31226 const base::Value** event_args);
[email protected]fb6ff23b2012-03-13 23:13:42227
[email protected]fb6ff23b2012-03-13 23:13:42228 // Possibly loads given extension's background page in preparation to
229 // dispatch an event.
[email protected]d9e559d2012-07-05 01:04:57230 void MaybeLoadLazyBackgroundPageToDispatchEvent(
[email protected]fb6ff23b2012-03-13 23:13:42231 Profile* profile,
[email protected]1c321ee52012-05-21 03:02:34232 const extensions::Extension* extension,
[email protected]fb6ff23b2012-03-13 23:13:42233 const linked_ptr<ExtensionEvent>& event);
234
[email protected]fb6ff23b2012-03-13 23:13:42235 // Track of the number of dispatched events that have not yet sent an
236 // ACK from the renderer.
[email protected]1c321ee52012-05-21 03:02:34237 void IncrementInFlightEvents(Profile* profile,
238 const extensions::Extension* extension);
[email protected]fb6ff23b2012-03-13 23:13:42239
[email protected]b6536df2012-03-16 18:55:23240 void DispatchPendingEvent(const linked_ptr<ExtensionEvent>& event,
241 ExtensionHost* host);
[email protected]fb6ff23b2012-03-13 23:13:42242
[email protected]d9e559d2012-07-05 01:04:57243 // Implementation of extensions::EventListenerMap::Delegate.
244 virtual void OnListenerAdded(const EventListener* listener) OVERRIDE;
245 virtual void OnListenerRemoved(const EventListener* listener) OVERRIDE;
246
[email protected]2c699652010-10-15 18:22:41247 Profile* profile_;
248
[email protected]6c2381d2011-10-19 02:52:53249 content::NotificationRegistrar registrar_;
[email protected]2c699652010-10-15 18:22:41250
251 scoped_refptr<ExtensionDevToolsManager> extension_devtools_manager_;
252
[email protected]d9e559d2012-07-05 01:04:57253 EventListenerMap listeners_;
[email protected]36531222012-02-07 19:41:27254
[email protected]2c699652010-10-15 18:22:41255 DISALLOW_COPY_AND_ASSIGN(ExtensionEventRouter);
256};
257
[email protected]d9e559d2012-07-05 01:04:57258struct ExtensionEvent {
259 std::string event_name;
260 scoped_ptr<Value> event_args;
261 GURL event_url;
262 Profile* restrict_to_profile;
263 scoped_ptr<Value> cross_incognito_args;
264 ExtensionEventRouter::UserGestureState user_gesture;
265 extensions::EventFilteringInfo info;
266
267 ExtensionEvent(const std::string& event_name,
268 const Value& event_args,
269 const GURL& event_url,
270 Profile* restrict_to_profile,
271 const Value& cross_incognito_args,
272 ExtensionEventRouter::UserGestureState user_gesture,
273 const extensions::EventFilteringInfo& info);
274
275 // TODO(gdk): This variant should be retired once the callers are switched to
276 // providing Values instead of just strings.
277 ExtensionEvent(const std::string& event_name,
278 const std::string& event_args,
279 const GURL& event_url,
280 Profile* restrict_to_profile,
281 const std::string& cross_incognito_args,
282 ExtensionEventRouter::UserGestureState user_gesture,
283 const extensions::EventFilteringInfo& info);
284
285 ExtensionEvent(const std::string& event_name,
286 const Value& event_args,
287 const GURL& event_url,
288 Profile* restrict_to_profile,
289 ExtensionEventRouter::UserGestureState user_gesture,
290 const extensions::EventFilteringInfo& info);
291
292 ~ExtensionEvent();
293};
294
295
[email protected]2c699652010-10-15 18:22:41296#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_EVENT_ROUTER_H_