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