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

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

Issue 9667015: Remove ExtensionMessageService's legacy support for devtools. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 9 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 | Annotate | Revision Log
OLDNEW
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 #include "chrome/browser/extensions/extension_message_service.h" 5 #include "chrome/browser/extensions/extension_message_service.h"
6 6
7 #include "base/atomic_sequence_num.h" 7 #include "base/atomic_sequence_num.h"
8 #include "base/json/json_writer.h" 8 #include "base/json/json_writer.h"
9 #include "base/stl_util.h" 9 #include "base/stl_util.h"
10 #include "base/values.h" 10 #include "base/values.h"
(...skipping 21 matching lines...) Expand all
32 #define GET_CHANNEL_OPENER_ID(channel_id) ((channel_id) * 2) 32 #define GET_CHANNEL_OPENER_ID(channel_id) ((channel_id) * 2)
33 #define GET_CHANNEL_RECEIVERS_ID(channel_id) ((channel_id) * 2 + 1) 33 #define GET_CHANNEL_RECEIVERS_ID(channel_id) ((channel_id) * 2 + 1)
34 34
35 // Port1 is always even, port2 is always odd. 35 // Port1 is always even, port2 is always odd.
36 #define IS_OPENER_PORT_ID(port_id) (((port_id) & 1) == 0) 36 #define IS_OPENER_PORT_ID(port_id) (((port_id) & 1) == 0)
37 37
38 // Change even to odd and vice versa, to get the other side of a given channel. 38 // Change even to odd and vice versa, to get the other side of a given channel.
39 #define GET_OPPOSITE_PORT_ID(source_port_id) ((source_port_id) ^ 1) 39 #define GET_OPPOSITE_PORT_ID(source_port_id) ((source_port_id) ^ 1)
40 40
41 struct ExtensionMessageService::MessagePort { 41 struct ExtensionMessageService::MessagePort {
42 IPC::Message::Sender* sender; 42 content::RenderProcessHost* process;
43 int routing_id; 43 int routing_id;
44 explicit MessagePort(IPC::Message::Sender* sender = NULL, 44 explicit MessagePort(content::RenderProcessHost* process = NULL,
45 int routing_id = MSG_ROUTING_CONTROL) 45 int routing_id = MSG_ROUTING_CONTROL)
46 : sender(sender), routing_id(routing_id) {} 46 : process(process), routing_id(routing_id) {}
47 }; 47 };
48 48
49 struct ExtensionMessageService::MessageChannel { 49 struct ExtensionMessageService::MessageChannel {
50 ExtensionMessageService::MessagePort opener; 50 ExtensionMessageService::MessagePort opener;
51 ExtensionMessageService::MessagePort receiver; 51 ExtensionMessageService::MessagePort receiver;
52 }; 52 };
53 53
54 const char ExtensionMessageService::kDispatchOnConnect[] = 54 const char ExtensionMessageService::kDispatchOnConnect[] =
55 "Port.dispatchOnConnect"; 55 "Port.dispatchOnConnect";
56 const char ExtensionMessageService::kDispatchOnDisconnect[] = 56 const char ExtensionMessageService::kDispatchOnDisconnect[] =
57 "Port.dispatchOnDisconnect"; 57 "Port.dispatchOnDisconnect";
58 58
59 namespace { 59 namespace {
60 60
61 static base::AtomicSequenceNumber g_next_channel_id(base::LINKER_INITIALIZED); 61 static base::AtomicSequenceNumber g_next_channel_id(base::LINKER_INITIALIZED);
62 62
63 static void DispatchOnConnect(const ExtensionMessageService::MessagePort& port, 63 static void DispatchOnConnect(const ExtensionMessageService::MessagePort& port,
64 int dest_port_id, 64 int dest_port_id,
65 const std::string& channel_name, 65 const std::string& channel_name,
66 const std::string& tab_json, 66 const std::string& tab_json,
67 const std::string& source_extension_id, 67 const std::string& source_extension_id,
68 const std::string& target_extension_id) { 68 const std::string& target_extension_id) {
69 ListValue args; 69 ListValue args;
70 args.Set(0, Value::CreateIntegerValue(dest_port_id)); 70 args.Set(0, Value::CreateIntegerValue(dest_port_id));
71 args.Set(1, Value::CreateStringValue(channel_name)); 71 args.Set(1, Value::CreateStringValue(channel_name));
72 args.Set(2, Value::CreateStringValue(tab_json)); 72 args.Set(2, Value::CreateStringValue(tab_json));
73 args.Set(3, Value::CreateStringValue(source_extension_id)); 73 args.Set(3, Value::CreateStringValue(source_extension_id));
74 args.Set(4, Value::CreateStringValue(target_extension_id)); 74 args.Set(4, Value::CreateStringValue(target_extension_id));
75 CHECK(port.sender); 75 CHECK(port.process);
76 port.sender->Send( 76 port.process->Send(
77 new ExtensionMsg_MessageInvoke( 77 new ExtensionMsg_MessageInvoke(
78 port.routing_id, 78 port.routing_id,
79 target_extension_id, 79 target_extension_id,
80 ExtensionMessageService::kDispatchOnConnect, args, GURL(), 80 ExtensionMessageService::kDispatchOnConnect, args, GURL(),
81 false)); // Not a user gesture 81 false)); // Not a user gesture
82 } 82 }
83 83
84 static void DispatchOnDisconnect( 84 static void DispatchOnDisconnect(
85 const ExtensionMessageService::MessagePort& port, int source_port_id, 85 const ExtensionMessageService::MessagePort& port, int source_port_id,
86 bool connection_error) { 86 bool connection_error) {
87 ListValue args; 87 ListValue args;
88 args.Set(0, Value::CreateIntegerValue(source_port_id)); 88 args.Set(0, Value::CreateIntegerValue(source_port_id));
89 args.Set(1, Value::CreateBooleanValue(connection_error)); 89 args.Set(1, Value::CreateBooleanValue(connection_error));
90 port.sender->Send(new ExtensionMsg_MessageInvoke(port.routing_id, 90 port.process->Send(new ExtensionMsg_MessageInvoke(port.routing_id,
91 "", ExtensionMessageService::kDispatchOnDisconnect, args, GURL(), 91 "", ExtensionMessageService::kDispatchOnDisconnect, args, GURL(),
92 false)); // Not a user gesture 92 false)); // Not a user gesture
93 } 93 }
94 94
95 static void DispatchOnMessage(const ExtensionMessageService::MessagePort& port, 95 static void DispatchOnMessage(const ExtensionMessageService::MessagePort& port,
96 const std::string& message, int target_port_id) { 96 const std::string& message, int target_port_id) {
97 port.sender->Send( 97 port.process->Send(
98 new ExtensionMsg_DeliverMessage( 98 new ExtensionMsg_DeliverMessage(
99 port.routing_id, target_port_id, message)); 99 port.routing_id, target_port_id, message));
100 } 100 }
101 101
102 static content::RenderProcessHost* GetExtensionProcess(Profile* profile, 102 static content::RenderProcessHost* GetExtensionProcess(Profile* profile,
103 const std::string& extension_id) { 103 const std::string& extension_id) {
104 SiteInstance* site_instance = 104 SiteInstance* site_instance =
105 profile->GetExtensionProcessManager()->GetSiteInstanceForURL( 105 profile->GetExtensionProcessManager()->GetSiteInstanceForURL(
106 Extension::GetBaseURLFromExtensionId(extension_id)); 106 Extension::GetBaseURLFromExtensionId(extension_id));
107 107
(...skipping 17 matching lines...) Expand all
125 DCHECK(GET_OPPOSITE_PORT_ID(port2_id) == port1_id); 125 DCHECK(GET_OPPOSITE_PORT_ID(port2_id) == port1_id);
126 DCHECK(GET_CHANNEL_ID(port1_id) == GET_CHANNEL_ID(port2_id)); 126 DCHECK(GET_CHANNEL_ID(port1_id) == GET_CHANNEL_ID(port2_id));
127 DCHECK(GET_CHANNEL_ID(port1_id) == channel_id); 127 DCHECK(GET_CHANNEL_ID(port1_id) == channel_id);
128 DCHECK(GET_CHANNEL_OPENER_ID(channel_id) == port1_id); 128 DCHECK(GET_CHANNEL_OPENER_ID(channel_id) == port1_id);
129 DCHECK(GET_CHANNEL_RECEIVERS_ID(channel_id) == port2_id); 129 DCHECK(GET_CHANNEL_RECEIVERS_ID(channel_id) == port2_id);
130 130
131 *port1 = port1_id; 131 *port1 = port1_id;
132 *port2 = port2_id; 132 *port2 = port2_id;
133 } 133 }
134 134
135 ExtensionMessageService::ExtensionMessageService(Profile* profile) 135 ExtensionMessageService::ExtensionMessageService(Profile* profile) {
Yoyo Zhou 2012/03/10 01:36:54 Apparently you no longer need this argument.
136 : profile_(profile) {
137 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, 136 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
138 content::NotificationService::AllBrowserContextsAndSources()); 137 content::NotificationService::AllBrowserContextsAndSources());
139 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, 138 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
140 content::NotificationService::AllBrowserContextsAndSources()); 139 content::NotificationService::AllBrowserContextsAndSources());
141 registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_DELETED,
142 content::NotificationService::AllBrowserContextsAndSources());
143 } 140 }
144 141
145 ExtensionMessageService::~ExtensionMessageService() { 142 ExtensionMessageService::~ExtensionMessageService() {
146 STLDeleteContainerPairSecondPointers(channels_.begin(), channels_.end()); 143 STLDeleteContainerPairSecondPointers(channels_.begin(), channels_.end());
147 channels_.clear(); 144 channels_.clear();
148 } 145 }
149 146
150 void ExtensionMessageService::DestroyingProfile() {
151 profile_ = NULL;
152 if (!registrar_.IsEmpty())
153 registrar_.RemoveAll();
154 }
155
156 void ExtensionMessageService::OpenChannelToExtension( 147 void ExtensionMessageService::OpenChannelToExtension(
157 int source_process_id, int source_routing_id, int receiver_port_id, 148 int source_process_id, int source_routing_id, int receiver_port_id,
158 const std::string& source_extension_id, 149 const std::string& source_extension_id,
159 const std::string& target_extension_id, 150 const std::string& target_extension_id,
160 const std::string& channel_name) { 151 const std::string& channel_name) {
161 content::RenderProcessHost* source = 152 content::RenderProcessHost* source =
162 content::RenderProcessHost::FromID(source_process_id); 153 content::RenderProcessHost::FromID(source_process_id);
163 if (!source) 154 if (!source)
164 return; 155 return;
165 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext()); 156 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext());
(...skipping 26 matching lines...) Expand all
192 content::RenderProcessHost* source = 183 content::RenderProcessHost* source =
193 content::RenderProcessHost::FromID(source_process_id); 184 content::RenderProcessHost::FromID(source_process_id);
194 if (!source) 185 if (!source)
195 return; 186 return;
196 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext()); 187 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext());
197 188
198 TabContentsWrapper* contents = NULL; 189 TabContentsWrapper* contents = NULL;
199 MessagePort receiver; 190 MessagePort receiver;
200 if (ExtensionTabUtil::GetTabById(tab_id, profile, true, 191 if (ExtensionTabUtil::GetTabById(tab_id, profile, true,
201 NULL, NULL, &contents, NULL)) { 192 NULL, NULL, &contents, NULL)) {
202 receiver.sender = contents->web_contents()->GetRenderViewHost(); 193 receiver.process = contents->web_contents()->GetRenderProcessHost();
203 receiver.routing_id = 194 receiver.routing_id =
204 contents->web_contents()->GetRenderViewHost()->GetRoutingID(); 195 contents->web_contents()->GetRenderViewHost()->GetRoutingID();
205 } 196 }
206 197
207 if (contents && contents->web_contents()->GetController().NeedsReload()) { 198 if (contents && contents->web_contents()->GetController().NeedsReload()) {
208 // The tab isn't loaded yet. Don't attempt to connect. Treat this as a 199 // The tab isn't loaded yet. Don't attempt to connect. Treat this as a
209 // disconnect. 200 // disconnect.
210 DispatchOnDisconnect(MessagePort(source, MSG_ROUTING_CONTROL), 201 DispatchOnDisconnect(MessagePort(source, MSG_ROUTING_CONTROL),
211 GET_OPPOSITE_PORT_ID(receiver_port_id), true); 202 GET_OPPOSITE_PORT_ID(receiver_port_id), true);
212 return; 203 return;
213 } 204 }
214 205
215 WebContents* source_contents = tab_util::GetWebContentsByID( 206 WebContents* source_contents = tab_util::GetWebContentsByID(
216 source_process_id, source_routing_id); 207 source_process_id, source_routing_id);
217 208
218 // Include info about the opener's tab (if it was a tab). 209 // Include info about the opener's tab (if it was a tab).
219 std::string tab_json = "null"; 210 std::string tab_json = "null";
220 if (source_contents) { 211 if (source_contents) {
221 scoped_ptr<DictionaryValue> tab_value( 212 scoped_ptr<DictionaryValue> tab_value(
222 ExtensionTabUtil::CreateTabValue(source_contents)); 213 ExtensionTabUtil::CreateTabValue(source_contents));
223 base::JSONWriter::Write(tab_value.get(), false, &tab_json); 214 base::JSONWriter::Write(tab_value.get(), false, &tab_json);
224 } 215 }
225 216
226 OpenChannelImpl(source, tab_json, receiver, receiver_port_id, 217 OpenChannelImpl(source, tab_json, receiver, receiver_port_id,
227 extension_id, extension_id, channel_name); 218 extension_id, extension_id, channel_name);
228 } 219 }
229 220
230 bool ExtensionMessageService::OpenChannelImpl( 221 bool ExtensionMessageService::OpenChannelImpl(
231 IPC::Message::Sender* source, 222 content::RenderProcessHost* source,
232 const std::string& tab_json, 223 const std::string& tab_json,
233 const MessagePort& receiver, int receiver_port_id, 224 const MessagePort& receiver, int receiver_port_id,
234 const std::string& source_extension_id, 225 const std::string& source_extension_id,
235 const std::string& target_extension_id, 226 const std::string& target_extension_id,
236 const std::string& channel_name) { 227 const std::string& channel_name) {
237 if (!source) 228 if (!source)
238 return false; // Closed while in flight. 229 return false; // Closed while in flight.
239 230
240 if (!receiver.sender) { 231 if (!receiver.process) {
241 // Treat it as a disconnect. 232 // Treat it as a disconnect.
242 DispatchOnDisconnect(MessagePort(source, MSG_ROUTING_CONTROL), 233 DispatchOnDisconnect(MessagePort(source, MSG_ROUTING_CONTROL),
243 GET_OPPOSITE_PORT_ID(receiver_port_id), true); 234 GET_OPPOSITE_PORT_ID(receiver_port_id), true);
244 return false; 235 return false;
245 } 236 }
246 237
247 // Add extra paranoid CHECKs, since we have crash reports of this being NULL. 238 // Add extra paranoid CHECKs, since we have crash reports of this being NULL.
248 // http://code.google.com/p/chromium/issues/detail?id=19067 239 // http://code.google.com/p/chromium/issues/detail?id=19067
249 CHECK(receiver.sender); 240 CHECK(receiver.process);
250 241
251 MessageChannel* channel(new MessageChannel); 242 MessageChannel* channel(new MessageChannel);
252 channel->opener = MessagePort(source, MSG_ROUTING_CONTROL); 243 channel->opener = MessagePort(source, MSG_ROUTING_CONTROL);
253 channel->receiver = receiver; 244 channel->receiver = receiver;
254 245
255 CHECK(receiver.sender); 246 CHECK(receiver.process);
256 247
257 CHECK(channels_.find(GET_CHANNEL_ID(receiver_port_id)) == channels_.end()); 248 CHECK(channels_.find(GET_CHANNEL_ID(receiver_port_id)) == channels_.end());
258 channels_[GET_CHANNEL_ID(receiver_port_id)] = channel; 249 channels_[GET_CHANNEL_ID(receiver_port_id)] = channel;
259 250
260 CHECK(receiver.sender); 251 CHECK(receiver.process);
261 252
262 // Send the connect event to the receiver. Give it the opener's port ID (the 253 // Send the connect event to the receiver. Give it the opener's port ID (the
263 // opener has the opposite port ID). 254 // opener has the opposite port ID).
264 DispatchOnConnect(receiver, receiver_port_id, channel_name, tab_json, 255 DispatchOnConnect(receiver, receiver_port_id, channel_name, tab_json,
265 source_extension_id, target_extension_id); 256 source_extension_id, target_extension_id);
266 257
267 return true; 258 return true;
268 } 259 }
269 260
270 int ExtensionMessageService::OpenSpecialChannelToExtension(
271 const std::string& extension_id, const std::string& channel_name,
272 const std::string& tab_json, IPC::Message::Sender* source) {
273 DCHECK(profile_);
274
275 int port1_id = -1;
276 int port2_id = -1;
277 // Create a channel ID for both sides of the channel.
278 AllocatePortIdPair(&port1_id, &port2_id);
279
280 MessagePort receiver(
281 GetExtensionProcess(profile_, extension_id),
282 MSG_ROUTING_CONTROL);
283 if (!OpenChannelImpl(source, tab_json, receiver, port2_id,
284 extension_id, extension_id, channel_name))
285 return -1;
286
287 return port1_id;
288 }
289
290 int ExtensionMessageService::OpenSpecialChannelToTab(
291 const std::string& extension_id, const std::string& channel_name,
292 WebContents* target_web_contents, IPC::Message::Sender* source) {
293 DCHECK(target_web_contents);
294
295 if (target_web_contents->GetController().NeedsReload()) {
296 // The tab isn't loaded yet. Don't attempt to connect.
297 return -1;
298 }
299
300 int port1_id = -1;
301 int port2_id = -1;
302 // Create a channel ID for both sides of the channel.
303 AllocatePortIdPair(&port1_id, &port2_id);
304
305 MessagePort receiver(
306 target_web_contents->GetRenderViewHost(),
307 target_web_contents->GetRenderViewHost()->GetRoutingID());
308 if (!OpenChannelImpl(source, "null", receiver, port2_id,
309 extension_id, extension_id, channel_name))
310 return -1;
311
312 return port1_id;
313 }
314
315 void ExtensionMessageService::CloseChannel(int port_id) { 261 void ExtensionMessageService::CloseChannel(int port_id) {
316 // Note: The channel might be gone already, if the other side closed first. 262 // Note: The channel might be gone already, if the other side closed first.
317 MessageChannelMap::iterator it = channels_.find(GET_CHANNEL_ID(port_id)); 263 MessageChannelMap::iterator it = channels_.find(GET_CHANNEL_ID(port_id));
318 if (it != channels_.end()) 264 if (it != channels_.end())
319 CloseChannelImpl(it, port_id, true); 265 CloseChannelImpl(it, port_id, true);
320 } 266 }
321 267
322 void ExtensionMessageService::CloseChannelImpl( 268 void ExtensionMessageService::CloseChannelImpl(
323 MessageChannelMap::iterator channel_iter, int closing_port_id, 269 MessageChannelMap::iterator channel_iter, int closing_port_id,
324 bool notify_other_port) { 270 bool notify_other_port) {
(...skipping 14 matching lines...) Expand all
339 if (iter == channels_.end()) 285 if (iter == channels_.end())
340 return; 286 return;
341 287
342 // Figure out which port the ID corresponds to. 288 // Figure out which port the ID corresponds to.
343 int dest_port_id = GET_OPPOSITE_PORT_ID(source_port_id); 289 int dest_port_id = GET_OPPOSITE_PORT_ID(source_port_id);
344 const MessagePort& port = IS_OPENER_PORT_ID(dest_port_id) ? 290 const MessagePort& port = IS_OPENER_PORT_ID(dest_port_id) ?
345 iter->second->opener : iter->second->receiver; 291 iter->second->opener : iter->second->receiver;
346 292
347 DispatchOnMessage(port, message, dest_port_id); 293 DispatchOnMessage(port, message, dest_port_id);
348 } 294 }
295
349 void ExtensionMessageService::Observe( 296 void ExtensionMessageService::Observe(
350 int type, 297 int type,
351 const content::NotificationSource& source, 298 const content::NotificationSource& source,
352 const content::NotificationDetails& details) { 299 const content::NotificationDetails& details) {
353 switch (type) { 300 switch (type) {
354 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: 301 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED:
355 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { 302 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: {
356 content::RenderProcessHost* renderer = 303 content::RenderProcessHost* renderer =
357 content::Source<content::RenderProcessHost>(source).ptr(); 304 content::Source<content::RenderProcessHost>(source).ptr();
358 OnSenderClosed(renderer); 305 OnProcessClosed(renderer);
359 break; 306 break;
360 } 307 }
361 case content::NOTIFICATION_RENDER_VIEW_HOST_DELETED:
362 OnSenderClosed(content::Source<content::RenderViewHost>(source).ptr());
363 break;
364 default: 308 default:
365 NOTREACHED(); 309 NOTREACHED();
366 return; 310 return;
367 } 311 }
368 } 312 }
369 313
370 void ExtensionMessageService::OnSenderClosed(IPC::Message::Sender* sender) { 314 void ExtensionMessageService::OnProcessClosed(
315 content::RenderProcessHost* process) {
371 // Close any channels that share this renderer. We notify the opposite 316 // Close any channels that share this renderer. We notify the opposite
372 // port that his pair has closed. 317 // port that his pair has closed.
373 for (MessageChannelMap::iterator it = channels_.begin(); 318 for (MessageChannelMap::iterator it = channels_.begin();
374 it != channels_.end(); ) { 319 it != channels_.end(); ) {
375 MessageChannelMap::iterator current = it++; 320 MessageChannelMap::iterator current = it++;
376 // If both sides are the same renderer, and it is closing, there is no 321 // If both sides are the same renderer, and it is closing, there is no
377 // "other" port, so there's no need to notify it. 322 // "other" port, so there's no need to notify it.
378 bool notify_other_port = 323 bool notify_other_port =
379 current->second->opener.sender != current->second->receiver.sender; 324 current->second->opener.process != current->second->receiver.process;
380 325
381 if (current->second->opener.sender == sender) { 326 if (current->second->opener.process == process) {
382 CloseChannelImpl(current, GET_CHANNEL_OPENER_ID(current->first), 327 CloseChannelImpl(current, GET_CHANNEL_OPENER_ID(current->first),
383 notify_other_port); 328 notify_other_port);
384 } else if (current->second->receiver.sender == sender) { 329 } else if (current->second->receiver.process == process) {
385 CloseChannelImpl(current, GET_CHANNEL_RECEIVERS_ID(current->first), 330 CloseChannelImpl(current, GET_CHANNEL_RECEIVERS_ID(current->first),
386 notify_other_port); 331 notify_other_port);
387 } 332 }
388 } 333 }
389 } 334 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698