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" |
11 #include "base/lazy_instance.h" | 11 #include "base/lazy_instance.h" |
12 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
13 #include "base/prefs/pref_service.h" | 13 #include "base/prefs/pref_service.h" |
14 #include "base/stl_util.h" | 14 #include "base/stl_util.h" |
15 #include "chrome/browser/chrome_notification_types.h" | 15 #include "chrome/browser/chrome_notification_types.h" |
16 #include "chrome/browser/extensions/api/messaging/extension_message_port.h" | 16 #include "chrome/browser/extensions/api/messaging/extension_message_port.h" |
17 #include "chrome/browser/extensions/api/messaging/incognito_connectability.h" | 17 #include "chrome/browser/extensions/api/messaging/incognito_connectability.h" |
18 #include "chrome/browser/extensions/api/messaging/native_message_port.h" | 18 #include "chrome/browser/extensions/api/messaging/native_message_port.h" |
19 #include "chrome/browser/extensions/api/tabs/tabs_constants.h" | 19 #include "chrome/browser/extensions/api/tabs/tabs_constants.h" |
20 #include "chrome/browser/extensions/extension_service.h" | 20 #include "chrome/browser/extensions/extension_service.h" |
21 #include "chrome/browser/extensions/extension_tab_util.h" | 21 #include "chrome/browser/extensions/extension_tab_util.h" |
22 #include "chrome/browser/extensions/extension_util.h" | 22 #include "chrome/browser/extensions/extension_util.h" |
23 #include "chrome/browser/profiles/profile.h" | 23 #include "chrome/browser/profiles/profile.h" |
24 #include "chrome/browser/tab_contents/tab_util.h" | 24 #include "chrome/browser/tab_contents/tab_util.h" |
25 #include "components/guest_view/common/guest_view_constants.h" | 25 #include "components/guest_view/common/guest_view_constants.h" |
26 #include "content/public/browser/browser_thread.h" | |
26 #include "content/public/browser/notification_service.h" | 27 #include "content/public/browser/notification_service.h" |
27 #include "content/public/browser/render_frame_host.h" | 28 #include "content/public/browser/render_frame_host.h" |
28 #include "content/public/browser/render_process_host.h" | 29 #include "content/public/browser/render_process_host.h" |
29 #include "content/public/browser/render_view_host.h" | 30 #include "content/public/browser/render_view_host.h" |
30 #include "content/public/browser/render_widget_host.h" | 31 #include "content/public/browser/render_widget_host.h" |
31 #include "content/public/browser/render_widget_host_view.h" | 32 #include "content/public/browser/render_widget_host_view.h" |
32 #include "content/public/browser/site_instance.h" | 33 #include "content/public/browser/site_instance.h" |
33 #include "content/public/browser/web_contents.h" | 34 #include "content/public/browser/web_contents.h" |
34 #include "content/public/common/child_process_host.h" | 35 #include "content/public/common/child_process_host.h" |
35 #include "extensions/browser/event_router.h" | 36 #include "extensions/browser/event_router.h" |
36 #include "extensions/browser/extension_host.h" | 37 #include "extensions/browser/extension_host.h" |
37 #include "extensions/browser/extension_registry.h" | 38 #include "extensions/browser/extension_registry.h" |
38 #include "extensions/browser/extension_system.h" | 39 #include "extensions/browser/extension_system.h" |
39 #include "extensions/browser/extensions_browser_client.h" | 40 #include "extensions/browser/extensions_browser_client.h" |
40 #include "extensions/browser/guest_view/web_view/web_view_guest.h" | 41 #include "extensions/browser/guest_view/web_view/web_view_guest.h" |
41 #include "extensions/browser/lazy_background_task_queue.h" | 42 #include "extensions/browser/lazy_background_task_queue.h" |
42 #include "extensions/browser/pref_names.h" | 43 #include "extensions/browser/pref_names.h" |
43 #include "extensions/browser/process_manager.h" | 44 #include "extensions/browser/process_manager.h" |
44 #include "extensions/common/extension.h" | 45 #include "extensions/common/extension.h" |
45 #include "extensions/common/manifest_constants.h" | 46 #include "extensions/common/manifest_constants.h" |
46 #include "extensions/common/manifest_handlers/background_info.h" | 47 #include "extensions/common/manifest_handlers/background_info.h" |
47 #include "extensions/common/manifest_handlers/externally_connectable.h" | 48 #include "extensions/common/manifest_handlers/externally_connectable.h" |
48 #include "extensions/common/manifest_handlers/incognito_info.h" | 49 #include "extensions/common/manifest_handlers/incognito_info.h" |
49 #include "extensions/common/permissions/permissions_data.h" | 50 #include "extensions/common/permissions/permissions_data.h" |
50 #include "net/base/completion_callback.h" | 51 #include "net/base/completion_callback.h" |
51 #include "url/gurl.h" | 52 #include "url/gurl.h" |
52 | 53 |
53 using content::BrowserContext; | 54 using content::BrowserContext; |
55 using content::BrowserThread; | |
54 using content::SiteInstance; | 56 using content::SiteInstance; |
55 using content::WebContents; | 57 using content::WebContents; |
56 | 58 |
57 // Since we have 2 ports for every channel, we just index channels by half the | 59 // Since we have 2 ports for every channel, we just index channels by half the |
58 // port ID. | 60 // port ID. |
59 #define GET_CHANNEL_ID(port_id) ((port_id) / 2) | 61 #define GET_CHANNEL_ID(port_id) ((port_id) / 2) |
60 #define GET_CHANNEL_OPENER_ID(channel_id) ((channel_id) * 2) | 62 #define GET_CHANNEL_OPENER_ID(channel_id) ((channel_id) * 2) |
61 #define GET_CHANNEL_RECEIVERS_ID(channel_id) ((channel_id) * 2 + 1) | 63 #define GET_CHANNEL_RECEIVERS_ID(channel_id) ((channel_id) * 2 + 1) |
62 | 64 |
63 // Port1 is always even, port2 is always odd. | 65 // Port1 is always even, port2 is always odd. |
64 #define IS_OPENER_PORT_ID(port_id) (((port_id) & 1) == 0) | 66 #define IS_OPENER_PORT_ID(port_id) (((port_id) & 1) == 0) |
65 | 67 |
66 // Change even to odd and vice versa, to get the other side of a given channel. | 68 // Change even to odd and vice versa, to get the other side of a given channel. |
67 #define GET_OPPOSITE_PORT_ID(source_port_id) ((source_port_id) ^ 1) | 69 #define GET_OPPOSITE_PORT_ID(source_port_id) ((source_port_id) ^ 1) |
68 | 70 |
69 namespace extensions { | 71 namespace extensions { |
70 | 72 |
71 MessageService::PolicyPermission MessageService::IsNativeMessagingHostAllowed( | 73 MessageService::PolicyPermission MessageService::IsNativeMessagingHostAllowed( |
72 const PrefService* pref_service, | 74 const PrefService* pref_service, |
73 const std::string& native_host_name) { | 75 const std::string& native_host_name) { |
76 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
77 | |
74 PolicyPermission allow_result = ALLOW_ALL; | 78 PolicyPermission allow_result = ALLOW_ALL; |
75 if (pref_service->IsManagedPreference( | 79 if (pref_service->IsManagedPreference( |
76 pref_names::kNativeMessagingUserLevelHosts)) { | 80 pref_names::kNativeMessagingUserLevelHosts)) { |
77 if (!pref_service->GetBoolean(pref_names::kNativeMessagingUserLevelHosts)) | 81 if (!pref_service->GetBoolean(pref_names::kNativeMessagingUserLevelHosts)) |
78 allow_result = ALLOW_SYSTEM_ONLY; | 82 allow_result = ALLOW_SYSTEM_ONLY; |
79 } | 83 } |
80 | 84 |
81 // All native messaging hosts are allowed if there is no blacklist. | 85 // All native messaging hosts are allowed if there is no blacklist. |
82 if (!pref_service->IsManagedPreference(pref_names::kNativeMessagingBlacklist)) | 86 if (!pref_service->IsManagedPreference(pref_names::kNativeMessagingBlacklist)) |
83 return allow_result; | 87 return allow_result; |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
183 | 187 |
184 } // namespace | 188 } // namespace |
185 | 189 |
186 content::RenderProcessHost* | 190 content::RenderProcessHost* |
187 MessageService::MessagePort::GetRenderProcessHost() { | 191 MessageService::MessagePort::GetRenderProcessHost() { |
188 return NULL; | 192 return NULL; |
189 } | 193 } |
190 | 194 |
191 // static | 195 // static |
192 void MessageService::AllocatePortIdPair(int* port1, int* port2) { | 196 void MessageService::AllocatePortIdPair(int* port1, int* port2) { |
197 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
198 | |
193 unsigned channel_id = | 199 unsigned channel_id = |
194 static_cast<unsigned>(g_next_channel_id.GetNext()) % (kint32max/2); | 200 static_cast<unsigned>(g_next_channel_id.GetNext()) % (kint32max/2); |
195 unsigned port1_id = channel_id * 2; | 201 unsigned port1_id = channel_id * 2; |
196 unsigned port2_id = channel_id * 2 + 1; | 202 unsigned port2_id = channel_id * 2 + 1; |
197 | 203 |
198 // Sanity checks to make sure our channel<->port converters are correct. | 204 // Sanity checks to make sure our channel<->port converters are correct. |
199 DCHECK(IS_OPENER_PORT_ID(port1_id)); | 205 DCHECK(IS_OPENER_PORT_ID(port1_id)); |
200 DCHECK_EQ(GET_OPPOSITE_PORT_ID(port1_id), port2_id); | 206 DCHECK_EQ(GET_OPPOSITE_PORT_ID(port1_id), port2_id); |
201 DCHECK_EQ(GET_OPPOSITE_PORT_ID(port2_id), port1_id); | 207 DCHECK_EQ(GET_OPPOSITE_PORT_ID(port2_id), port1_id); |
202 DCHECK_EQ(GET_CHANNEL_ID(port1_id), GET_CHANNEL_ID(port2_id)); | 208 DCHECK_EQ(GET_CHANNEL_ID(port1_id), GET_CHANNEL_ID(port2_id)); |
203 DCHECK_EQ(GET_CHANNEL_ID(port1_id), channel_id); | 209 DCHECK_EQ(GET_CHANNEL_ID(port1_id), channel_id); |
204 DCHECK_EQ(GET_CHANNEL_OPENER_ID(channel_id), port1_id); | 210 DCHECK_EQ(GET_CHANNEL_OPENER_ID(channel_id), port1_id); |
205 DCHECK_EQ(GET_CHANNEL_RECEIVERS_ID(channel_id), port2_id); | 211 DCHECK_EQ(GET_CHANNEL_RECEIVERS_ID(channel_id), port2_id); |
206 | 212 |
207 *port1 = port1_id; | 213 *port1 = port1_id; |
208 *port2 = port2_id; | 214 *port2 = port2_id; |
209 } | 215 } |
210 | 216 |
211 MessageService::MessageService(BrowserContext* context) | 217 MessageService::MessageService(BrowserContext* context) |
212 : lazy_background_task_queue_( | 218 : lazy_background_task_queue_( |
213 LazyBackgroundTaskQueue::Get(context)), | 219 LazyBackgroundTaskQueue::Get(context)), |
214 weak_factory_(this) { | 220 weak_factory_(this) { |
221 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
222 | |
215 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, | 223 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
216 content::NotificationService::AllBrowserContextsAndSources()); | 224 content::NotificationService::AllBrowserContextsAndSources()); |
217 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, | 225 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, |
218 content::NotificationService::AllBrowserContextsAndSources()); | 226 content::NotificationService::AllBrowserContextsAndSources()); |
219 } | 227 } |
220 | 228 |
221 MessageService::~MessageService() { | 229 MessageService::~MessageService() { |
230 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
231 | |
222 STLDeleteContainerPairSecondPointers(channels_.begin(), channels_.end()); | 232 STLDeleteContainerPairSecondPointers(channels_.begin(), channels_.end()); |
223 channels_.clear(); | 233 channels_.clear(); |
224 } | 234 } |
225 | 235 |
226 static base::LazyInstance<BrowserContextKeyedAPIFactory<MessageService> > | 236 static base::LazyInstance<BrowserContextKeyedAPIFactory<MessageService> > |
227 g_factory = LAZY_INSTANCE_INITIALIZER; | 237 g_factory = LAZY_INSTANCE_INITIALIZER; |
228 | 238 |
229 // static | 239 // static |
230 BrowserContextKeyedAPIFactory<MessageService>* | 240 BrowserContextKeyedAPIFactory<MessageService>* |
231 MessageService::GetFactoryInstance() { | 241 MessageService::GetFactoryInstance() { |
232 return g_factory.Pointer(); | 242 return g_factory.Pointer(); |
233 } | 243 } |
234 | 244 |
235 // static | 245 // static |
236 MessageService* MessageService::Get(BrowserContext* context) { | 246 MessageService* MessageService::Get(BrowserContext* context) { |
237 return BrowserContextKeyedAPIFactory<MessageService>::Get(context); | 247 return BrowserContextKeyedAPIFactory<MessageService>::Get(context); |
238 } | 248 } |
239 | 249 |
240 void MessageService::OpenChannelToExtension( | 250 void MessageService::OpenChannelToExtension( |
241 int source_process_id, int source_routing_id, int receiver_port_id, | 251 int source_process_id, int source_routing_id, int receiver_port_id, |
242 const std::string& source_extension_id, | 252 const std::string& source_extension_id, |
243 const std::string& target_extension_id, | 253 const std::string& target_extension_id, |
244 const GURL& source_url, | 254 const GURL& source_url, |
245 const std::string& channel_name, | 255 const std::string& channel_name, |
246 bool include_tls_channel_id) { | 256 bool include_tls_channel_id) { |
257 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
258 | |
247 content::RenderProcessHost* source = | 259 content::RenderProcessHost* source = |
248 content::RenderProcessHost::FromID(source_process_id); | 260 content::RenderProcessHost::FromID(source_process_id); |
249 if (!source) | 261 if (!source) |
250 return; | 262 return; |
251 BrowserContext* context = source->GetBrowserContext(); | 263 BrowserContext* context = source->GetBrowserContext(); |
252 | 264 |
253 ExtensionRegistry* registry = ExtensionRegistry::Get(context); | 265 ExtensionRegistry* registry = ExtensionRegistry::Get(context); |
254 const Extension* target_extension = | 266 const Extension* target_extension = |
255 registry->enabled_extensions().GetByID(target_extension_id); | 267 registry->enabled_extensions().GetByID(target_extension_id); |
256 if (!target_extension) { | 268 if (!target_extension) { |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
392 | 404 |
393 OnOpenChannelAllowed(params.Pass(), true); | 405 OnOpenChannelAllowed(params.Pass(), true); |
394 } | 406 } |
395 | 407 |
396 void MessageService::OpenChannelToNativeApp( | 408 void MessageService::OpenChannelToNativeApp( |
397 int source_process_id, | 409 int source_process_id, |
398 int source_routing_id, | 410 int source_routing_id, |
399 int receiver_port_id, | 411 int receiver_port_id, |
400 const std::string& source_extension_id, | 412 const std::string& source_extension_id, |
401 const std::string& native_app_name) { | 413 const std::string& native_app_name) { |
414 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
415 | |
402 content::RenderProcessHost* source = | 416 content::RenderProcessHost* source = |
403 content::RenderProcessHost::FromID(source_process_id); | 417 content::RenderProcessHost::FromID(source_process_id); |
404 if (!source) | 418 if (!source) |
405 return; | 419 return; |
406 | 420 |
407 #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) | 421 #if defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX) |
408 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext()); | 422 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext()); |
409 ExtensionService* extension_service = | 423 ExtensionService* extension_service = |
410 ExtensionSystem::Get(profile)->extension_service(); | 424 ExtensionSystem::Get(profile)->extension_service(); |
411 bool has_permission = false; | 425 bool has_permission = false; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
470 source, receiver_port_id, kNativeMessagingNotSupportedError); | 484 source, receiver_port_id, kNativeMessagingNotSupportedError); |
471 #endif // !(defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)) | 485 #endif // !(defined(OS_WIN) || defined(OS_MACOSX) || defined(OS_LINUX)) |
472 } | 486 } |
473 | 487 |
474 void MessageService::OpenChannelToTab(int source_process_id, | 488 void MessageService::OpenChannelToTab(int source_process_id, |
475 int receiver_port_id, | 489 int receiver_port_id, |
476 int tab_id, | 490 int tab_id, |
477 int frame_id, | 491 int frame_id, |
478 const std::string& extension_id, | 492 const std::string& extension_id, |
479 const std::string& channel_name) { | 493 const std::string& channel_name) { |
494 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
495 | |
480 content::RenderProcessHost* source = | 496 content::RenderProcessHost* source = |
481 content::RenderProcessHost::FromID(source_process_id); | 497 content::RenderProcessHost::FromID(source_process_id); |
482 if (!source) | 498 if (!source) |
483 return; | 499 return; |
484 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext()); | 500 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext()); |
485 | 501 |
486 WebContents* contents = NULL; | 502 WebContents* contents = NULL; |
487 scoped_ptr<MessagePort> receiver; | 503 scoped_ptr<MessagePort> receiver; |
488 if (!ExtensionTabUtil::GetTabById(tab_id, profile, true, NULL, NULL, | 504 if (!ExtensionTabUtil::GetTabById(tab_id, profile, true, NULL, NULL, |
489 &contents, NULL) || | 505 &contents, NULL) || |
(...skipping 19 matching lines...) Expand all Loading... | |
509 // Frame ID 0 is main frame. | 525 // Frame ID 0 is main frame. |
510 receiver_routing_id = contents->GetMainFrame()->GetRoutingID(); | 526 receiver_routing_id = contents->GetMainFrame()->GetRoutingID(); |
511 } else { | 527 } else { |
512 DCHECK_EQ(-1, frame_id); | 528 DCHECK_EQ(-1, frame_id); |
513 // If the frame ID is not set (i.e. -1), then the channel has to be opened | 529 // If the frame ID is not set (i.e. -1), then the channel has to be opened |
514 // in every frame. | 530 // in every frame. |
515 // TODO(robwu): Update logic so that frames that are not hosted in the main | 531 // TODO(robwu): Update logic so that frames that are not hosted in the main |
516 // frame's process can also receive the port. | 532 // frame's process can also receive the port. |
517 receiver_routing_id = MSG_ROUTING_CONTROL; | 533 receiver_routing_id = MSG_ROUTING_CONTROL; |
518 } | 534 } |
519 receiver.reset(new ExtensionMessagePort( | 535 receiver.reset(new ExtensionMessagePort(contents->GetRenderProcessHost(), |
520 contents->GetRenderProcessHost(), receiver_routing_id, extension_id)); | 536 receiver_routing_id, extension_id)); |
521 | 537 |
522 scoped_ptr<OpenChannelParams> params(new OpenChannelParams( | 538 scoped_ptr<OpenChannelParams> params(new OpenChannelParams( |
523 source_process_id, | 539 source_process_id, |
524 scoped_ptr<base::DictionaryValue>(), // Source tab doesn't make sense | 540 scoped_ptr<base::DictionaryValue>(), // Source tab doesn't make sense |
525 // for opening to tabs. | 541 // for opening to tabs. |
526 -1, // If there is no tab, then there is no frame either. | 542 -1, // If there is no tab, then there is no frame either. |
527 frame_id, | 543 frame_id, |
528 receiver.release(), receiver_port_id, extension_id, extension_id, | 544 receiver.release(), receiver_port_id, extension_id, extension_id, |
529 GURL(), // Source URL doesn't make sense for opening to tabs. | 545 GURL(), // Source URL doesn't make sense for opening to tabs. |
530 channel_name, | 546 channel_name, |
531 false, // Connections to tabs don't get TLS channel IDs. | 547 false, // Connections to tabs don't get TLS channel IDs. |
532 false)); // Connections to tabs aren't webview guests. | 548 false)); // Connections to tabs aren't webview guests. |
533 OpenChannelImpl(params.Pass()); | 549 OpenChannelImpl(contents->GetBrowserContext(), params.Pass(), |
550 nullptr /* extension */, false /* did_enqueue */); | |
534 } | 551 } |
535 | 552 |
536 void MessageService::OpenChannelImpl(scoped_ptr<OpenChannelParams> params) { | 553 void MessageService::OpenChannelImpl(BrowserContext* browser_context, |
554 scoped_ptr<OpenChannelParams> params, | |
555 const Extension* target_extension, | |
556 bool did_enqueue) { | |
557 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
Devlin
2015/08/07 21:25:47
DCHECK_EQ(target_extension != nullptr, params->ext
not at google - send to devlin
2015/08/10 20:48:33
Alright, though it's !empty() not empty. I.e. pres
| |
558 | |
537 content::RenderProcessHost* source = | 559 content::RenderProcessHost* source = |
538 content::RenderProcessHost::FromID(params->source_process_id); | 560 content::RenderProcessHost::FromID(params->source_process_id); |
539 if (!source) | 561 if (!source) |
540 return; // Closed while in flight. | 562 return; // Closed while in flight. |
541 | 563 |
542 if (!params->receiver || !params->receiver->GetRenderProcessHost()) { | 564 if (!params->receiver || !params->receiver->GetRenderProcessHost()) { |
543 DispatchOnDisconnect(source, params->receiver_port_id, | 565 DispatchOnDisconnect(source, params->receiver_port_id, |
544 kReceivingEndDoesntExistError); | 566 kReceivingEndDoesntExistError); |
545 return; | 567 return; |
546 } | 568 } |
547 | 569 |
548 // Add extra paranoid CHECKs, since we have crash reports of this being NULL. | |
549 // http://code.google.com/p/chromium/issues/detail?id=19067 | |
550 CHECK(params->receiver->GetRenderProcessHost()); | |
551 | |
552 MessageChannel* channel(new MessageChannel); | 570 MessageChannel* channel(new MessageChannel); |
553 channel->opener.reset(new ExtensionMessagePort(source, MSG_ROUTING_CONTROL, | 571 channel->opener.reset(new ExtensionMessagePort(source, MSG_ROUTING_CONTROL, |
554 params->source_extension_id)); | 572 params->source_extension_id)); |
555 channel->receiver.reset(params->receiver.release()); | 573 channel->receiver.reset(params->receiver.release()); |
556 | |
557 CHECK(channel->receiver->GetRenderProcessHost()); | |
558 | |
559 AddChannel(channel, params->receiver_port_id); | 574 AddChannel(channel, params->receiver_port_id); |
560 | 575 |
561 CHECK(channel->receiver->GetRenderProcessHost()); | |
562 | |
563 int guest_process_id = content::ChildProcessHost::kInvalidUniqueID; | 576 int guest_process_id = content::ChildProcessHost::kInvalidUniqueID; |
564 int guest_render_frame_routing_id = MSG_ROUTING_NONE; | 577 int guest_render_frame_routing_id = MSG_ROUTING_NONE; |
565 if (params->include_guest_process_info) { | 578 if (params->include_guest_process_info) { |
566 guest_process_id = params->source_process_id; | 579 guest_process_id = params->source_process_id; |
567 guest_render_frame_routing_id = params->source_frame_id; | 580 guest_render_frame_routing_id = params->source_frame_id; |
568 auto* guest_rfh = content::RenderFrameHost::FromID( | 581 auto* guest_rfh = content::RenderFrameHost::FromID( |
569 guest_process_id, guest_render_frame_routing_id); | 582 guest_process_id, guest_render_frame_routing_id); |
570 // Reset the |source_frame_id| parameter. | 583 // Reset the |source_frame_id| parameter. |
571 params->source_frame_id = -1; | 584 params->source_frame_id = -1; |
572 | 585 |
573 DCHECK(guest_rfh == nullptr || | 586 DCHECK(guest_rfh == nullptr || |
574 WebViewGuest::FromWebContents( | 587 WebViewGuest::FromWebContents( |
575 WebContents::FromRenderFrameHost(guest_rfh)) != nullptr); | 588 WebContents::FromRenderFrameHost(guest_rfh)) != nullptr); |
576 } | 589 } |
577 | 590 |
578 // Send the connect event to the receiver. Give it the opener's port ID (the | 591 // Send the connect event to the receiver. Give it the opener's port ID (the |
579 // opener has the opposite port ID). | 592 // opener has the opposite port ID). |
580 channel->receiver->DispatchOnConnect(params->receiver_port_id, | 593 channel->receiver->DispatchOnConnect( |
581 params->channel_name, | 594 params->receiver_port_id, params->channel_name, params->source_tab.Pass(), |
582 params->source_tab.Pass(), | 595 params->source_frame_id, params->target_frame_id, guest_process_id, |
583 params->source_frame_id, | 596 guest_render_frame_routing_id, params->source_extension_id, |
584 params->target_frame_id, | 597 params->target_extension_id, params->source_url, params->tls_channel_id); |
585 guest_process_id, | 598 |
586 guest_render_frame_routing_id, | 599 // Report the event to the event router, if the target is an extension. |
587 params->source_extension_id, | 600 // |
588 params->target_extension_id, | 601 // First, determine what event this will be (runtime.onConnect vs |
589 params->source_url, | 602 // runtime.onMessage etc), and what the event target is (view vs background |
590 params->tls_channel_id); | 603 // page etc). |
604 // | |
605 // Yes - even though this is opening a channel, they may actually be | |
606 // runtime.onRequest/onMessage events because those single-use events are | |
607 // built using the connect framework (see messaging.js). | |
608 // | |
609 // Likewise, if you're wondering about native messaging events, these are | |
610 // only initiated *by* the extension, so aren't really events, just the | |
611 // endpoint of a communication channel. | |
612 if (target_extension) { | |
613 events::HistogramValue histogram_value = events::UNKNOWN; | |
614 bool is_external = | |
615 params->source_extension_id != params->target_extension_id; | |
616 if (params->channel_name == "chrome.runtime.onRequest") { | |
617 histogram_value = is_external ? events::RUNTIME_ON_REQUEST_EXTERNAL | |
618 : events::RUNTIME_ON_REQUEST; | |
619 } else if (params->channel_name == "chrome.runtime.onMessage") { | |
620 histogram_value = is_external ? events::RUNTIME_ON_MESSAGE_EXTERNAL | |
621 : events::RUNTIME_ON_MESSAGE; | |
622 } else { | |
623 histogram_value = is_external ? events::RUNTIME_ON_CONNECT_EXTERNAL | |
624 : events::RUNTIME_ON_CONNECT; | |
625 } | |
626 EventRouter::Get(browser_context) | |
627 ->ReportEvent(histogram_value, target_extension, did_enqueue); | |
628 } | |
591 | 629 |
592 // Keep both ends of the channel alive until the channel is closed. | 630 // Keep both ends of the channel alive until the channel is closed. |
593 channel->opener->IncrementLazyKeepaliveCount(); | 631 channel->opener->IncrementLazyKeepaliveCount(); |
594 channel->receiver->IncrementLazyKeepaliveCount(); | 632 channel->receiver->IncrementLazyKeepaliveCount(); |
595 } | 633 } |
596 | 634 |
597 void MessageService::AddChannel(MessageChannel* channel, int receiver_port_id) { | 635 void MessageService::AddChannel(MessageChannel* channel, int receiver_port_id) { |
636 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
637 | |
598 int channel_id = GET_CHANNEL_ID(receiver_port_id); | 638 int channel_id = GET_CHANNEL_ID(receiver_port_id); |
599 CHECK(channels_.find(channel_id) == channels_.end()); | 639 CHECK(channels_.find(channel_id) == channels_.end()); |
600 channels_[channel_id] = channel; | 640 channels_[channel_id] = channel; |
601 pending_lazy_background_page_channels_.erase(channel_id); | 641 pending_lazy_background_page_channels_.erase(channel_id); |
602 } | 642 } |
603 | 643 |
604 void MessageService::CloseChannel(int port_id, | 644 void MessageService::CloseChannel(int port_id, |
605 const std::string& error_message) { | 645 const std::string& error_message) { |
646 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
647 | |
606 // Note: The channel might be gone already, if the other side closed first. | 648 // Note: The channel might be gone already, if the other side closed first. |
607 int channel_id = GET_CHANNEL_ID(port_id); | 649 int channel_id = GET_CHANNEL_ID(port_id); |
608 MessageChannelMap::iterator it = channels_.find(channel_id); | 650 MessageChannelMap::iterator it = channels_.find(channel_id); |
609 if (it == channels_.end()) { | 651 if (it == channels_.end()) { |
610 PendingLazyBackgroundPageChannelMap::iterator pending = | 652 PendingLazyBackgroundPageChannelMap::iterator pending = |
611 pending_lazy_background_page_channels_.find(channel_id); | 653 pending_lazy_background_page_channels_.find(channel_id); |
612 if (pending != pending_lazy_background_page_channels_.end()) { | 654 if (pending != pending_lazy_background_page_channels_.end()) { |
613 lazy_background_task_queue_->AddPendingTask( | 655 lazy_background_task_queue_->AddPendingTask( |
614 pending->second.first, pending->second.second, | 656 pending->second.first, pending->second.second, |
615 base::Bind(&MessageService::PendingLazyBackgroundPageCloseChannel, | 657 base::Bind(&MessageService::PendingLazyBackgroundPageCloseChannel, |
616 weak_factory_.GetWeakPtr(), port_id, error_message)); | 658 weak_factory_.GetWeakPtr(), port_id, error_message)); |
617 } | 659 } |
618 return; | 660 return; |
619 } | 661 } |
620 CloseChannelImpl(it, port_id, error_message, true); | 662 CloseChannelImpl(it, port_id, error_message, true); |
621 } | 663 } |
622 | 664 |
623 void MessageService::CloseChannelImpl( | 665 void MessageService::CloseChannelImpl( |
624 MessageChannelMap::iterator channel_iter, | 666 MessageChannelMap::iterator channel_iter, |
625 int closing_port_id, | 667 int closing_port_id, |
626 const std::string& error_message, | 668 const std::string& error_message, |
627 bool notify_other_port) { | 669 bool notify_other_port) { |
670 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
671 | |
628 MessageChannel* channel = channel_iter->second; | 672 MessageChannel* channel = channel_iter->second; |
629 | 673 |
630 // Notify the other side. | 674 // Notify the other side. |
631 if (notify_other_port) { | 675 if (notify_other_port) { |
632 MessagePort* port = IS_OPENER_PORT_ID(closing_port_id) ? | 676 MessagePort* port = IS_OPENER_PORT_ID(closing_port_id) ? |
633 channel->receiver.get() : channel->opener.get(); | 677 channel->receiver.get() : channel->opener.get(); |
634 port->DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(closing_port_id), | 678 port->DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(closing_port_id), |
635 error_message); | 679 error_message); |
636 } | 680 } |
637 | 681 |
638 // Balance the IncrementLazyKeepaliveCount() in OpenChannelImpl. | 682 // Balance the IncrementLazyKeepaliveCount() in OpenChannelImpl. |
639 channel->opener->DecrementLazyKeepaliveCount(); | 683 channel->opener->DecrementLazyKeepaliveCount(); |
640 channel->receiver->DecrementLazyKeepaliveCount(); | 684 channel->receiver->DecrementLazyKeepaliveCount(); |
641 | 685 |
642 delete channel_iter->second; | 686 delete channel_iter->second; |
643 channels_.erase(channel_iter); | 687 channels_.erase(channel_iter); |
644 } | 688 } |
645 | 689 |
646 void MessageService::PostMessage(int source_port_id, const Message& message) { | 690 void MessageService::PostMessage(int source_port_id, const Message& message) { |
691 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
692 | |
647 int channel_id = GET_CHANNEL_ID(source_port_id); | 693 int channel_id = GET_CHANNEL_ID(source_port_id); |
648 MessageChannelMap::iterator iter = channels_.find(channel_id); | 694 MessageChannelMap::iterator iter = channels_.find(channel_id); |
649 if (iter == channels_.end()) { | 695 if (iter == channels_.end()) { |
650 // If this channel is pending, queue up the PostMessage to run once | 696 // If this channel is pending, queue up the PostMessage to run once |
651 // the channel opens. | 697 // the channel opens. |
652 EnqueuePendingMessage(source_port_id, channel_id, message); | 698 EnqueuePendingMessage(source_port_id, channel_id, message); |
653 return; | 699 return; |
654 } | 700 } |
655 | 701 |
656 DispatchMessage(source_port_id, iter->second, message); | 702 DispatchMessage(source_port_id, iter->second, message); |
657 } | 703 } |
658 | 704 |
659 void MessageService::Observe(int type, | 705 void MessageService::Observe(int type, |
660 const content::NotificationSource& source, | 706 const content::NotificationSource& source, |
661 const content::NotificationDetails& details) { | 707 const content::NotificationDetails& details) { |
708 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
709 | |
662 switch (type) { | 710 switch (type) { |
663 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: | 711 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: |
664 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { | 712 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { |
665 content::RenderProcessHost* renderer = | 713 content::RenderProcessHost* renderer = |
666 content::Source<content::RenderProcessHost>(source).ptr(); | 714 content::Source<content::RenderProcessHost>(source).ptr(); |
667 OnProcessClosed(renderer); | 715 OnProcessClosed(renderer); |
668 break; | 716 break; |
669 } | 717 } |
670 default: | 718 default: |
671 NOTREACHED(); | 719 NOTREACHED(); |
672 return; | 720 return; |
673 } | 721 } |
674 } | 722 } |
675 | 723 |
676 void MessageService::OnProcessClosed(content::RenderProcessHost* process) { | 724 void MessageService::OnProcessClosed(content::RenderProcessHost* process) { |
725 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
726 | |
677 // Close any channels that share this renderer. We notify the opposite | 727 // Close any channels that share this renderer. We notify the opposite |
678 // port that his pair has closed. | 728 // port that its pair has closed. |
679 for (MessageChannelMap::iterator it = channels_.begin(); | 729 for (MessageChannelMap::iterator it = channels_.begin(); |
680 it != channels_.end(); ) { | 730 it != channels_.end(); ) { |
681 MessageChannelMap::iterator current = it++; | 731 MessageChannelMap::iterator current = it++; |
682 | 732 |
683 content::RenderProcessHost* opener_process = | 733 content::RenderProcessHost* opener_process = |
684 current->second->opener->GetRenderProcessHost(); | 734 current->second->opener->GetRenderProcessHost(); |
685 content::RenderProcessHost* receiver_process = | 735 content::RenderProcessHost* receiver_process = |
686 current->second->receiver->GetRenderProcessHost(); | 736 current->second->receiver->GetRenderProcessHost(); |
687 | 737 |
688 // Only notify the other side if it has a different porocess host. | 738 // Only notify the other side if it has a different porocess host. |
689 bool notify_other_port = opener_process && receiver_process && | 739 bool notify_other_port = opener_process && receiver_process && |
690 opener_process != receiver_process; | 740 opener_process != receiver_process; |
691 | 741 |
692 if (opener_process == process) { | 742 if (opener_process == process) { |
693 CloseChannelImpl(current, GET_CHANNEL_OPENER_ID(current->first), | 743 CloseChannelImpl(current, GET_CHANNEL_OPENER_ID(current->first), |
694 std::string(), notify_other_port); | 744 std::string(), notify_other_port); |
695 } else if (receiver_process == process) { | 745 } else if (receiver_process == process) { |
696 CloseChannelImpl(current, GET_CHANNEL_RECEIVERS_ID(current->first), | 746 CloseChannelImpl(current, GET_CHANNEL_RECEIVERS_ID(current->first), |
697 std::string(), notify_other_port); | 747 std::string(), notify_other_port); |
698 } | 748 } |
699 } | 749 } |
700 } | 750 } |
701 | 751 |
702 void MessageService::EnqueuePendingMessage(int source_port_id, | 752 void MessageService::EnqueuePendingMessage(int source_port_id, |
703 int channel_id, | 753 int channel_id, |
704 const Message& message) { | 754 const Message& message) { |
755 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
756 | |
705 PendingChannelMap::iterator pending_for_incognito = | 757 PendingChannelMap::iterator pending_for_incognito = |
706 pending_incognito_channels_.find(channel_id); | 758 pending_incognito_channels_.find(channel_id); |
707 if (pending_for_incognito != pending_incognito_channels_.end()) { | 759 if (pending_for_incognito != pending_incognito_channels_.end()) { |
708 pending_for_incognito->second.push_back( | 760 pending_for_incognito->second.push_back( |
709 PendingMessage(source_port_id, message)); | 761 PendingMessage(source_port_id, message)); |
710 // A channel should only be holding pending messages because it is in one | 762 // A channel should only be holding pending messages because it is in one |
711 // of these states. | 763 // of these states. |
712 DCHECK(!ContainsKey(pending_tls_channel_id_channels_, channel_id)); | 764 DCHECK(!ContainsKey(pending_tls_channel_id_channels_, channel_id)); |
713 DCHECK(!ContainsKey(pending_lazy_background_page_channels_, channel_id)); | 765 DCHECK(!ContainsKey(pending_lazy_background_page_channels_, channel_id)); |
714 return; | 766 return; |
(...skipping 10 matching lines...) Expand all Loading... | |
725 } | 777 } |
726 EnqueuePendingMessageForLazyBackgroundLoad(source_port_id, | 778 EnqueuePendingMessageForLazyBackgroundLoad(source_port_id, |
727 channel_id, | 779 channel_id, |
728 message); | 780 message); |
729 } | 781 } |
730 | 782 |
731 void MessageService::EnqueuePendingMessageForLazyBackgroundLoad( | 783 void MessageService::EnqueuePendingMessageForLazyBackgroundLoad( |
732 int source_port_id, | 784 int source_port_id, |
733 int channel_id, | 785 int channel_id, |
734 const Message& message) { | 786 const Message& message) { |
787 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
788 | |
735 PendingLazyBackgroundPageChannelMap::iterator pending = | 789 PendingLazyBackgroundPageChannelMap::iterator pending = |
736 pending_lazy_background_page_channels_.find(channel_id); | 790 pending_lazy_background_page_channels_.find(channel_id); |
737 if (pending != pending_lazy_background_page_channels_.end()) { | 791 if (pending != pending_lazy_background_page_channels_.end()) { |
738 lazy_background_task_queue_->AddPendingTask( | 792 lazy_background_task_queue_->AddPendingTask( |
739 pending->second.first, pending->second.second, | 793 pending->second.first, pending->second.second, |
740 base::Bind(&MessageService::PendingLazyBackgroundPagePostMessage, | 794 base::Bind(&MessageService::PendingLazyBackgroundPagePostMessage, |
741 weak_factory_.GetWeakPtr(), source_port_id, message)); | 795 weak_factory_.GetWeakPtr(), source_port_id, message)); |
742 } | 796 } |
743 } | 797 } |
744 | 798 |
745 void MessageService::DispatchMessage(int source_port_id, | 799 void MessageService::DispatchMessage(int source_port_id, |
746 MessageChannel* channel, | 800 MessageChannel* channel, |
747 const Message& message) { | 801 const Message& message) { |
802 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
803 | |
748 // Figure out which port the ID corresponds to. | 804 // Figure out which port the ID corresponds to. |
749 int dest_port_id = GET_OPPOSITE_PORT_ID(source_port_id); | 805 int dest_port_id = GET_OPPOSITE_PORT_ID(source_port_id); |
750 MessagePort* port = IS_OPENER_PORT_ID(dest_port_id) ? | 806 MessagePort* port = IS_OPENER_PORT_ID(dest_port_id) ? |
751 channel->opener.get() : channel->receiver.get(); | 807 channel->opener.get() : channel->receiver.get(); |
752 | 808 |
753 port->DispatchOnMessage(message, dest_port_id); | 809 port->DispatchOnMessage(message, dest_port_id); |
754 } | 810 } |
755 | 811 |
756 bool MessageService::MaybeAddPendingLazyBackgroundPageOpenChannelTask( | 812 bool MessageService::MaybeAddPendingLazyBackgroundPageOpenChannelTask( |
757 BrowserContext* context, | 813 BrowserContext* context, |
758 const Extension* extension, | 814 const Extension* extension, |
759 scoped_ptr<OpenChannelParams>* params, | 815 scoped_ptr<OpenChannelParams>* params, |
760 const PendingMessagesQueue& pending_messages) { | 816 const PendingMessagesQueue& pending_messages) { |
817 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
818 | |
761 if (!BackgroundInfo::HasLazyBackgroundPage(extension)) | 819 if (!BackgroundInfo::HasLazyBackgroundPage(extension)) |
762 return false; | 820 return false; |
763 | 821 |
764 // If the extension uses spanning incognito mode, make sure we're always | 822 // If the extension uses spanning incognito mode, make sure we're always |
765 // using the original profile since that is what the extension process | 823 // using the original profile since that is what the extension process |
766 // will use. | 824 // will use. |
767 if (!IncognitoInfo::IsSplitMode(extension)) | 825 if (!IncognitoInfo::IsSplitMode(extension)) |
768 context = ExtensionsBrowserClient::Get()->GetOriginalContext(context); | 826 context = ExtensionsBrowserClient::Get()->GetOriginalContext(context); |
769 | 827 |
770 if (!lazy_background_task_queue_->ShouldEnqueueTask(context, extension)) | 828 if (!lazy_background_task_queue_->ShouldEnqueueTask(context, extension)) |
(...skipping 10 matching lines...) Expand all Loading... | |
781 | 839 |
782 for (const PendingMessage& message : pending_messages) { | 840 for (const PendingMessage& message : pending_messages) { |
783 EnqueuePendingMessageForLazyBackgroundLoad(message.first, channel_id, | 841 EnqueuePendingMessageForLazyBackgroundLoad(message.first, channel_id, |
784 message.second); | 842 message.second); |
785 } | 843 } |
786 return true; | 844 return true; |
787 } | 845 } |
788 | 846 |
789 void MessageService::OnOpenChannelAllowed(scoped_ptr<OpenChannelParams> params, | 847 void MessageService::OnOpenChannelAllowed(scoped_ptr<OpenChannelParams> params, |
790 bool allowed) { | 848 bool allowed) { |
849 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
850 | |
791 int channel_id = GET_CHANNEL_ID(params->receiver_port_id); | 851 int channel_id = GET_CHANNEL_ID(params->receiver_port_id); |
792 | 852 |
793 PendingChannelMap::iterator pending_for_incognito = | 853 PendingChannelMap::iterator pending_for_incognito = |
794 pending_incognito_channels_.find(channel_id); | 854 pending_incognito_channels_.find(channel_id); |
795 if (pending_for_incognito == pending_incognito_channels_.end()) { | 855 if (pending_for_incognito == pending_incognito_channels_.end()) { |
796 NOTREACHED(); | 856 NOTREACHED(); |
797 return; | 857 return; |
798 } | 858 } |
799 PendingMessagesQueue pending_messages; | 859 PendingMessagesQueue pending_messages; |
800 pending_messages.swap(pending_for_incognito->second); | 860 pending_messages.swap(pending_for_incognito->second); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
845 DispatchOnDisconnect(source, params->receiver_port_id, | 905 DispatchOnDisconnect(source, params->receiver_port_id, |
846 kReceivingEndDoesntExistError); | 906 kReceivingEndDoesntExistError); |
847 return; | 907 return; |
848 } | 908 } |
849 | 909 |
850 // The target might be a lazy background page. In that case, we have to check | 910 // The target might be a lazy background page. In that case, we have to check |
851 // if it is loaded and ready, and if not, queue up the task and load the | 911 // if it is loaded and ready, and if not, queue up the task and load the |
852 // page. | 912 // page. |
853 if (!MaybeAddPendingLazyBackgroundPageOpenChannelTask( | 913 if (!MaybeAddPendingLazyBackgroundPageOpenChannelTask( |
854 context, target_extension, ¶ms, pending_messages)) { | 914 context, target_extension, ¶ms, pending_messages)) { |
855 OpenChannelImpl(params.Pass()); | 915 OpenChannelImpl(context, params.Pass(), target_extension, |
916 false /* did_enqueue */); | |
856 DispatchPendingMessages(pending_messages, channel_id); | 917 DispatchPendingMessages(pending_messages, channel_id); |
857 } | 918 } |
858 } | 919 } |
859 | 920 |
860 void MessageService::GotChannelID(scoped_ptr<OpenChannelParams> params, | 921 void MessageService::GotChannelID(scoped_ptr<OpenChannelParams> params, |
861 const std::string& tls_channel_id) { | 922 const std::string& tls_channel_id) { |
923 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
924 | |
862 params->tls_channel_id.assign(tls_channel_id); | 925 params->tls_channel_id.assign(tls_channel_id); |
863 int channel_id = GET_CHANNEL_ID(params->receiver_port_id); | 926 int channel_id = GET_CHANNEL_ID(params->receiver_port_id); |
864 | 927 |
865 PendingChannelMap::iterator pending_for_tls_channel_id = | 928 PendingChannelMap::iterator pending_for_tls_channel_id = |
866 pending_tls_channel_id_channels_.find(channel_id); | 929 pending_tls_channel_id_channels_.find(channel_id); |
867 if (pending_for_tls_channel_id == pending_tls_channel_id_channels_.end()) { | 930 if (pending_for_tls_channel_id == pending_tls_channel_id_channels_.end()) { |
868 NOTREACHED(); | 931 NOTREACHED(); |
869 return; | 932 return; |
870 } | 933 } |
871 PendingMessagesQueue pending_messages; | 934 PendingMessagesQueue pending_messages; |
(...skipping 12 matching lines...) Expand all Loading... | |
884 const Extension* target_extension = | 947 const Extension* target_extension = |
885 registry->enabled_extensions().GetByID(params->target_extension_id); | 948 registry->enabled_extensions().GetByID(params->target_extension_id); |
886 if (!target_extension) { | 949 if (!target_extension) { |
887 DispatchOnDisconnect(source, params->receiver_port_id, | 950 DispatchOnDisconnect(source, params->receiver_port_id, |
888 kReceivingEndDoesntExistError); | 951 kReceivingEndDoesntExistError); |
889 return; | 952 return; |
890 } | 953 } |
891 | 954 |
892 if (!MaybeAddPendingLazyBackgroundPageOpenChannelTask( | 955 if (!MaybeAddPendingLazyBackgroundPageOpenChannelTask( |
893 context, target_extension, ¶ms, pending_messages)) { | 956 context, target_extension, ¶ms, pending_messages)) { |
894 OpenChannelImpl(params.Pass()); | 957 OpenChannelImpl(context, params.Pass(), target_extension, |
958 false /* did_enqueue */); | |
895 DispatchPendingMessages(pending_messages, channel_id); | 959 DispatchPendingMessages(pending_messages, channel_id); |
896 } | 960 } |
897 } | 961 } |
898 | 962 |
899 void MessageService::PendingLazyBackgroundPageOpenChannel( | 963 void MessageService::PendingLazyBackgroundPageOpenChannel( |
900 scoped_ptr<OpenChannelParams> params, | 964 scoped_ptr<OpenChannelParams> params, |
901 int source_process_id, | 965 int source_process_id, |
902 ExtensionHost* host) { | 966 ExtensionHost* host) { |
967 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
968 | |
903 if (!host) | 969 if (!host) |
904 return; // TODO(mpcomplete): notify source of disconnect? | 970 return; // TODO(mpcomplete): notify source of disconnect? |
905 | 971 |
906 params->receiver.reset(new ExtensionMessagePort(host->render_process_host(), | 972 params->receiver.reset(new ExtensionMessagePort(host->render_process_host(), |
907 MSG_ROUTING_CONTROL, | 973 MSG_ROUTING_CONTROL, |
908 params->target_extension_id)); | 974 params->target_extension_id)); |
909 OpenChannelImpl(params.Pass()); | 975 OpenChannelImpl(host->browser_context(), params.Pass(), host->extension(), |
976 true /* did_enqueue */); | |
910 } | 977 } |
911 | 978 |
912 void MessageService::DispatchOnDisconnect(content::RenderProcessHost* source, | 979 void MessageService::DispatchOnDisconnect(content::RenderProcessHost* source, |
913 int port_id, | 980 int port_id, |
914 const std::string& error_message) { | 981 const std::string& error_message) { |
982 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
983 | |
915 ExtensionMessagePort port(source, MSG_ROUTING_CONTROL, ""); | 984 ExtensionMessagePort port(source, MSG_ROUTING_CONTROL, ""); |
916 port.DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(port_id), error_message); | 985 port.DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(port_id), error_message); |
917 } | 986 } |
918 | 987 |
919 void MessageService::DispatchPendingMessages(const PendingMessagesQueue& queue, | 988 void MessageService::DispatchPendingMessages(const PendingMessagesQueue& queue, |
920 int channel_id) { | 989 int channel_id) { |
990 DCHECK_CURRENTLY_ON(BrowserThread::UI); | |
991 | |
921 MessageChannelMap::iterator channel_iter = channels_.find(channel_id); | 992 MessageChannelMap::iterator channel_iter = channels_.find(channel_id); |
922 if (channel_iter != channels_.end()) { | 993 if (channel_iter != channels_.end()) { |
923 for (const PendingMessage& message : queue) { | 994 for (const PendingMessage& message : queue) { |
924 DispatchMessage(message.first, channel_iter->second, message.second); | 995 DispatchMessage(message.first, channel_iter->second, message.second); |
925 } | 996 } |
926 } | 997 } |
927 } | 998 } |
928 | 999 |
929 } // namespace extensions | 1000 } // namespace extensions |
OLD | NEW |