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 #include "chrome/browser/extensions/api/messaging/message_service.h" | 5 #include "chrome/browser/extensions/api/messaging/message_service.h" |
6 | 6 |
7 #include "base/atomic_sequence_num.h" | 7 #include "base/atomic_sequence_num.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/callback.h" | 9 #include "base/callback.h" |
10 #include "base/json/json_writer.h" | 10 #include "base/json/json_writer.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 #include "chrome/common/extensions/background_info.h" | 25 #include "chrome/common/extensions/background_info.h" |
26 #include "chrome/common/extensions/extension.h" | 26 #include "chrome/common/extensions/extension.h" |
27 #include "chrome/common/extensions/extension_messages.h" | 27 #include "chrome/common/extensions/extension_messages.h" |
28 #include "chrome/common/extensions/incognito_handler.h" | 28 #include "chrome/common/extensions/incognito_handler.h" |
29 #include "content/public/browser/browser_thread.h" | 29 #include "content/public/browser/browser_thread.h" |
30 #include "content/public/browser/notification_service.h" | 30 #include "content/public/browser/notification_service.h" |
31 #include "content/public/browser/render_process_host.h" | 31 #include "content/public/browser/render_process_host.h" |
32 #include "content/public/browser/render_view_host.h" | 32 #include "content/public/browser/render_view_host.h" |
33 #include "content/public/browser/site_instance.h" | 33 #include "content/public/browser/site_instance.h" |
34 #include "content/public/browser/web_contents.h" | 34 #include "content/public/browser/web_contents.h" |
| 35 #include "googleurl/src/gurl.h" |
35 | 36 |
36 using content::SiteInstance; | 37 using content::SiteInstance; |
37 using content::WebContents; | 38 using content::WebContents; |
38 | 39 |
39 // Since we have 2 ports for every channel, we just index channels by half the | 40 // Since we have 2 ports for every channel, we just index channels by half the |
40 // port ID. | 41 // port ID. |
41 #define GET_CHANNEL_ID(port_id) ((port_id) / 2) | 42 #define GET_CHANNEL_ID(port_id) ((port_id) / 2) |
42 #define GET_CHANNEL_OPENER_ID(channel_id) ((channel_id) * 2) | 43 #define GET_CHANNEL_OPENER_ID(channel_id) ((channel_id) * 2) |
43 #define GET_CHANNEL_RECEIVERS_ID(channel_id) ((channel_id) * 2 + 1) | 44 #define GET_CHANNEL_RECEIVERS_ID(channel_id) ((channel_id) * 2 + 1) |
44 | 45 |
(...skipping 14 matching lines...) Expand all Loading... |
59 "Native Messaging is not supported on this platform."; | 60 "Native Messaging is not supported on this platform."; |
60 } | 61 } |
61 | 62 |
62 struct MessageService::MessageChannel { | 63 struct MessageService::MessageChannel { |
63 scoped_ptr<MessagePort> opener; | 64 scoped_ptr<MessagePort> opener; |
64 scoped_ptr<MessagePort> receiver; | 65 scoped_ptr<MessagePort> receiver; |
65 }; | 66 }; |
66 | 67 |
67 struct MessageService::OpenChannelParams { | 68 struct MessageService::OpenChannelParams { |
68 content::RenderProcessHost* source; | 69 content::RenderProcessHost* source; |
69 std::string tab_json; | 70 DictionaryValue source_tab; |
70 scoped_ptr<MessagePort> receiver; | 71 scoped_ptr<MessagePort> receiver; |
71 int receiver_port_id; | 72 int receiver_port_id; |
72 std::string source_extension_id; | 73 std::string source_extension_id; |
73 std::string target_extension_id; | 74 std::string target_extension_id; |
| 75 GURL source_url; |
74 std::string channel_name; | 76 std::string channel_name; |
75 | 77 |
76 // Takes ownership of receiver. | 78 // Takes ownership of receiver. |
77 OpenChannelParams(content::RenderProcessHost* source, | 79 OpenChannelParams(content::RenderProcessHost* source, |
78 const std::string& tab_json, | 80 scoped_ptr<DictionaryValue> source_tab, |
79 MessagePort* receiver, | 81 MessagePort* receiver, |
80 int receiver_port_id, | 82 int receiver_port_id, |
81 const std::string& source_extension_id, | 83 const std::string& source_extension_id, |
82 const std::string& target_extension_id, | 84 const std::string& target_extension_id, |
| 85 const GURL& source_url, |
83 const std::string& channel_name) | 86 const std::string& channel_name) |
84 : source(source), | 87 : source(source), |
85 tab_json(tab_json), | |
86 receiver(receiver), | 88 receiver(receiver), |
87 receiver_port_id(receiver_port_id), | 89 receiver_port_id(receiver_port_id), |
88 source_extension_id(source_extension_id), | 90 source_extension_id(source_extension_id), |
89 target_extension_id(target_extension_id), | 91 target_extension_id(target_extension_id), |
90 channel_name(channel_name) {} | 92 source_url(source_url), |
| 93 channel_name(channel_name) { |
| 94 if (source_tab) |
| 95 this->source_tab.Swap(source_tab.get()); |
| 96 } |
| 97 |
| 98 private: |
| 99 DISALLOW_COPY_AND_ASSIGN(OpenChannelParams); |
91 }; | 100 }; |
92 | 101 |
93 namespace { | 102 namespace { |
94 | 103 |
95 static base::StaticAtomicSequenceNumber g_next_channel_id; | 104 static base::StaticAtomicSequenceNumber g_next_channel_id; |
96 | 105 |
97 static content::RenderProcessHost* GetExtensionProcess( | 106 static content::RenderProcessHost* GetExtensionProcess( |
98 Profile* profile, const std::string& extension_id) { | 107 Profile* profile, const std::string& extension_id) { |
99 SiteInstance* site_instance = | 108 SiteInstance* site_instance = |
100 extensions::ExtensionSystem::Get(profile)->process_manager()-> | 109 extensions::ExtensionSystem::Get(profile)->process_manager()-> |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 | 154 |
146 MessageService::~MessageService() { | 155 MessageService::~MessageService() { |
147 STLDeleteContainerPairSecondPointers(channels_.begin(), channels_.end()); | 156 STLDeleteContainerPairSecondPointers(channels_.begin(), channels_.end()); |
148 channels_.clear(); | 157 channels_.clear(); |
149 } | 158 } |
150 | 159 |
151 void MessageService::OpenChannelToExtension( | 160 void MessageService::OpenChannelToExtension( |
152 int source_process_id, int source_routing_id, int receiver_port_id, | 161 int source_process_id, int source_routing_id, int receiver_port_id, |
153 const std::string& source_extension_id, | 162 const std::string& source_extension_id, |
154 const std::string& target_extension_id, | 163 const std::string& target_extension_id, |
| 164 const GURL& source_url, |
155 const std::string& channel_name) { | 165 const std::string& channel_name) { |
156 content::RenderProcessHost* source = | 166 content::RenderProcessHost* source = |
157 content::RenderProcessHost::FromID(source_process_id); | 167 content::RenderProcessHost::FromID(source_process_id); |
158 if (!source) | 168 if (!source) |
159 return; | 169 return; |
160 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext()); | 170 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext()); |
161 | 171 |
| 172 const Extension* target_extension = ExtensionSystem::Get(profile)-> |
| 173 extension_service()->extensions()->GetByID(target_extension_id); |
| 174 if (!target_extension) { |
| 175 // Treat it as a disconnect. |
| 176 ExtensionMessagePort port(source, MSG_ROUTING_CONTROL, std::string()); |
| 177 port.DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(receiver_port_id), |
| 178 kReceivingEndDoesntExistError); |
| 179 return; |
| 180 } |
| 181 |
162 // Note: we use the source's profile here. If the source is an incognito | 182 // Note: we use the source's profile here. If the source is an incognito |
163 // process, we will use the incognito EPM to find the right extension process, | 183 // process, we will use the incognito EPM to find the right extension process, |
164 // which depends on whether the extension uses spanning or split mode. | 184 // which depends on whether the extension uses spanning or split mode. |
165 MessagePort* receiver = new ExtensionMessagePort( | 185 MessagePort* receiver = new ExtensionMessagePort( |
166 GetExtensionProcess(profile, target_extension_id), MSG_ROUTING_CONTROL, | 186 GetExtensionProcess(profile, target_extension_id), MSG_ROUTING_CONTROL, |
167 target_extension_id); | 187 target_extension_id); |
168 WebContents* source_contents = tab_util::GetWebContentsByID( | 188 WebContents* source_contents = tab_util::GetWebContentsByID( |
169 source_process_id, source_routing_id); | 189 source_process_id, source_routing_id); |
170 | 190 |
171 // Include info about the opener's tab (if it was a tab). | 191 // Include info about the opener's tab (if it was a tab). |
172 std::string tab_json = "null"; | 192 scoped_ptr<DictionaryValue> source_tab; |
173 if (source_contents) { | 193 GURL source_url_for_tab; |
174 scoped_ptr<DictionaryValue> tab_value(ExtensionTabUtil::CreateTabValue( | 194 |
175 source_contents)); | 195 if (source_contents && ExtensionTabUtil::GetTabId(source_contents) >= 0) { |
176 base::JSONWriter::Write(tab_value.get(), &tab_json); | 196 // Platform apps can be sent messages, but don't have a Tab concept. |
| 197 if (!target_extension->is_platform_app()) |
| 198 source_tab.reset(ExtensionTabUtil::CreateTabValue(source_contents)); |
| 199 source_url_for_tab = source_url; |
177 } | 200 } |
178 | 201 |
179 OpenChannelParams* params = new OpenChannelParams(source, tab_json, receiver, | 202 OpenChannelParams* params = new OpenChannelParams(source, |
| 203 source_tab.Pass(), |
| 204 receiver, |
180 receiver_port_id, | 205 receiver_port_id, |
181 source_extension_id, | 206 source_extension_id, |
182 target_extension_id, | 207 target_extension_id, |
| 208 source_url_for_tab, |
183 channel_name); | 209 channel_name); |
184 | 210 |
185 // The target might be a lazy background page. In that case, we have to check | 211 // The target might be a lazy background page. In that case, we have to check |
186 // if it is loaded and ready, and if not, queue up the task and load the | 212 // if it is loaded and ready, and if not, queue up the task and load the |
187 // page. | 213 // page. |
188 if (MaybeAddPendingOpenChannelTask(profile, params)) { | 214 if (MaybeAddPendingOpenChannelTask(profile, target_extension, params)) { |
189 return; | 215 return; |
190 } | 216 } |
191 | 217 |
192 OpenChannelImpl(scoped_ptr<OpenChannelParams>(params)); | 218 OpenChannelImpl(make_scoped_ptr(params)); |
193 } | 219 } |
194 | 220 |
195 void MessageService::OpenChannelToNativeApp( | 221 void MessageService::OpenChannelToNativeApp( |
196 int source_process_id, | 222 int source_process_id, |
197 int source_routing_id, | 223 int source_routing_id, |
198 int receiver_port_id, | 224 int receiver_port_id, |
199 const std::string& source_extension_id, | 225 const std::string& source_extension_id, |
200 const std::string& native_app_name) { | 226 const std::string& native_app_name) { |
201 content::RenderProcessHost* source = | 227 content::RenderProcessHost* source = |
202 content::RenderProcessHost::FromID(source_process_id); | 228 content::RenderProcessHost::FromID(source_process_id); |
(...skipping 12 matching lines...) Expand all Loading... |
215 APIPermission::kNativeMessaging); | 241 APIPermission::kNativeMessaging); |
216 } | 242 } |
217 | 243 |
218 if (!has_permission) { | 244 if (!has_permission) { |
219 ExtensionMessagePort port(source, MSG_ROUTING_CONTROL, std::string()); | 245 ExtensionMessagePort port(source, MSG_ROUTING_CONTROL, std::string()); |
220 port.DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(receiver_port_id), | 246 port.DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(receiver_port_id), |
221 kMissingPermissionError); | 247 kMissingPermissionError); |
222 return; | 248 return; |
223 } | 249 } |
224 | 250 |
225 WebContents* source_contents = tab_util::GetWebContentsByID( | |
226 source_process_id, source_routing_id); | |
227 | |
228 // Include info about the opener's tab (if it was a tab). | |
229 std::string tab_json = "null"; | |
230 if (source_contents) { | |
231 scoped_ptr<DictionaryValue> tab_value(ExtensionTabUtil::CreateTabValue( | |
232 source_contents)); | |
233 base::JSONWriter::Write(tab_value.get(), &tab_json); | |
234 } | |
235 | |
236 scoped_ptr<MessageChannel> channel(new MessageChannel()); | 251 scoped_ptr<MessageChannel> channel(new MessageChannel()); |
237 channel->opener.reset(new ExtensionMessagePort(source, MSG_ROUTING_CONTROL, | 252 channel->opener.reset(new ExtensionMessagePort(source, MSG_ROUTING_CONTROL, |
238 source_extension_id)); | 253 source_extension_id)); |
239 | 254 |
240 scoped_ptr<NativeMessageProcessHost> native_process = | 255 scoped_ptr<NativeMessageProcessHost> native_process = |
241 NativeMessageProcessHost::Create( | 256 NativeMessageProcessHost::Create( |
242 base::WeakPtr<NativeMessageProcessHost::Client>( | 257 base::WeakPtr<NativeMessageProcessHost::Client>( |
243 weak_factory_.GetWeakPtr()), | 258 weak_factory_.GetWeakPtr()), |
244 source_extension_id, native_app_name, receiver_port_id); | 259 source_extension_id, native_app_name, receiver_port_id); |
245 | 260 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 | 302 |
288 if (contents && contents->GetController().NeedsReload()) { | 303 if (contents && contents->GetController().NeedsReload()) { |
289 // The tab isn't loaded yet. Don't attempt to connect. Treat this as a | 304 // The tab isn't loaded yet. Don't attempt to connect. Treat this as a |
290 // disconnect. | 305 // disconnect. |
291 ExtensionMessagePort port(source, MSG_ROUTING_CONTROL, extension_id); | 306 ExtensionMessagePort port(source, MSG_ROUTING_CONTROL, extension_id); |
292 port.DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(receiver_port_id), | 307 port.DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(receiver_port_id), |
293 kReceivingEndDoesntExistError); | 308 kReceivingEndDoesntExistError); |
294 return; | 309 return; |
295 } | 310 } |
296 | 311 |
297 WebContents* source_contents = tab_util::GetWebContentsByID( | 312 scoped_ptr<OpenChannelParams> params(new OpenChannelParams( |
298 source_process_id, source_routing_id); | 313 source, |
299 | 314 scoped_ptr<DictionaryValue>(), // Source tab doesn't make sense for |
300 // Include info about the opener's tab (if it was a tab). | 315 // opening to tabs. |
301 std::string tab_json = "null"; | 316 receiver.release(), |
302 if (source_contents) { | 317 receiver_port_id, |
303 scoped_ptr<DictionaryValue> tab_value(ExtensionTabUtil::CreateTabValue( | 318 extension_id, |
304 source_contents)); | 319 extension_id, |
305 base::JSONWriter::Write(tab_value.get(), &tab_json); | 320 GURL(), // Source URL doesn't make sense for opening to tabs. |
306 } | 321 channel_name)); |
307 | |
308 scoped_ptr<OpenChannelParams> params(new OpenChannelParams(source, tab_json, | |
309 receiver.release(), | |
310 receiver_port_id, | |
311 extension_id, | |
312 extension_id, | |
313 channel_name)); | |
314 OpenChannelImpl(params.Pass()); | 322 OpenChannelImpl(params.Pass()); |
315 } | 323 } |
316 | 324 |
317 bool MessageService::OpenChannelImpl(scoped_ptr<OpenChannelParams> params) { | 325 bool MessageService::OpenChannelImpl(scoped_ptr<OpenChannelParams> params) { |
318 if (!params->source) | 326 if (!params->source) |
319 return false; // Closed while in flight. | 327 return false; // Closed while in flight. |
320 | 328 |
321 if (!params->receiver.get() || !params->receiver->GetRenderProcessHost()) { | 329 if (!params->receiver || !params->receiver->GetRenderProcessHost()) { |
322 // Treat it as a disconnect. | 330 // Treat it as a disconnect. |
323 ExtensionMessagePort port( | 331 ExtensionMessagePort port( |
324 params->source, MSG_ROUTING_CONTROL, std::string()); | 332 params->source, MSG_ROUTING_CONTROL, std::string()); |
325 port.DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(params->receiver_port_id), | 333 port.DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(params->receiver_port_id), |
326 kReceivingEndDoesntExistError); | 334 kReceivingEndDoesntExistError); |
327 return false; | 335 return false; |
328 } | 336 } |
329 | 337 |
330 // Add extra paranoid CHECKs, since we have crash reports of this being NULL. | 338 // Add extra paranoid CHECKs, since we have crash reports of this being NULL. |
331 // http://code.google.com/p/chromium/issues/detail?id=19067 | 339 // http://code.google.com/p/chromium/issues/detail?id=19067 |
332 CHECK(params->receiver->GetRenderProcessHost()); | 340 CHECK(params->receiver->GetRenderProcessHost()); |
333 | 341 |
334 MessageChannel* channel(new MessageChannel); | 342 MessageChannel* channel(new MessageChannel); |
335 channel->opener.reset(new ExtensionMessagePort(params->source, | 343 channel->opener.reset(new ExtensionMessagePort(params->source, |
336 MSG_ROUTING_CONTROL, | 344 MSG_ROUTING_CONTROL, |
337 params->source_extension_id)); | 345 params->source_extension_id)); |
338 channel->receiver.reset(params->receiver.release()); | 346 channel->receiver.reset(params->receiver.release()); |
339 | 347 |
340 CHECK(channel->receiver->GetRenderProcessHost()); | 348 CHECK(channel->receiver->GetRenderProcessHost()); |
341 | 349 |
342 AddChannel(channel, params->receiver_port_id); | 350 AddChannel(channel, params->receiver_port_id); |
343 | 351 |
344 CHECK(channel->receiver->GetRenderProcessHost()); | 352 CHECK(channel->receiver->GetRenderProcessHost()); |
345 | 353 |
346 // Send the connect event to the receiver. Give it the opener's port ID (the | 354 // Send the connect event to the receiver. Give it the opener's port ID (the |
347 // opener has the opposite port ID). | 355 // opener has the opposite port ID). |
348 channel->receiver->DispatchOnConnect(params->receiver_port_id, | 356 channel->receiver->DispatchOnConnect(params->receiver_port_id, |
349 params->channel_name, params->tab_json, | 357 params->channel_name, |
| 358 params->source_tab, |
350 params->source_extension_id, | 359 params->source_extension_id, |
351 params->target_extension_id); | 360 params->target_extension_id, |
| 361 params->source_url); |
352 | 362 |
353 // Keep both ends of the channel alive until the channel is closed. | 363 // Keep both ends of the channel alive until the channel is closed. |
354 channel->opener->IncrementLazyKeepaliveCount(); | 364 channel->opener->IncrementLazyKeepaliveCount(); |
355 channel->receiver->IncrementLazyKeepaliveCount(); | 365 channel->receiver->IncrementLazyKeepaliveCount(); |
356 return true; | 366 return true; |
357 } | 367 } |
358 | 368 |
359 void MessageService::AddChannel(MessageChannel* channel, int receiver_port_id) { | 369 void MessageService::AddChannel(MessageChannel* channel, int receiver_port_id) { |
360 int channel_id = GET_CHANNEL_ID(receiver_port_id); | 370 int channel_id = GET_CHANNEL_ID(receiver_port_id); |
361 CHECK(channels_.find(channel_id) == channels_.end()); | 371 CHECK(channels_.find(channel_id) == channels_.end()); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
472 std::string(), notify_other_port); | 482 std::string(), notify_other_port); |
473 } else if (receiver_process == process) { | 483 } else if (receiver_process == process) { |
474 CloseChannelImpl(current, GET_CHANNEL_RECEIVERS_ID(current->first), | 484 CloseChannelImpl(current, GET_CHANNEL_RECEIVERS_ID(current->first), |
475 std::string(), notify_other_port); | 485 std::string(), notify_other_port); |
476 } | 486 } |
477 } | 487 } |
478 } | 488 } |
479 | 489 |
480 bool MessageService::MaybeAddPendingOpenChannelTask( | 490 bool MessageService::MaybeAddPendingOpenChannelTask( |
481 Profile* profile, | 491 Profile* profile, |
| 492 const Extension* extension, |
482 OpenChannelParams* params) { | 493 OpenChannelParams* params) { |
483 ExtensionService* service = profile->GetExtensionService(); | 494 if (!BackgroundInfo::HasLazyBackgroundPage(extension)) |
484 const std::string& extension_id = params->target_extension_id; | 495 return false; |
485 const Extension* extension = service->extensions()->GetByID(extension_id); | |
486 if (extension && BackgroundInfo::HasLazyBackgroundPage(extension)) { | |
487 // If the extension uses spanning incognito mode, make sure we're always | |
488 // using the original profile since that is what the extension process | |
489 // will use. | |
490 if (!IncognitoInfo::IsSplitMode(extension)) | |
491 profile = profile->GetOriginalProfile(); | |
492 | 496 |
493 if (lazy_background_task_queue_->ShouldEnqueueTask(profile, extension)) { | 497 // If the extension uses spanning incognito mode, make sure we're always |
494 pending_channels_[GET_CHANNEL_ID(params->receiver_port_id)] = | 498 // using the original profile since that is what the extension process |
495 PendingChannel(profile, extension_id); | 499 // will use. |
496 scoped_ptr<OpenChannelParams> scoped_params(params); | 500 if (!IncognitoInfo::IsSplitMode(extension)) |
497 lazy_background_task_queue_->AddPendingTask(profile, extension_id, | 501 profile = profile->GetOriginalProfile(); |
498 base::Bind(&MessageService::PendingOpenChannel, | |
499 weak_factory_.GetWeakPtr(), base::Passed(&scoped_params), | |
500 params->source->GetID())); | |
501 return true; | |
502 } | |
503 } | |
504 | 502 |
505 return false; | 503 if (!lazy_background_task_queue_->ShouldEnqueueTask(profile, extension)) |
| 504 return false; |
| 505 |
| 506 pending_channels_[GET_CHANNEL_ID(params->receiver_port_id)] = |
| 507 PendingChannel(profile, extension->id()); |
| 508 scoped_ptr<OpenChannelParams> scoped_params(params); |
| 509 lazy_background_task_queue_->AddPendingTask(profile, extension->id(), |
| 510 base::Bind(&MessageService::PendingOpenChannel, |
| 511 weak_factory_.GetWeakPtr(), base::Passed(&scoped_params), |
| 512 params->source->GetID())); |
| 513 return true; |
506 } | 514 } |
507 | 515 |
508 void MessageService::PendingOpenChannel(scoped_ptr<OpenChannelParams> params, | 516 void MessageService::PendingOpenChannel(scoped_ptr<OpenChannelParams> params, |
509 int source_process_id, | 517 int source_process_id, |
510 ExtensionHost* host) { | 518 ExtensionHost* host) { |
511 if (!host) | 519 if (!host) |
512 return; // TODO(mpcomplete): notify source of disconnect? | 520 return; // TODO(mpcomplete): notify source of disconnect? |
513 | 521 |
514 // Re-lookup the source process since it may no longer be valid. | 522 // Re-lookup the source process since it may no longer be valid. |
515 content::RenderProcessHost* source = | 523 content::RenderProcessHost* source = |
516 content::RenderProcessHost::FromID(source_process_id); | 524 content::RenderProcessHost::FromID(source_process_id); |
517 if (!source) | 525 if (!source) |
518 return; | 526 return; |
519 | 527 |
520 params->source = source; | 528 params->source = source; |
521 params->receiver.reset(new ExtensionMessagePort(host->render_process_host(), | 529 params->receiver.reset(new ExtensionMessagePort(host->render_process_host(), |
522 MSG_ROUTING_CONTROL, | 530 MSG_ROUTING_CONTROL, |
523 params->target_extension_id)); | 531 params->target_extension_id)); |
524 OpenChannelImpl(params.Pass()); | 532 OpenChannelImpl(params.Pass()); |
525 } | 533 } |
526 | 534 |
527 } // namespace extensions | 535 } // namespace extensions |
OLD | NEW |