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 "base/values.h" | 15 #include "base/values.h" |
| 16 #include "chrome/browser/chrome_notification_types.h" | 16 #include "chrome/browser/chrome_notification_types.h" |
| 17 #include "chrome/browser/extensions/api/messaging/extension_message_port.h" | 17 #include "chrome/browser/extensions/api/messaging/extension_message_port.h" |
| 18 #include "chrome/browser/extensions/api/messaging/incognito_connectability.h" | 18 #include "chrome/browser/extensions/api/messaging/incognito_connectability.h" |
| 19 #include "chrome/browser/extensions/api/messaging/native_message_port.h" | 19 #include "chrome/browser/extensions/api/messaging/native_message_port.h" |
| 20 #include "chrome/browser/extensions/api/tabs/tabs_constants.h" | 20 #include "chrome/browser/extensions/api/tabs/tabs_constants.h" |
| 21 #include "chrome/browser/extensions/extension_service.h" | 21 #include "chrome/browser/extensions/extension_service.h" |
| 22 #include "chrome/browser/extensions/extension_tab_util.h" | 22 #include "chrome/browser/extensions/extension_tab_util.h" |
| 23 #include "chrome/browser/extensions/extension_util.h" | 23 #include "chrome/browser/extensions/extension_util.h" |
| 24 #include "chrome/browser/profiles/profile.h" | 24 #include "chrome/browser/profiles/profile.h" |
| 25 #include "chrome/browser/tab_contents/tab_util.h" | 25 #include "chrome/browser/tab_contents/tab_util.h" |
| 26 #include "content/public/browser/notification_service.h" | 26 #include "content/public/browser/notification_service.h" |
| 27 #include "content/public/browser/render_frame_host.h" | |
| 27 #include "content/public/browser/render_process_host.h" | 28 #include "content/public/browser/render_process_host.h" |
| 28 #include "content/public/browser/render_view_host.h" | 29 #include "content/public/browser/render_view_host.h" |
| 29 #include "content/public/browser/render_widget_host.h" | 30 #include "content/public/browser/render_widget_host.h" |
| 30 #include "content/public/browser/render_widget_host_view.h" | 31 #include "content/public/browser/render_widget_host_view.h" |
| 31 #include "content/public/browser/site_instance.h" | 32 #include "content/public/browser/site_instance.h" |
| 32 #include "content/public/browser/web_contents.h" | 33 #include "content/public/browser/web_contents.h" |
| 33 #include "extensions/browser/extension_host.h" | 34 #include "extensions/browser/extension_host.h" |
| 34 #include "extensions/browser/extension_system.h" | 35 #include "extensions/browser/extension_system.h" |
| 35 #include "extensions/browser/extensions_browser_client.h" | 36 #include "extensions/browser/extensions_browser_client.h" |
| 36 #include "extensions/browser/lazy_background_task_queue.h" | 37 #include "extensions/browser/lazy_background_task_queue.h" |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 111 "administrator."; | 112 "administrator."; |
| 112 #endif | 113 #endif |
| 113 | 114 |
| 114 struct MessageService::MessageChannel { | 115 struct MessageService::MessageChannel { |
| 115 scoped_ptr<MessagePort> opener; | 116 scoped_ptr<MessagePort> opener; |
| 116 scoped_ptr<MessagePort> receiver; | 117 scoped_ptr<MessagePort> receiver; |
| 117 }; | 118 }; |
| 118 | 119 |
| 119 struct MessageService::OpenChannelParams { | 120 struct MessageService::OpenChannelParams { |
| 120 content::RenderProcessHost* source; | 121 content::RenderProcessHost* source; |
| 121 base::DictionaryValue source_tab; | 122 scoped_ptr<base::DictionaryValue> source_tab; |
| 123 int source_frame_id; | |
| 122 scoped_ptr<MessagePort> receiver; | 124 scoped_ptr<MessagePort> receiver; |
| 123 int receiver_port_id; | 125 int receiver_port_id; |
| 124 std::string source_extension_id; | 126 std::string source_extension_id; |
| 125 std::string target_extension_id; | 127 std::string target_extension_id; |
| 126 GURL source_url; | 128 GURL source_url; |
| 127 std::string channel_name; | 129 std::string channel_name; |
| 128 bool include_tls_channel_id; | 130 bool include_tls_channel_id; |
| 129 std::string tls_channel_id; | 131 std::string tls_channel_id; |
| 130 | 132 |
| 131 // Takes ownership of receiver. | 133 // Takes ownership of receiver. |
| 132 OpenChannelParams(content::RenderProcessHost* source, | 134 OpenChannelParams(content::RenderProcessHost* source, |
| 133 scoped_ptr<base::DictionaryValue> source_tab, | 135 scoped_ptr<base::DictionaryValue> source_tab, |
| 136 int source_frame_id, | |
| 134 MessagePort* receiver, | 137 MessagePort* receiver, |
| 135 int receiver_port_id, | 138 int receiver_port_id, |
| 136 const std::string& source_extension_id, | 139 const std::string& source_extension_id, |
| 137 const std::string& target_extension_id, | 140 const std::string& target_extension_id, |
| 138 const GURL& source_url, | 141 const GURL& source_url, |
| 139 const std::string& channel_name, | 142 const std::string& channel_name, |
| 140 bool include_tls_channel_id) | 143 bool include_tls_channel_id) |
| 141 : source(source), | 144 : source(source), |
| 145 source_frame_id(source_frame_id), | |
| 142 receiver(receiver), | 146 receiver(receiver), |
| 143 receiver_port_id(receiver_port_id), | 147 receiver_port_id(receiver_port_id), |
| 144 source_extension_id(source_extension_id), | 148 source_extension_id(source_extension_id), |
| 145 target_extension_id(target_extension_id), | 149 target_extension_id(target_extension_id), |
| 146 source_url(source_url), | 150 source_url(source_url), |
| 147 channel_name(channel_name), | 151 channel_name(channel_name), |
| 148 include_tls_channel_id(include_tls_channel_id) { | 152 include_tls_channel_id(include_tls_channel_id) { |
| 149 if (source_tab) | 153 if (source_tab) |
| 150 this->source_tab.Swap(source_tab.get()); | 154 this->source_tab = source_tab.Pass(); |
| 151 } | 155 } |
| 152 | 156 |
| 153 private: | 157 private: |
| 154 DISALLOW_COPY_AND_ASSIGN(OpenChannelParams); | 158 DISALLOW_COPY_AND_ASSIGN(OpenChannelParams); |
| 155 }; | 159 }; |
| 156 | 160 |
| 157 namespace { | 161 namespace { |
| 158 | 162 |
| 159 static base::StaticAtomicSequenceNumber g_next_channel_id; | 163 static base::StaticAtomicSequenceNumber g_next_channel_id; |
| 160 static base::StaticAtomicSequenceNumber g_channel_id_overflow_count; | 164 static base::StaticAtomicSequenceNumber g_channel_id_overflow_count; |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 291 if (!is_externally_connectable) { | 295 if (!is_externally_connectable) { |
| 292 // Important: use kReceivingEndDoesntExistError here so that we don't | 296 // Important: use kReceivingEndDoesntExistError here so that we don't |
| 293 // leak information about this extension to callers. This way it's | 297 // leak information about this extension to callers. This way it's |
| 294 // indistinguishable from the extension just not existing. | 298 // indistinguishable from the extension just not existing. |
| 295 DispatchOnDisconnect( | 299 DispatchOnDisconnect( |
| 296 source, receiver_port_id, kReceivingEndDoesntExistError); | 300 source, receiver_port_id, kReceivingEndDoesntExistError); |
| 297 return; | 301 return; |
| 298 } | 302 } |
| 299 } | 303 } |
| 300 | 304 |
| 301 WebContents* source_contents = tab_util::GetWebContentsByID( | 305 WebContents* source_contents = tab_util::GetWebContentsByFrameID( |
| 302 source_process_id, source_routing_id); | 306 source_process_id, source_routing_id); |
| 303 | 307 |
| 304 if (context->IsOffTheRecord() && | 308 if (context->IsOffTheRecord() && |
| 305 !util::IsIncognitoEnabled(target_extension_id, context)) { | 309 !util::IsIncognitoEnabled(target_extension_id, context)) { |
| 306 // Give the user a chance to accept an incognito connection from the web if | 310 // Give the user a chance to accept an incognito connection from the web if |
| 307 // they haven't already, with the conditions: | 311 // they haven't already, with the conditions: |
| 308 // - Only for spanning-mode incognito. We don't want the complication of | 312 // - Only for spanning-mode incognito. We don't want the complication of |
| 309 // spinning up an additional process here which might need to do some | 313 // spinning up an additional process here which might need to do some |
| 310 // setup that we're not expecting. | 314 // setup that we're not expecting. |
| 311 // - Only for extensions that can't normally be enabled in incognito, since | 315 // - Only for extensions that can't normally be enabled in incognito, since |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 325 // Note: we use the source's profile here. If the source is an incognito | 329 // Note: we use the source's profile here. If the source is an incognito |
| 326 // process, we will use the incognito EPM to find the right extension process, | 330 // process, we will use the incognito EPM to find the right extension process, |
| 327 // which depends on whether the extension uses spanning or split mode. | 331 // which depends on whether the extension uses spanning or split mode. |
| 328 MessagePort* receiver = new ExtensionMessagePort( | 332 MessagePort* receiver = new ExtensionMessagePort( |
| 329 GetExtensionProcess(context, target_extension_id), | 333 GetExtensionProcess(context, target_extension_id), |
| 330 MSG_ROUTING_CONTROL, | 334 MSG_ROUTING_CONTROL, |
| 331 target_extension_id); | 335 target_extension_id); |
| 332 | 336 |
| 333 // Include info about the opener's tab (if it was a tab). | 337 // Include info about the opener's tab (if it was a tab). |
| 334 scoped_ptr<base::DictionaryValue> source_tab; | 338 scoped_ptr<base::DictionaryValue> source_tab; |
| 339 int source_frame_id = -1; | |
| 335 if (source_contents && ExtensionTabUtil::GetTabId(source_contents) >= 0) { | 340 if (source_contents && ExtensionTabUtil::GetTabId(source_contents) >= 0) { |
| 336 // Only the tab id is useful to platform apps for internal use. The | 341 // Only the tab id is useful to platform apps for internal use. The |
| 337 // unnecessary bits will be stripped out in | 342 // unnecessary bits will be stripped out in |
| 338 // MessagingBindings::DispatchOnConnect(). | 343 // MessagingBindings::DispatchOnConnect(). |
| 339 source_tab.reset(ExtensionTabUtil::CreateTabValue(source_contents)); | 344 source_tab.reset(ExtensionTabUtil::CreateTabValue(source_contents)); |
| 345 | |
| 346 content::RenderFrameHost* rfh = | |
| 347 content::RenderFrameHost::FromID(source_process_id, source_routing_id); | |
| 348 // Main frame's frameId is 0. | |
|
Charlie Reis
2014/11/13 19:47:05
Is the source_frame_id a new API addition? Do we
robwu
2014/11/13 22:35:30
frameId is consistent with the existing webNavigat
Charlie Reis
2014/11/18 23:08:58
I brought it up in case we wanted to remain flexib
| |
| 349 if (rfh) | |
| 350 source_frame_id = !rfh->GetParent() ? 0 : source_routing_id; | |
| 340 } | 351 } |
| 341 | 352 |
| 342 OpenChannelParams* params = new OpenChannelParams( | 353 OpenChannelParams* params = new OpenChannelParams( |
| 343 source, source_tab.Pass(), receiver, receiver_port_id, | 354 source, source_tab.Pass(), source_frame_id, receiver, receiver_port_id, |
| 344 source_extension_id, target_extension_id, source_url, channel_name, | 355 source_extension_id, target_extension_id, source_url, channel_name, |
| 345 include_tls_channel_id); | 356 include_tls_channel_id); |
| 346 | 357 |
| 347 // If the target requests the TLS channel id, begin the lookup for it. | 358 // If the target requests the TLS channel id, begin the lookup for it. |
| 348 // The target might also be a lazy background page, checked next, but the | 359 // The target might also be a lazy background page, checked next, but the |
| 349 // loading of lazy background pages continues asynchronously, so enqueue | 360 // loading of lazy background pages continues asynchronously, so enqueue |
| 350 // messages awaiting TLS channel ID first. | 361 // messages awaiting TLS channel ID first. |
| 351 if (include_tls_channel_id) { | 362 if (include_tls_channel_id) { |
| 352 pending_tls_channel_id_channels_[GET_CHANNEL_ID(params->receiver_port_id)] | 363 pending_tls_channel_id_channels_[GET_CHANNEL_ID(params->receiver_port_id)] |
| 353 = PendingMessagesQueue(); | 364 = PendingMessagesQueue(); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 456 content::RenderProcessHost* source = | 467 content::RenderProcessHost* source = |
| 457 content::RenderProcessHost::FromID(source_process_id); | 468 content::RenderProcessHost::FromID(source_process_id); |
| 458 if (!source) | 469 if (!source) |
| 459 return; | 470 return; |
| 460 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext()); | 471 Profile* profile = Profile::FromBrowserContext(source->GetBrowserContext()); |
| 461 | 472 |
| 462 WebContents* contents = NULL; | 473 WebContents* contents = NULL; |
| 463 scoped_ptr<MessagePort> receiver; | 474 scoped_ptr<MessagePort> receiver; |
| 464 if (ExtensionTabUtil::GetTabById(tab_id, profile, true, | 475 if (ExtensionTabUtil::GetTabById(tab_id, profile, true, |
| 465 NULL, NULL, &contents, NULL)) { | 476 NULL, NULL, &contents, NULL)) { |
| 477 // TODO(robwu): Update logic so that frames that are not hosted in the main | |
| 478 // frame's process can also receive the port. | |
| 466 receiver.reset(new ExtensionMessagePort( | 479 receiver.reset(new ExtensionMessagePort( |
| 467 contents->GetRenderProcessHost(), | 480 contents->GetRenderProcessHost(), |
| 468 contents->GetRenderViewHost()->GetRoutingID(), | 481 contents->GetMainFrame()->GetRoutingID(), |
| 469 extension_id)); | 482 extension_id)); |
| 470 } | 483 } |
| 471 | 484 |
| 472 if (contents && contents->GetController().NeedsReload()) { | 485 if (contents && contents->GetController().NeedsReload()) { |
| 473 // The tab isn't loaded yet. Don't attempt to connect. | 486 // The tab isn't loaded yet. Don't attempt to connect. |
| 474 DispatchOnDisconnect( | 487 DispatchOnDisconnect( |
| 475 source, receiver_port_id, kReceivingEndDoesntExistError); | 488 source, receiver_port_id, kReceivingEndDoesntExistError); |
| 476 return; | 489 return; |
| 477 } | 490 } |
| 478 | 491 |
| 479 scoped_ptr<OpenChannelParams> params(new OpenChannelParams( | 492 scoped_ptr<OpenChannelParams> params(new OpenChannelParams( |
| 480 source, | 493 source, |
| 481 scoped_ptr<base::DictionaryValue>(), // Source tab doesn't make sense | 494 scoped_ptr<base::DictionaryValue>(), // Source tab doesn't make sense |
| 482 // for opening to tabs. | 495 // for opening to tabs. |
| 496 -1, // If there is no tab, then there is no frame either. | |
| 483 receiver.release(), | 497 receiver.release(), |
| 484 receiver_port_id, | 498 receiver_port_id, |
| 485 extension_id, | 499 extension_id, |
| 486 extension_id, | 500 extension_id, |
| 487 GURL(), // Source URL doesn't make sense for opening to tabs. | 501 GURL(), // Source URL doesn't make sense for opening to tabs. |
| 488 channel_name, | 502 channel_name, |
| 489 false)); // Connections to tabs don't get TLS channel IDs. | 503 false)); // Connections to tabs don't get TLS channel IDs. |
| 490 OpenChannelImpl(params.Pass()); | 504 OpenChannelImpl(params.Pass()); |
| 491 } | 505 } |
| 492 | 506 |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 514 CHECK(channel->receiver->GetRenderProcessHost()); | 528 CHECK(channel->receiver->GetRenderProcessHost()); |
| 515 | 529 |
| 516 AddChannel(channel, params->receiver_port_id); | 530 AddChannel(channel, params->receiver_port_id); |
| 517 | 531 |
| 518 CHECK(channel->receiver->GetRenderProcessHost()); | 532 CHECK(channel->receiver->GetRenderProcessHost()); |
| 519 | 533 |
| 520 // Send the connect event to the receiver. Give it the opener's port ID (the | 534 // Send the connect event to the receiver. Give it the opener's port ID (the |
| 521 // opener has the opposite port ID). | 535 // opener has the opposite port ID). |
| 522 channel->receiver->DispatchOnConnect(params->receiver_port_id, | 536 channel->receiver->DispatchOnConnect(params->receiver_port_id, |
| 523 params->channel_name, | 537 params->channel_name, |
| 524 params->source_tab, | 538 params->source_tab.Pass(), |
| 539 params->source_frame_id, | |
| 525 params->source_extension_id, | 540 params->source_extension_id, |
| 526 params->target_extension_id, | 541 params->target_extension_id, |
| 527 params->source_url, | 542 params->source_url, |
| 528 params->tls_channel_id); | 543 params->tls_channel_id); |
| 529 | 544 |
| 530 // Keep both ends of the channel alive until the channel is closed. | 545 // Keep both ends of the channel alive until the channel is closed. |
| 531 channel->opener->IncrementLazyKeepaliveCount(); | 546 channel->opener->IncrementLazyKeepaliveCount(); |
| 532 channel->receiver->IncrementLazyKeepaliveCount(); | 547 channel->receiver->IncrementLazyKeepaliveCount(); |
| 533 return true; | 548 return true; |
| 534 } | 549 } |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 783 } | 798 } |
| 784 | 799 |
| 785 void MessageService::DispatchOnDisconnect(content::RenderProcessHost* source, | 800 void MessageService::DispatchOnDisconnect(content::RenderProcessHost* source, |
| 786 int port_id, | 801 int port_id, |
| 787 const std::string& error_message) { | 802 const std::string& error_message) { |
| 788 ExtensionMessagePort port(source, MSG_ROUTING_CONTROL, ""); | 803 ExtensionMessagePort port(source, MSG_ROUTING_CONTROL, ""); |
| 789 port.DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(port_id), error_message); | 804 port.DispatchOnDisconnect(GET_OPPOSITE_PORT_ID(port_id), error_message); |
| 790 } | 805 } |
| 791 | 806 |
| 792 } // namespace extensions | 807 } // namespace extensions |
| OLD | NEW |