diff options
11 files changed, 69 insertions, 30 deletions
diff --git a/chrome/browser/debugger/extension_ports_remote_service.cc b/chrome/browser/debugger/extension_ports_remote_service.cc index 3c0275d..cf46fb8 100644 --- a/chrome/browser/debugger/extension_ports_remote_service.cc +++ b/chrome/browser/debugger/extension_ports_remote_service.cc @@ -226,6 +226,7 @@ bool ExtensionPortsRemoteService::Send(IPC::Message *message) { IPC_BEGIN_MESSAGE_MAP(ExtensionPortsRemoteService, *message) IPC_MESSAGE_HANDLER(ExtensionMsg_MessageInvoke, OnExtensionMessageInvoke) + IPC_MESSAGE_HANDLER(ExtensionMsg_DeliverMessage, OnDeliverMessage) IPC_MESSAGE_UNHANDLED_ERROR() IPC_END_MESSAGE_MAP() @@ -238,13 +239,7 @@ void ExtensionPortsRemoteService::OnExtensionMessageInvoke( const std::string& function_name, const ListValue& args, const GURL& event_url) { - if (function_name == ExtensionMessageService::kDispatchOnMessage) { - DCHECK_EQ(args.GetSize(), 2u); - std::string message; - int port_id; - if (args.GetString(0, &message) && args.GetInteger(1, &port_id)) - OnExtensionMessage(message, port_id); - } else if (function_name == ExtensionMessageService::kDispatchOnDisconnect) { + if (function_name == ExtensionMessageService::kDispatchOnDisconnect) { DCHECK_EQ(args.GetSize(), 1u); int port_id; if (args.GetInteger(0, &port_id)) @@ -258,8 +253,8 @@ void ExtensionPortsRemoteService::OnExtensionMessageInvoke( } } -void ExtensionPortsRemoteService::OnExtensionMessage( - const std::string& message, int port_id) { +void ExtensionPortsRemoteService::OnDeliverMessage( + int port_id, const std::string& message) { VLOG(1) << "Message event: from port " << port_id << ", < " << message << ">"; // Transpose the information into a JSON message for the external client. DictionaryValue content; diff --git a/chrome/browser/debugger/extension_ports_remote_service.h b/chrome/browser/debugger/extension_ports_remote_service.h index 0a5eea6..401f560 100644 --- a/chrome/browser/debugger/extension_ports_remote_service.h +++ b/chrome/browser/debugger/extension_ports_remote_service.h @@ -77,14 +77,15 @@ class ExtensionPortsRemoteService : public DevToolsRemoteListener, const std::string& tool, const std::string& destination); - // Handles a message from the ExtensionMessageService. + // Handles requests from ExtensionMessageService to invoke specific + // JavaScript functions. Currently we only handle the "disconnect" function. void OnExtensionMessageInvoke(const std::string& extension_id, const std::string& function_name, const base::ListValue& args, const GURL& event_url); // Handles a message sent from an extension through the // ExtensionMessageService, to be passed to the external client. - void OnExtensionMessage(const std::string& message, int port_id); + void OnDeliverMessage(int port_id, const std::string& message); // Handles a disconnect event sent from the ExtensionMessageService. void OnExtensionPortDisconnected(int port_id); diff --git a/chrome/browser/extensions/extension_message_service.cc b/chrome/browser/extensions/extension_message_service.cc index 57df12a..1fe3455 100644 --- a/chrome/browser/extensions/extension_message_service.cc +++ b/chrome/browser/extensions/extension_message_service.cc @@ -50,8 +50,6 @@ const char ExtensionMessageService::kDispatchOnConnect[] = "Port.dispatchOnConnect"; const char ExtensionMessageService::kDispatchOnDisconnect[] = "Port.dispatchOnDisconnect"; -const char ExtensionMessageService::kDispatchOnMessage[] = - "Port.dispatchOnMessage"; namespace { @@ -88,12 +86,10 @@ static void DispatchOnDisconnect( } static void DispatchOnMessage(const ExtensionMessageService::MessagePort& port, - const std::string& message, int source_port_id) { - ListValue args; - args.Set(0, Value::CreateStringValue(message)); - args.Set(1, Value::CreateIntegerValue(source_port_id)); - port.sender->Send(new ExtensionMsg_MessageInvoke(port.routing_id, - "", ExtensionMessageService::kDispatchOnMessage, args, GURL())); + const std::string& message, int target_port_id) { + port.sender->Send( + new ExtensionMsg_DeliverMessage( + port.routing_id, target_port_id, message)); } } // namespace diff --git a/chrome/browser/extensions/extension_message_service.h b/chrome/browser/extensions/extension_message_service.h index cfcd7fe..380e3a9 100644 --- a/chrome/browser/extensions/extension_message_service.h +++ b/chrome/browser/extensions/extension_message_service.h @@ -56,7 +56,6 @@ class ExtensionMessageService // Javascript function name constants. static const char kDispatchOnConnect[]; static const char kDispatchOnDisconnect[]; - static const char kDispatchOnMessage[]; // Allocates a pair of port ids. // NOTE: this can be called from any thread. diff --git a/chrome/browser/extensions/extension_messages_browsertest.cc b/chrome/browser/extensions/extension_messages_browsertest.cc index ace9c0c..56be33c 100644 --- a/chrome/browser/extensions/extension_messages_browsertest.cc +++ b/chrome/browser/extensions/extension_messages_browsertest.cc @@ -8,6 +8,7 @@ #include "chrome/common/extensions/extension_messages.h" #include "chrome/common/render_messages.h" #include "chrome/renderer/extensions/event_bindings.h" +#include "chrome/renderer/extensions/renderer_extension_bindings.h" #include "chrome/test/base/render_view_test.h" #include "content/common/view_messages.h" #include "testing/gtest/include/gtest/gtest.h" @@ -34,14 +35,6 @@ static void DispatchOnDisconnect(int source_port_id) { "", ExtensionMessageService::kDispatchOnDisconnect, args, NULL, GURL()); } -static void DispatchOnMessage(const std::string& message, int source_port_id) { - ListValue args; - args.Set(0, Value::CreateStringValue(message)); - args.Set(1, Value::CreateIntegerValue(source_port_id)); - EventBindings::CallFunction( - "", ExtensionMessageService::kDispatchOnMessage, args, NULL, GURL()); -} - // Tests that the bindings for opening a channel to an extension and sending // and receiving messages through that channel all works. TEST_F(RenderViewTest, ExtensionMessagesOpenChannel) { @@ -76,7 +69,7 @@ TEST_F(RenderViewTest, ExtensionMessagesOpenChannel) { // Now simulate getting a message back from the other side. render_thread_.sink().ClearMessages(); const int kPortId = 0; - DispatchOnMessage("{\"val\": 42}", kPortId); + RendererExtensionBindings::DeliverMessage(kPortId, "{\"val\": 42}"); // Verify that we got it. const IPC::Message* alert_msg = @@ -128,7 +121,7 @@ TEST_F(RenderViewTest, ExtensionMessagesOnConnect) { // Now simulate getting a message back from the channel opener. render_thread_.sink().ClearMessages(); - DispatchOnMessage("{\"val\": 42}", kPortId); + RendererExtensionBindings::DeliverMessage(kPortId, "{\"val\": 42}"); // Verify that we got it. const IPC::Message* alert_msg = diff --git a/chrome/common/extensions/extension_messages.h b/chrome/common/extensions/extension_messages.h index 32dbd91..ee69e1a 100644 --- a/chrome/common/extensions/extension_messages.h +++ b/chrome/common/extensions/extension_messages.h @@ -325,3 +325,8 @@ IPC_MESSAGE_ROUTED3(ExtensionMsg_InlineWebstoreInstallResponse, int32 /* install id */, bool /* whether the install was successful */, std::string /* error */) + +// Deliver a message sent with ExtensionHostMsg_PostMessage. +IPC_MESSAGE_ROUTED2(ExtensionMsg_DeliverMessage, + int /* target_port_id */, + std::string /* message */) diff --git a/chrome/renderer/extensions/extension_dispatcher.cc b/chrome/renderer/extensions/extension_dispatcher.cc index 85c4e70..3133925 100644 --- a/chrome/renderer/extensions/extension_dispatcher.cc +++ b/chrome/renderer/extensions/extension_dispatcher.cc @@ -60,6 +60,7 @@ bool ExtensionDispatcher::OnControlMessageReceived( bool handled = true; IPC_BEGIN_MESSAGE_MAP(ExtensionDispatcher, message) IPC_MESSAGE_HANDLER(ExtensionMsg_MessageInvoke, OnMessageInvoke) + IPC_MESSAGE_HANDLER(ExtensionMsg_DeliverMessage, OnDeliverMessage) IPC_MESSAGE_HANDLER(ExtensionMsg_SetFunctionNames, OnSetFunctionNames) IPC_MESSAGE_HANDLER(ExtensionMsg_Loaded, OnLoaded) IPC_MESSAGE_HANDLER(ExtensionMsg_Unloaded, OnUnloaded) @@ -146,6 +147,11 @@ void ExtensionDispatcher::OnMessageInvoke(const std::string& extension_id, } } +void ExtensionDispatcher::OnDeliverMessage(int target_port_id, + const std::string& message) { + RendererExtensionBindings::DeliverMessage(target_port_id, message); +} + void ExtensionDispatcher::OnLoaded(const ExtensionMsg_Loaded_Params& params) { scoped_refptr<const Extension> extension(params.ConvertToExtension()); if (!extension) { diff --git a/chrome/renderer/extensions/extension_dispatcher.h b/chrome/renderer/extensions/extension_dispatcher.h index 84a62cd..b50b012 100644 --- a/chrome/renderer/extensions/extension_dispatcher.h +++ b/chrome/renderer/extensions/extension_dispatcher.h @@ -69,6 +69,7 @@ class ExtensionDispatcher : public RenderProcessObserver { const std::string& function_name, const base::ListValue& args, const GURL& event_url); + void OnDeliverMessage(int target_port_id, const std::string& message); void OnSetFunctionNames(const std::vector<std::string>& names); void OnLoaded(const ExtensionMsg_Loaded_Params& params); void OnUnloaded(const std::string& id); diff --git a/chrome/renderer/extensions/renderer_extension_bindings.cc b/chrome/renderer/extensions/renderer_extension_bindings.cc index ec8619c..e772e0b 100644 --- a/chrome/renderer/extensions/renderer_extension_bindings.cc +++ b/chrome/renderer/extensions/renderer_extension_bindings.cc @@ -253,3 +253,34 @@ v8::Extension* RendererExtensionBindings::Get(ExtensionDispatcher* dispatcher) { static v8::Extension* extension = new ExtensionImpl(dispatcher); return extension; } + +void RendererExtensionBindings::DeliverMessage(int target_port_id, + const std::string& message) { + v8::HandleScope handle_scope; + + bindings_utils::ContextList contexts = bindings_utils::GetContexts(); + for (bindings_utils::ContextList::iterator it = contexts.begin(); + it != contexts.end(); ++it) { + + v8::Handle<v8::Context> context = (*it)->context; + if (context.IsEmpty()) + continue; + + // Check to see whether the context has this port before bothering to create + // the message. + v8::Handle<v8::Value> port_id_handle = v8::Integer::New(target_port_id); + v8::Handle<v8::Value> has_port = + bindings_utils::CallFunctionInContext( + context, "Port.hasPort", 1, &port_id_handle); + CHECK(!has_port.IsEmpty()); + if (!has_port->BooleanValue()) + continue; + + std::vector<v8::Handle<v8::Value> > arguments; + arguments.push_back(v8::String::New(message.c_str(), message.size())); + arguments.push_back(port_id_handle); + bindings_utils::CallFunctionInContext( + context, "Port.dispatchOnMessage", + arguments.size(), &arguments[0]); + } +} diff --git a/chrome/renderer/extensions/renderer_extension_bindings.h b/chrome/renderer/extensions/renderer_extension_bindings.h index 29df94a..c98a0ae 100644 --- a/chrome/renderer/extensions/renderer_extension_bindings.h +++ b/chrome/renderer/extensions/renderer_extension_bindings.h @@ -6,6 +6,8 @@ #define CHROME_RENDERER_EXTENSIONS_RENDERER_EXTENSION_BINDINGS_H_ #pragma once +#include <string> + class ExtensionDispatcher; namespace v8 { @@ -21,6 +23,9 @@ class RendererExtensionBindings { // Creates an instance of the extension. static v8::Extension* Get(ExtensionDispatcher* dispatcher); + + // Delivers a message sent using content script messaging. + static void DeliverMessage(int target_port_id, const std::string& message); }; #endif // CHROME_RENDERER_EXTENSIONS_RENDERER_EXTENSION_BINDINGS_H_ diff --git a/chrome/renderer/resources/renderer_extension_bindings.js b/chrome/renderer/resources/renderer_extension_bindings.js index 0c7ef88..52327c3 100644 --- a/chrome/renderer/resources/renderer_extension_bindings.js +++ b/chrome/renderer/resources/renderer_extension_bindings.js @@ -46,6 +46,13 @@ var chrome = chrome || {}; chromeHidden.Port = {}; + // Returns true if the specified port id is in this context. This is used by + // the C++ to avoid creating the javascript message for all the contexts that + // don't care about a particular message. + chromeHidden.Port.hasPort = function(portId) { + return portId in ports; + }; + // Hidden port creation function. We don't want to expose an API that lets // people add arbitrary port IDs to the port list. chromeHidden.Port.createPort = function(portId, opt_name) { |