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