| 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 std::string& extension_id, |
| 94 const EventFilteringInfo& info); | 95 events::HistogramValue histogram_value, |
| 96 const std::string& event_name, |
| 97 scoped_ptr<base::ListValue> event_args, |
| 98 UserGestureState user_gesture, |
| 99 const EventFilteringInfo& info); |
| 95 | 100 |
| 96 // An EventRouter is shared between |browser_context| and its associated | 101 // An EventRouter is shared between |browser_context| and its associated |
| 97 // incognito context. |extension_prefs| may be NULL in tests. | 102 // incognito context. |extension_prefs| may be NULL in tests. |
| 98 EventRouter(content::BrowserContext* browser_context, | 103 EventRouter(content::BrowserContext* browser_context, |
| 99 ExtensionPrefs* extension_prefs); | 104 ExtensionPrefs* extension_prefs); |
| 100 ~EventRouter() override; | 105 ~EventRouter() override; |
| 101 | 106 |
| 102 // Add or remove an extension as an event listener for |event_name|. | 107 // Add or remove an extension as an event listener for |event_name|. |
| 103 // | 108 // |
| 104 // Note that multiple extensions can share a process due to process | 109 // 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 | 183 // 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: | 184 // to extensions that haven't had a chance to add their own listeners yet, eg: |
| 180 // newly installed extensions. | 185 // newly installed extensions. |
| 181 void DispatchEventWithLazyListener(const std::string& extension_id, | 186 void DispatchEventWithLazyListener(const std::string& extension_id, |
| 182 scoped_ptr<Event> event); | 187 scoped_ptr<Event> event); |
| 183 | 188 |
| 184 // Record the Event Ack from the renderer. (One less event in-flight.) | 189 // Record the Event Ack from the renderer. (One less event in-flight.) |
| 185 void OnEventAck(content::BrowserContext* context, | 190 void OnEventAck(content::BrowserContext* context, |
| 186 const std::string& extension_id); | 191 const std::string& extension_id); |
| 187 | 192 |
| 193 // Reports UMA for an event dispatched to |extension| with histogram value |
| 194 // |histogram_value|. Must be called on the UI thread. |
| 195 // |
| 196 // |did_enqueue| should be true if the event was queued waiting for a process |
| 197 // to start, like an event page. |
| 198 void ReportEvent(events::HistogramValue histogram_value, |
| 199 const Extension* extension, |
| 200 bool did_enqueue); |
| 201 |
| 188 private: | 202 private: |
| 189 friend class EventRouterTest; | 203 friend class EventRouterTest; |
| 190 | 204 |
| 191 // The extension and process that contains the event listener for a given | 205 // The extension and process that contains the event listener for a given |
| 192 // event. | 206 // event. |
| 193 struct ListenerProcess; | 207 struct ListenerProcess; |
| 194 | 208 |
| 195 // A map between an event name and a set of extensions that are listening | 209 // A map between an event name and a set of extensions that are listening |
| 196 // to that event. | 210 // to that event. |
| 197 typedef std::map<std::string, std::set<ListenerProcess> > ListenerMap; | 211 typedef std::map<std::string, std::set<ListenerProcess> > ListenerMap; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 222 const Extension* extension, | 236 const Extension* extension, |
| 223 UnloadedExtensionInfo::Reason reason) override; | 237 UnloadedExtensionInfo::Reason reason) override; |
| 224 | 238 |
| 225 // Returns true if the given listener map contains a event listeners for | 239 // 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 | 240 // the given event. If |extension_id| is non-empty, we also check that that |
| 227 // extension is one of the listeners. | 241 // extension is one of the listeners. |
| 228 bool HasEventListenerImpl(const ListenerMap& listeners, | 242 bool HasEventListenerImpl(const ListenerMap& listeners, |
| 229 const std::string& extension_id, | 243 const std::string& extension_id, |
| 230 const std::string& event_name); | 244 const std::string& event_name); |
| 231 | 245 |
| 232 // Shared by DispatchEvent*. If |restrict_to_extension_id| is empty, the | 246 // Shared by all event dispatch methods. If |restrict_to_extension_id| is |
| 233 // event is broadcast. | 247 // 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. | 248 // list may not be delayed again. |
| 235 void DispatchEventImpl(const std::string& restrict_to_extension_id, | 249 void DispatchEventImpl(const std::string& restrict_to_extension_id, |
| 236 const linked_ptr<Event>& event); | 250 const linked_ptr<Event>& event); |
| 237 | 251 |
| 238 // Ensures that all lazy background pages that are interested in the given | 252 // 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. | 253 // event are loaded, and queues the event if the page is not ready yet. |
| 240 // Inserts an EventDispatchIdentifier into |already_dispatched| for each lazy | 254 // Inserts an EventDispatchIdentifier into |already_dispatched| for each lazy |
| 241 // event dispatch that is queued. | 255 // event dispatch that is queued. |
| 242 void DispatchLazyEvent(const std::string& extension_id, | 256 void DispatchLazyEvent(const std::string& extension_id, |
| 243 const linked_ptr<Event>& event, | 257 const linked_ptr<Event>& event, |
| 244 std::set<EventDispatchIdentifier>* already_dispatched, | 258 std::set<EventDispatchIdentifier>* already_dispatched, |
| 245 const base::DictionaryValue* listener_filter); | 259 const base::DictionaryValue* listener_filter); |
| 246 | 260 |
| 247 // Dispatches the event to the specified extension or URL running in | 261 // Dispatches the event to the specified extension or URL running in |
| 248 // |process|. | 262 // |process|. |
| 249 void DispatchEventToProcess(const std::string& extension_id, | 263 void DispatchEventToProcess(const std::string& extension_id, |
| 250 const GURL& listener_url, | 264 const GURL& listener_url, |
| 251 content::RenderProcessHost* process, | 265 content::RenderProcessHost* process, |
| 252 const linked_ptr<Event>& event, | 266 const linked_ptr<Event>& event, |
| 253 const base::DictionaryValue* listener_filter); | 267 const base::DictionaryValue* listener_filter, |
| 268 bool did_enqueue); |
| 254 | 269 |
| 255 // Returns false when the event is scoped to a context and the listening | 270 // 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 | 271 // 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 | 272 // |event_args| with the proper arguments to send, which may differ if |
| 258 // the event crosses the incognito boundary. | 273 // the event crosses the incognito boundary. |
| 259 bool CanDispatchEventToBrowserContext(content::BrowserContext* context, | 274 bool CanDispatchEventToBrowserContext(content::BrowserContext* context, |
| 260 const Extension* extension, | 275 const Extension* extension, |
| 261 const linked_ptr<Event>& event); | 276 const linked_ptr<Event>& event); |
| 262 | 277 |
| 263 // Possibly loads given extension's background page in preparation to | 278 // Possibly loads given extension's background page in preparation to |
| (...skipping 21 matching lines...) Expand all Loading... |
| 285 const std::string& extension_id); | 300 const std::string& extension_id); |
| 286 | 301 |
| 287 // Track the dispatched events that have not yet sent an ACK from the | 302 // Track the dispatched events that have not yet sent an ACK from the |
| 288 // renderer. | 303 // renderer. |
| 289 void IncrementInFlightEvents(content::BrowserContext* context, | 304 void IncrementInFlightEvents(content::BrowserContext* context, |
| 290 const Extension* extension, | 305 const Extension* extension, |
| 291 int event_id, | 306 int event_id, |
| 292 const std::string& event_name); | 307 const std::string& event_name); |
| 293 | 308 |
| 294 // static | 309 // static |
| 295 static void IncrementInFlightEventsOnUI(void* browser_context_id, | 310 static void DoDispatchEventToSenderBookkeepingOnUI( |
| 296 const std::string& extension_id, | 311 void* browser_context_id, |
| 297 int event_id, | 312 const std::string& extension_id, |
| 298 const std::string& event_name); | 313 int event_id, |
| 314 events::HistogramValue histogram_value, |
| 315 const std::string& event_name); |
| 299 | 316 |
| 300 void DispatchPendingEvent(const linked_ptr<Event>& event, | 317 void DispatchPendingEvent(const linked_ptr<Event>& event, |
| 301 ExtensionHost* host); | 318 ExtensionHost* host); |
| 302 | 319 |
| 303 // Implementation of EventListenerMap::Delegate. | 320 // Implementation of EventListenerMap::Delegate. |
| 304 void OnListenerAdded(const EventListener* listener) override; | 321 void OnListenerAdded(const EventListener* listener) override; |
| 305 void OnListenerRemoved(const EventListener* listener) override; | 322 void OnListenerRemoved(const EventListener* listener) override; |
| 306 | 323 |
| 307 // RenderProcessHostObserver implementation. | 324 // RenderProcessHostObserver implementation. |
| 308 void RenderProcessExited(content::RenderProcessHost* host, | 325 void RenderProcessExited(content::RenderProcessHost* host, |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 411 const std::string event_name; | 428 const std::string event_name; |
| 412 | 429 |
| 413 const std::string extension_id; | 430 const std::string extension_id; |
| 414 const GURL listener_url; | 431 const GURL listener_url; |
| 415 content::BrowserContext* browser_context; | 432 content::BrowserContext* browser_context; |
| 416 }; | 433 }; |
| 417 | 434 |
| 418 } // namespace extensions | 435 } // namespace extensions |
| 419 | 436 |
| 420 #endif // EXTENSIONS_BROWSER_EVENT_ROUTER_H_ | 437 #endif // EXTENSIONS_BROWSER_EVENT_ROUTER_H_ |
| OLD | NEW |