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