Chromium Code Reviews| 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 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 <map> | 8 #include <map> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <string> | 10 #include <string> |
| 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/containers/hash_tables.h" | 15 #include "base/containers/hash_tables.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/event_filtering_info.h" | 27 #include "extensions/common/event_filtering_info.h" |
| 28 #include "ipc/ipc_sender.h" | 28 #include "ipc/ipc_sender.h" |
| 29 #include "url/gurl.h" | |
| 29 | 30 |
| 30 class GURL; | 31 class GURL; |
| 31 class PrefService; | 32 class PrefService; |
| 32 | 33 |
| 33 namespace content { | 34 namespace content { |
| 34 class BrowserContext; | 35 class BrowserContext; |
| 35 class RenderProcessHost; | 36 class RenderProcessHost; |
| 36 } | 37 } |
| 37 | 38 |
| 38 namespace extensions { | 39 namespace extensions { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 78 | 79 |
| 79 // Gets the EventRouter for |browser_context|. | 80 // Gets the EventRouter for |browser_context|. |
| 80 static EventRouter* Get(content::BrowserContext* browser_context); | 81 static EventRouter* Get(content::BrowserContext* browser_context); |
| 81 | 82 |
| 82 // Converts event names like "foo.onBar/123" into "foo.onBar". Event names | 83 // Converts event names like "foo.onBar/123" into "foo.onBar". Event names |
| 83 // without a "/" are returned unchanged. | 84 // without a "/" are returned unchanged. |
| 84 static std::string GetBaseEventName(const std::string& full_event_name); | 85 static std::string GetBaseEventName(const std::string& full_event_name); |
| 85 | 86 |
| 86 // Sends an event via ipc_sender to the given extension. Can be called on any | 87 // Sends an event via ipc_sender to the given extension. Can be called on any |
| 87 // thread. | 88 // thread. |
| 88 static void DispatchEvent(IPC::Sender* ipc_sender, | 89 // |
| 89 void* browser_context_id, | 90 // It is very rare to call this function directly. Instead use the instance |
| 90 const std::string& extension_id, | 91 // methods BroadcastEvent or DispatchEventToExtension. |
| 91 const std::string& event_name, | 92 static void DispatchEventToSender(IPC::Sender* ipc_sender, |
| 92 scoped_ptr<base::ListValue> event_args, | 93 void* browser_context_id, |
| 93 UserGestureState user_gesture, | 94 const GURL& url, |
| 94 const EventFilteringInfo& info); | 95 const std::string& extension_id, |
| 96 events::HistogramValue histogram_value, | |
| 97 const std::string& event_name, | |
| 98 scoped_ptr<base::ListValue> event_args, | |
| 99 UserGestureState user_gesture, | |
| 100 const EventFilteringInfo& info); | |
| 95 | 101 |
| 96 // An EventRouter is shared between |browser_context| and its associated | 102 // An EventRouter is shared between |browser_context| and its associated |
| 97 // incognito context. |extension_prefs| may be NULL in tests. | 103 // incognito context. |extension_prefs| may be NULL in tests. |
| 98 EventRouter(content::BrowserContext* browser_context, | 104 EventRouter(content::BrowserContext* browser_context, |
| 99 ExtensionPrefs* extension_prefs); | 105 ExtensionPrefs* extension_prefs); |
| 100 ~EventRouter() override; | 106 ~EventRouter() override; |
| 101 | 107 |
| 102 // Add or remove an extension as an event listener for |event_name|. | 108 // Add or remove an extension as an event listener for |event_name|. |
| 103 // | 109 // |
| 104 // Note that multiple extensions can share a process due to process | 110 // Note that multiple extensions can share a process due to process |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 178 // listener for it. NOTE: This should be used rarely, for dispatching events | 184 // listener for it. NOTE: This should be used rarely, for dispatching events |
| 179 // to extensions that haven't had a chance to add their own listeners yet, eg: | 185 // to extensions that haven't had a chance to add their own listeners yet, eg: |
| 180 // newly installed extensions. | 186 // newly installed extensions. |
| 181 void DispatchEventWithLazyListener(const std::string& extension_id, | 187 void DispatchEventWithLazyListener(const std::string& extension_id, |
| 182 scoped_ptr<Event> event); | 188 scoped_ptr<Event> event); |
| 183 | 189 |
| 184 // Record the Event Ack from the renderer. (One less event in-flight.) | 190 // Record the Event Ack from the renderer. (One less event in-flight.) |
| 185 void OnEventAck(content::BrowserContext* context, | 191 void OnEventAck(content::BrowserContext* context, |
| 186 const std::string& extension_id); | 192 const std::string& extension_id); |
| 187 | 193 |
| 194 // Reports UMA for an event dispatched with histogram value |histogram_value|. | |
| 195 // Must be called on the UI thread. | |
| 196 // | |
| 197 // The target of the event - extension background page, view, webui, etc - | |
| 198 // can be determined by the |process_id| and |url| tuple. If the URL is | |
|
Devlin
2015/08/05 21:34:09
What process id?
not at google - send to devlin
2015/08/07 20:55:03
Fixed.
| |
| 199 // unknown, which may be the case for hand-written events (like messaging), | |
| 200 // it may be blank. | |
| 201 // | |
| 202 // |did_enqueue| should be true if the event was queued waiting for a process | |
| 203 // to start, like an event page. | |
| 204 void ReportEvent(events::HistogramValue histogram_value, | |
| 205 const GURL& url, | |
| 206 bool did_enqueue); | |
| 207 | |
| 188 private: | 208 private: |
| 189 friend class EventRouterTest; | 209 friend class EventRouterTest; |
| 190 | 210 |
| 211 enum ExtensionPageType { | |
| 212 EXTENSION_PAGE_NONE, | |
| 213 EXTENSION_PAGE_VIEW, | |
| 214 EXTENSION_PAGE_PERSISTENT_BACKGROUND, | |
| 215 EXTENSION_PAGE_DORMANT_EVENT, | |
| 216 EXTENSION_PAGE_AWAKE_EVENT, | |
| 217 }; | |
| 218 | |
| 191 // The extension and process that contains the event listener for a given | 219 // The extension and process that contains the event listener for a given |
| 192 // event. | 220 // event. |
| 193 struct ListenerProcess; | 221 struct ListenerProcess; |
| 194 | 222 |
| 195 // A map between an event name and a set of extensions that are listening | 223 // A map between an event name and a set of extensions that are listening |
| 196 // to that event. | 224 // to that event. |
| 197 typedef std::map<std::string, std::set<ListenerProcess> > ListenerMap; | 225 typedef std::map<std::string, std::set<ListenerProcess> > ListenerMap; |
| 198 | 226 |
| 199 // An identifier for an event dispatch that is used to prevent double dispatch | 227 // An identifier for an event dispatch that is used to prevent double dispatch |
| 200 // due to race conditions between the direct and lazy dispatch paths. | 228 // due to race conditions between the direct and lazy dispatch paths. |
| 201 typedef std::pair<const content::BrowserContext*, std::string> | 229 typedef std::pair<const content::BrowserContext*, std::string> |
| 202 EventDispatchIdentifier; | 230 EventDispatchIdentifier; |
| 203 | 231 |
| 204 // TODO(gdk): Document this. | 232 // TODO(gdk): Document this. |
| 205 static void DispatchExtensionMessage( | 233 static void DispatchExtensionMessage( |
| 206 IPC::Sender* ipc_sender, | 234 IPC::Sender* ipc_sender, |
| 207 void* browser_context_id, | 235 void* browser_context_id, |
| 208 const std::string& extension_id, | 236 const std::string& extension_id, |
| 209 int event_id, | 237 int event_id, |
| 210 const std::string& event_name, | 238 const std::string& event_name, |
| 211 base::ListValue* event_args, | 239 base::ListValue* event_args, |
| 212 UserGestureState user_gesture, | 240 UserGestureState user_gesture, |
| 213 const extensions::EventFilteringInfo& info); | 241 const extensions::EventFilteringInfo& info); |
| 214 | 242 |
| 243 ExtensionPageType GetExtensionPageType(const Extension* extension, | |
| 244 const GURL& url, | |
| 245 bool did_enqueue); | |
| 246 | |
| 215 void Observe(int type, | 247 void Observe(int type, |
| 216 const content::NotificationSource& source, | 248 const content::NotificationSource& source, |
| 217 const content::NotificationDetails& details) override; | 249 const content::NotificationDetails& details) override; |
| 218 // ExtensionRegistryObserver implementation. | 250 // ExtensionRegistryObserver implementation. |
| 219 void OnExtensionLoaded(content::BrowserContext* browser_context, | 251 void OnExtensionLoaded(content::BrowserContext* browser_context, |
| 220 const Extension* extension) override; | 252 const Extension* extension) override; |
| 221 void OnExtensionUnloaded(content::BrowserContext* browser_context, | 253 void OnExtensionUnloaded(content::BrowserContext* browser_context, |
| 222 const Extension* extension, | 254 const Extension* extension, |
| 223 UnloadedExtensionInfo::Reason reason) override; | 255 UnloadedExtensionInfo::Reason reason) override; |
| 224 | 256 |
| 225 // Returns true if the given listener map contains a event listeners for | 257 // Returns true if the given listener map contains a event listeners for |
| 226 // the given event. If |extension_id| is non-empty, we also check that that | 258 // the given event. If |extension_id| is non-empty, we also check that that |
| 227 // extension is one of the listeners. | 259 // extension is one of the listeners. |
| 228 bool HasEventListenerImpl(const ListenerMap& listeners, | 260 bool HasEventListenerImpl(const ListenerMap& listeners, |
| 229 const std::string& extension_id, | 261 const std::string& extension_id, |
| 230 const std::string& event_name); | 262 const std::string& event_name); |
| 231 | 263 |
| 232 // Shared by DispatchEvent*. If |restrict_to_extension_id| is empty, the | 264 // Shared by all event dispatch methods. If |restrict_to_extension_id| is |
| 233 // event is broadcast. | 265 // empty, the event is broadcast. An event that just came off the pending |
| 234 // An event that just came off the pending list may not be delayed again. | 266 // list may not be delayed again. |
| 235 void DispatchEventImpl(const std::string& restrict_to_extension_id, | 267 void DispatchEventImpl(const std::string& restrict_to_extension_id, |
| 236 const linked_ptr<Event>& event); | 268 const linked_ptr<Event>& event); |
| 237 | 269 |
| 238 // Ensures that all lazy background pages that are interested in the given | 270 // Ensures that all lazy background pages that are interested in the given |
| 239 // event are loaded, and queues the event if the page is not ready yet. | 271 // event are loaded, and queues the event if the page is not ready yet. |
| 240 // Inserts an EventDispatchIdentifier into |already_dispatched| for each lazy | 272 // Inserts an EventDispatchIdentifier into |already_dispatched| for each lazy |
| 241 // event dispatch that is queued. | 273 // event dispatch that is queued. |
| 242 void DispatchLazyEvent(const std::string& extension_id, | 274 void DispatchLazyEvent(const std::string& extension_id, |
| 243 const linked_ptr<Event>& event, | 275 const linked_ptr<Event>& event, |
| 244 std::set<EventDispatchIdentifier>* already_dispatched, | 276 std::set<EventDispatchIdentifier>* already_dispatched, |
| 245 const base::DictionaryValue* listener_filter); | 277 const base::DictionaryValue* listener_filter); |
| 246 | 278 |
| 247 // Dispatches the event to the specified extension or URL running in | 279 // Dispatches the event to the specified extension or URL running in |
| 248 // |process|. | 280 // |process|. |
| 249 void DispatchEventToProcess(const std::string& extension_id, | 281 void DispatchEventToProcess(const std::string& extension_id, |
| 250 const GURL& listener_url, | 282 const GURL& listener_url, |
| 251 content::RenderProcessHost* process, | 283 content::RenderProcessHost* process, |
| 252 const linked_ptr<Event>& event, | 284 const linked_ptr<Event>& event, |
| 253 const base::DictionaryValue* listener_filter); | 285 const base::DictionaryValue* listener_filter, |
| 286 bool did_enqueue); | |
| 254 | 287 |
| 255 // Returns false when the event is scoped to a context and the listening | 288 // Returns false when the event is scoped to a context and the listening |
| 256 // extension does not have access to events from that context. Also fills | 289 // extension does not have access to events from that context. Also fills |
| 257 // |event_args| with the proper arguments to send, which may differ if | 290 // |event_args| with the proper arguments to send, which may differ if |
| 258 // the event crosses the incognito boundary. | 291 // the event crosses the incognito boundary. |
| 259 bool CanDispatchEventToBrowserContext(content::BrowserContext* context, | 292 bool CanDispatchEventToBrowserContext(content::BrowserContext* context, |
| 260 const Extension* extension, | 293 const Extension* extension, |
| 261 const linked_ptr<Event>& event); | 294 const linked_ptr<Event>& event); |
| 262 | 295 |
| 263 // Possibly loads given extension's background page in preparation to | 296 // Possibly loads given extension's background page in preparation to |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 285 const std::string& extension_id); | 318 const std::string& extension_id); |
| 286 | 319 |
| 287 // Track the dispatched events that have not yet sent an ACK from the | 320 // Track the dispatched events that have not yet sent an ACK from the |
| 288 // renderer. | 321 // renderer. |
| 289 void IncrementInFlightEvents(content::BrowserContext* context, | 322 void IncrementInFlightEvents(content::BrowserContext* context, |
| 290 const Extension* extension, | 323 const Extension* extension, |
| 291 int event_id, | 324 int event_id, |
| 292 const std::string& event_name); | 325 const std::string& event_name); |
| 293 | 326 |
| 294 // static | 327 // static |
| 295 static void IncrementInFlightEventsOnUI(void* browser_context_id, | 328 static void DoDispatchEventToSenderBookkeepingOnUI( |
| 296 const std::string& extension_id, | 329 void* browser_context_id, |
| 297 int event_id, | 330 const std::string& extension_id, |
| 298 const std::string& event_name); | 331 const GURL& url, |
| 332 int event_id, | |
| 333 events::HistogramValue histogram_value, | |
| 334 const std::string& event_name); | |
| 299 | 335 |
| 300 void DispatchPendingEvent(const linked_ptr<Event>& event, | 336 void DispatchPendingEvent(const linked_ptr<Event>& event, |
| 301 ExtensionHost* host); | 337 ExtensionHost* host); |
| 302 | 338 |
| 303 // Implementation of EventListenerMap::Delegate. | 339 // Implementation of EventListenerMap::Delegate. |
| 304 void OnListenerAdded(const EventListener* listener) override; | 340 void OnListenerAdded(const EventListener* listener) override; |
| 305 void OnListenerRemoved(const EventListener* listener) override; | 341 void OnListenerRemoved(const EventListener* listener) override; |
| 306 | 342 |
| 307 // RenderProcessHostObserver implementation. | 343 // RenderProcessHostObserver implementation. |
| 308 void RenderProcessExited(content::RenderProcessHost* host, | 344 void RenderProcessExited(content::RenderProcessHost* host, |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 411 const std::string event_name; | 447 const std::string event_name; |
| 412 | 448 |
| 413 const std::string extension_id; | 449 const std::string extension_id; |
| 414 const GURL listener_url; | 450 const GURL listener_url; |
| 415 content::BrowserContext* browser_context; | 451 content::BrowserContext* browser_context; |
| 416 }; | 452 }; |
| 417 | 453 |
| 418 } // namespace extensions | 454 } // namespace extensions |
| 419 | 455 |
| 420 #endif // EXTENSIONS_BROWSER_EVENT_ROUTER_H_ | 456 #endif // EXTENSIONS_BROWSER_EVENT_ROUTER_H_ |
| OLD | NEW |