Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(67)

Side by Side Diff: chrome/browser/extensions/extension_message_service.h

Issue 3117024: Clean up ExtensionMessageService. (Closed)
Patch Set: comments fixed Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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_MESSAGE_SERVICE_H_ 5 #ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_MESSAGE_SERVICE_H_
6 #define CHROME_BROWSER_EXTENSIONS_EXTENSION_MESSAGE_SERVICE_H_ 6 #define CHROME_BROWSER_EXTENSIONS_EXTENSION_MESSAGE_SERVICE_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/lock.h"
14 #include "base/ref_counted.h" 13 #include "base/ref_counted.h"
15 #include "chrome/common/notification_registrar.h" 14 #include "chrome/common/notification_registrar.h"
16 #include "chrome/browser/chrome_thread.h"
17 #include "chrome/browser/extensions/extension_devtools_manager.h" 15 #include "chrome/browser/extensions/extension_devtools_manager.h"
18 #include "ipc/ipc_message.h" 16 #include "ipc/ipc_message.h"
19 17
20 class GURL; 18 class GURL;
21 class Profile; 19 class Profile;
22 class RenderProcessHost;
23 class ResourceMessageFilter;
24 class TabContents; 20 class TabContents;
25 21
26 // This class manages message and event passing between renderer processes. 22 // This class manages message and event passing between renderer processes.
27 // It maintains a list of processes that are listening to events and a set of 23 // It maintains a list of processes that are listening to events and a set of
28 // open channels. 24 // open channels.
29 // 25 //
30 // Messaging works this way: 26 // Messaging works this way:
31 // - An extension-owned script context (like a toolstrip or a content script) 27 // - An extension-owned script context (like a toolstrip or a content script)
32 // adds an event listener to the "onConnect" event. 28 // adds an event listener to the "onConnect" event.
33 // - Another context calls "extension.connect()" to open a channel to the 29 // - Another context calls "extension.connect()" to open a channel to the
34 // extension process, or an extension context calls "tabs.connect(tabId)" to 30 // extension process, or an extension context calls "tabs.connect(tabId)" to
35 // open a channel to the content scripts for the given tab. The EMS notifies 31 // open a channel to the content scripts for the given tab. The EMS notifies
36 // the target process/tab, which then calls the onConnect event in every 32 // the target process/tab, which then calls the onConnect event in every
37 // context owned by the connecting extension in that process/tab. 33 // context owned by the connecting extension in that process/tab.
38 // - Once the channel is established, either side can call postMessage to send 34 // - Once the channel is established, either side can call postMessage to send
39 // a message to the opposite side of the channel, which may have multiple 35 // a message to the opposite side of the channel, which may have multiple
40 // listeners. 36 // listeners.
41 // 37 //
42 // Terminology: 38 // Terminology:
43 // channel: connection between two ports 39 // channel: connection between two ports
44 // port: an IPC::Message::Sender interface and an optional routing_id (in the 40 // port: an IPC::Message::Sender interface and an optional routing_id (in the
45 // case that the port is a tab). The Sender is usually either a 41 // case that the port is a tab). The Sender is usually either a
46 // RenderProcessHost or a RenderViewHost. 42 // RenderProcessHost or a RenderViewHost.
43
44 // TODO(mpcomplete): Remove refcounting and make Profile the sole owner of this
45 // class. Then we can get rid of ProfileDestroyed().
47 class ExtensionMessageService 46 class ExtensionMessageService
48 : public base::RefCountedThreadSafe< 47 : public base::RefCounted<ExtensionMessageService>,
49 ExtensionMessageService, ChromeThread::DeleteOnUIThread>,
50 public NotificationObserver { 48 public NotificationObserver {
51 public: 49 public:
52 // Javascript function name constants. 50 // Javascript function name constants.
53 static const char kDispatchOnConnect[]; 51 static const char kDispatchOnConnect[];
54 static const char kDispatchOnDisconnect[]; 52 static const char kDispatchOnDisconnect[];
55 static const char kDispatchOnMessage[]; 53 static const char kDispatchOnMessage[];
56 static const char kDispatchEvent[]; 54 static const char kDispatchEvent[];
57 static const char kDispatchError[]; 55 static const char kDispatchError[];
58 56
59 // A messaging channel. Note that the opening port can be the same as the 57 // A messaging channel. Note that the opening port can be the same as the
60 // receiver, if an extension toolstrip wants to talk to its tab (for example). 58 // receiver, if an extension toolstrip wants to talk to its tab (for example).
61 struct MessageChannel; 59 struct MessageChannel;
62 struct MessagePort; 60 struct MessagePort;
63 61
64 // Returns the event name for an event that is extension-specific. 62 // Returns the event name for an event that is extension-specific.
65 static std::string GetPerExtensionEventName(const std::string& event_name, 63 static std::string GetPerExtensionEventName(const std::string& event_name,
66 const std::string& extension_id); 64 const std::string& extension_id);
67 65
68 // --- UI thread only: 66 // Allocates a pair of port ids.
67 // NOTE: this can be called from any thread.
68 static void AllocatePortIdPair(int* port1, int* port2);
69 69
70 explicit ExtensionMessageService(Profile* profile); 70 explicit ExtensionMessageService(Profile* profile);
71 71
72 // Notification that our owning profile is going away. 72 // Notification that our owning profile is going away.
73 void ProfileDestroyed(); 73 void ProfileDestroyed();
74 74
75 // Add or remove |render_process_pid| as a listener for |event_name|. 75 // Add or remove |render_process_pid| as a listener for |event_name|.
76 void AddEventListener(const std::string& event_name, int render_process_id); 76 void AddEventListener(const std::string& event_name, int render_process_id);
77 void RemoveEventListener(const std::string& event_name, 77 void RemoveEventListener(const std::string& event_name,
78 int render_process_id); 78 int render_process_id);
79 79
80 // Returns true if there is at least one listener for the given event. 80 // Returns true if there is at least one listener for the given event.
81 bool HasEventListener(const std::string& event_name); 81 bool HasEventListener(const std::string& event_name);
82 82
83 // Closes the message channel associated with the given port, and notifies
84 // the other side.
85 void CloseChannel(int port_id);
86
87 // Sends a message from a renderer to the given port.
88 void PostMessageFromRenderer(int port_id, const std::string& message);
89
90 // Send an event to every registered extension renderer. If 83 // Send an event to every registered extension renderer. If
91 // |has_incognito_data| is true, the event is only sent to extension with the 84 // |has_incognito_data| is true, the event is only sent to extension with the
92 // permission to access incognito data. If |event_url| is not empty, the 85 // permission to access incognito data. If |event_url| is not empty, the
93 // event is only sent to extension with host permissions for this url. 86 // event is only sent to extension with host permissions for this url.
94 virtual void DispatchEventToRenderers( 87 virtual void DispatchEventToRenderers(
95 const std::string& event_name, const std::string& event_args, 88 const std::string& event_name, const std::string& event_args,
96 bool has_incognito_data, const GURL& event_url); 89 bool has_incognito_data, const GURL& event_url);
97 90
98 // Same as above, except use the extension-specific naming scheme for the 91 // Same as above, except use the extension-specific naming scheme for the
99 // event. This is used by events that are per-extension. 92 // event. This is used by events that are per-extension.
100 void DispatchEventToExtension( 93 void DispatchEventToExtension(
101 const std::string& extension_id, 94 const std::string& extension_id,
102 const std::string& event_name, const std::string& event_args, 95 const std::string& event_name, const std::string& event_args,
103 bool has_incognito_data, const GURL& event_url); 96 bool has_incognito_data, const GURL& event_url);
104 97
98 // Given an extension's ID, opens a channel between the given renderer "port"
99 // and every listening context owned by that extension. |channel_name| is
100 // an optional identifier for use by extension developers.
101 void OpenChannelToExtension(
102 int source_process_id, int source_routing_id, int receiver_port_id,
103 const std::string& source_extension_id,
104 const std::string& target_extension_id,
105 const std::string& channel_name);
106
107 // Same as above, but opens a channel to the tab with the given ID. Messages
108 // are restricted to that tab, so if there are multiple tabs in that process,
109 // only the targeted tab will receive messages.
110 void OpenChannelToTab(
111 int source_process_id, int source_routing_id, int receiver_port_id,
112 int tab_id, const std::string& extension_id,
113 const std::string& channel_name);
114
105 // Given an extension ID, opens a channel between the given 115 // Given an extension ID, opens a channel between the given
106 // automation "port" or DevTools service and that extension. the 116 // automation "port" or DevTools service and that extension. the
107 // channel will be open to the extension process hosting the 117 // channel will be open to the extension process hosting the
108 // background page and tool strip. 118 // background page and tool strip.
109 // 119 //
110 // Returns a port ID to be used for posting messages between the 120 // Returns a port ID to be used for posting messages between the
111 // processes, or -1 if the extension doesn't exist. 121 // processes, or -1 if the extension doesn't exist.
112 int OpenSpecialChannelToExtension( 122 int OpenSpecialChannelToExtension(
113 const std::string& extension_id, const std::string& channel_name, 123 const std::string& extension_id, const std::string& channel_name,
114 const std::string& tab_json, IPC::Message::Sender* source); 124 const std::string& tab_json, IPC::Message::Sender* source);
115 125
116 // Given an extension ID, opens a channel between the given DevTools 126 // Given an extension ID, opens a channel between the given DevTools
117 // service and the content script for that extension running in the 127 // service and the content script for that extension running in the
118 // designated tab. 128 // designated tab.
119 // 129 //
120 // Returns a port ID identifying the DevTools end of the channel, to 130 // Returns a port ID identifying the DevTools end of the channel, to
121 // be used for posting messages. May return -1 on failure, although 131 // be used for posting messages. May return -1 on failure, although
122 // the code doesn't detect whether the extension actually exists. 132 // the code doesn't detect whether the extension actually exists.
123 int OpenSpecialChannelToTab( 133 int OpenSpecialChannelToTab(
124 const std::string& extension_id, const std::string& channel_name, 134 const std::string& extension_id, const std::string& channel_name,
125 TabContents* target_tab_contents, IPC::Message::Sender* source); 135 TabContents* target_tab_contents, IPC::Message::Sender* source);
126 136
127 // --- IO thread only: 137 // Closes the message channel associated with the given port, and notifies
138 // the other side.
139 void CloseChannel(int port_id);
128 140
129 // Given an extension's ID, opens a channel between the given renderer "port" 141 // Sends a message from a renderer to the given port.
130 // and every listening context owned by that extension. Returns a port ID 142 void PostMessageFromRenderer(int port_id, const std::string& message);
131 // to be used for posting messages between the processes. |channel_name| is
132 // an optional identifier for use by extension developers.
133 // This runs on the IO thread so that it can be used in a synchronous IPC
134 // message.
135 int OpenChannelToExtension(int routing_id,
136 const std::string& source_extension_id,
137 const std::string& target_extension_id,
138 const std::string& channel_name,
139 ResourceMessageFilter* source);
140
141 // Same as above, but opens a channel to the tab with the given ID. Messages
142 // are restricted to that tab, so if there are multiple tabs in that process,
143 // only the targeted tab will receive messages.
144 int OpenChannelToTab(int routing_id, int tab_id,
145 const std::string& extension_id,
146 const std::string& channel_name,
147 ResourceMessageFilter* source);
148 143
149 private: 144 private:
150 friend class ChromeThread; 145 friend class base::RefCounted<ExtensionMessageService>;
151 friend class DeleteTask<ExtensionMessageService>;
152 friend class MockExtensionMessageService; 146 friend class MockExtensionMessageService;
153 147
154 // A map of channel ID to its channel object. 148 // A map of channel ID to its channel object.
155 typedef std::map<int, MessageChannel*> MessageChannelMap; 149 typedef std::map<int, MessageChannel*> MessageChannelMap;
156 150
157 virtual ~ExtensionMessageService(); 151 virtual ~ExtensionMessageService();
158 152
159 // Allocates a pair of port ids. 153 // Common among Open(Special)Channel* variants.
160 // NOTE: this can be called from any thread. 154 bool OpenChannelImpl(
161 void AllocatePortIdPair(int* port1, int* port2);
162
163 void CloseChannelImpl(MessageChannelMap::iterator channel_iter, int port_id,
164 bool notify_other_port);
165
166 // --- UI thread only:
167
168 // Handles channel creation and notifies the destinations that a channel was
169 // opened.
170 void OpenChannelToExtensionOnUIThread(
171 int source_process_id, int source_routing_id, int receiver_port_id,
172 const std::string& source_extension_id,
173 const std::string& target_extension_id,
174 const std::string& channel_name);
175
176 void OpenChannelToTabOnUIThread(
177 int source_process_id, int source_routing_id, int receiver_port_id,
178 int tab_id, const std::string& extension_id,
179 const std::string& channel_name);
180
181 // Common between OpenChannelOnUIThread and OpenSpecialChannelToExtension.
182 bool OpenChannelOnUIThreadImpl(
183 IPC::Message::Sender* source, 155 IPC::Message::Sender* source,
184 const std::string& tab_json, 156 const std::string& tab_json,
185 const MessagePort& receiver, int receiver_port_id, 157 const MessagePort& receiver, int receiver_port_id,
186 const std::string& source_extension_id, 158 const std::string& source_extension_id,
187 const std::string& target_extension_id, 159 const std::string& target_extension_id,
188 const std::string& channel_name); 160 const std::string& channel_name);
189 161
162 void CloseChannelImpl(MessageChannelMap::iterator channel_iter, int port_id,
163 bool notify_other_port);
164
190 // NotificationObserver interface. 165 // NotificationObserver interface.
191 void Observe(NotificationType type, 166 void Observe(NotificationType type,
192 const NotificationSource& source, 167 const NotificationSource& source,
193 const NotificationDetails& details); 168 const NotificationDetails& details);
194 169
195 // An IPC sender that might be in our list of channels has closed. 170 // An IPC sender that might be in our list of channels has closed.
196 void OnSenderClosed(IPC::Message::Sender* sender); 171 void OnSenderClosed(IPC::Message::Sender* sender);
197 172
198 Profile* profile_; 173 Profile* profile_;
199 174
200 NotificationRegistrar registrar_; 175 NotificationRegistrar registrar_;
201 176
202 MessageChannelMap channels_; 177 MessageChannelMap channels_;
203 178
204 scoped_refptr<ExtensionDevToolsManager> extension_devtools_manager_; 179 scoped_refptr<ExtensionDevToolsManager> extension_devtools_manager_;
205 180
206 // A map between an event name and a set of process id's that are listening 181 // A map between an event name and a set of process id's that are listening
207 // to that event. 182 // to that event.
208 typedef std::map<std::string, std::set<int> > ListenerMap; 183 typedef std::map<std::string, std::set<int> > ListenerMap;
209 ListenerMap listeners_; 184 ListenerMap listeners_;
210 185
211 // --- UI or IO thread:
212
213 // For generating unique channel IDs.
214 int next_port_id_;
215
216 // Protects the next_port_id_ variable, since it can be
217 // used on the IO thread or the UI thread.
218 Lock next_port_id_lock_;
219
220 DISALLOW_COPY_AND_ASSIGN(ExtensionMessageService); 186 DISALLOW_COPY_AND_ASSIGN(ExtensionMessageService);
221 }; 187 };
222 188
223 #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_MESSAGE_SERVICE_H_ 189 #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_MESSAGE_SERVICE_H_
OLDNEW
« no previous file with comments | « chrome/browser/debugger/extension_ports_remote_service.cc ('k') | chrome/browser/extensions/extension_message_service.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698