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)); |
| 537 |
| 538 const Extension* extension = nullptr; |
| 539 if (!extension_id.empty()) { |
| 540 // Source extension == target extension so the extension must exist, or |
| 541 // where did the IPC come from? |
| 542 extension = ExtensionRegistry::Get(profile)->enabled_extensions().GetByID( |
| 543 extension_id); |
| 544 DCHECK(extension); |
| 545 } |
521 | 546 |
522 scoped_ptr<OpenChannelParams> params(new OpenChannelParams( | 547 scoped_ptr<OpenChannelParams> params(new OpenChannelParams( |
523 source_process_id, | 548 source_process_id, |
524 scoped_ptr<base::DictionaryValue>(), // Source tab doesn't make sense | 549 scoped_ptr<base::DictionaryValue>(), // Source tab doesn't make sense |
525 // for opening to tabs. | 550 // for opening to tabs. |
526 -1, // If there is no tab, then there is no frame either. | 551 -1, // If there is no tab, then there is no frame either. |
527 frame_id, | 552 frame_id, |
528 receiver.release(), receiver_port_id, extension_id, extension_id, | 553 receiver.release(), receiver_port_id, extension_id, extension_id, |
529 GURL(), // Source URL doesn't make sense for opening to tabs. | 554 GURL(), // Source URL doesn't make sense for opening to tabs. |
530 channel_name, | 555 channel_name, |
531 false, // Connections to tabs don't get TLS channel IDs. | 556 false, // Connections to tabs don't get TLS channel IDs. |
532 false)); // Connections to tabs aren't webview guests. | 557 false)); // Connections to tabs aren't webview guests. |
533 OpenChannelImpl(params.Pass()); | 558 OpenChannelImpl(contents->GetBrowserContext(), params.Pass(), extension, |
| 559 false /* did_enqueue */); |
534 } | 560 } |
535 | 561 |
536 void MessageService::OpenChannelImpl(scoped_ptr<OpenChannelParams> params) { | 562 void MessageService::OpenChannelImpl(BrowserContext* browser_context, |
| 563 scoped_ptr<OpenChannelParams> params, |
| 564 const Extension* target_extension, |
| 565 bool did_enqueue) { |
| 566 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 567 DCHECK_EQ(target_extension != nullptr, !params->target_extension_id.empty()); |
| 568 |
537 content::RenderProcessHost* source = | 569 content::RenderProcessHost* source = |
538 content::RenderProcessHost::FromID(params->source_process_id); | 570 content::RenderProcessHost::FromID(params->source_process_id); |
539 if (!source) | 571 if (!source) |
540 return; // Closed while in flight. | 572 return; // Closed while in flight. |
541 | 573 |
542 if (!params->receiver || !params->receiver->GetRenderProcessHost()) { | 574 if (!params->receiver || !params->receiver->GetRenderProcessHost()) { |
543 DispatchOnDisconnect(source, params->receiver_port_id, | 575 DispatchOnDisconnect(source, params->receiver_port_id, |
544 kReceivingEndDoesntExistError); | 576 kReceivingEndDoesntExistError); |
545 return; | 577 return; |
546 } | 578 } |
547 | 579 |
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); | 580 MessageChannel* channel(new MessageChannel); |
553 channel->opener.reset(new ExtensionMessagePort(source, MSG_ROUTING_CONTROL, | 581 channel->opener.reset(new ExtensionMessagePort(source, MSG_ROUTING_CONTROL, |
554 params->source_extension_id)); | 582 params->source_extension_id)); |
555 channel->receiver.reset(params->receiver.release()); | 583 channel->receiver.reset(params->receiver.release()); |
556 | |
557 CHECK(channel->receiver->GetRenderProcessHost()); | |
558 | |
559 AddChannel(channel, params->receiver_port_id); | 584 AddChannel(channel, params->receiver_port_id); |
560 | 585 |
561 CHECK(channel->receiver->GetRenderProcessHost()); | |
562 | |
563 int guest_process_id = content::ChildProcessHost::kInvalidUniqueID; | 586 int guest_process_id = content::ChildProcessHost::kInvalidUniqueID; |
564 int guest_render_frame_routing_id = MSG_ROUTING_NONE; | 587 int guest_render_frame_routing_id = MSG_ROUTING_NONE; |
565 if (params->include_guest_process_info) { | 588 if (params->include_guest_process_info) { |
566 guest_process_id = params->source_process_id; | 589 guest_process_id = params->source_process_id; |
567 guest_render_frame_routing_id = params->source_frame_id; | 590 guest_render_frame_routing_id = params->source_frame_id; |
568 auto* guest_rfh = content::RenderFrameHost::FromID( | 591 auto* guest_rfh = content::RenderFrameHost::FromID( |
569 guest_process_id, guest_render_frame_routing_id); | 592 guest_process_id, guest_render_frame_routing_id); |
570 // Reset the |source_frame_id| parameter. | 593 // Reset the |source_frame_id| parameter. |
571 params->source_frame_id = -1; | 594 params->source_frame_id = -1; |
572 | 595 |
573 DCHECK(guest_rfh == nullptr || | 596 DCHECK(guest_rfh == nullptr || |
574 WebViewGuest::FromWebContents( | 597 WebViewGuest::FromWebContents( |
575 WebContents::FromRenderFrameHost(guest_rfh)) != nullptr); | 598 WebContents::FromRenderFrameHost(guest_rfh)) != nullptr); |
576 } | 599 } |
577 | 600 |
578 // Send the connect event to the receiver. Give it the opener's port ID (the | 601 // Send the connect event to the receiver. Give it the opener's port ID (the |
579 // opener has the opposite port ID). | 602 // opener has the opposite port ID). |
580 channel->receiver->DispatchOnConnect(params->receiver_port_id, | 603 channel->receiver->DispatchOnConnect( |
581 params->channel_name, | 604 params->receiver_port_id, params->channel_name, params->source_tab.Pass(), |
582 params->source_tab.Pass(), | 605 params->source_frame_id, params->target_frame_id, guest_process_id, |
583 params->source_frame_id, | 606 guest_render_frame_routing_id, params->source_extension_id, |
584 params->target_frame_id, | 607 params->target_extension_id, params->source_url, params->tls_channel_id); |
585 guest_process_id, | 608 |
586 guest_render_frame_routing_id, | 609 // Report the event to the event router, if the target is an extension. |
587 params->source_extension_id, | 610 // |
588 params->target_extension_id, | 611 // First, determine what event this will be (runtime.onConnect vs |
589 params->source_url, | 612 // runtime.onMessage etc), and what the event target is (view vs background |
590 params->tls_channel_id); | 613 // page etc). |
| 614 // |
| 615 // Yes - even though this is opening a channel, they may actually be |
| 616 // runtime.onRequest/onMessage events because those single-use events are |
| 617 // built using the connect framework (see messaging.js). |
| 618 // |
| 619 // Likewise, if you're wondering about native messaging events, these are |
| 620 // only initiated *by* the extension, so aren't really events, just the |
| 621 // endpoint of a communication channel. |
| 622 if (target_extension) { |
| 623 events::HistogramValue histogram_value = events::UNKNOWN; |
| 624 bool is_external = |
| 625 params->source_extension_id != params->target_extension_id; |
| 626 if (params->channel_name == "chrome.runtime.onRequest") { |
| 627 histogram_value = is_external ? events::RUNTIME_ON_REQUEST_EXTERNAL |
| 628 : events::RUNTIME_ON_REQUEST; |
| 629 } else if (params->channel_name == "chrome.runtime.onMessage") { |
| 630 histogram_value = is_external ? events::RUNTIME_ON_MESSAGE_EXTERNAL |
| 631 : events::RUNTIME_ON_MESSAGE; |
| 632 } else { |
| 633 histogram_value = is_external ? events::RUNTIME_ON_CONNECT_EXTERNAL |
| 634 : events::RUNTIME_ON_CONNECT; |
| 635 } |
| 636 EventRouter::Get(browser_context) |
| 637 ->ReportEvent(histogram_value, target_extension, did_enqueue); |
| 638 } |
591 | 639 |
592 // Keep both ends of the channel alive until the channel is closed. | 640 // Keep both ends of the channel alive until the channel is closed. |
593 channel->opener->IncrementLazyKeepaliveCount(); | 641 channel->opener->IncrementLazyKeepaliveCount(); |
594 channel->receiver->IncrementLazyKeepaliveCount(); | 642 channel->receiver->IncrementLazyKeepaliveCount(); |
595 } | 643 } |
596 | 644 |
597 void MessageService::AddChannel(MessageChannel* channel, int receiver_port_id) { | 645 void MessageService::AddChannel(MessageChannel* channel, int receiver_port_id) { |
| 646 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 647 |
598 int channel_id = GET_CHANNEL_ID(receiver_port_id); | 648 int channel_id = GET_CHANNEL_ID(receiver_port_id); |
599 CHECK(channels_.find(channel_id) == channels_.end()); | 649 CHECK(channels_.find(channel_id) == channels_.end()); |
600 channels_[channel_id] = channel; | 650 channels_[channel_id] = channel; |
601 pending_lazy_background_page_channels_.erase(channel_id); | 651 pending_lazy_background_page_channels_.erase(channel_id); |
602 } | 652 } |
603 | 653 |
604 void MessageService::CloseChannel(int port_id, | 654 void MessageService::CloseChannel(int port_id, |
605 const std::string& error_message) { | 655 const std::string& error_message) { |
| 656 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 657 |
606 // Note: The channel might be gone already, if the other side closed first. | 658 // Note: The channel might be gone already, if the other side closed first. |
607 int channel_id = GET_CHANNEL_ID(port_id); | 659 int channel_id = GET_CHANNEL_ID(port_id); |
608 MessageChannelMap::iterator it = channels_.find(channel_id); | 660 MessageChannelMap::iterator it = channels_.find(channel_id); |
609 if (it == channels_.end()) { | 661 if (it == channels_.end()) { |
610 PendingLazyBackgroundPageChannelMap::iterator pending = | 662 PendingLazyBackgroundPageChannelMap::iterator pending = |
611 pending_lazy_background_page_channels_.find(channel_id); | 663 pending_lazy_background_page_channels_.find(channel_id); |
612 if (pending != pending_lazy_background_page_channels_.end()) { | 664 if (pending != pending_lazy_background_page_channels_.end()) { |
613 lazy_background_task_queue_->AddPendingTask( | 665 lazy_background_task_queue_->AddPendingTask( |
614 pending->second.first, pending->second.second, | 666 pending->second.first, pending->second.second, |
615 base::Bind(&MessageService::PendingLazyBackgroundPageCloseChannel, | 667 base::Bind(&MessageService::PendingLazyBackgroundPageCloseChannel, |
616 weak_factory_.GetWeakPtr(), port_id, error_message)); | 668 weak_factory_.GetWeakPtr(), port_id, error_message)); |
617 } | 669 } |
618 return; | 670 return; |
619 } | 671 } |
620 CloseChannelImpl(it, port_id, error_message, true); | 672 CloseChannelImpl(it, port_id, error_message, true); |
621 } | 673 } |
622 | 674 |
623 void MessageService::CloseChannelImpl( | 675 void MessageService::CloseChannelImpl( |
624 MessageChannelMap::iterator channel_iter, | 676 MessageChannelMap::iterator channel_iter, |
625 int closing_port_id, | 677 int closing_port_id, |
626 const std::string& error_message, | 678 const std::string& error_message, |
627 bool notify_other_port) { | 679 bool notify_other_port) { |
| 680 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 681 |
628 MessageChannel* channel = channel_iter->second; | 682 MessageChannel* channel = channel_iter->second; |
629 | 683 |
630 // Notify the other side. | 684 // Notify the other side. |
631 if (notify_other_port) { | 685 if (notify_other_port) { |
632 MessagePort* port = IS_OPENER_PORT_ID(closing_port_id) ? | 686 MessagePort* port = IS_OPENER_PORT_ID(closing_port_id) ? |
633 channel->receiver.get() : channel->opener.get(); | 687 channel->receiver.get() : channel->opener.get(); |
634 port->DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(closing_port_id), | 688 port->DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(closing_port_id), |
635 error_message); | 689 error_message); |
636 } | 690 } |
637 | 691 |
638 // Balance the IncrementLazyKeepaliveCount() in OpenChannelImpl. | 692 // Balance the IncrementLazyKeepaliveCount() in OpenChannelImpl. |
639 channel->opener->DecrementLazyKeepaliveCount(); | 693 channel->opener->DecrementLazyKeepaliveCount(); |
640 channel->receiver->DecrementLazyKeepaliveCount(); | 694 channel->receiver->DecrementLazyKeepaliveCount(); |
641 | 695 |
642 delete channel_iter->second; | 696 delete channel_iter->second; |
643 channels_.erase(channel_iter); | 697 channels_.erase(channel_iter); |
644 } | 698 } |
645 | 699 |
646 void MessageService::PostMessage(int source_port_id, const Message& message) { | 700 void MessageService::PostMessage(int source_port_id, const Message& message) { |
| 701 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 702 |
647 int channel_id = GET_CHANNEL_ID(source_port_id); | 703 int channel_id = GET_CHANNEL_ID(source_port_id); |
648 MessageChannelMap::iterator iter = channels_.find(channel_id); | 704 MessageChannelMap::iterator iter = channels_.find(channel_id); |
649 if (iter == channels_.end()) { | 705 if (iter == channels_.end()) { |
650 // If this channel is pending, queue up the PostMessage to run once | 706 // If this channel is pending, queue up the PostMessage to run once |
651 // the channel opens. | 707 // the channel opens. |
652 EnqueuePendingMessage(source_port_id, channel_id, message); | 708 EnqueuePendingMessage(source_port_id, channel_id, message); |
653 return; | 709 return; |
654 } | 710 } |
655 | 711 |
656 DispatchMessage(source_port_id, iter->second, message); | 712 DispatchMessage(source_port_id, iter->second, message); |
657 } | 713 } |
658 | 714 |
659 void MessageService::Observe(int type, | 715 void MessageService::Observe(int type, |
660 const content::NotificationSource& source, | 716 const content::NotificationSource& source, |
661 const content::NotificationDetails& details) { | 717 const content::NotificationDetails& details) { |
| 718 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 719 |
662 switch (type) { | 720 switch (type) { |
663 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: | 721 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: |
664 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { | 722 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { |
665 content::RenderProcessHost* renderer = | 723 content::RenderProcessHost* renderer = |
666 content::Source<content::RenderProcessHost>(source).ptr(); | 724 content::Source<content::RenderProcessHost>(source).ptr(); |
667 OnProcessClosed(renderer); | 725 OnProcessClosed(renderer); |
668 break; | 726 break; |
669 } | 727 } |
670 default: | 728 default: |
671 NOTREACHED(); | 729 NOTREACHED(); |
672 return; | 730 return; |
673 } | 731 } |
674 } | 732 } |
675 | 733 |
676 void MessageService::OnProcessClosed(content::RenderProcessHost* process) { | 734 void MessageService::OnProcessClosed(content::RenderProcessHost* process) { |
| 735 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 736 |
677 // Close any channels that share this renderer. We notify the opposite | 737 // Close any channels that share this renderer. We notify the opposite |
678 // port that his pair has closed. | 738 // port that its pair has closed. |
679 for (MessageChannelMap::iterator it = channels_.begin(); | 739 for (MessageChannelMap::iterator it = channels_.begin(); |
680 it != channels_.end(); ) { | 740 it != channels_.end(); ) { |
681 MessageChannelMap::iterator current = it++; | 741 MessageChannelMap::iterator current = it++; |
682 | 742 |
683 content::RenderProcessHost* opener_process = | 743 content::RenderProcessHost* opener_process = |
684 current->second->opener->GetRenderProcessHost(); | 744 current->second->opener->GetRenderProcessHost(); |
685 content::RenderProcessHost* receiver_process = | 745 content::RenderProcessHost* receiver_process = |
686 current->second->receiver->GetRenderProcessHost(); | 746 current->second->receiver->GetRenderProcessHost(); |
687 | 747 |
688 // Only notify the other side if it has a different porocess host. | 748 // Only notify the other side if it has a different porocess host. |
689 bool notify_other_port = opener_process && receiver_process && | 749 bool notify_other_port = opener_process && receiver_process && |
690 opener_process != receiver_process; | 750 opener_process != receiver_process; |
691 | 751 |
692 if (opener_process == process) { | 752 if (opener_process == process) { |
693 CloseChannelImpl(current, GET_CHANNEL_OPENER_ID(current->first), | 753 CloseChannelImpl(current, GET_CHANNEL_OPENER_ID(current->first), |
694 std::string(), notify_other_port); | 754 std::string(), notify_other_port); |
695 } else if (receiver_process == process) { | 755 } else if (receiver_process == process) { |
696 CloseChannelImpl(current, GET_CHANNEL_RECEIVERS_ID(current->first), | 756 CloseChannelImpl(current, GET_CHANNEL_RECEIVERS_ID(current->first), |
697 std::string(), notify_other_port); | 757 std::string(), notify_other_port); |
698 } | 758 } |
699 } | 759 } |
700 } | 760 } |
701 | 761 |
702 void MessageService::EnqueuePendingMessage(int source_port_id, | 762 void MessageService::EnqueuePendingMessage(int source_port_id, |
703 int channel_id, | 763 int channel_id, |
704 const Message& message) { | 764 const Message& message) { |
| 765 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 766 |
705 PendingChannelMap::iterator pending_for_incognito = | 767 PendingChannelMap::iterator pending_for_incognito = |
706 pending_incognito_channels_.find(channel_id); | 768 pending_incognito_channels_.find(channel_id); |
707 if (pending_for_incognito != pending_incognito_channels_.end()) { | 769 if (pending_for_incognito != pending_incognito_channels_.end()) { |
708 pending_for_incognito->second.push_back( | 770 pending_for_incognito->second.push_back( |
709 PendingMessage(source_port_id, message)); | 771 PendingMessage(source_port_id, message)); |
710 // A channel should only be holding pending messages because it is in one | 772 // A channel should only be holding pending messages because it is in one |
711 // of these states. | 773 // of these states. |
712 DCHECK(!ContainsKey(pending_tls_channel_id_channels_, channel_id)); | 774 DCHECK(!ContainsKey(pending_tls_channel_id_channels_, channel_id)); |
713 DCHECK(!ContainsKey(pending_lazy_background_page_channels_, channel_id)); | 775 DCHECK(!ContainsKey(pending_lazy_background_page_channels_, channel_id)); |
714 return; | 776 return; |
(...skipping 10 matching lines...) Expand all Loading... |
725 } | 787 } |
726 EnqueuePendingMessageForLazyBackgroundLoad(source_port_id, | 788 EnqueuePendingMessageForLazyBackgroundLoad(source_port_id, |
727 channel_id, | 789 channel_id, |
728 message); | 790 message); |
729 } | 791 } |
730 | 792 |
731 void MessageService::EnqueuePendingMessageForLazyBackgroundLoad( | 793 void MessageService::EnqueuePendingMessageForLazyBackgroundLoad( |
732 int source_port_id, | 794 int source_port_id, |
733 int channel_id, | 795 int channel_id, |
734 const Message& message) { | 796 const Message& message) { |
| 797 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 798 |
735 PendingLazyBackgroundPageChannelMap::iterator pending = | 799 PendingLazyBackgroundPageChannelMap::iterator pending = |
736 pending_lazy_background_page_channels_.find(channel_id); | 800 pending_lazy_background_page_channels_.find(channel_id); |
737 if (pending != pending_lazy_background_page_channels_.end()) { | 801 if (pending != pending_lazy_background_page_channels_.end()) { |
738 lazy_background_task_queue_->AddPendingTask( | 802 lazy_background_task_queue_->AddPendingTask( |
739 pending->second.first, pending->second.second, | 803 pending->second.first, pending->second.second, |
740 base::Bind(&MessageService::PendingLazyBackgroundPagePostMessage, | 804 base::Bind(&MessageService::PendingLazyBackgroundPagePostMessage, |
741 weak_factory_.GetWeakPtr(), source_port_id, message)); | 805 weak_factory_.GetWeakPtr(), source_port_id, message)); |
742 } | 806 } |
743 } | 807 } |
744 | 808 |
745 void MessageService::DispatchMessage(int source_port_id, | 809 void MessageService::DispatchMessage(int source_port_id, |
746 MessageChannel* channel, | 810 MessageChannel* channel, |
747 const Message& message) { | 811 const Message& message) { |
| 812 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 813 |
748 // Figure out which port the ID corresponds to. | 814 // Figure out which port the ID corresponds to. |
749 int dest_port_id = GET_OPPOSITE_PORT_ID(source_port_id); | 815 int dest_port_id = GET_OPPOSITE_PORT_ID(source_port_id); |
750 MessagePort* port = IS_OPENER_PORT_ID(dest_port_id) ? | 816 MessagePort* port = IS_OPENER_PORT_ID(dest_port_id) ? |
751 channel->opener.get() : channel->receiver.get(); | 817 channel->opener.get() : channel->receiver.get(); |
752 | 818 |
753 port->DispatchOnMessage(message, dest_port_id); | 819 port->DispatchOnMessage(message, dest_port_id); |
754 } | 820 } |
755 | 821 |
756 bool MessageService::MaybeAddPendingLazyBackgroundPageOpenChannelTask( | 822 bool MessageService::MaybeAddPendingLazyBackgroundPageOpenChannelTask( |
757 BrowserContext* context, | 823 BrowserContext* context, |
758 const Extension* extension, | 824 const Extension* extension, |
759 scoped_ptr<OpenChannelParams>* params, | 825 scoped_ptr<OpenChannelParams>* params, |
760 const PendingMessagesQueue& pending_messages) { | 826 const PendingMessagesQueue& pending_messages) { |
| 827 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 828 |
761 if (!BackgroundInfo::HasLazyBackgroundPage(extension)) | 829 if (!BackgroundInfo::HasLazyBackgroundPage(extension)) |
762 return false; | 830 return false; |
763 | 831 |
764 // If the extension uses spanning incognito mode, make sure we're always | 832 // If the extension uses spanning incognito mode, make sure we're always |
765 // using the original profile since that is what the extension process | 833 // using the original profile since that is what the extension process |
766 // will use. | 834 // will use. |
767 if (!IncognitoInfo::IsSplitMode(extension)) | 835 if (!IncognitoInfo::IsSplitMode(extension)) |
768 context = ExtensionsBrowserClient::Get()->GetOriginalContext(context); | 836 context = ExtensionsBrowserClient::Get()->GetOriginalContext(context); |
769 | 837 |
770 if (!lazy_background_task_queue_->ShouldEnqueueTask(context, extension)) | 838 if (!lazy_background_task_queue_->ShouldEnqueueTask(context, extension)) |
(...skipping 10 matching lines...) Expand all Loading... |
781 | 849 |
782 for (const PendingMessage& message : pending_messages) { | 850 for (const PendingMessage& message : pending_messages) { |
783 EnqueuePendingMessageForLazyBackgroundLoad(message.first, channel_id, | 851 EnqueuePendingMessageForLazyBackgroundLoad(message.first, channel_id, |
784 message.second); | 852 message.second); |
785 } | 853 } |
786 return true; | 854 return true; |
787 } | 855 } |
788 | 856 |
789 void MessageService::OnOpenChannelAllowed(scoped_ptr<OpenChannelParams> params, | 857 void MessageService::OnOpenChannelAllowed(scoped_ptr<OpenChannelParams> params, |
790 bool allowed) { | 858 bool allowed) { |
| 859 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 860 |
791 int channel_id = GET_CHANNEL_ID(params->receiver_port_id); | 861 int channel_id = GET_CHANNEL_ID(params->receiver_port_id); |
792 | 862 |
793 PendingChannelMap::iterator pending_for_incognito = | 863 PendingChannelMap::iterator pending_for_incognito = |
794 pending_incognito_channels_.find(channel_id); | 864 pending_incognito_channels_.find(channel_id); |
795 if (pending_for_incognito == pending_incognito_channels_.end()) { | 865 if (pending_for_incognito == pending_incognito_channels_.end()) { |
796 NOTREACHED(); | 866 NOTREACHED(); |
797 return; | 867 return; |
798 } | 868 } |
799 PendingMessagesQueue pending_messages; | 869 PendingMessagesQueue pending_messages; |
800 pending_messages.swap(pending_for_incognito->second); | 870 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, | 915 DispatchOnDisconnect(source, params->receiver_port_id, |
846 kReceivingEndDoesntExistError); | 916 kReceivingEndDoesntExistError); |
847 return; | 917 return; |
848 } | 918 } |
849 | 919 |
850 // The target might be a lazy background page. In that case, we have to check | 920 // 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 | 921 // if it is loaded and ready, and if not, queue up the task and load the |
852 // page. | 922 // page. |
853 if (!MaybeAddPendingLazyBackgroundPageOpenChannelTask( | 923 if (!MaybeAddPendingLazyBackgroundPageOpenChannelTask( |
854 context, target_extension, ¶ms, pending_messages)) { | 924 context, target_extension, ¶ms, pending_messages)) { |
855 OpenChannelImpl(params.Pass()); | 925 OpenChannelImpl(context, params.Pass(), target_extension, |
| 926 false /* did_enqueue */); |
856 DispatchPendingMessages(pending_messages, channel_id); | 927 DispatchPendingMessages(pending_messages, channel_id); |
857 } | 928 } |
858 } | 929 } |
859 | 930 |
860 void MessageService::GotChannelID(scoped_ptr<OpenChannelParams> params, | 931 void MessageService::GotChannelID(scoped_ptr<OpenChannelParams> params, |
861 const std::string& tls_channel_id) { | 932 const std::string& tls_channel_id) { |
| 933 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 934 |
862 params->tls_channel_id.assign(tls_channel_id); | 935 params->tls_channel_id.assign(tls_channel_id); |
863 int channel_id = GET_CHANNEL_ID(params->receiver_port_id); | 936 int channel_id = GET_CHANNEL_ID(params->receiver_port_id); |
864 | 937 |
865 PendingChannelMap::iterator pending_for_tls_channel_id = | 938 PendingChannelMap::iterator pending_for_tls_channel_id = |
866 pending_tls_channel_id_channels_.find(channel_id); | 939 pending_tls_channel_id_channels_.find(channel_id); |
867 if (pending_for_tls_channel_id == pending_tls_channel_id_channels_.end()) { | 940 if (pending_for_tls_channel_id == pending_tls_channel_id_channels_.end()) { |
868 NOTREACHED(); | 941 NOTREACHED(); |
869 return; | 942 return; |
870 } | 943 } |
871 PendingMessagesQueue pending_messages; | 944 PendingMessagesQueue pending_messages; |
(...skipping 12 matching lines...) Expand all Loading... |
884 const Extension* target_extension = | 957 const Extension* target_extension = |
885 registry->enabled_extensions().GetByID(params->target_extension_id); | 958 registry->enabled_extensions().GetByID(params->target_extension_id); |
886 if (!target_extension) { | 959 if (!target_extension) { |
887 DispatchOnDisconnect(source, params->receiver_port_id, | 960 DispatchOnDisconnect(source, params->receiver_port_id, |
888 kReceivingEndDoesntExistError); | 961 kReceivingEndDoesntExistError); |
889 return; | 962 return; |
890 } | 963 } |
891 | 964 |
892 if (!MaybeAddPendingLazyBackgroundPageOpenChannelTask( | 965 if (!MaybeAddPendingLazyBackgroundPageOpenChannelTask( |
893 context, target_extension, ¶ms, pending_messages)) { | 966 context, target_extension, ¶ms, pending_messages)) { |
894 OpenChannelImpl(params.Pass()); | 967 OpenChannelImpl(context, params.Pass(), target_extension, |
| 968 false /* did_enqueue */); |
895 DispatchPendingMessages(pending_messages, channel_id); | 969 DispatchPendingMessages(pending_messages, channel_id); |
896 } | 970 } |
897 } | 971 } |
898 | 972 |
899 void MessageService::PendingLazyBackgroundPageOpenChannel( | 973 void MessageService::PendingLazyBackgroundPageOpenChannel( |
900 scoped_ptr<OpenChannelParams> params, | 974 scoped_ptr<OpenChannelParams> params, |
901 int source_process_id, | 975 int source_process_id, |
902 ExtensionHost* host) { | 976 ExtensionHost* host) { |
| 977 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 978 |
903 if (!host) | 979 if (!host) |
904 return; // TODO(mpcomplete): notify source of disconnect? | 980 return; // TODO(mpcomplete): notify source of disconnect? |
905 | 981 |
906 params->receiver.reset(new ExtensionMessagePort(host->render_process_host(), | 982 params->receiver.reset(new ExtensionMessagePort(host->render_process_host(), |
907 MSG_ROUTING_CONTROL, | 983 MSG_ROUTING_CONTROL, |
908 params->target_extension_id)); | 984 params->target_extension_id)); |
909 OpenChannelImpl(params.Pass()); | 985 OpenChannelImpl(host->browser_context(), params.Pass(), host->extension(), |
| 986 true /* did_enqueue */); |
910 } | 987 } |
911 | 988 |
912 void MessageService::DispatchOnDisconnect(content::RenderProcessHost* source, | 989 void MessageService::DispatchOnDisconnect(content::RenderProcessHost* source, |
913 int port_id, | 990 int port_id, |
914 const std::string& error_message) { | 991 const std::string& error_message) { |
| 992 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 993 |
915 ExtensionMessagePort port(source, MSG_ROUTING_CONTROL, ""); | 994 ExtensionMessagePort port(source, MSG_ROUTING_CONTROL, ""); |
916 port.DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(port_id), error_message); | 995 port.DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(port_id), error_message); |
917 } | 996 } |
918 | 997 |
919 void MessageService::DispatchPendingMessages(const PendingMessagesQueue& queue, | 998 void MessageService::DispatchPendingMessages(const PendingMessagesQueue& queue, |
920 int channel_id) { | 999 int channel_id) { |
| 1000 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 1001 |
921 MessageChannelMap::iterator channel_iter = channels_.find(channel_id); | 1002 MessageChannelMap::iterator channel_iter = channels_.find(channel_id); |
922 if (channel_iter != channels_.end()) { | 1003 if (channel_iter != channels_.end()) { |
923 for (const PendingMessage& message : queue) { | 1004 for (const PendingMessage& message : queue) { |
924 DispatchMessage(message.first, channel_iter->second, message.second); | 1005 DispatchMessage(message.first, channel_iter->second, message.second); |
925 } | 1006 } |
926 } | 1007 } |
927 } | 1008 } |
928 | 1009 |
929 } // namespace extensions | 1010 } // namespace extensions |
OLD | NEW |