summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authormpcomplete@google.com <mpcomplete@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-17 19:32:43 +0000
committermpcomplete@google.com <mpcomplete@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-17 19:32:43 +0000
commitdfcb62a173898e182e2f10ca635deb753977b9f8 (patch)
tree39d4ca8b82cfc9f39f1726d4b0ad061cb141c516 /chrome
parent851c567a756e96913098ac03d84fb9ea5761558d (diff)
downloadchromium_src-dfcb62a173898e182e2f10ca635deb753977b9f8.zip
chromium_src-dfcb62a173898e182e2f10ca635deb753977b9f8.tar.gz
chromium_src-dfcb62a173898e182e2f10ca635deb753977b9f8.tar.bz2
Add a port disconnect event for when one side of an extension message port
goes away. Combine the various ExtensionMessageService IPC message into a single "Invoke" message. BUG=12686 TEST=no Review URL: http://codereview.chromium.org/126234 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18645 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/automation/extension_port_container.cc21
-rw-r--r--chrome/browser/automation/extension_port_container.h4
-rw-r--r--chrome/browser/extensions/extension_message_service.cc75
-rw-r--r--chrome/browser/extensions/extension_message_service.h6
-rw-r--r--chrome/browser/extensions/extension_messages_unittest.cc53
-rw-r--r--chrome/common/render_messages_internal.h22
-rw-r--r--chrome/renderer/extensions/renderer_extension_bindings.cc78
-rw-r--r--chrome/renderer/extensions/renderer_extension_bindings.h16
-rw-r--r--chrome/renderer/render_thread.cc24
-rw-r--r--chrome/renderer/render_thread.h7
-rw-r--r--chrome/renderer/renderer_resources.grd2
-rw-r--r--chrome/renderer/resources/renderer_extension_bindings.js17
12 files changed, 222 insertions, 103 deletions
diff --git a/chrome/browser/automation/extension_port_container.cc b/chrome/browser/automation/extension_port_container.cc
index a0846e5..7fd04dd 100644
--- a/chrome/browser/automation/extension_port_container.cc
+++ b/chrome/browser/automation/extension_port_container.cc
@@ -7,6 +7,7 @@
#include "base/logging.h"
#include "base/json_reader.h"
#include "base/json_writer.h"
+#include "base/values.h"
#include "chrome/common/render_messages.h"
#include "chrome/browser/automation/automation_provider.h"
#include "chrome/browser/automation/extension_automation_constants.h"
@@ -91,8 +92,8 @@ bool ExtensionPortContainer::Send(IPC::Message *message) {
DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI);
IPC_BEGIN_MESSAGE_MAP(ExtensionPortContainer, *message)
- IPC_MESSAGE_HANDLER(ViewMsg_ExtensionHandleMessage,
- OnExtensionHandleMessage)
+ IPC_MESSAGE_HANDLER(ViewMsg_ExtensionMessageInvoke,
+ OnExtensionMessageInvoke)
IPC_MESSAGE_UNHANDLED_ERROR()
IPC_END_MESSAGE_MAP()
@@ -100,6 +101,22 @@ bool ExtensionPortContainer::Send(IPC::Message *message) {
return true;
}
+void ExtensionPortContainer::OnExtensionMessageInvoke(
+ const std::string& function_name, const ListValue& args) {
+ if (function_name == ExtensionMessageService::kDispatchOnMessage) {
+ DCHECK_EQ(args.GetSize(), 2);
+
+ std::string message;
+ int source_port_id;
+ if (args.GetString(0, &message) && args.GetInteger(1, &source_port_id))
+ OnExtensionHandleMessage(message, source_port_id);
+ } else if (function_name == ExtensionMessageService::kDispatchOnDisconnect) {
+ // do nothing
+ } else {
+ NOTREACHED() << function_name << " shouldn't be called.";
+ }
+}
+
void ExtensionPortContainer::OnExtensionHandleMessage(
const std::string& message, int source_port_id) {
// Compose the reply message and fire it away.
diff --git a/chrome/browser/automation/extension_port_container.h b/chrome/browser/automation/extension_port_container.h
index 2758a9d..d9244b0 100644
--- a/chrome/browser/automation/extension_port_container.h
+++ b/chrome/browser/automation/extension_port_container.h
@@ -12,6 +12,7 @@
class AutomationProvider;
class ExtensionMessageService;
+class ListValue;
class MessageLoop;
class RenderViewHost;
@@ -56,6 +57,9 @@ class ExtensionPortContainer : public IPC::Message::Sender {
int connection_id);
// Sends a response to the
void SendConnectionResponse(int connection_id, int port_id);
+
+ void OnExtensionMessageInvoke(const std::string& function_name,
+ const ListValue& args);
void OnExtensionHandleMessage(const std::string& message, int source_port_id);
// Our automation provider.
diff --git a/chrome/browser/extensions/extension_message_service.cc b/chrome/browser/extensions/extension_message_service.cc
index 39570a1..33fbcf2 100644
--- a/chrome/browser/extensions/extension_message_service.cc
+++ b/chrome/browser/extensions/extension_message_service.cc
@@ -24,6 +24,8 @@
// Since we have 2 ports for every channel, we just index channels by half the
// port ID.
#define GET_CHANNEL_ID(port_id) ((port_id) / 2)
+#define GET_CHANNEL_PORT1(channel_id) ((channel_id) * 2)
+#define GET_CHANNEL_PORT2(channel_id) ((channel_id) * 2 + 1)
// Port1 is always even, port2 is always odd.
#define IS_PORT1_ID(port_id) (((port_id) & 1) == 0)
@@ -40,6 +42,43 @@ struct SingletonData {
Lock lock;
InstanceMap map;
};
+
+static void DispatchOnConnect(IPC::Message::Sender* channel, int source_port_id,
+ const std::string& tab_json) {
+ ListValue args;
+ args.Set(0, Value::CreateIntegerValue(source_port_id));
+ args.Set(1, Value::CreateStringValue(tab_json));
+ channel->Send(new ViewMsg_ExtensionMessageInvoke(
+ ExtensionMessageService::kDispatchOnConnect, args));
+}
+
+static void DispatchOnDisconnect(IPC::Message::Sender* channel,
+ int source_port_id) {
+ ListValue args;
+ args.Set(0, Value::CreateIntegerValue(source_port_id));
+ channel->Send(new ViewMsg_ExtensionMessageInvoke(
+ ExtensionMessageService::kDispatchOnDisconnect, args));
+}
+
+static void DispatchOnMessage(IPC::Message::Sender* channel,
+ const std::string& message, int source_port_id) {
+ ListValue args;
+ args.Set(0, Value::CreateStringValue(message));
+ args.Set(1, Value::CreateIntegerValue(source_port_id));
+ channel->Send(new ViewMsg_ExtensionMessageInvoke(
+ ExtensionMessageService::kDispatchOnMessage, args));
+}
+
+static void DispatchEvent(IPC::Message::Sender* channel,
+ const std::string& event_name,
+ const std::string& event_args) {
+ ListValue args;
+ args.Set(0, Value::CreateStringValue(event_name));
+ args.Set(1, Value::CreateStringValue(event_args));
+ channel->Send(new ViewMsg_ExtensionMessageInvoke(
+ ExtensionMessageService::kDispatchEvent, args));
+}
+
} // namespace
// Since ExtensionMessageService is a collection of Singletons, we don't need to
@@ -49,6 +88,16 @@ template <> struct RunnableMethodTraits<ExtensionMessageService> {
static void ReleaseCallee(ExtensionMessageService*) {}
};
+
+const char ExtensionMessageService::kDispatchOnConnect[] =
+ "chrome.Port.dispatchOnConnect_";
+const char ExtensionMessageService::kDispatchOnDisconnect[] =
+ "chrome.Port.dispatchOnDisconnect_";
+const char ExtensionMessageService::kDispatchOnMessage[] =
+ "chrome.Port.dispatchOnMessage_";
+const char ExtensionMessageService::kDispatchEvent[] =
+ "chrome.Event.dispatchJSON_";
+
// static
ExtensionMessageService* ExtensionMessageService::GetInstance(
URLRequestContext* context) {
@@ -121,6 +170,10 @@ void ExtensionMessageService::AllocatePortIdPair(int* port1, int* port2) {
DCHECK(GET_OPPOSITE_PORT_ID(port2_id) == port1_id);
DCHECK(GET_CHANNEL_ID(port1_id) == GET_CHANNEL_ID(port2_id));
+ int channel_id = GET_CHANNEL_ID(port1_id);
+ DCHECK(GET_CHANNEL_PORT1(channel_id) == port1_id);
+ DCHECK(GET_CHANNEL_PORT2(channel_id) == port2_id);
+
*port1 = port1_id;
*port2 = port2_id;
}
@@ -206,9 +259,8 @@ void ExtensionMessageService::OpenChannelOnUIThreadImpl(
JSONWriter::Write(tab_value, false, &tab_json);
}
- // Send each process the id for the opposite port.
- channel.port2->Send(new ViewMsg_ExtensionHandleConnect(source_port_id,
- tab_json));
+ // Send the process the id for the opposite port.
+ DispatchOnConnect(channel.port2, source_port_id, tab_json);
}
int ExtensionMessageService::OpenAutomationChannelToExtension(
@@ -263,7 +315,7 @@ void ExtensionMessageService::PostMessageFromRenderer(
IS_PORT1_ID(port_id) ? channel.port1 : channel.port2;
int source_port_id = GET_OPPOSITE_PORT_ID(port_id);
- dest->Send(new ViewMsg_ExtensionHandleMessage(message, source_port_id));
+ DispatchOnMessage(dest, message, source_port_id);
}
void ExtensionMessageService::DispatchEventToRenderers(
@@ -283,7 +335,7 @@ void ExtensionMessageService::DispatchEventToRenderers(
continue;
}
- renderer->Send(new ViewMsg_ExtensionHandleEvent(event_name, event_args));
+ DispatchEvent(renderer, event_name, event_args);
}
}
@@ -308,12 +360,19 @@ void ExtensionMessageService::Observe(NotificationType type,
}
}
- // Close any channels that share this renderer.
- // TODO(mpcomplete): should we notify the other side of the port?
+ // Close any channels that share this renderer. We notify the opposite
+ // port that his pair has closed.
for (MessageChannelMap::iterator it = channels_.begin();
it != channels_.end(); ) {
MessageChannelMap::iterator current = it++;
- if (current->second.port1 == renderer || current->second.port2 == renderer)
+ if (current->second.port1 == renderer) {
+ DispatchOnDisconnect(current->second.port2,
+ GET_CHANNEL_PORT1(current->first));
+ channels_.erase(current);
+ } else if (current->second.port2 == renderer) {
+ DispatchOnDisconnect(current->second.port1,
+ GET_CHANNEL_PORT2(current->first));
channels_.erase(current);
+ }
}
}
diff --git a/chrome/browser/extensions/extension_message_service.h b/chrome/browser/extensions/extension_message_service.h
index 2a0a2bc..dde7280 100644
--- a/chrome/browser/extensions/extension_message_service.h
+++ b/chrome/browser/extensions/extension_message_service.h
@@ -29,6 +29,12 @@ class URLRequestContext;
// messages on the IO thread.
class ExtensionMessageService : public NotificationObserver {
public:
+ // Javascript function name constants.
+ static const char kDispatchOnConnect[];
+ static const char kDispatchOnDisconnect[];
+ static const char kDispatchOnMessage[];
+ static const char kDispatchEvent[];
+
// Returns the message service for the given context. Messages can only
// be sent within a single context.
static ExtensionMessageService* GetInstance(URLRequestContext* context);
diff --git a/chrome/browser/extensions/extension_messages_unittest.cc b/chrome/browser/extensions/extension_messages_unittest.cc
index c3e92ce..45de6c7 100644
--- a/chrome/browser/extensions/extension_messages_unittest.cc
+++ b/chrome/browser/extensions/extension_messages_unittest.cc
@@ -2,12 +2,36 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "chrome/browser/extensions/extension_message_service.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/render_view_test.h"
#include "testing/gtest/include/gtest/gtest.h"
+static void DispatchOnConnect(int source_port_id, const std::string& tab_json) {
+ ListValue args;
+ args.Set(0, Value::CreateIntegerValue(source_port_id));
+ args.Set(1, Value::CreateStringValue(tab_json));
+ RendererExtensionBindings::Invoke(
+ ExtensionMessageService::kDispatchOnConnect, args);
+}
+
+static void DispatchOnDisconnect(int source_port_id) {
+ ListValue args;
+ args.Set(0, Value::CreateIntegerValue(source_port_id));
+ RendererExtensionBindings::Invoke(
+ ExtensionMessageService::kDispatchOnDisconnect, args);
+}
+
+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));
+ RendererExtensionBindings::Invoke(
+ ExtensionMessageService::kDispatchOnMessage, args);
+}
+
// Tests that the bindings for opening a channel to an extension and sending
// and receiving messages through that channel all works.
TEST_F(RenderViewTest, DISABLED_ExtensionMessagesOpenChannel) {
@@ -39,7 +63,7 @@ TEST_F(RenderViewTest, DISABLED_ExtensionMessagesOpenChannel) {
// Now simulate getting a message back from the other side.
render_thread_.sink().ClearMessages();
const int kPortId = 0;
- RendererExtensionBindings::HandleMessage("{\"val\": 42}", kPortId);
+ DispatchOnMessage("{\"val\": 42}", kPortId);
// Verify that we got it.
const IPC::Message* alert_msg =
@@ -52,25 +76,29 @@ TEST_F(RenderViewTest, DISABLED_ExtensionMessagesOpenChannel) {
EXPECT_EQ(L"content got: 42", alert_param.a);
}
-// Tests that the bindings for handling a new channel connection and sending
-// and receiving messages through that channel all works.
+// Tests that the bindings for handling a new channel connection and channel
+// closing all works.
TEST_F(RenderViewTest, DISABLED_ExtensionMessagesOnConnect) {
LoadHTML("<body></body>");
ExecuteJavaScript(
"chrome.self.onConnect.addListener(function (port) {"
+ " port.test = 24;"
" port.onMessage.addListener(doOnMessage);"
+ " port.onDisconnect.addListener(doOnDisconnect);"
" port.postMessage({message: 'onconnect from ' + port.tab.url});"
"});"
"function doOnMessage(msg, port) {"
" alert('got: ' + msg.val);"
+ "}"
+ "function doOnDisconnect(port) {"
+ " alert('disconnected: ' + port.test);"
"}");
render_thread_.sink().ClearMessages();
// Simulate a new connection being opened.
const int kPortId = 0;
- RendererExtensionBindings::HandleConnect(kPortId,
- "{\"url\":\"foo://bar\"}");
+ DispatchOnConnect(kPortId, "{\"url\":\"foo://bar\"}");
// Verify that we handled the new connection by posting a message.
const IPC::Message* post_msg =
@@ -83,7 +111,7 @@ TEST_F(RenderViewTest, DISABLED_ExtensionMessagesOnConnect) {
// Now simulate getting a message back from the channel opener.
render_thread_.sink().ClearMessages();
- RendererExtensionBindings::HandleMessage("{\"val\": 42}", kPortId);
+ DispatchOnMessage("{\"val\": 42}", kPortId);
// Verify that we got it.
const IPC::Message* alert_msg =
@@ -94,4 +122,17 @@ TEST_F(RenderViewTest, DISABLED_ExtensionMessagesOnConnect) {
ViewHostMsg_RunJavaScriptMessage::SendParam alert_param;
ASSERT_TRUE(IPC::ReadParam(alert_msg, &iter, &alert_param));
EXPECT_EQ(L"got: 42", alert_param.a);
+
+ // Now simulate the channel closing.
+ render_thread_.sink().ClearMessages();
+ DispatchOnDisconnect(kPortId);
+
+ // Verify that we got it.
+ alert_msg =
+ render_thread_.sink().GetUniqueMessageMatching(
+ ViewHostMsg_RunJavaScriptMessage::ID);
+ ASSERT_TRUE(alert_msg);
+ iter = IPC::SyncMessage::GetDataIterator(alert_msg);
+ ASSERT_TRUE(IPC::ReadParam(alert_msg, &iter, &alert_param));
+ EXPECT_EQ(L"disconnected: 24", alert_param.a);
}
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index 7de2db7..594d553 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -545,23 +545,11 @@ IPC_BEGIN_MESSAGES(View)
std::string /* response */,
std::string /* error */)
- // Tell the extension process about a new channel that has been opened from a
- // renderer. source_port_id identifies the port that the extension can
- // respond to. tab_json is a JSON value for the tab that opened the
- // connection, if any.
- IPC_MESSAGE_CONTROL2(ViewMsg_ExtensionHandleConnect,
- int /* source_port_id */,
- std::string /* tab_json */)
-
- // Send a javascript message to a renderer from the given port.
- IPC_MESSAGE_CONTROL2(ViewMsg_ExtensionHandleMessage,
- std::string /* message */,
- int /* source_port_id */)
-
- // Route a browser event to all extension renderers within this process.
- IPC_MESSAGE_CONTROL2(ViewMsg_ExtensionHandleEvent,
- std::string /* event_name */,
- std::string /* event_data */)
+ // Call a javascript function in every registered context in this process.
+ // |args| is a list of primitive Value types that are passed to the function.
+ IPC_MESSAGE_CONTROL2(ViewMsg_ExtensionMessageInvoke,
+ std::string /* function_name */,
+ ListValue /* args */)
// Tell the renderer process all known extension function names.
IPC_MESSAGE_CONTROL1(ViewMsg_Extension_SetFunctionNames,
diff --git a/chrome/renderer/extensions/renderer_extension_bindings.cc b/chrome/renderer/extensions/renderer_extension_bindings.cc
index 86d3d15..0931c8c 100644
--- a/chrome/renderer/extensions/renderer_extension_bindings.cc
+++ b/chrome/renderer/extensions/renderer_extension_bindings.cc
@@ -6,6 +6,7 @@
#include "app/resource_bundle.h"
#include "base/basictypes.h"
+#include "base/values.h"
#include "chrome/common/render_messages.h"
#include "chrome/renderer/extensions/bindings_utils.h"
#include "chrome/renderer/extensions/event_bindings.h"
@@ -81,6 +82,51 @@ class ExtensionImpl : public v8::Extension {
}
};
+// Convert a ListValue to a vector of V8 values.
+static std::vector< v8::Handle<v8::Value> > ListValueToV8(
+ const ListValue& value) {
+ std::vector< v8::Handle<v8::Value> > v8_values;
+
+ for (size_t i = 0; i < value.GetSize(); ++i) {
+ Value* elem = NULL;
+ value.Get(i, &elem);
+ switch (elem->GetType()) {
+ case Value::TYPE_NULL:
+ v8_values.push_back(v8::Null());
+ break;
+ case Value::TYPE_BOOLEAN: {
+ bool val;
+ elem->GetAsBoolean(&val);
+ v8_values.push_back(v8::Boolean::New(val));
+ break;
+ }
+ case Value::TYPE_INTEGER: {
+ int val;
+ elem->GetAsInteger(&val);
+ v8_values.push_back(v8::Integer::New(val));
+ break;
+ }
+ case Value::TYPE_REAL: {
+ double val;
+ elem->GetAsReal(&val);
+ v8_values.push_back(v8::Number::New(val));
+ break;
+ }
+ case Value::TYPE_STRING: {
+ std::string val;
+ elem->GetAsString(&val);
+ v8_values.push_back(v8::String::New(val.c_str()));
+ break;
+ }
+ default:
+ NOTREACHED() << "Unsupported Value type.";
+ break;
+ }
+ }
+
+ return v8_values;
+}
+
} // namespace
const char* RendererExtensionBindings::kName =
@@ -90,33 +136,9 @@ v8::Extension* RendererExtensionBindings::Get() {
return new ExtensionImpl();
}
-void RendererExtensionBindings::HandleConnect(int port_id,
- const std::string& tab_json) {
- v8::HandleScope handle_scope;
- v8::Handle<v8::Value> argv[2];
- argv[0] = v8::Integer::New(port_id);
- argv[1] = v8::String::New(tab_json.c_str());
- EventBindings::CallFunction("chrome.Port.dispatchOnConnect_",
- arraysize(argv), argv);
-}
-
-void RendererExtensionBindings::HandleMessage(const std::string& message,
- int port_id) {
- v8::HandleScope handle_scope;
- v8::Handle<v8::Value> argv[2];
- argv[0] = v8::String::New(message.c_str());
- argv[1] = v8::Integer::New(port_id);
- EventBindings::CallFunction("chrome.Port.dispatchOnMessage_",
- arraysize(argv), argv);
-}
-
-void RendererExtensionBindings::HandleEvent(const std::string& event_name,
- const std::string& args) {
+void RendererExtensionBindings::Invoke(const std::string& function_name,
+ const ListValue& args) {
v8::HandleScope handle_scope;
- v8::Handle<v8::Value> argv[2];
- argv[0] = v8::String::New(event_name.c_str());
- argv[1] = v8::String::New(args.c_str());
-
- EventBindings::CallFunction("chrome.Event.dispatchJSON_",
- arraysize(argv), argv);
+ std::vector< v8::Handle<v8::Value> > argv = ListValueToV8(args);
+ EventBindings::CallFunction(function_name, argv.size(), &argv[0]);
}
diff --git a/chrome/renderer/extensions/renderer_extension_bindings.h b/chrome/renderer/extensions/renderer_extension_bindings.h
index ad370af..5196807 100644
--- a/chrome/renderer/extensions/renderer_extension_bindings.h
+++ b/chrome/renderer/extensions/renderer_extension_bindings.h
@@ -9,6 +9,7 @@
#include <string>
+class ListValue;
class RenderThreadBase;
// This class adds extension-related javascript bindings to a renderer. It is
@@ -21,19 +22,8 @@ class RendererExtensionBindings {
// Creates an instance of the extension.
static v8::Extension* Get();
- // Notify any listeners that a message channel has been opened to this
- // process. |tab_json| is the info for the tab that initiated this
- // connection, or "null" if the initiator was not a tab.
- static void HandleConnect(int port_id, const std::string& tab_json);
-
- // Dispatch the given message sent on this channel.
- static void HandleMessage(const std::string& message, int port_id);
-
- // Send this event to all extensions in this process. |args| is a JSON-
- // serialized array that will be deserialized and provided to the callback
- // function in event_bindings.js
- static void HandleEvent(const std::string& event_name,
- const std::string& args);
+ // Call the given javascript function with the specified arguments.
+ static void Invoke(const std::string& function_name, const ListValue& args);
};
#endif // CHROME_RENDERER_EXTENSIONS_RENDERER_EXTENSION_BINDINGS_H_
diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc
index e615a49..e4905982 100644
--- a/chrome/renderer/render_thread.cc
+++ b/chrome/renderer/render_thread.cc
@@ -226,12 +226,8 @@ void RenderThread::OnControlMessageReceived(const IPC::Message& msg) {
OnUpdateUserScripts)
// TODO(rafaelw): create an ExtensionDispatcher that handles extension
// messages seperates their handling from the RenderThread.
- IPC_MESSAGE_HANDLER(ViewMsg_ExtensionHandleConnect,
- OnExtensionHandleConnect)
- IPC_MESSAGE_HANDLER(ViewMsg_ExtensionHandleMessage,
- OnExtensionHandleMessage)
- IPC_MESSAGE_HANDLER(ViewMsg_ExtensionHandleEvent,
- OnExtensionHandleEvent)
+ IPC_MESSAGE_HANDLER(ViewMsg_ExtensionMessageInvoke,
+ OnExtensionMessageInvoke)
IPC_MESSAGE_HANDLER(ViewMsg_Extension_SetFunctionNames,
OnSetExtensionFunctionNames)
IPC_MESSAGE_HANDLER(ViewMsg_PurgePluginListCache,
@@ -382,19 +378,9 @@ void RenderThread::EnsureWebKitInitialized() {
WebKit::enableMediaPlayer();
}
-void RenderThread::OnExtensionHandleConnect(int port_id,
- const std::string& tab_json) {
- RendererExtensionBindings::HandleConnect(port_id, tab_json);
-}
-
-void RenderThread::OnExtensionHandleMessage(const std::string& message,
- int port_id) {
- RendererExtensionBindings::HandleMessage(message, port_id);
-}
-
-void RenderThread::OnExtensionHandleEvent(const std::string event_name,
- const std::string event_data) {
- RendererExtensionBindings::HandleEvent(event_name, event_data);
+void RenderThread::OnExtensionMessageInvoke(const std::string& function_name,
+ const ListValue& args) {
+ RendererExtensionBindings::Invoke(function_name, args);
}
void RenderThread::OnPurgePluginListCache() {
diff --git a/chrome/renderer/render_thread.h b/chrome/renderer/render_thread.h
index 56be75e..83475d9 100644
--- a/chrome/renderer/render_thread.h
+++ b/chrome/renderer/render_thread.h
@@ -18,6 +18,7 @@
class AppCacheDispatcher;
class DevToolsAgentFilter;
class FilePath;
+class ListValue;
class NotificationService;
class RenderDnsMaster;
class RendererHistogram;
@@ -135,10 +136,8 @@ class RenderThread : public RenderThreadBase,
// Send all histograms to browser.
void OnGetRendererHistograms(int sequence_number);
- void OnExtensionHandleConnect(int channel_id, const std::string& tab_json);
- void OnExtensionHandleMessage(const std::string& message, int channel_id);
- void OnExtensionHandleEvent(const std::string event_name,
- const std::string event_data);
+ void OnExtensionMessageInvoke(const std::string& function_name,
+ const ListValue& args);
void OnPurgePluginListCache();
// Gather usage statistics from the in-memory cache and inform our host.
diff --git a/chrome/renderer/renderer_resources.grd b/chrome/renderer/renderer_resources.grd
index cda253b..c59e98c 100644
--- a/chrome/renderer/renderer_resources.grd
+++ b/chrome/renderer/renderer_resources.grd
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- This comment is only here because changes to resources are not picked up
-without changes to the corresponding grd file. -->
+without changes to the corresponding grd file. -->
<grit latest_public_release="0" current_release="1">
<outputs>
<output filename="grit/renderer_resources.h" type="rc_header">
diff --git a/chrome/renderer/resources/renderer_extension_bindings.js b/chrome/renderer/resources/renderer_extension_bindings.js
index cc232b4..31b97ed 100644
--- a/chrome/renderer/resources/renderer_extension_bindings.js
+++ b/chrome/renderer/resources/renderer_extension_bindings.js
@@ -1,5 +1,5 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// -----------------------------------------------------------------------------
@@ -19,11 +19,9 @@ var chrome = chrome || {};
throw new Error("Port '" + portId + "' already exists.");
}
this.portId_ = portId; // TODO(mpcomplete): readonly
+ this.onDisconnect = new chrome.Event();
this.onMessage = new chrome.Event();
chrome.Port.ports_[portId] = this;
- // Note: this object will never get GCed. If we ever care, we could
- // add an "ondetach" method to the onMessage Event that gets called
- // when there are no more listeners.
};
// Map of port IDs to port object.
@@ -39,6 +37,15 @@ var chrome = chrome || {};
chrome.Event.dispatch_("channel-connect", [port]);
};
+ // Called by native code when a channel has been closed.
+ chrome.Port.dispatchOnDisconnect_ = function(portId) {
+ var port = chrome.Port.ports_[portId];
+ if (port) {
+ port.onDisconnect.dispatch(port);
+ delete chrome.Port.ports_[portId];
+ }
+ };
+
// Called by native code when a message has been sent to the given port.
chrome.Port.dispatchOnMessage_ = function(msg, portId) {
var port = chrome.Port.ports_[portId];