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. |
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 virtual bool IsValidPort(); | |
Devlin
2015/10/30 01:49:39
comment and newline, and I think I'd prefer this t
robwu
2015/11/02 19:08:34
Done.
| |
71 // Notify the port that the channel has been opened. | 65 // Notify the port that the channel has been opened. |
72 virtual void DispatchOnConnect(int dest_port_id, | 66 virtual void DispatchOnConnect(const std::string& channel_name, |
73 const std::string& channel_name, | |
74 scoped_ptr<base::DictionaryValue> source_tab, | 67 scoped_ptr<base::DictionaryValue> source_tab, |
75 int source_frame_id, | 68 int source_frame_id, |
76 int target_tab_id, | |
77 int target_frame_id, | |
78 int guest_process_id, | 69 int guest_process_id, |
79 int guest_render_frame_routing_id, | 70 int guest_render_frame_routing_id, |
80 const std::string& source_extension_id, | 71 const std::string& source_extension_id, |
81 const std::string& target_extension_id, | 72 const std::string& target_extension_id, |
82 const GURL& source_url, | 73 const GURL& source_url, |
83 const std::string& tls_channel_id) {} | 74 const std::string& tls_channel_id) {} |
84 | 75 |
85 // Notify the port that the channel has been closed. If |error_message| is | 76 // 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. | 77 // non-empty, it indicates an error occurred while opening the connection. |
87 virtual void DispatchOnDisconnect(int source_port_id, | 78 virtual void DispatchOnDisconnect(const std::string& error_message) {} |
88 const std::string& error_message) {} | |
89 | 79 |
90 // Dispatch a message to this end of the communication. | 80 // Dispatch a message to this end of the communication. |
91 virtual void DispatchOnMessage(const Message& message, | 81 virtual void DispatchOnMessage(const Message& message) = 0; |
92 int target_port_id) = 0; | |
93 | 82 |
94 // MessagPorts that target extensions will need to adjust their keepalive | 83 // Mark the port as opened by the specific frame. |
84 virtual void OpenPort(int process_id, int routing_id) {} | |
85 | |
86 // Close the port for the given frame. | |
87 virtual void ClosePort(int process_id, int routing_id) {} | |
88 | |
89 // MessagePorts that target extensions will need to adjust their keepalive | |
95 // counts for their lazy background page. | 90 // counts for their lazy background page. |
96 virtual void IncrementLazyKeepaliveCount() {} | 91 virtual void IncrementLazyKeepaliveCount() {} |
97 virtual void DecrementLazyKeepaliveCount() {} | 92 virtual void DecrementLazyKeepaliveCount() {} |
98 | 93 |
99 // Get the RenderProcessHost (if any) associated with the port. | |
100 virtual content::RenderProcessHost* GetRenderProcessHost(); | |
101 | |
102 protected: | 94 protected: |
103 MessagePort() {} | 95 MessagePort() {} |
104 | 96 |
105 private: | 97 private: |
106 DISALLOW_COPY_AND_ASSIGN(MessagePort); | 98 DISALLOW_COPY_AND_ASSIGN(MessagePort); |
107 }; | 99 }; |
108 | 100 |
109 enum PolicyPermission { | 101 enum PolicyPermission { |
110 DISALLOW, // The host is not allowed. | 102 DISALLOW, // The host is not allowed. |
111 ALLOW_SYSTEM_ONLY, // Allowed only when installed on system level. | 103 ALLOW_SYSTEM_ONLY, // Allowed only when installed on system level. |
(...skipping 25 matching lines...) Expand all Loading... | |
137 const std::string& source_extension_id, | 129 const std::string& source_extension_id, |
138 const std::string& target_extension_id, | 130 const std::string& target_extension_id, |
139 const GURL& source_url, | 131 const GURL& source_url, |
140 const std::string& channel_name, | 132 const std::string& channel_name, |
141 bool include_tls_channel_id); | 133 bool include_tls_channel_id); |
142 | 134 |
143 // Same as above, but opens a channel to the tab with the given ID. Messages | 135 // 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, | 136 // are restricted to that tab, so if there are multiple tabs in that process, |
145 // only the targeted tab will receive messages. | 137 // only the targeted tab will receive messages. |
146 void OpenChannelToTab(int source_process_id, | 138 void OpenChannelToTab(int source_process_id, |
139 int source_routing_id, | |
147 int receiver_port_id, | 140 int receiver_port_id, |
148 int tab_id, | 141 int tab_id, |
149 int frame_id, | 142 int frame_id, |
150 const std::string& extension_id, | 143 const std::string& extension_id, |
151 const std::string& channel_name); | 144 const std::string& channel_name); |
152 | 145 |
153 void OpenChannelToNativeApp( | 146 void OpenChannelToNativeApp( |
154 int source_process_id, | 147 int source_process_id, |
155 int source_routing_id, | 148 int source_routing_id, |
156 int receiver_port_id, | 149 int receiver_port_id, |
157 const std::string& source_extension_id, | 150 const std::string& source_extension_id, |
158 const std::string& native_app_name); | 151 const std::string& native_app_name); |
159 | 152 |
153 // Acknowledges open port in the frame identified by (process_id, routing_id). | |
154 void OpenPort(int port_id, int process_id, int routing_id); | |
155 | |
156 // Closes the given port in the given frame. If this was the last frame or if | |
157 // |force_close| is true, then the other side is closed as well. | |
158 void ClosePort(int port_id, int process_id, int routing_id, bool force_close); | |
159 | |
160 // Closes the message channel associated with the given port, and notifies | 160 // Closes the message channel associated with the given port, and notifies |
161 // the other side. | 161 // the other side. |
162 void CloseChannel(int port_id, const std::string& error_message); | 162 void CloseChannel(int port_id, const std::string& error_message); |
163 | 163 |
164 // Enqueues a message on a pending channel, or sends a message to the given | 164 // Enqueues a message on a pending channel, or sends a message to the given |
165 // port if the channel isn't pending. | 165 // port if the channel isn't pending. |
166 void PostMessage(int port_id, const Message& message); | 166 void PostMessage(int port_id, const Message& message); |
167 | 167 |
168 private: | 168 private: |
169 friend class MockMessageService; | 169 friend class MockMessageService; |
(...skipping 22 matching lines...) Expand all Loading... | |
192 // |target_extension| will be non-null if |params->target_extension_id| is | 192 // |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. | 193 // non-empty, that is, if the target is an extension, it must exist. |
194 // | 194 // |
195 // |did_enqueue| will be true if the channel opening was delayed while | 195 // |did_enqueue| will be true if the channel opening was delayed while |
196 // waiting for an event page to start, false otherwise. | 196 // waiting for an event page to start, false otherwise. |
197 void OpenChannelImpl(content::BrowserContext* browser_context, | 197 void OpenChannelImpl(content::BrowserContext* browser_context, |
198 scoped_ptr<OpenChannelParams> params, | 198 scoped_ptr<OpenChannelParams> params, |
199 const Extension* target_extension, | 199 const Extension* target_extension, |
200 bool did_enqueue); | 200 bool did_enqueue); |
201 | 201 |
202 void ClosePortImpl(int port_id, int process_id, int routing_id, | |
203 bool force_close, const std::string& error_message); | |
204 | |
202 void CloseChannelImpl(MessageChannelMap::iterator channel_iter, | 205 void CloseChannelImpl(MessageChannelMap::iterator channel_iter, |
203 int port_id, | 206 int port_id, |
204 const std::string& error_message, | 207 const std::string& error_message, |
205 bool notify_other_port); | 208 bool notify_other_port); |
206 | 209 |
207 // Have MessageService take ownership of |channel|, and remove any pending | 210 // Have MessageService take ownership of |channel|, and remove any pending |
208 // channels with the same id. | 211 // channels with the same id. |
209 void AddChannel(MessageChannel* channel, int receiver_port_id); | 212 void AddChannel(MessageChannel* channel, int receiver_port_id); |
210 | 213 |
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 | 214 // If the channel is being opened from an incognito tab the user must allow |
220 // the connection. | 215 // the connection. |
221 void OnOpenChannelAllowed(scoped_ptr<OpenChannelParams> params, bool allowed); | 216 void OnOpenChannelAllowed(scoped_ptr<OpenChannelParams> params, bool allowed); |
222 void GotChannelID(scoped_ptr<OpenChannelParams> params, | 217 void GotChannelID(scoped_ptr<OpenChannelParams> params, |
223 const std::string& tls_channel_id); | 218 const std::string& tls_channel_id); |
224 | 219 |
225 // Enqueues a message on a pending channel. | 220 // Enqueues a message on a pending channel. |
226 void EnqueuePendingMessage(int port_id, int channel_id, | 221 void EnqueuePendingMessage(int port_id, int channel_id, |
227 const Message& message); | 222 const Message& message); |
228 | 223 |
(...skipping 15 matching lines...) Expand all Loading... | |
244 scoped_ptr<OpenChannelParams>* params, | 239 scoped_ptr<OpenChannelParams>* params, |
245 const PendingMessagesQueue& pending_messages); | 240 const PendingMessagesQueue& pending_messages); |
246 | 241 |
247 // Callbacks for LazyBackgroundTaskQueue tasks. The queue passes in an | 242 // Callbacks for LazyBackgroundTaskQueue tasks. The queue passes in an |
248 // ExtensionHost to its task callbacks, though some of our callbacks don't | 243 // ExtensionHost to its task callbacks, though some of our callbacks don't |
249 // use that argument. | 244 // use that argument. |
250 void PendingLazyBackgroundPageOpenChannel( | 245 void PendingLazyBackgroundPageOpenChannel( |
251 scoped_ptr<OpenChannelParams> params, | 246 scoped_ptr<OpenChannelParams> params, |
252 int source_process_id, | 247 int source_process_id, |
253 extensions::ExtensionHost* host); | 248 extensions::ExtensionHost* host); |
254 void PendingLazyBackgroundPageCloseChannel(int port_id, | 249 void PendingLazyBackgroundPageClosePort(int port_id, |
255 const std::string& error_message, | 250 int process_id, |
256 extensions::ExtensionHost* host) { | 251 int routing_id, |
252 bool force_close, | |
253 const std::string& error_message, | |
254 extensions::ExtensionHost* host) { | |
257 if (host) | 255 if (host) |
258 CloseChannel(port_id, error_message); | 256 ClosePortImpl(port_id, process_id, routing_id, force_close, |
257 error_message); | |
259 } | 258 } |
260 void PendingLazyBackgroundPagePostMessage(int port_id, | 259 void PendingLazyBackgroundPagePostMessage(int port_id, |
261 const Message& message, | 260 const Message& message, |
262 extensions::ExtensionHost* host) { | 261 extensions::ExtensionHost* host) { |
263 if (host) | 262 if (host) |
264 PostMessage(port_id, message); | 263 PostMessage(port_id, message); |
265 } | 264 } |
266 | 265 |
267 // Immediate dispatches a disconnect to |source| for |port_id|. Sets source's | 266 // Immediate dispatches a disconnect to |source| for |port_id|. Sets source's |
268 // runtime.lastMessage to |error_message|, if any. | 267 // runtime.lastMessage to |error_message|, if any. |
269 void DispatchOnDisconnect(content::RenderProcessHost* source, | 268 void DispatchOnDisconnect(content::RenderFrameHost* source, |
270 int port_id, | 269 int port_id, |
271 const std::string& error_message); | 270 const std::string& error_message); |
272 | 271 |
273 void DispatchPendingMessages(const PendingMessagesQueue& queue, | 272 void DispatchPendingMessages(const PendingMessagesQueue& queue, |
274 int channel_id); | 273 int channel_id); |
275 | 274 |
276 // BrowserContextKeyedAPI implementation. | 275 // BrowserContextKeyedAPI implementation. |
277 static const char* service_name() { | 276 static const char* service_name() { |
278 return "MessageService"; | 277 return "MessageService"; |
279 } | 278 } |
280 static const bool kServiceRedirectedInIncognito = true; | 279 static const bool kServiceRedirectedInIncognito = true; |
281 static const bool kServiceIsCreatedWithBrowserContext = false; | 280 static const bool kServiceIsCreatedWithBrowserContext = false; |
282 static const bool kServiceIsNULLWhileTesting = true; | 281 static const bool kServiceIsNULLWhileTesting = true; |
283 | 282 |
284 content::NotificationRegistrar registrar_; | |
285 MessageChannelMap channels_; | 283 MessageChannelMap channels_; |
286 // A set of channel IDs waiting for TLS channel IDs to complete opening, and | 284 // 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 | 285 // 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 | 286 // following two maps form a pipeline where messages are queued before the |
289 // channel they are addressed to is ready. | 287 // channel they are addressed to is ready. |
290 PendingChannelMap pending_tls_channel_id_channels_; | 288 PendingChannelMap pending_tls_channel_id_channels_; |
291 // A set of channel IDs waiting for user permission to cross the border | 289 // 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 | 290 // between an incognito page and an app or extension, and any pending messages |
293 // queued to be sent on those channels. | 291 // queued to be sent on those channels. |
294 PendingChannelMap pending_incognito_channels_; | 292 PendingChannelMap pending_incognito_channels_; |
295 PendingLazyBackgroundPageChannelMap pending_lazy_background_page_channels_; | 293 PendingLazyBackgroundPageChannelMap pending_lazy_background_page_channels_; |
296 MessagePropertyProvider property_provider_; | 294 MessagePropertyProvider property_provider_; |
297 | 295 |
298 // Weak pointer. Guaranteed to outlive this class. | 296 // Weak pointer. Guaranteed to outlive this class. |
299 LazyBackgroundTaskQueue* lazy_background_task_queue_; | 297 LazyBackgroundTaskQueue* lazy_background_task_queue_; |
300 | 298 |
301 base::WeakPtrFactory<MessageService> weak_factory_; | 299 base::WeakPtrFactory<MessageService> weak_factory_; |
302 | 300 |
303 DISALLOW_COPY_AND_ASSIGN(MessageService); | 301 DISALLOW_COPY_AND_ASSIGN(MessageService); |
304 }; | 302 }; |
305 | 303 |
306 } // namespace extensions | 304 } // namespace extensions |
307 | 305 |
308 #endif // CHROME_BROWSER_EXTENSIONS_API_MESSAGING_MESSAGE_SERVICE_H_ | 306 #endif // CHROME_BROWSER_EXTENSIONS_API_MESSAGING_MESSAGE_SERVICE_H_ |
OLD | NEW |