| 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 |