Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6998)

Unified Diff: chrome/renderer/extensions/miscellaneous_bindings.cc

Issue 16226004: Replace JSON (de)serialization of extension messages with direct Value pickling. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/renderer/extensions/miscellaneous_bindings.cc
diff --git a/chrome/renderer/extensions/miscellaneous_bindings.cc b/chrome/renderer/extensions/miscellaneous_bindings.cc
index 0f376539edbc371458034631877955dace21dc2f..b5c670999426a28f38d9457298c60cddb176b94b 100644
--- a/chrome/renderer/extensions/miscellaneous_bindings.cc
+++ b/chrome/renderer/extensions/miscellaneous_bindings.cc
@@ -95,43 +95,65 @@ class ExtensionImpl : public extensions::ChromeV8Extension {
if (!renderview)
return v8::Undefined();
- if (args.Length() >= 2 && args[0]->IsInt32() && args[1]->IsString()) {
- int port_id = args[0]->Int32Value();
- if (!HasPortData(port_id)) {
- return v8::ThrowException(v8::Exception::Error(
- v8::String::New(kPortClosedError)));
- }
- std::string message = *v8::String::Utf8Value(args[1]->ToString());
- renderview->Send(new ExtensionHostMsg_PostMessage(
- renderview->GetRoutingID(), port_id, message));
+ // Arguments are (int32 port_id, object message).
+ CHECK_EQ(2, args.Length());
+ CHECK(args[0]->IsInt32());
+
+ int port_id = args[0]->Int32Value();
+ if (!HasPortData(port_id)) {
+ return v8::ThrowException(v8::Exception::Error(
+ v8::String::New(kPortClosedError)));
}
+
+ // The message can be any base::Value but IPC can't serialize that, so we
+ // give it a singleton base::ListValue instead, or an empty list if the
+ // argument was undefined (v8 value converter will return NULL for this).
+ scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create());
+ scoped_ptr<base::Value> message(
+ converter->FromV8Value(args[1], context()->v8_context()));
+ ListValue message_as_list;
+ if (message)
+ message_as_list.Append(message.release());
+
+ renderview->Send(new ExtensionHostMsg_PostMessage(
+ renderview->GetRoutingID(), port_id, message_as_list));
+
return v8::Undefined();
}
// Forcefully disconnects a port.
v8::Handle<v8::Value> CloseChannel(const v8::Arguments& args) {
- if (args.Length() >= 2 && args[0]->IsInt32() && args[1]->IsBoolean()) {
- int port_id = args[0]->Int32Value();
- if (!HasPortData(port_id)) {
- return v8::Undefined();
- }
- // Send via the RenderThread because the RenderView might be closing.
- bool notify_browser = args[1]->BooleanValue();
- if (notify_browser)
- content::RenderThread::Get()->Send(
- new ExtensionHostMsg_CloseChannel(port_id, std::string()));
- ClearPortData(port_id);
+ // Arguments are (int32 port_id, boolean notify_browser).
+ CHECK_EQ(2, args.Length());
+ CHECK(args[0]->IsInt32());
+ CHECK(args[1]->IsBoolean());
+
+ int port_id = args[0]->Int32Value();
+ if (!HasPortData(port_id))
+ return v8::Undefined();
+
+ // Send via the RenderThread because the RenderView might be closing.
+ bool notify_browser = args[1]->BooleanValue();
+ if (notify_browser) {
+ content::RenderThread::Get()->Send(
+ new ExtensionHostMsg_CloseChannel(port_id, std::string()));
}
+
+ ClearPortData(port_id);
+
return v8::Undefined();
}
// A new port has been created for a context. This occurs both when script
// opens a connection, and when a connection is opened to this script.
v8::Handle<v8::Value> PortAddRef(const v8::Arguments& args) {
- if (args.Length() >= 1 && args[0]->IsInt32()) {
- int port_id = args[0]->Int32Value();
- ++GetPortData(port_id).ref_count;
- }
+ // Arguments are (int32 port_id).
+ CHECK_EQ(1, args.Length());
+ CHECK(args[0]->IsInt32());
+
+ int port_id = args[0]->Int32Value();
+ ++GetPortData(port_id).ref_count;
+
return v8::Undefined();
}
@@ -139,15 +161,18 @@ class ExtensionImpl : public extensions::ChromeV8Extension {
// frames with a reference to a given port, we will disconnect it and notify
// the other end of the channel.
v8::Handle<v8::Value> PortRelease(const v8::Arguments& args) {
- if (args.Length() >= 1 && args[0]->IsInt32()) {
- int port_id = args[0]->Int32Value();
- if (HasPortData(port_id) && --GetPortData(port_id).ref_count == 0) {
- // Send via the RenderThread because the RenderView might be closing.
- content::RenderThread::Get()->Send(
- new ExtensionHostMsg_CloseChannel(port_id, std::string()));
- ClearPortData(port_id);
- }
+ // Arguments are (int32 port_id).
+ CHECK_EQ(1, args.Length());
+ CHECK(args[0]->IsInt32());
+
+ int port_id = args[0]->Int32Value();
+ if (HasPortData(port_id) && --GetPortData(port_id).ref_count == 0) {
+ // Send via the RenderThread because the RenderView might be closing.
+ content::RenderThread::Get()->Send(
+ new ExtensionHostMsg_CloseChannel(port_id, std::string()));
+ ClearPortData(port_id);
}
+
return v8::Undefined();
}
@@ -222,6 +247,10 @@ void MiscellaneousBindings::DispatchOnConnect(
continue;
}
+ // TODO(kalman): remove when ContextSet::ForEach is available.
+ if ((*it)->v8_context().IsEmpty())
+ continue;
+
v8::Handle<v8::Value> tab = v8::Null();
if (!source_tab.empty())
tab = converter->ToV8Value(&source_tab, (*it)->v8_context());
@@ -271,7 +300,7 @@ void MiscellaneousBindings::DispatchOnConnect(
void MiscellaneousBindings::DeliverMessage(
const ChromeV8ContextSet::ContextSet& contexts,
int target_port_id,
- const std::string& message,
+ const base::ListValue& message,
content::RenderView* restrict_to_render_view) {
v8::HandleScope handle_scope;
@@ -282,6 +311,13 @@ void MiscellaneousBindings::DeliverMessage(
continue;
}
+ // TODO(kalman): remove when ContextSet::ForEach is available.
+ if ((*it)->v8_context().IsEmpty())
+ continue;
+
+ v8::Handle<v8::Context> context = (*it)->v8_context();
+ v8::Context::Scope context_scope(context);
+
// 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);
@@ -302,7 +338,19 @@ void MiscellaneousBindings::DeliverMessage(
continue;
std::vector<v8::Handle<v8::Value> > arguments;
- arguments.push_back(v8::String::New(message.c_str(), message.size()));
+
+ // Convert the message to a v8 object; either a value or undefined.
+ // See PostMessage for more details.
+ if (message.empty()) {
+ arguments.push_back(v8::Undefined());
+ } else {
+ CHECK_EQ(1u, message.GetSize());
+ const base::Value* message_value = NULL;
+ message.Get(0, &message_value);
+ scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create());
+ arguments.push_back(converter->ToV8Value(message_value, context));
+ }
+
arguments.push_back(port_id_handle);
CHECK((*it)->CallChromeHiddenMethod("Port.dispatchOnMessage",
arguments.size(),
@@ -326,6 +374,10 @@ void MiscellaneousBindings::DispatchOnDisconnect(
continue;
}
+ // TODO(kalman): remove when ContextSet::ForEach is available.
+ if ((*it)->v8_context().IsEmpty())
+ continue;
+
std::vector<v8::Handle<v8::Value> > arguments;
arguments.push_back(v8::Integer::New(port_id));
if (!error_message.empty()) {
« no previous file with comments | « chrome/renderer/extensions/miscellaneous_bindings.h ('k') | chrome/renderer/resources/extensions/miscellaneous_bindings.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698