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