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