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

Side by Side 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: disable test on win 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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/renderer/extensions/miscellaneous_bindings.h" 5 #include "chrome/renderer/extensions/miscellaneous_bindings.h"
6 6
7 #include <map> 7 #include <map>
8 #include <string> 8 #include <string>
9 9
10 #include "base/basictypes.h" 10 #include "base/basictypes.h"
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 } 88 }
89 89
90 virtual ~ExtensionImpl() {} 90 virtual ~ExtensionImpl() {}
91 91
92 // Sends a message along the given channel. 92 // Sends a message along the given channel.
93 v8::Handle<v8::Value> PostMessage(const v8::Arguments& args) { 93 v8::Handle<v8::Value> PostMessage(const v8::Arguments& args) {
94 content::RenderView* renderview = GetRenderView(); 94 content::RenderView* renderview = GetRenderView();
95 if (!renderview) 95 if (!renderview)
96 return v8::Undefined(); 96 return v8::Undefined();
97 97
98 if (args.Length() >= 2 && args[0]->IsInt32() && args[1]->IsString()) { 98 // Arguments are (int32 port_id, object message).
99 int port_id = args[0]->Int32Value(); 99 CHECK_EQ(2, args.Length());
100 if (!HasPortData(port_id)) { 100 CHECK(args[0]->IsInt32());
101 return v8::ThrowException(v8::Exception::Error( 101
102 v8::String::New(kPortClosedError))); 102 int port_id = args[0]->Int32Value();
103 } 103 if (!HasPortData(port_id)) {
104 std::string message = *v8::String::Utf8Value(args[1]->ToString()); 104 return v8::ThrowException(v8::Exception::Error(
105 renderview->Send(new ExtensionHostMsg_PostMessage( 105 v8::String::New(kPortClosedError)));
106 renderview->GetRoutingID(), port_id, message));
107 } 106 }
107
108 // The message can be any base::Value but IPC can't serialize that, so we
109 // give it a singleton base::ListValue instead, or an empty list if the
110 // argument was undefined (v8 value converter will return NULL for this).
111 scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create());
112 scoped_ptr<base::Value> message(
113 converter->FromV8Value(args[1], v8_context()));
114 ListValue message_as_list;
115 if (message)
116 message_as_list.Append(message.release());
117
118 renderview->Send(new ExtensionHostMsg_PostMessage(
119 renderview->GetRoutingID(), port_id, message_as_list));
120
108 return v8::Undefined(); 121 return v8::Undefined();
109 } 122 }
110 123
111 // Forcefully disconnects a port. 124 // Forcefully disconnects a port.
112 v8::Handle<v8::Value> CloseChannel(const v8::Arguments& args) { 125 v8::Handle<v8::Value> CloseChannel(const v8::Arguments& args) {
113 if (args.Length() >= 2 && args[0]->IsInt32() && args[1]->IsBoolean()) { 126 // Arguments are (int32 port_id, boolean notify_browser).
114 int port_id = args[0]->Int32Value(); 127 CHECK_EQ(2, args.Length());
115 if (!HasPortData(port_id)) { 128 CHECK(args[0]->IsInt32());
116 return v8::Undefined(); 129 CHECK(args[1]->IsBoolean());
117 } 130
118 // Send via the RenderThread because the RenderView might be closing. 131 int port_id = args[0]->Int32Value();
119 bool notify_browser = args[1]->BooleanValue(); 132 if (!HasPortData(port_id))
120 if (notify_browser) 133 return v8::Undefined();
121 content::RenderThread::Get()->Send( 134
122 new ExtensionHostMsg_CloseChannel(port_id, std::string())); 135 // Send via the RenderThread because the RenderView might be closing.
123 ClearPortData(port_id); 136 bool notify_browser = args[1]->BooleanValue();
137 if (notify_browser) {
138 content::RenderThread::Get()->Send(
139 new ExtensionHostMsg_CloseChannel(port_id, std::string()));
124 } 140 }
141
142 ClearPortData(port_id);
143
125 return v8::Undefined(); 144 return v8::Undefined();
126 } 145 }
127 146
128 // A new port has been created for a context. This occurs both when script 147 // A new port has been created for a context. This occurs both when script
129 // opens a connection, and when a connection is opened to this script. 148 // opens a connection, and when a connection is opened to this script.
130 v8::Handle<v8::Value> PortAddRef(const v8::Arguments& args) { 149 v8::Handle<v8::Value> PortAddRef(const v8::Arguments& args) {
131 if (args.Length() >= 1 && args[0]->IsInt32()) { 150 // Arguments are (int32 port_id).
132 int port_id = args[0]->Int32Value(); 151 CHECK_EQ(1, args.Length());
133 ++GetPortData(port_id).ref_count; 152 CHECK(args[0]->IsInt32());
134 } 153
154 int port_id = args[0]->Int32Value();
155 ++GetPortData(port_id).ref_count;
156
135 return v8::Undefined(); 157 return v8::Undefined();
136 } 158 }
137 159
138 // The frame a port lived in has been destroyed. When there are no more 160 // The frame a port lived in has been destroyed. When there are no more
139 // frames with a reference to a given port, we will disconnect it and notify 161 // frames with a reference to a given port, we will disconnect it and notify
140 // the other end of the channel. 162 // the other end of the channel.
141 v8::Handle<v8::Value> PortRelease(const v8::Arguments& args) { 163 v8::Handle<v8::Value> PortRelease(const v8::Arguments& args) {
142 if (args.Length() >= 1 && args[0]->IsInt32()) { 164 // Arguments are (int32 port_id).
143 int port_id = args[0]->Int32Value(); 165 CHECK_EQ(1, args.Length());
144 if (HasPortData(port_id) && --GetPortData(port_id).ref_count == 0) { 166 CHECK(args[0]->IsInt32());
145 // Send via the RenderThread because the RenderView might be closing. 167
146 content::RenderThread::Get()->Send( 168 int port_id = args[0]->Int32Value();
147 new ExtensionHostMsg_CloseChannel(port_id, std::string())); 169 if (HasPortData(port_id) && --GetPortData(port_id).ref_count == 0) {
148 ClearPortData(port_id); 170 // Send via the RenderThread because the RenderView might be closing.
149 } 171 content::RenderThread::Get()->Send(
172 new ExtensionHostMsg_CloseChannel(port_id, std::string()));
173 ClearPortData(port_id);
150 } 174 }
175
151 return v8::Undefined(); 176 return v8::Undefined();
152 } 177 }
153 178
154 struct GCCallbackArgs { 179 struct GCCallbackArgs {
155 GCCallbackArgs(v8::Handle<v8::Object> object, 180 GCCallbackArgs(v8::Handle<v8::Object> object,
156 v8::Handle<v8::Function> callback) 181 v8::Handle<v8::Function> callback)
157 : object(object), callback(callback) {} 182 : object(object), callback(callback) {}
158 183
159 extensions::ScopedPersistent<v8::Object> object; 184 extensions::ScopedPersistent<v8::Object> object;
160 extensions::ScopedPersistent<v8::Function> callback; 185 extensions::ScopedPersistent<v8::Function> callback;
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
264 content::RenderThread::Get()->Send( 289 content::RenderThread::Get()->Send(
265 new ExtensionHostMsg_CloseChannel( 290 new ExtensionHostMsg_CloseChannel(
266 target_port_id, kReceivingEndDoesntExistError)); 291 target_port_id, kReceivingEndDoesntExistError));
267 } 292 }
268 } 293 }
269 294
270 // static 295 // static
271 void MiscellaneousBindings::DeliverMessage( 296 void MiscellaneousBindings::DeliverMessage(
272 const ChromeV8ContextSet::ContextSet& contexts, 297 const ChromeV8ContextSet::ContextSet& contexts,
273 int target_port_id, 298 int target_port_id,
274 const std::string& message, 299 const base::ListValue& message,
275 content::RenderView* restrict_to_render_view) { 300 content::RenderView* restrict_to_render_view) {
276 v8::HandleScope handle_scope; 301 v8::HandleScope handle_scope;
277 302
278 for (ChromeV8ContextSet::ContextSet::const_iterator it = contexts.begin(); 303 for (ChromeV8ContextSet::ContextSet::const_iterator it = contexts.begin();
279 it != contexts.end(); ++it) { 304 it != contexts.end(); ++it) {
280 if (restrict_to_render_view && 305 if (restrict_to_render_view &&
281 restrict_to_render_view != (*it)->GetRenderView()) { 306 restrict_to_render_view != (*it)->GetRenderView()) {
282 continue; 307 continue;
283 } 308 }
284 309
310 v8::Handle<v8::Context> context = (*it)->v8_context();
311 v8::Context::Scope context_scope(context);
312
285 // Check to see whether the context has this port before bothering to create 313 // Check to see whether the context has this port before bothering to create
286 // the message. 314 // the message.
287 v8::Handle<v8::Value> port_id_handle = v8::Integer::New(target_port_id); 315 v8::Handle<v8::Value> port_id_handle = v8::Integer::New(target_port_id);
288 v8::Handle<v8::Value> has_port; 316 v8::Handle<v8::Value> has_port;
289 v8::TryCatch try_catch; 317 v8::TryCatch try_catch;
290 if (!(*it)->CallChromeHiddenMethod("Port.hasPort", 1, &port_id_handle, 318 if (!(*it)->CallChromeHiddenMethod("Port.hasPort", 1, &port_id_handle,
291 &has_port)) { 319 &has_port)) {
292 continue; 320 continue;
293 } 321 }
294 322
295 if (try_catch.HasCaught()) { 323 if (try_catch.HasCaught()) {
296 LOG(ERROR) << "Exception caught when calling Port.hasPort."; 324 LOG(ERROR) << "Exception caught when calling Port.hasPort.";
297 continue; 325 continue;
298 } 326 }
299 327
300 CHECK(!has_port.IsEmpty()); 328 CHECK(!has_port.IsEmpty());
301 if (!has_port->BooleanValue()) 329 if (!has_port->BooleanValue())
302 continue; 330 continue;
303 331
304 std::vector<v8::Handle<v8::Value> > arguments; 332 std::vector<v8::Handle<v8::Value> > arguments;
305 arguments.push_back(v8::String::New(message.c_str(), message.size())); 333
334 // Convert the message to a v8 object; either a value or undefined.
335 // See PostMessage for more details.
336 if (message.empty()) {
337 arguments.push_back(v8::Undefined());
338 } else {
339 CHECK_EQ(1u, message.GetSize());
340 const base::Value* message_value = NULL;
341 message.Get(0, &message_value);
342 scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create());
343 arguments.push_back(converter->ToV8Value(message_value, context));
344 }
345
306 arguments.push_back(port_id_handle); 346 arguments.push_back(port_id_handle);
307 CHECK((*it)->CallChromeHiddenMethod("Port.dispatchOnMessage", 347 CHECK((*it)->CallChromeHiddenMethod("Port.dispatchOnMessage",
308 arguments.size(), 348 arguments.size(),
309 &arguments[0], 349 &arguments[0],
310 NULL)); 350 NULL));
311 } 351 }
312 } 352 }
313 353
314 // static 354 // static
315 void MiscellaneousBindings::DispatchOnDisconnect( 355 void MiscellaneousBindings::DispatchOnDisconnect(
(...skipping 17 matching lines...) Expand all
333 } else { 373 } else {
334 arguments.push_back(v8::Null()); 374 arguments.push_back(v8::Null());
335 } 375 }
336 (*it)->CallChromeHiddenMethod("Port.dispatchOnDisconnect", 376 (*it)->CallChromeHiddenMethod("Port.dispatchOnDisconnect",
337 arguments.size(), &arguments[0], 377 arguments.size(), &arguments[0],
338 NULL); 378 NULL);
339 } 379 }
340 } 380 }
341 381
342 } // namespace extensions 382 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698