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

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

Issue 155707: Changed the extension.connect() API not to broadcast to all tabs. Added a (Closed)
Patch Set: review comments Created 11 years, 5 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) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 7
8 #include <map> 8 #include <map>
9 #include <set> 9 #include <set>
10 #include <string> 10 #include <string>
11 11
12 #include "base/linked_ptr.h" 12 #include "base/linked_ptr.h"
13 #include "base/lock.h" 13 #include "base/lock.h"
14 #include "base/ref_counted.h"
14 #include "chrome/common/ipc_message.h" 15 #include "chrome/common/ipc_message.h"
15 #include "chrome/common/notification_registrar.h" 16 #include "chrome/common/notification_registrar.h"
16 17
17 class MessageLoop; 18 class MessageLoop;
19 class Profile;
18 class RenderProcessHost; 20 class RenderProcessHost;
19 class ResourceMessageFilter; 21 class ResourceMessageFilter;
20 class URLRequestContext; 22 class URLRequestContext;
21 23
22 // This class manages message and event passing between renderer processes. 24 // This class manages message and event passing between renderer processes.
23 // It maintains a list of processes that are listening to events (including 25 // It maintains a list of processes that are listening to events and a set of
24 // messaging events), as well as a set of open channels. 26 // open channels.
25 // 27 //
26 // Messaging works this way: 28 // Messaging works this way:
27 // - An extension-owned script context (like a toolstrip or a content script) 29 // - An extension-owned script context (like a toolstrip or a content script)
28 // adds an event listener to the "onConnect" event. We keep track here of a 30 // adds an event listener to the "onConnect" event.
29 // list of "listeners" that registered interest in receiving extension 31 // - Another context calls "extension.connect()" to open a channel to the
30 // messages. 32 // extension process, or an extension context calls "tabs.connect(tabId)" to
31 // - Another context calls "connect()" to open a channel to every listener 33 // open a channel to the content scripts for the given tab. The EMS notifies
32 // owned by the same extension. This is a broadcast event, so every listener 34 // the target process/tab, which then calls the onConnect event in every
33 // will get notified. 35 // context owned by the connecting extension in that process/tab.
34 // - Once the channel is established, either side can call postMessage to send 36 // - Once the channel is established, either side can call postMessage to send
35 // a message to the opposite side of the channel, which may have multiple 37 // a message to the opposite side of the channel, which may have multiple
36 // listeners. 38 // listeners.
37 // 39 //
38 // Terminology: 40 // Terminology:
39 // channel: connection between two ports (one side of which can have multiple 41 // channel: connection between two ports
40 // listeners) 42 // port: an IPC::Message::Sender interface and an optional routing_id (in the
41 // port: one or more IPC::Message::Sender interfaces through which we 43 // case that the port is a tab). The Sender is usually either a
42 // communicate to process(es). These are generally RenderProcessHosts. 44 // RenderProcessHost or a RenderViewHost.
43 class ExtensionMessageService : public NotificationObserver { 45 class ExtensionMessageService :
46 public base::RefCountedThreadSafe<ExtensionMessageService>,
47 public NotificationObserver {
44 public: 48 public:
45 // Javascript function name constants. 49 // Javascript function name constants.
46 static const char kDispatchOnConnect[]; 50 static const char kDispatchOnConnect[];
47 static const char kDispatchOnDisconnect[]; 51 static const char kDispatchOnDisconnect[];
48 static const char kDispatchOnMessage[]; 52 static const char kDispatchOnMessage[];
49 static const char kDispatchEvent[]; 53 static const char kDispatchEvent[];
50 static const char kDispatchError[]; 54 static const char kDispatchError[];
51 55
52 // Returns the message service for the given context. Messages can only 56 // A messaging channel. Note that the opening port can be the same as the
53 // be sent within a single context. 57 // receiver, if an extension toolstrip wants to talk to its tab (for example).
54 static ExtensionMessageService* GetInstance(URLRequestContext* context); 58 struct MessageChannel;
55 59 struct MessagePort;
56 ExtensionMessageService();
57 60
58 // --- UI thread only: 61 // --- UI thread only:
59 62
60 // UI-thread specific initialization. Does nothing if called more than once. 63 ExtensionMessageService(Profile* profile);
61 void Init(); 64 ~ExtensionMessageService();
65
66 // Notification that our owning profile is going away.
67 void ProfileDestroyed() { profile_ = NULL; }
62 68
63 // Add or remove |render_process_pid| as a listener for |event_name|. 69 // Add or remove |render_process_pid| as a listener for |event_name|.
64 void AddEventListener(std::string event_name, int render_process_id); 70 void AddEventListener(std::string event_name, int render_process_id);
65 void RemoveEventListener(std::string event_name, int render_process_id); 71 void RemoveEventListener(std::string event_name, int render_process_id);
66 72
67 // Closes the message channel associated with the given port, and notifies 73 // Closes the message channel associated with the given port, and notifies
68 // the other side. 74 // the other side.
69 void CloseChannel(int port_id); 75 void CloseChannel(int port_id);
70 76
71 // Sends a message from a renderer to the given port. 77 // Sends a message from a renderer to the given port.
72 void PostMessageFromRenderer(int port_id, const std::string& message); 78 void PostMessageFromRenderer(int port_id, const std::string& message);
73 79
74 // Send an event to every registered extension renderer. 80 // Send an event to every registered extension renderer.
75 void DispatchEventToRenderers( 81 void DispatchEventToRenderers(
76 const std::string& event_name, const std::string& event_args); 82 const std::string& event_name, const std::string& event_args);
77 83
78 // Given an extension's ID, opens a channel between the given automation 84 // Given an extension's ID, opens a channel between the given automation
79 // "port" and that extension. Returns a channel ID to be used for posting 85 // "port" and that extension. Returns a channel ID to be used for posting
80 // messages between the processes, or -1 if the extension doesn't exist. 86 // messages between the processes, or -1 if the extension doesn't exist.
81 int OpenAutomationChannelToExtension(int source_process_id, 87 int OpenAutomationChannelToExtension(int source_process_id,
82 int routing_id, 88 int routing_id,
83 const std::string& extension_id, 89 const std::string& extension_id,
84 IPC::Message::Sender* source); 90 IPC::Message::Sender* source);
85 91
86 // NotificationObserver interface.
87 void Observe(NotificationType type,
88 const NotificationSource& source,
89 const NotificationDetails& details);
90
91 // --- IO thread only: 92 // --- IO thread only:
92 93
93 // Given an extension's ID, opens a channel between the given renderer "port" 94 // Given an extension's ID, opens a channel between the given renderer "port"
94 // and every listening context owned by that extension. Returns a port ID 95 // and every listening context owned by that extension. Returns a port ID
95 // to be used for posting messages between the processes. |channel_name| is 96 // to be used for posting messages between the processes. |channel_name| is
96 // an optional identifier for use by extension developers. 97 // an optional identifier for use by extension developers.
97 // This runs on the IO thread so that it can be used in a synchronous IPC 98 // This runs on the IO thread so that it can be used in a synchronous IPC
98 // message. 99 // message.
99 int OpenChannelToExtension(int routing_id, const std::string& extension_id, 100 int OpenChannelToExtension(int routing_id, const std::string& extension_id,
100 const std::string& channel_name, 101 const std::string& channel_name,
101 ResourceMessageFilter* source); 102 ResourceMessageFilter* source);
102 103
104 // Same as above, but opens a channel to the tab with the given ID. Messages
105 // are restricted to that tab, so if there are multiple tabs in that process,
106 // only the targeted tab will receive messages.
107 int OpenChannelToTab(int routing_id, int tab_id,
108 const std::string& extension_id,
109 const std::string& channel_name,
110 ResourceMessageFilter* source);
111
103 private: 112 private:
104 // A messaging channel. Since messages are broadcast, the channel can have
105 // multiple processes listening for messages. Note that the opening port
106 // can also be among the receivers, if an extension toolstrip wants to talk
107 // to its tab (for example).
108 struct MessageChannel {
109 typedef std::set<IPC::Message::Sender*> Ports;
110 Ports opener; // only 1 opener, but we use a set to simplify logic
111 Ports receivers;
112 };
113
114 // A map of channel ID to its channel object. 113 // A map of channel ID to its channel object.
115 typedef std::map<int, linked_ptr<MessageChannel> > MessageChannelMap; 114 typedef std::map<int, linked_ptr<MessageChannel> > MessageChannelMap;
116 115
117 // Allocates a pair of port ids. 116 // Allocates a pair of port ids.
118 // NOTE: this can be called from any thread. 117 // NOTE: this can be called from any thread.
119 void AllocatePortIdPair(int* port1, int* port2); 118 void AllocatePortIdPair(int* port1, int* port2);
120 119
121 void CloseChannelImpl(MessageChannelMap::iterator channel_iter, int port_id); 120 void CloseChannelImpl(MessageChannelMap::iterator channel_iter, int port_id);
122 121
123 // The UI message loop, used for posting tasks. 122 // The UI message loop, used for posting tasks.
124 MessageLoop* ui_loop_; 123 MessageLoop* ui_loop_;
125 124
126 // --- UI thread only: 125 // --- UI thread only:
127 126
128 // Handles channel creation and notifies the destinations that a channel was 127 // Handles channel creation and notifies the destinations that a channel was
129 // opened. 128 // opened.
130 void OpenChannelOnUIThread(int source_routing_id, 129 void OpenChannelToExtensionOnUIThread(
131 int source_port_id, int source_process_id, 130 int source_process_id, int source_routing_id, int receiver_port_id,
132 const std::string& extension_id, const std::string& channel_name); 131 const std::string& extension_id, const std::string& channel_name);
132
133 void OpenChannelToTabOnUIThread(
134 int source_process_id, int source_routing_id, int receiver_port_id,
135 int tab_id, const std::string& extension_id,
136 const std::string& channel_name);
133 137
134 // Common between OpenChannelOnUIThread and OpenAutomationChannelToExtension. 138 // Common between OpenChannelOnUIThread and OpenAutomationChannelToExtension.
135 void OpenChannelOnUIThreadImpl( 139 void OpenChannelOnUIThreadImpl(
136 int source_routing_id, int source_port_id, int source_process_id, 140 IPC::Message::Sender* source, int source_process_id, int source_routing_id,
137 IPC::Message::Sender* source, const std::string& extension_id, 141 const MessagePort& receiver, int receiver_port_id,
138 const std::string& channel_name); 142 const std::string& extension_id, const std::string& channel_name);
143
144 // NotificationObserver interface.
145 void Observe(NotificationType type,
146 const NotificationSource& source,
147 const NotificationDetails& details);
148
149 // An IPC sender that might be in our list of channels has closed.
150 void OnSenderClosed(IPC::Message::Sender* sender);
151
152 Profile* profile_;
139 153
140 NotificationRegistrar registrar_; 154 NotificationRegistrar registrar_;
141 155
142 MessageChannelMap channels_; 156 MessageChannelMap channels_;
143 157
144 // A map between an event name and a set of process id's that are listening 158 // A map between an event name and a set of process id's that are listening
145 // to that event. 159 // to that event.
146 typedef std::map<std::string, std::set<int> > ListenerMap; 160 typedef std::map<std::string, std::set<int> > ListenerMap;
147 ListenerMap listeners_; 161 ListenerMap listeners_;
148 162
149 // --- UI or IO thread: 163 // --- UI or IO thread:
150 164
151 // True if Init has been called.
152 bool initialized_;
153
154 // For generating unique channel IDs. 165 // For generating unique channel IDs.
155 int next_port_id_; 166 int next_port_id_;
156 167
157 // Protects the next_port_id_ variable, since it can be 168 // Protects the next_port_id_ variable, since it can be
158 // used on the IO thread or the UI thread. 169 // used on the IO thread or the UI thread.
159 Lock next_port_id_lock_; 170 Lock next_port_id_lock_;
160 171
161 DISALLOW_COPY_AND_ASSIGN(ExtensionMessageService); 172 DISALLOW_COPY_AND_ASSIGN(ExtensionMessageService);
162 }; 173 };
163 174
164 #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_MESSAGE_SERVICE_H_ 175 #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_MESSAGE_SERVICE_H_
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_function_dispatcher.cc ('k') | chrome/browser/extensions/extension_message_service.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698