Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(36)

Side by Side Diff: extensions/browser/event_router.h

Issue 2886923002: [extension SW]: Support event listener registration and event dispatching. (Closed)
Patch Set: address comments Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 EXTENSIONS_BROWSER_EVENT_ROUTER_H_ 5 #ifndef EXTENSIONS_BROWSER_EVENT_ROUTER_H_
6 #define EXTENSIONS_BROWSER_EVENT_ROUTER_H_ 6 #define EXTENSIONS_BROWSER_EVENT_ROUTER_H_
7 7
8 #include <set> 8 #include <set>
9 #include <string> 9 #include <string>
10 #include <unordered_map> 10 #include <unordered_map>
11 #include <utility> 11 #include <utility>
12 12
13 #include "base/callback.h" 13 #include "base/callback.h"
14 #include "base/compiler_specific.h" 14 #include "base/compiler_specific.h"
15 #include "base/macros.h" 15 #include "base/macros.h"
16 #include "base/memory/linked_ptr.h" 16 #include "base/memory/linked_ptr.h"
17 #include "base/memory/ref_counted.h" 17 #include "base/memory/ref_counted.h"
18 #include "base/scoped_observer.h" 18 #include "base/scoped_observer.h"
19 #include "base/values.h" 19 #include "base/values.h"
20 #include "components/keyed_service/core/keyed_service.h" 20 #include "components/keyed_service/core/keyed_service.h"
21 #include "content/public/browser/notification_observer.h" 21 #include "content/public/browser/notification_observer.h"
22 #include "content/public/browser/notification_registrar.h" 22 #include "content/public/browser/notification_registrar.h"
23 #include "content/public/browser/render_process_host_observer.h" 23 #include "content/public/browser/render_process_host_observer.h"
24 #include "extensions/browser/event_listener_map.h" 24 #include "extensions/browser/event_listener_map.h"
25 #include "extensions/browser/extension_event_histogram_value.h" 25 #include "extensions/browser/extension_event_histogram_value.h"
26 #include "extensions/browser/extension_registry_observer.h" 26 #include "extensions/browser/extension_registry_observer.h"
27 #include "extensions/common/constants.h"
27 #include "extensions/common/event_filtering_info.h" 28 #include "extensions/common/event_filtering_info.h"
28 #include "ipc/ipc_sender.h" 29 #include "ipc/ipc_sender.h"
29 #include "url/gurl.h" 30 #include "url/gurl.h"
30 31
31 class GURL; 32 class GURL;
32 33
33 namespace content { 34 namespace content {
34 class BrowserContext; 35 class BrowserContext;
35 class RenderProcessHost; 36 class RenderProcessHost;
36 } 37 }
(...skipping 16 matching lines...) Expand all
53 // These constants convey the state of our knowledge of whether we're in 54 // These constants convey the state of our knowledge of whether we're in
54 // a user-caused gesture as part of DispatchEvent. 55 // a user-caused gesture as part of DispatchEvent.
55 enum UserGestureState { 56 enum UserGestureState {
56 USER_GESTURE_UNKNOWN = 0, 57 USER_GESTURE_UNKNOWN = 0,
57 USER_GESTURE_ENABLED = 1, 58 USER_GESTURE_ENABLED = 1,
58 USER_GESTURE_NOT_ENABLED = 2, 59 USER_GESTURE_NOT_ENABLED = 2,
59 }; 60 };
60 61
61 // The pref key for the list of event names for which an extension has 62 // The pref key for the list of event names for which an extension has
62 // registered from its lazy background page. 63 // registered from its lazy background page.
63 static const char kRegisteredEvents[]; 64 static const char kRegisteredLazyEvents[];
65 // The pref key for the list of event names for which an extension has
66 // registered from its service worker.
67 static const char kRegisteredServiceWorkerEvents[];
64 68
65 // Observers register interest in events with a particular name and are 69 // Observers register interest in events with a particular name and are
66 // notified when a listener is added or removed. Observers are matched by 70 // notified when a listener is added or removed. Observers are matched by
67 // the base name of the event (e.g. adding an event listener for event name 71 // the base name of the event (e.g. adding an event listener for event name
68 // "foo.onBar/123" will trigger observers registered for "foo.onBar"). 72 // "foo.onBar/123" will trigger observers registered for "foo.onBar").
69 class Observer { 73 class Observer {
70 public: 74 public:
71 // Called when a listener is added. 75 // Called when a listener is added.
72 virtual void OnListenerAdded(const EventListenerInfo& details) {} 76 virtual void OnListenerAdded(const EventListenerInfo& details) {}
73 // Called when a listener is removed. 77 // Called when a listener is removed.
(...skipping 30 matching lines...) Expand all
104 ExtensionPrefs* extension_prefs); 108 ExtensionPrefs* extension_prefs);
105 ~EventRouter() override; 109 ~EventRouter() override;
106 110
107 // Add or remove an extension as an event listener for |event_name|. 111 // Add or remove an extension as an event listener for |event_name|.
108 // 112 //
109 // Note that multiple extensions can share a process due to process 113 // Note that multiple extensions can share a process due to process
110 // collapsing. Also, a single extension can have 2 processes if it is a split 114 // collapsing. Also, a single extension can have 2 processes if it is a split
111 // mode extension. 115 // mode extension.
112 void AddEventListener(const std::string& event_name, 116 void AddEventListener(const std::string& event_name,
113 content::RenderProcessHost* process, 117 content::RenderProcessHost* process,
114 const std::string& extension_id); 118 const ExtensionId& extension_id);
119 void AddServiceWorkerEventListener(const std::string& event_name,
120 content::RenderProcessHost* process,
121 const ExtensionId& extension_id,
122 int worker_thread_id);
115 void RemoveEventListener(const std::string& event_name, 123 void RemoveEventListener(const std::string& event_name,
116 content::RenderProcessHost* process, 124 content::RenderProcessHost* process,
117 const std::string& extension_id); 125 const ExtensionId& extension_id);
126 void RemoveServiceWorkerEventListener(const std::string& event_name,
127 content::RenderProcessHost* process,
128 const ExtensionId& extension_id,
129 int worker_thread_id);
118 130
119 // Add or remove a URL as an event listener for |event_name|. 131 // Add or remove a URL as an event listener for |event_name|.
120 void AddEventListenerForURL(const std::string& event_name, 132 void AddEventListenerForURL(const std::string& event_name,
121 content::RenderProcessHost* process, 133 content::RenderProcessHost* process,
122 const GURL& listener_url); 134 const GURL& listener_url);
123 void RemoveEventListenerForURL(const std::string& event_name, 135 void RemoveEventListenerForURL(const std::string& event_name,
124 content::RenderProcessHost* process, 136 content::RenderProcessHost* process,
125 const GURL& listener_url); 137 const GURL& listener_url);
126 138
127 EventListenerMap& listeners() { return listeners_; } 139 EventListenerMap& listeners() { return listeners_; }
128 140
129 // Registers an observer to be notified when an event listener for 141 // Registers an observer to be notified when an event listener for
130 // |event_name| is added or removed. There can currently be only one observer 142 // |event_name| is added or removed. There can currently be only one observer
131 // for each distinct |event_name|. 143 // for each distinct |event_name|.
132 void RegisterObserver(Observer* observer, const std::string& event_name); 144 void RegisterObserver(Observer* observer, const std::string& event_name);
133 145
134 // Unregisters an observer from all events. 146 // Unregisters an observer from all events.
135 void UnregisterObserver(Observer* observer); 147 void UnregisterObserver(Observer* observer);
136 148
137 // Add or remove the extension as having a lazy background page that listens 149 // Add or remove the extension as having a lazy background page that listens
138 // to the event. The difference from the above methods is that these will be 150 // to the event. The difference from the above methods is that these will be
139 // remembered even after the process goes away. We use this list to decide 151 // remembered even after the process goes away. We use this list to decide
140 // which extension pages to load when dispatching an event. 152 // which extension pages to load when dispatching an event.
141 void AddLazyEventListener(const std::string& event_name, 153 void AddLazyEventListener(const std::string& event_name,
142 const std::string& extension_id); 154 const ExtensionId& extension_id);
143 void RemoveLazyEventListener(const std::string& event_name, 155 void RemoveLazyEventListener(const std::string& event_name,
144 const std::string& extension_id); 156 const ExtensionId& extension_id);
157 // Similar to Add/RemoveLazyEventListener, but applies to extension service
158 // workers.
159 void AddLazyServiceWorkerEventListener(const std::string& event_name,
160 const ExtensionId& extension_id,
161 int worker_thread_id);
162 void RemoveLazyServiceWorkerEventListener(const std::string& event_name,
163 const ExtensionId& extension_id,
164 int worker_thread_id);
145 165
146 // If |add_lazy_listener| is true also add the lazy version of this listener. 166 // If |add_lazy_listener| is true also add the lazy version of this listener.
147 void AddFilteredEventListener(const std::string& event_name, 167 void AddFilteredEventListener(const std::string& event_name,
148 content::RenderProcessHost* process, 168 content::RenderProcessHost* process,
149 const std::string& extension_id, 169 const std::string& extension_id,
150 const base::DictionaryValue& filter, 170 const base::DictionaryValue& filter,
151 bool add_lazy_listener); 171 bool add_lazy_listener);
152 172
153 // If |remove_lazy_listener| is true also remove the lazy version of this 173 // If |remove_lazy_listener| is true also remove the lazy version of this
154 // listener. 174 // listener.
(...skipping 24 matching lines...) Expand all
179 // newly installed extensions. 199 // newly installed extensions.
180 void DispatchEventWithLazyListener(const std::string& extension_id, 200 void DispatchEventWithLazyListener(const std::string& extension_id,
181 std::unique_ptr<Event> event); 201 std::unique_ptr<Event> event);
182 202
183 // Record the Event Ack from the renderer. (One less event in-flight.) 203 // Record the Event Ack from the renderer. (One less event in-flight.)
184 void OnEventAck(content::BrowserContext* context, 204 void OnEventAck(content::BrowserContext* context,
185 const std::string& extension_id); 205 const std::string& extension_id);
186 206
187 // Returns whether or not the given extension has any registered events. 207 // Returns whether or not the given extension has any registered events.
188 bool HasRegisteredEvents(const ExtensionId& extension_id) const { 208 bool HasRegisteredEvents(const ExtensionId& extension_id) const {
189 return !GetRegisteredEvents(extension_id).empty(); 209 return !GetRegisteredEvents(extension_id, RegisteredEventType::kLazy)
210 .empty();
190 } 211 }
191 212
192 // Clears registered events for testing purposes. 213 // Clears registered events for testing purposes.
193 void ClearRegisteredEventsForTest(const ExtensionId& extension_id) { 214 void ClearRegisteredEventsForTest(const ExtensionId& extension_id);
194 SetRegisteredEvents(extension_id, std::set<std::string>());
195 }
196 215
197 // Reports UMA for an event dispatched to |extension| with histogram value 216 // Reports UMA for an event dispatched to |extension| with histogram value
198 // |histogram_value|. Must be called on the UI thread. 217 // |histogram_value|. Must be called on the UI thread.
199 // 218 //
200 // |did_enqueue| should be true if the event was queued waiting for a process 219 // |did_enqueue| should be true if the event was queued waiting for a process
201 // to start, like an event page. 220 // to start, like an event page.
202 void ReportEvent(events::HistogramValue histogram_value, 221 void ReportEvent(events::HistogramValue histogram_value,
203 const Extension* extension, 222 const Extension* extension,
204 bool did_enqueue); 223 bool did_enqueue);
205 224
206 private: 225 private:
207 friend class EventRouterFilterTest; 226 friend class EventRouterFilterTest;
208 friend class EventRouterTest; 227 friend class EventRouterTest;
209 228
229 enum class RegisteredEventType {
230 kLazy,
231 kServiceWorker,
232 };
233
210 // An identifier for an event dispatch that is used to prevent double dispatch 234 // An identifier for an event dispatch that is used to prevent double dispatch
211 // due to race conditions between the direct and lazy dispatch paths. 235 // due to race conditions between the direct and lazy dispatch paths.
212 typedef std::pair<const content::BrowserContext*, std::string> 236 typedef std::tuple<const content::BrowserContext*, std::string, int>
213 EventDispatchIdentifier; 237 EventDispatchIdentifier;
214 238
215 // TODO(gdk): Document this. 239 // TODO(gdk): Document this.
216 static void DispatchExtensionMessage( 240 static void DispatchExtensionMessage(
217 IPC::Sender* ipc_sender, 241 IPC::Sender* ipc_sender,
242 int worker_thread_id,
218 void* browser_context_id, 243 void* browser_context_id,
219 const std::string& extension_id, 244 const std::string& extension_id,
220 int event_id, 245 int event_id,
221 const std::string& event_name, 246 const std::string& event_name,
222 base::ListValue* event_args, 247 base::ListValue* event_args,
223 UserGestureState user_gesture, 248 UserGestureState user_gesture,
224 const extensions::EventFilteringInfo& info); 249 const extensions::EventFilteringInfo& info);
225 250
226 // Returns or sets the list of events for which the given extension has 251 // Returns or sets the list of events for which the given extension has
227 // registered. 252 // registered.
228 std::set<std::string> GetRegisteredEvents( 253 std::set<std::string> GetRegisteredEvents(const std::string& extension_id,
229 const std::string& extension_id) const; 254 RegisteredEventType type) const;
230 void SetRegisteredEvents(const std::string& extension_id, 255 void SetRegisteredEvents(const std::string& extension_id,
231 const std::set<std::string>& events); 256 const std::set<std::string>& events,
257 RegisteredEventType type);
232 258
233 void Observe(int type, 259 void Observe(int type,
234 const content::NotificationSource& source, 260 const content::NotificationSource& source,
235 const content::NotificationDetails& details) override; 261 const content::NotificationDetails& details) override;
236 // ExtensionRegistryObserver implementation. 262 // ExtensionRegistryObserver implementation.
237 void OnExtensionLoaded(content::BrowserContext* browser_context, 263 void OnExtensionLoaded(content::BrowserContext* browser_context,
238 const Extension* extension) override; 264 const Extension* extension) override;
239 void OnExtensionUnloaded(content::BrowserContext* browser_context, 265 void OnExtensionUnloaded(content::BrowserContext* browser_context,
240 const Extension* extension, 266 const Extension* extension,
241 UnloadedExtensionReason reason) override; 267 UnloadedExtensionReason reason) override;
242 268
269 void AddLazyEventListenerImpl(const std::string& event_name,
270 const ExtensionId& extension_id,
271 int worker_thread_id);
272 void RemoveLazyEventListenerImpl(const std::string& event_name,
273 const ExtensionId& extension_id,
274 int worker_thread_id);
275
243 // Shared by all event dispatch methods. If |restrict_to_extension_id| is 276 // Shared by all event dispatch methods. If |restrict_to_extension_id| is
244 // empty, the event is broadcast. An event that just came off the pending 277 // empty, the event is broadcast. An event that just came off the pending
245 // list may not be delayed again. 278 // list may not be delayed again.
246 void DispatchEventImpl(const std::string& restrict_to_extension_id, 279 void DispatchEventImpl(const std::string& restrict_to_extension_id,
247 const linked_ptr<Event>& event); 280 const linked_ptr<Event>& event);
248 281
249 // Ensures that all lazy background pages that are interested in the given 282 // Ensures that all lazy background pages that are interested in the given
250 // event are loaded, and queues the event if the page is not ready yet. 283 // event are loaded, and queues the event if the page is not ready yet.
251 // Inserts an EventDispatchIdentifier into |already_dispatched| for each lazy 284 // Inserts an EventDispatchIdentifier into |already_dispatched| for each lazy
252 // event dispatch that is queued. 285 // event dispatch that is queued.
253 void DispatchLazyEvent(const std::string& extension_id, 286 void DispatchLazyEvent(const std::string& extension_id,
254 const linked_ptr<Event>& event, 287 const linked_ptr<Event>& event,
255 std::set<EventDispatchIdentifier>* already_dispatched, 288 std::set<EventDispatchIdentifier>* already_dispatched,
256 const base::DictionaryValue* listener_filter); 289 const base::DictionaryValue* listener_filter);
257 290
258 // Dispatches the event to the specified extension or URL running in 291 // Dispatches the event to the specified extension or URL running in
259 // |process|. 292 // |process|.
260 void DispatchEventToProcess(const std::string& extension_id, 293 void DispatchEventToProcess(const std::string& extension_id,
261 const GURL& listener_url, 294 const GURL& listener_url,
262 content::RenderProcessHost* process, 295 content::RenderProcessHost* process,
296 int worker_thread_id,
263 const linked_ptr<Event>& event, 297 const linked_ptr<Event>& event,
264 const base::DictionaryValue* listener_filter, 298 const base::DictionaryValue* listener_filter,
265 bool did_enqueue); 299 bool did_enqueue);
266 300
267 // Returns false when the event is scoped to a context and the listening 301 // Returns false when the event is scoped to a context and the listening
268 // extension does not have access to events from that context. Also fills 302 // extension does not have access to events from that context. Also fills
269 // |event_args| with the proper arguments to send, which may differ if 303 // |event_args| with the proper arguments to send, which may differ if
270 // the event crosses the incognito boundary. 304 // the event crosses the incognito boundary.
271 bool CanDispatchEventToBrowserContext(content::BrowserContext* context, 305 bool CanDispatchEventToBrowserContext(content::BrowserContext* context,
272 const Extension* extension, 306 const Extension* extension,
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 const std::string event_name; 459 const std::string event_name;
426 460
427 const std::string extension_id; 461 const std::string extension_id;
428 const GURL listener_url; 462 const GURL listener_url;
429 content::BrowserContext* const browser_context; 463 content::BrowserContext* const browser_context;
430 }; 464 };
431 465
432 } // namespace extensions 466 } // namespace extensions
433 467
434 #endif // EXTENSIONS_BROWSER_EVENT_ROUTER_H_ 468 #endif // EXTENSIONS_BROWSER_EVENT_ROUTER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698