OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_EVENT_ROUTER_H_ | 5 #ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_EVENT_ROUTER_H_ |
6 #define CHROME_BROWSER_EXTENSIONS_EXTENSION_EVENT_ROUTER_H_ | 6 #define CHROME_BROWSER_EXTENSIONS_EXTENSION_EVENT_ROUTER_H_ |
7 #pragma once | 7 #pragma once |
8 | 8 |
9 #include <map> | 9 #include <map> |
10 #include <set> | 10 #include <set> |
11 #include <string> | 11 #include <string> |
12 | 12 |
13 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
14 #include "base/memory/linked_ptr.h" | 14 #include "base/memory/linked_ptr.h" |
15 #include "base/memory/ref_counted.h" | 15 #include "base/memory/ref_counted.h" |
16 #include "base/values.h" | 16 #include "base/values.h" |
17 #include "chrome/browser/extensions/event_listener_map.h" | |
18 #include "chrome/common/extensions/event_filtering_info.h" | |
17 #include "content/public/browser/notification_observer.h" | 19 #include "content/public/browser/notification_observer.h" |
18 #include "content/public/browser/notification_registrar.h" | 20 #include "content/public/browser/notification_registrar.h" |
19 #include "ipc/ipc_sender.h" | 21 #include "ipc/ipc_sender.h" |
20 | 22 |
21 class GURL; | 23 class GURL; |
22 class ExtensionHost; | 24 class ExtensionHost; |
23 class ExtensionDevToolsManager; | 25 class ExtensionDevToolsManager; |
24 class Profile; | 26 class Profile; |
25 | 27 |
26 namespace content { | 28 namespace content { |
27 class RenderProcessHost; | 29 class RenderProcessHost; |
28 } | 30 } |
29 | 31 |
30 namespace extensions { | 32 namespace extensions { |
31 class Extension; | 33 class Extension; |
32 } | 34 } |
33 | 35 |
34 class ExtensionEventRouter : public content::NotificationObserver { | 36 struct ExtensionEvent; |
37 | |
38 using extensions::EventFilteringInfo; | |
39 using extensions::EventListener; | |
40 using extensions::EventListenerMap; | |
41 | |
42 class ExtensionEventRouter : public content::NotificationObserver, | |
43 public extensions::EventListenerMap::Delegate { | |
35 public: | 44 public: |
36 // These constants convey the state of our knowledge of whether we're in | 45 // These constants convey the state of our knowledge of whether we're in |
37 // a user-caused gesture as part of DispatchEvent. | 46 // a user-caused gesture as part of DispatchEvent. |
38 enum UserGestureState { | 47 enum UserGestureState { |
39 USER_GESTURE_UNKNOWN = 0, | 48 USER_GESTURE_UNKNOWN = 0, |
40 USER_GESTURE_ENABLED = 1, | 49 USER_GESTURE_ENABLED = 1, |
41 USER_GESTURE_NOT_ENABLED = 2, | 50 USER_GESTURE_NOT_ENABLED = 2, |
42 }; | 51 }; |
43 | 52 |
44 // Sends an event via ipc_sender to the given extension. Can be called on | 53 // Sends an event via ipc_sender to the given extension. Can be called on |
45 // any thread. | 54 // any thread. |
46 static void DispatchEvent(IPC::Sender* ipc_sender, | 55 static void DispatchEvent(IPC::Sender* ipc_sender, |
47 const std::string& extension_id, | 56 const std::string& extension_id, |
48 const std::string& event_name, | 57 const std::string& event_name, |
49 const base::Value& event_args, | 58 const base::Value& event_args, |
50 const GURL& event_url, | 59 const GURL& event_url, |
51 UserGestureState user_gesture); | 60 UserGestureState user_gesture, |
61 const extensions::EventFilteringInfo& info); | |
52 | 62 |
53 // This invocation is deprecated. All future consumers of this API should be | 63 // This invocation is deprecated. All future consumers of this API should be |
54 // sending Values as event arguments, using the above version. | 64 // sending Values as event arguments, using the above version. |
55 static void DispatchEvent(IPC::Sender* ipc_sender, | 65 static void DispatchEvent(IPC::Sender* ipc_sender, |
56 const std::string& extension_id, | 66 const std::string& extension_id, |
57 const std::string& event_name, | 67 const std::string& event_name, |
58 const std::string& event_args, | 68 const std::string& event_args, |
59 const GURL& event_url, | 69 const GURL& event_url, |
60 UserGestureState user_gesture); | 70 UserGestureState user_gesture, |
71 const extensions::EventFilteringInfo& info); | |
61 | 72 |
62 explicit ExtensionEventRouter(Profile* profile); | 73 explicit ExtensionEventRouter(Profile* profile); |
63 virtual ~ExtensionEventRouter(); | 74 virtual ~ExtensionEventRouter(); |
64 | 75 |
65 // Add or remove the process/extension pair as a listener for |event_name|. | 76 // Add or remove the process/extension pair as a listener for |event_name|. |
66 // Note that multiple extensions can share a process due to process | 77 // Note that multiple extensions can share a process due to process |
67 // collapsing. Also, a single extension can have 2 processes if it is a split | 78 // collapsing. Also, a single extension can have 2 processes if it is a split |
68 // mode extension. | 79 // mode extension. |
69 void AddEventListener(const std::string& event_name, | 80 void AddEventListener(const std::string& event_name, |
70 content::RenderProcessHost* process, | 81 content::RenderProcessHost* process, |
71 const std::string& extension_id); | 82 const std::string& extension_id); |
72 void RemoveEventListener(const std::string& event_name, | 83 void RemoveEventListener(const std::string& event_name, |
73 content::RenderProcessHost* process, | 84 content::RenderProcessHost* process, |
74 const std::string& extension_id); | 85 const std::string& extension_id); |
75 | 86 |
76 // Add or remove the extension as having a lazy background page that listens | 87 // Add or remove the extension as having a lazy background page that listens |
77 // to the event. The difference from the above methods is that these will be | 88 // to the event. The difference from the above methods is that these will be |
78 // remembered even after the process goes away. We use this list to decide | 89 // remembered even after the process goes away. We use this list to decide |
79 // which extension pages to load when dispatching an event. | 90 // which extension pages to load when dispatching an event. |
80 void AddLazyEventListener(const std::string& event_name, | 91 void AddLazyEventListener(const std::string& event_name, |
81 const std::string& extension_id); | 92 const std::string& extension_id); |
82 void RemoveLazyEventListener(const std::string& event_name, | 93 void RemoveLazyEventListener(const std::string& event_name, |
83 const std::string& extension_id); | 94 const std::string& extension_id); |
84 | 95 |
96 // 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); | |
battre
2012/06/19 14:26:23
nit: indent
koz (OOO until 15th September)
2012/06/20 08:05:56
Done.
| |
110 | |
85 // Returns true if there is at least one listener for the given event. | 111 // Returns true if there is at least one listener for the given event. |
86 bool HasEventListener(const std::string& event_name); | 112 bool HasEventListener(const std::string& event_name); |
87 | 113 |
88 // Returns true if the extension is listening to the given event. | 114 // Returns true if the extension is listening to the given event. |
89 bool ExtensionHasEventListener(const std::string& extension_id, | 115 bool ExtensionHasEventListener(const std::string& extension_id, |
90 const std::string& event_name); | 116 const std::string& event_name); |
91 | 117 |
92 // Send an event to every registered extension renderer. If | 118 // Send an event to every registered extension renderer. If |
93 // |restrict_to_profile| is non-NULL, then the event will not be sent to other | 119 // |restrict_to_profile| is non-NULL, then the event will not be sent to other |
94 // profiles unless the extension has permission (e.g. incognito tab update -> | 120 // profiles unless the extension has permission (e.g. incognito tab update -> |
95 // normal profile only works if extension is allowed incognito access). If | 121 // normal profile only works if extension is allowed incognito access). If |
96 // |event_url| is not empty, the event is only sent to extension with host | 122 // |event_url| is not empty, the event is only sent to extension with host |
97 // permissions for this url. | 123 // permissions for this url. |
98 void DispatchEventToRenderers( | 124 void DispatchEventToRenderers( |
99 const std::string& event_name, | 125 const std::string& event_name, |
100 const std::string& event_args, | 126 const std::string& event_args, |
101 Profile* restrict_to_profile, | 127 Profile* restrict_to_profile, |
102 const GURL& event_url); | 128 const GURL& event_url, |
129 extensions::EventFilteringInfo info); | |
103 | 130 |
104 // Same as above, except only send the event to the given extension. | 131 // Same as above, except only send the event to the given extension. |
105 virtual void DispatchEventToExtension( | 132 virtual void DispatchEventToExtension( |
106 const std::string& extension_id, | 133 const std::string& extension_id, |
107 const std::string& event_name, | 134 const std::string& event_name, |
108 const base::Value& event_args, | 135 const base::Value& event_args, |
109 Profile* restrict_to_profile, | 136 Profile* restrict_to_profile, |
110 const GURL& event_url); | 137 const GURL& event_url); |
111 | 138 |
112 // This invocation is deprecated. The above variant which uses a Value for | 139 // This invocation is deprecated. The above variant which uses a Value for |
(...skipping 26 matching lines...) Expand all Loading... | |
139 const std::string& event_name, | 166 const std::string& event_name, |
140 const std::string& event_args, | 167 const std::string& event_args, |
141 Profile* restrict_to_profile, | 168 Profile* restrict_to_profile, |
142 const std::string& cross_incognito_args, | 169 const std::string& cross_incognito_args, |
143 const GURL& event_url); | 170 const GURL& event_url); |
144 | 171 |
145 // Record the Event Ack from the renderer. (One less event in-flight.) | 172 // Record the Event Ack from the renderer. (One less event in-flight.) |
146 void OnEventAck(Profile* profile, const std::string& extension_id); | 173 void OnEventAck(Profile* profile, const std::string& extension_id); |
147 | 174 |
148 private: | 175 private: |
149 // The details of an event to be dispatched. | |
150 struct ExtensionEvent; | |
151 | |
152 // The extension and process that contains the event listener for a given | 176 // The extension and process that contains the event listener for a given |
153 // event. | 177 // event. |
154 struct ListenerProcess; | 178 struct ListenerProcess; |
155 | 179 |
156 // A map between an event name and a set of extensions that are listening | 180 // A map between an event name and a set of extensions that are listening |
157 // to that event. | 181 // to that event. |
158 typedef std::map<std::string, std::set<ListenerProcess> > ListenerMap; | 182 typedef std::map<std::string, std::set<ListenerProcess> > ListenerMap; |
159 | 183 |
160 virtual void Observe(int type, | 184 virtual void Observe(int type, |
161 const content::NotificationSource& source, | 185 const content::NotificationSource& source, |
162 const content::NotificationDetails& details) OVERRIDE; | 186 const content::NotificationDetails& details) OVERRIDE; |
163 | 187 |
164 // Returns true if the given listener map contains a event listeners for | 188 // Returns true if the given listener map contains a event listeners for |
165 // the given event. If |extension_id| is non-empty, we also check that that | 189 // the given event. If |extension_id| is non-empty, we also check that that |
166 // extension is one of the listeners. | 190 // extension is one of the listeners. |
167 bool HasEventListenerImpl(const ListenerMap& listeners, | 191 bool HasEventListenerImpl(const ListenerMap& listeners, |
168 const std::string& extension_id, | 192 const std::string& extension_id, |
169 const std::string& event_name); | 193 const std::string& event_name); |
170 | 194 |
171 // Shared by DispatchEvent*. If |extension_id| is empty, the event is | 195 // Shared by DispatchEvent*. If |extension_id| is empty, the event is |
battre
2012/06/19 14:26:23
update comment (|extension_id| is renamed)
koz (OOO until 15th September)
2012/06/20 08:05:56
Done.
| |
172 // broadcast. If |process| is non-NULL, the event is only dispatched to that | 196 // broadcast. If |process| is non-NULL, the event is only dispatched to that |
battre
2012/06/19 14:26:23
can you also update this? there is no |process| an
koz (OOO until 15th September)
2012/06/20 08:05:56
Done.
| |
173 // particular process. | 197 // particular process. |
174 // An event that just came off the pending list may not be delayed again. | 198 // An event that just came off the pending list may not be delayed again. |
175 void DispatchEventImpl(const std::string& extension_id, | 199 void DispatchEventImpl(const std::string& restrict_to_extension_id, |
176 const linked_ptr<ExtensionEvent>& event); | 200 const linked_ptr<ExtensionEvent>& event); |
177 | 201 |
178 // Dispatches the event to a single listener process. | 202 // Ensures that all lazy background pages that are interested in the given |
179 void DispatchEventToListener(const ListenerProcess& listener, | 203 // event are loaded, and queues the event if the page is not ready yet. |
180 const linked_ptr<ExtensionEvent>& event); | 204 void DispatchLazyEvent(const std::string& extension_id, |
205 const linked_ptr<ExtensionEvent>& event); | |
206 | |
207 // Dispatches the event to the specified extension running in |process|. | |
208 void DispatchEventToProcess(const std::string& extension_id, | |
209 content::RenderProcessHost* process, | |
210 const linked_ptr<ExtensionEvent>& event); | |
181 | 211 |
182 // Returns false when the event is scoped to a profile and the listening | 212 // Returns false when the event is scoped to a profile and the listening |
183 // extension does not have access to events from that profile. Also fills | 213 // extension does not have access to events from that profile. Also fills |
184 // |event_args| with the proper arguments to send, which may differ if | 214 // |event_args| with the proper arguments to send, which may differ if |
185 // the event crosses the incognito boundary. | 215 // the event crosses the incognito boundary. |
186 bool CanDispatchEventToProfile( | 216 bool CanDispatchEventToProfile( |
187 Profile* profile, | 217 Profile* profile, |
188 const extensions::Extension* extension, | 218 const extensions::Extension* extension, |
189 const linked_ptr<ExtensionEvent>& event, | 219 const linked_ptr<ExtensionEvent>& event, |
190 const base::Value** event_args); | 220 const base::Value** event_args); |
191 | 221 |
192 // Ensures that all lazy background pages that are interested in the given | |
193 // event are loaded, and queues the event if the page is not ready yet. | |
194 // If |extension_id| is non-empty, we load only that extension's page | |
195 // (assuming it is interested in the event). | |
196 void LoadLazyBackgroundPagesForEvent( | |
197 const std::string& extension_id, | |
198 const linked_ptr<ExtensionEvent>& event); | |
199 | |
200 // Possibly loads given extension's background page in preparation to | 222 // Possibly loads given extension's background page in preparation to |
201 // dispatch an event. | 223 // dispatch an event. |
202 void MaybeLoadLazyBackgroundPage( | 224 void MaybeLoadLazyBackgroundPage( |
203 Profile* profile, | 225 Profile* profile, |
204 const extensions::Extension* extension, | 226 const extensions::Extension* extension, |
205 const linked_ptr<ExtensionEvent>& event); | 227 const linked_ptr<ExtensionEvent>& event); |
206 | 228 |
207 // Track of the number of dispatched events that have not yet sent an | 229 // Track of the number of dispatched events that have not yet sent an |
208 // ACK from the renderer. | 230 // ACK from the renderer. |
209 void IncrementInFlightEvents(Profile* profile, | 231 void IncrementInFlightEvents(Profile* profile, |
210 const extensions::Extension* extension); | 232 const extensions::Extension* extension); |
211 | 233 |
212 void DispatchPendingEvent(const linked_ptr<ExtensionEvent>& event, | 234 void DispatchPendingEvent(const linked_ptr<ExtensionEvent>& event, |
213 ExtensionHost* host); | 235 ExtensionHost* host); |
214 | 236 |
battre
2012/06/19 14:26:23
// Implementation of extensions::EventListenerMap:
koz (OOO until 15th September)
2012/06/20 08:05:56
Done.
| |
237 void OnListenerAdded(const EventListener* listener) OVERRIDE; | |
238 void OnListenerRemoved(const EventListener* listener) OVERRIDE; | |
239 | |
215 Profile* profile_; | 240 Profile* profile_; |
216 | 241 |
217 content::NotificationRegistrar registrar_; | 242 content::NotificationRegistrar registrar_; |
218 | 243 |
219 scoped_refptr<ExtensionDevToolsManager> extension_devtools_manager_; | 244 scoped_refptr<ExtensionDevToolsManager> extension_devtools_manager_; |
220 | 245 |
221 // The list of active extension processes that are listening to events. | 246 EventListenerMap listeners_; |
222 ListenerMap listeners_; | |
223 | |
224 // The list of all the lazy (non-persistent) background pages that are | |
225 // listening to events. This is just a cache of the real list, which is | |
226 // stored on disk in the extension prefs. | |
227 ListenerMap lazy_listeners_; | |
228 | 247 |
229 DISALLOW_COPY_AND_ASSIGN(ExtensionEventRouter); | 248 DISALLOW_COPY_AND_ASSIGN(ExtensionEventRouter); |
230 }; | 249 }; |
231 | 250 |
251 struct ExtensionEvent { | |
252 std::string event_name; | |
253 scoped_ptr<Value> event_args; | |
254 GURL event_url; | |
255 Profile* restrict_to_profile; | |
256 scoped_ptr<Value> cross_incognito_args; | |
257 ExtensionEventRouter::UserGestureState user_gesture; | |
258 extensions::EventFilteringInfo info; | |
259 | |
260 ExtensionEvent(const std::string& event_name, | |
261 const Value& event_args, | |
262 const GURL& event_url, | |
263 Profile* restrict_to_profile, | |
264 const Value& cross_incognito_args, | |
265 ExtensionEventRouter::UserGestureState user_gesture, | |
266 const extensions::EventFilteringInfo& info); | |
267 | |
268 // TODO(gdk): This variant should be retired once the callers are switched to | |
269 // providing Values instead of just strings. | |
270 ExtensionEvent(const std::string& event_name, | |
271 const std::string& event_args, | |
272 const GURL& event_url, | |
273 Profile* restrict_to_profile, | |
274 const std::string& cross_incognito_args, | |
275 ExtensionEventRouter::UserGestureState user_gesture, | |
276 const extensions::EventFilteringInfo& info); | |
277 | |
278 ExtensionEvent(const std::string& event_name, | |
279 const Value& event_args, | |
280 const GURL& event_url, | |
281 Profile* restrict_to_profile, | |
282 ExtensionEventRouter::UserGestureState user_gesture, | |
283 const extensions::EventFilteringInfo& info); | |
284 | |
285 ~ExtensionEvent(); | |
286 }; | |
287 | |
288 | |
232 #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_EVENT_ROUTER_H_ | 289 #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_EVENT_ROUTER_H_ |
OLD | NEW |