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