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_API_MESSAGING_MESSAGE_SERVICE_H_ | 5 #ifndef CHROME_BROWSER_EXTENSIONS_API_MESSAGING_MESSAGE_SERVICE_H_ |
| 6 #define CHROME_BROWSER_EXTENSIONS_API_MESSAGING_MESSAGE_SERVICE_H_ | 6 #define CHROME_BROWSER_EXTENSIONS_API_MESSAGING_MESSAGE_SERVICE_H_ |
| 7 | 7 |
| 8 #include <map> | 8 #include <map> |
| 9 #include <set> | 9 #include <set> |
| 10 #include <string> | 10 #include <string> |
| 11 #include <vector> | 11 #include <vector> |
| 12 | 12 |
| 13 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
| 14 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.h" |
| 15 #include "base/memory/weak_ptr.h" | 15 #include "base/memory/weak_ptr.h" |
| 16 #include "base/values.h" | 16 #include "base/values.h" |
| 17 #include "chrome/browser/extensions/api/messaging/message_property_provider.h" | 17 #include "chrome/browser/extensions/api/messaging/message_property_provider.h" |
| 18 #include "content/public/browser/notification_observer.h" | |
| 19 #include "content/public/browser/notification_registrar.h" | |
| 20 #include "extensions/browser/api/messaging/native_message_host.h" | 18 #include "extensions/browser/api/messaging/native_message_host.h" |
| 21 #include "extensions/browser/browser_context_keyed_api_factory.h" | 19 #include "extensions/browser/browser_context_keyed_api_factory.h" |
| 22 #include "extensions/common/api/messaging/message.h" | 20 #include "extensions/common/api/messaging/message.h" |
| 23 | 21 |
| 24 class GURL; | 22 class GURL; |
| 25 class Profile; | 23 class Profile; |
| 26 | 24 |
| 27 namespace content { | 25 namespace content { |
| 28 class BrowserContext; | 26 class BrowserContext; |
| 29 class RenderProcessHost; | |
| 30 class WebContents; | |
| 31 } | 27 } |
| 32 | 28 |
| 33 namespace extensions { | 29 namespace extensions { |
| 34 class Extension; | 30 class Extension; |
| 35 class ExtensionHost; | 31 class ExtensionHost; |
| 36 class LazyBackgroundTaskQueue; | 32 class LazyBackgroundTaskQueue; |
| 37 | 33 |
| 38 // This class manages message and event passing between renderer processes. | 34 // This class manages message and event passing between renderer processes. |
| 39 // It maintains a list of processes that are listening to events and a set of | 35 // It maintains a list of processes that are listening to events and a set of |
| 40 // open channels. | 36 // open channels. |
| 41 // | 37 // |
| 42 // Messaging works this way: | 38 // Messaging works this way: |
| 43 // - An extension-owned script context (like a background page or a content | 39 // - An extension-owned script context (like a background page or a content |
| 44 // script) adds an event listener to the "onConnect" event. | 40 // script) adds an event listener to the "onConnect" event. |
| 45 // - Another context calls "runtime.connect()" to open a channel to the | 41 // - Another context calls "runtime.connect()" to open a channel to the |
| 46 // extension process, or an extension context calls "tabs.connect(tabId)" to | 42 // extension process, or an extension context calls "tabs.connect(tabId)" to |
| 47 // open a channel to the content scripts for the given tab. The EMS notifies | 43 // open a channel to the content scripts for the given tab. The EMS notifies |
| 48 // the target process/tab, which then calls the onConnect event in every | 44 // the target process/tab, which then calls the onConnect event in every |
| 49 // context owned by the connecting extension in that process/tab. | 45 // context owned by the connecting extension in that process/tab. |
| 50 // - Once the channel is established, either side can call postMessage to send | 46 // - Once the channel is established, either side can call postMessage to send |
| 51 // a message to the opposite side of the channel, which may have multiple | 47 // a message to the opposite side of the channel, which may have multiple |
| 52 // listeners. | 48 // listeners. |
| 53 // | 49 // |
| 54 // Terminology: | 50 // Terminology: |
| 55 // channel: connection between two ports | 51 // channel: connection between two ports |
| 56 // port: an IPC::Message::Process interface and an optional routing_id (in the | 52 // port: One sender or receivers tied to one or more RenderFrameHost instances. |
|
Devlin
2015/12/12 14:25:00
nit: receiver (singular)
robwu
2015/12/14 20:55:41
Done.
| |
| 57 // case that the port is a tab). The Process is usually either a | 53 class MessageService : public BrowserContextKeyedAPI { |
| 58 // RenderProcessHost or a RenderViewHost. | |
| 59 class MessageService : public BrowserContextKeyedAPI, | |
| 60 public content::NotificationObserver { | |
| 61 public: | 54 public: |
| 62 // A messaging channel. Note that the opening port can be the same as the | 55 // A messaging channel. Note that the opening port can be the same as the |
| 63 // receiver, if an extension background page wants to talk to its tab (for | 56 // receiver, if an extension background page wants to talk to its tab (for |
| 64 // example). | 57 // example). |
| 65 struct MessageChannel; | 58 struct MessageChannel; |
| 66 | 59 |
| 67 // One side of the communication handled by extensions::MessageService. | 60 // One side of the communication handled by extensions::MessageService. |
| 68 class MessagePort { | 61 class MessagePort { |
| 69 public: | 62 public: |
| 70 virtual ~MessagePort() {} | 63 virtual ~MessagePort() {} |
| 64 | |
| 65 // Called right before a port is connected to a channel. If false, the port | |
| 66 // is not used and the channel is closed. | |
| 67 virtual bool IsValidPort() = 0; | |
| 68 | |
| 71 // Notify the port that the channel has been opened. | 69 // Notify the port that the channel has been opened. |
| 72 virtual void DispatchOnConnect(int dest_port_id, | 70 virtual void DispatchOnConnect(const std::string& channel_name, |
| 73 const std::string& channel_name, | |
| 74 scoped_ptr<base::DictionaryValue> source_tab, | 71 scoped_ptr<base::DictionaryValue> source_tab, |
| 75 int source_frame_id, | 72 int source_frame_id, |
| 76 int target_tab_id, | |
| 77 int target_frame_id, | |
| 78 int guest_process_id, | 73 int guest_process_id, |
| 79 int guest_render_frame_routing_id, | 74 int guest_render_frame_routing_id, |
| 80 const std::string& source_extension_id, | 75 const std::string& source_extension_id, |
| 81 const std::string& target_extension_id, | 76 const std::string& target_extension_id, |
| 82 const GURL& source_url, | 77 const GURL& source_url, |
| 83 const std::string& tls_channel_id) {} | 78 const std::string& tls_channel_id) {} |
| 84 | 79 |
| 85 // Notify the port that the channel has been closed. If |error_message| is | 80 // Notify the port that the channel has been closed. If |error_message| is |
| 86 // non-empty, it indicates an error occurred while opening the connection. | 81 // non-empty, it indicates an error occurred while opening the connection. |
| 87 virtual void DispatchOnDisconnect(int source_port_id, | 82 virtual void DispatchOnDisconnect(const std::string& error_message) {} |
| 88 const std::string& error_message) {} | |
| 89 | 83 |
| 90 // Dispatch a message to this end of the communication. | 84 // Dispatch a message to this end of the communication. |
| 91 virtual void DispatchOnMessage(const Message& message, | 85 virtual void DispatchOnMessage(const Message& message) = 0; |
| 92 int target_port_id) = 0; | |
| 93 | 86 |
| 94 // MessagPorts that target extensions will need to adjust their keepalive | 87 // Mark the port as opened by the specific frame. |
| 88 virtual void OpenPort(int process_id, int routing_id) {} | |
| 89 | |
| 90 // Close the port for the given frame. | |
| 91 virtual void ClosePort(int process_id, int routing_id) {} | |
| 92 | |
| 93 // MessagePorts that target extensions will need to adjust their keepalive | |
| 95 // counts for their lazy background page. | 94 // counts for their lazy background page. |
| 96 virtual void IncrementLazyKeepaliveCount() {} | 95 virtual void IncrementLazyKeepaliveCount() {} |
| 97 virtual void DecrementLazyKeepaliveCount() {} | 96 virtual void DecrementLazyKeepaliveCount() {} |
| 98 | 97 |
| 99 // Get the RenderProcessHost (if any) associated with the port. | |
| 100 virtual content::RenderProcessHost* GetRenderProcessHost(); | |
| 101 | |
| 102 protected: | 98 protected: |
| 103 MessagePort() {} | 99 MessagePort() {} |
| 104 | 100 |
| 105 private: | 101 private: |
| 106 DISALLOW_COPY_AND_ASSIGN(MessagePort); | 102 DISALLOW_COPY_AND_ASSIGN(MessagePort); |
| 107 }; | 103 }; |
| 108 | 104 |
| 109 enum PolicyPermission { | 105 enum PolicyPermission { |
| 110 DISALLOW, // The host is not allowed. | 106 DISALLOW, // The host is not allowed. |
| 111 ALLOW_SYSTEM_ONLY, // Allowed only when installed on system level. | 107 ALLOW_SYSTEM_ONLY, // Allowed only when installed on system level. |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 137 const std::string& source_extension_id, | 133 const std::string& source_extension_id, |
| 138 const std::string& target_extension_id, | 134 const std::string& target_extension_id, |
| 139 const GURL& source_url, | 135 const GURL& source_url, |
| 140 const std::string& channel_name, | 136 const std::string& channel_name, |
| 141 bool include_tls_channel_id); | 137 bool include_tls_channel_id); |
| 142 | 138 |
| 143 // Same as above, but opens a channel to the tab with the given ID. Messages | 139 // Same as above, but opens a channel to the tab with the given ID. Messages |
| 144 // are restricted to that tab, so if there are multiple tabs in that process, | 140 // are restricted to that tab, so if there are multiple tabs in that process, |
| 145 // only the targeted tab will receive messages. | 141 // only the targeted tab will receive messages. |
| 146 void OpenChannelToTab(int source_process_id, | 142 void OpenChannelToTab(int source_process_id, |
| 143 int source_routing_id, | |
| 147 int receiver_port_id, | 144 int receiver_port_id, |
| 148 int tab_id, | 145 int tab_id, |
| 149 int frame_id, | 146 int frame_id, |
| 150 const std::string& extension_id, | 147 const std::string& extension_id, |
| 151 const std::string& channel_name); | 148 const std::string& channel_name); |
| 152 | 149 |
| 153 void OpenChannelToNativeApp( | 150 void OpenChannelToNativeApp( |
| 154 int source_process_id, | 151 int source_process_id, |
| 155 int source_routing_id, | 152 int source_routing_id, |
| 156 int receiver_port_id, | 153 int receiver_port_id, |
| 157 const std::string& source_extension_id, | 154 const std::string& source_extension_id, |
| 158 const std::string& native_app_name); | 155 const std::string& native_app_name); |
| 159 | 156 |
| 157 // Acknowledges open port in the frame identified by (process_id, routing_id). | |
|
Devlin
2015/12/12 14:25:00
"Acknowledges" is a little misleading - it also (u
robwu
2015/12/14 20:55:41
I changed this to "Mark the given port as opened b
| |
| 158 void OpenPort(int port_id, int process_id, int routing_id); | |
| 159 | |
| 160 // Closes the given port in the given frame. If this was the last frame or if | |
| 161 // |force_close| is true, then the other side is closed as well. | |
| 162 void ClosePort(int port_id, int process_id, int routing_id, bool force_close); | |
| 163 | |
| 160 // Closes the message channel associated with the given port, and notifies | 164 // Closes the message channel associated with the given port, and notifies |
| 161 // the other side. | 165 // the other side. |
| 162 void CloseChannel(int port_id, const std::string& error_message); | 166 void CloseChannel(int port_id, const std::string& error_message); |
| 163 | 167 |
| 164 // Enqueues a message on a pending channel, or sends a message to the given | 168 // Enqueues a message on a pending channel, or sends a message to the given |
| 165 // port if the channel isn't pending. | 169 // port if the channel isn't pending. |
| 166 void PostMessage(int port_id, const Message& message); | 170 void PostMessage(int port_id, const Message& message); |
| 167 | 171 |
| 168 private: | 172 private: |
| 169 friend class MockMessageService; | 173 friend class MockMessageService; |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 192 // |target_extension| will be non-null if |params->target_extension_id| is | 196 // |target_extension| will be non-null if |params->target_extension_id| is |
| 193 // non-empty, that is, if the target is an extension, it must exist. | 197 // non-empty, that is, if the target is an extension, it must exist. |
| 194 // | 198 // |
| 195 // |did_enqueue| will be true if the channel opening was delayed while | 199 // |did_enqueue| will be true if the channel opening was delayed while |
| 196 // waiting for an event page to start, false otherwise. | 200 // waiting for an event page to start, false otherwise. |
| 197 void OpenChannelImpl(content::BrowserContext* browser_context, | 201 void OpenChannelImpl(content::BrowserContext* browser_context, |
| 198 scoped_ptr<OpenChannelParams> params, | 202 scoped_ptr<OpenChannelParams> params, |
| 199 const Extension* target_extension, | 203 const Extension* target_extension, |
| 200 bool did_enqueue); | 204 bool did_enqueue); |
| 201 | 205 |
| 206 void ClosePortImpl(int port_id, | |
| 207 int process_id, | |
| 208 int routing_id, | |
| 209 bool force_close, | |
| 210 const std::string& error_message); | |
| 211 | |
| 202 void CloseChannelImpl(MessageChannelMap::iterator channel_iter, | 212 void CloseChannelImpl(MessageChannelMap::iterator channel_iter, |
| 203 int port_id, | 213 int port_id, |
| 204 const std::string& error_message, | 214 const std::string& error_message, |
| 205 bool notify_other_port); | 215 bool notify_other_port); |
| 206 | 216 |
| 207 // Have MessageService take ownership of |channel|, and remove any pending | 217 // Have MessageService take ownership of |channel|, and remove any pending |
| 208 // channels with the same id. | 218 // channels with the same id. |
| 209 void AddChannel(MessageChannel* channel, int receiver_port_id); | 219 void AddChannel(MessageChannel* channel, int receiver_port_id); |
| 210 | 220 |
| 211 // content::NotificationObserver interface. | |
| 212 void Observe(int type, | |
| 213 const content::NotificationSource& source, | |
| 214 const content::NotificationDetails& details) override; | |
| 215 | |
| 216 // A process that might be in our list of channels has closed. | |
| 217 void OnProcessClosed(content::RenderProcessHost* process); | |
| 218 | |
| 219 // If the channel is being opened from an incognito tab the user must allow | 221 // If the channel is being opened from an incognito tab the user must allow |
| 220 // the connection. | 222 // the connection. |
| 221 void OnOpenChannelAllowed(scoped_ptr<OpenChannelParams> params, bool allowed); | 223 void OnOpenChannelAllowed(scoped_ptr<OpenChannelParams> params, bool allowed); |
| 222 void GotChannelID(scoped_ptr<OpenChannelParams> params, | 224 void GotChannelID(scoped_ptr<OpenChannelParams> params, |
| 223 const std::string& tls_channel_id); | 225 const std::string& tls_channel_id); |
| 224 | 226 |
| 225 // Enqueues a message on a pending channel. | 227 // Enqueues a message on a pending channel. |
| 226 void EnqueuePendingMessage(int port_id, int channel_id, | 228 void EnqueuePendingMessage(int port_id, int channel_id, |
| 227 const Message& message); | 229 const Message& message); |
| 228 | 230 |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 244 scoped_ptr<OpenChannelParams>* params, | 246 scoped_ptr<OpenChannelParams>* params, |
| 245 const PendingMessagesQueue& pending_messages); | 247 const PendingMessagesQueue& pending_messages); |
| 246 | 248 |
| 247 // Callbacks for LazyBackgroundTaskQueue tasks. The queue passes in an | 249 // Callbacks for LazyBackgroundTaskQueue tasks. The queue passes in an |
| 248 // ExtensionHost to its task callbacks, though some of our callbacks don't | 250 // ExtensionHost to its task callbacks, though some of our callbacks don't |
| 249 // use that argument. | 251 // use that argument. |
| 250 void PendingLazyBackgroundPageOpenChannel( | 252 void PendingLazyBackgroundPageOpenChannel( |
| 251 scoped_ptr<OpenChannelParams> params, | 253 scoped_ptr<OpenChannelParams> params, |
| 252 int source_process_id, | 254 int source_process_id, |
| 253 extensions::ExtensionHost* host); | 255 extensions::ExtensionHost* host); |
| 254 void PendingLazyBackgroundPageCloseChannel(int port_id, | 256 void PendingLazyBackgroundPageClosePort(int port_id, |
| 255 const std::string& error_message, | 257 int process_id, |
| 256 extensions::ExtensionHost* host) { | 258 int routing_id, |
| 259 bool force_close, | |
| 260 const std::string& error_message, | |
| 261 extensions::ExtensionHost* host) { | |
| 257 if (host) | 262 if (host) |
| 258 CloseChannel(port_id, error_message); | 263 ClosePortImpl(port_id, process_id, routing_id, force_close, |
| 264 error_message); | |
| 259 } | 265 } |
| 260 void PendingLazyBackgroundPagePostMessage(int port_id, | 266 void PendingLazyBackgroundPagePostMessage(int port_id, |
| 261 const Message& message, | 267 const Message& message, |
| 262 extensions::ExtensionHost* host) { | 268 extensions::ExtensionHost* host) { |
| 263 if (host) | 269 if (host) |
| 264 PostMessage(port_id, message); | 270 PostMessage(port_id, message); |
| 265 } | 271 } |
| 266 | 272 |
| 267 // Immediate dispatches a disconnect to |source| for |port_id|. Sets source's | 273 // Immediate dispatches a disconnect to |source| for |port_id|. Sets source's |
| 268 // runtime.lastMessage to |error_message|, if any. | 274 // runtime.lastMessage to |error_message|, if any. |
| 269 void DispatchOnDisconnect(content::RenderProcessHost* source, | 275 void DispatchOnDisconnect(content::RenderFrameHost* source, |
| 270 int port_id, | 276 int port_id, |
| 271 const std::string& error_message); | 277 const std::string& error_message); |
| 272 | 278 |
| 273 void DispatchPendingMessages(const PendingMessagesQueue& queue, | 279 void DispatchPendingMessages(const PendingMessagesQueue& queue, |
| 274 int channel_id); | 280 int channel_id); |
| 275 | 281 |
| 276 // BrowserContextKeyedAPI implementation. | 282 // BrowserContextKeyedAPI implementation. |
| 277 static const char* service_name() { | 283 static const char* service_name() { |
| 278 return "MessageService"; | 284 return "MessageService"; |
| 279 } | 285 } |
| 280 static const bool kServiceRedirectedInIncognito = true; | 286 static const bool kServiceRedirectedInIncognito = true; |
| 281 static const bool kServiceIsCreatedWithBrowserContext = false; | 287 static const bool kServiceIsCreatedWithBrowserContext = false; |
| 282 static const bool kServiceIsNULLWhileTesting = true; | 288 static const bool kServiceIsNULLWhileTesting = true; |
| 283 | 289 |
| 284 content::NotificationRegistrar registrar_; | |
| 285 MessageChannelMap channels_; | 290 MessageChannelMap channels_; |
| 286 // A set of channel IDs waiting for TLS channel IDs to complete opening, and | 291 // A set of channel IDs waiting for TLS channel IDs to complete opening, and |
| 287 // any pending messages queued to be sent on those channels. This and the | 292 // any pending messages queued to be sent on those channels. This and the |
| 288 // following two maps form a pipeline where messages are queued before the | 293 // following two maps form a pipeline where messages are queued before the |
| 289 // channel they are addressed to is ready. | 294 // channel they are addressed to is ready. |
| 290 PendingChannelMap pending_tls_channel_id_channels_; | 295 PendingChannelMap pending_tls_channel_id_channels_; |
| 291 // A set of channel IDs waiting for user permission to cross the border | 296 // A set of channel IDs waiting for user permission to cross the border |
| 292 // between an incognito page and an app or extension, and any pending messages | 297 // between an incognito page and an app or extension, and any pending messages |
| 293 // queued to be sent on those channels. | 298 // queued to be sent on those channels. |
| 294 PendingChannelMap pending_incognito_channels_; | 299 PendingChannelMap pending_incognito_channels_; |
| 295 PendingLazyBackgroundPageChannelMap pending_lazy_background_page_channels_; | 300 PendingLazyBackgroundPageChannelMap pending_lazy_background_page_channels_; |
| 296 MessagePropertyProvider property_provider_; | 301 MessagePropertyProvider property_provider_; |
| 297 | 302 |
| 298 // Weak pointer. Guaranteed to outlive this class. | 303 // Weak pointer. Guaranteed to outlive this class. |
| 299 LazyBackgroundTaskQueue* lazy_background_task_queue_; | 304 LazyBackgroundTaskQueue* lazy_background_task_queue_; |
| 300 | 305 |
| 301 base::WeakPtrFactory<MessageService> weak_factory_; | 306 base::WeakPtrFactory<MessageService> weak_factory_; |
| 302 | 307 |
| 303 DISALLOW_COPY_AND_ASSIGN(MessageService); | 308 DISALLOW_COPY_AND_ASSIGN(MessageService); |
| 304 }; | 309 }; |
| 305 | 310 |
| 306 } // namespace extensions | 311 } // namespace extensions |
| 307 | 312 |
| 308 #endif // CHROME_BROWSER_EXTENSIONS_API_MESSAGING_MESSAGE_SERVICE_H_ | 313 #endif // CHROME_BROWSER_EXTENSIONS_API_MESSAGING_MESSAGE_SERVICE_H_ |
| OLD | NEW |