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

Side by Side Diff: chrome/renderer/extensions/miscellaneous_bindings.cc

Issue 15841013: Make miscellaneous_bindings and event_bindings Required as needed. Previously (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 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(
122 new ExtensionHostMsg_CloseChannel(port_id, std::string()));
123 ClearPortData(port_id);
124 } 134 }
135 // Send via the RenderThread because the RenderView might be closing.
136 bool notify_browser = args[1]->BooleanValue();
137 if (notify_browser)
138 content::RenderThread::Get()->Send(
139 new ExtensionHostMsg_CloseChannel(port_id, std::string()));
140 ClearPortData(port_id);
141
125 return v8::Undefined(); 142 return v8::Undefined();
126 } 143 }
127 144
128 // A new port has been created for a context. This occurs both when script 145 // 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. 146 // opens a connection, and when a connection is opened to this script.
130 v8::Handle<v8::Value> PortAddRef(const v8::Arguments& args) { 147 v8::Handle<v8::Value> PortAddRef(const v8::Arguments& args) {
131 if (args.Length() >= 1 && args[0]->IsInt32()) { 148 // Arguments are (int32 port_id).
132 int port_id = args[0]->Int32Value(); 149 CHECK_EQ(1, args.Length());
133 ++GetPortData(port_id).ref_count; 150 CHECK(args[0]->IsInt32());
134 } 151
152 int port_id = args[0]->Int32Value();
153 ++GetPortData(port_id).ref_count;
154
135 return v8::Undefined(); 155 return v8::Undefined();
136 } 156 }
137 157
138 // The frame a port lived in has been destroyed. When there are no more 158 // 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 159 // frames with a reference to a given port, we will disconnect it and notify
140 // the other end of the channel. 160 // the other end of the channel.
141 v8::Handle<v8::Value> PortRelease(const v8::Arguments& args) { 161 v8::Handle<v8::Value> PortRelease(const v8::Arguments& args) {
142 if (args.Length() >= 1 && args[0]->IsInt32()) { 162 // Arguments are (int32 port_id).
143 int port_id = args[0]->Int32Value(); 163 CHECK_EQ(1, args.Length());
144 if (HasPortData(port_id) && --GetPortData(port_id).ref_count == 0) { 164 CHECK(args[0]->IsInt32());
145 // Send via the RenderThread because the RenderView might be closing. 165
146 content::RenderThread::Get()->Send( 166 int port_id = args[0]->Int32Value();
147 new ExtensionHostMsg_CloseChannel(port_id, std::string())); 167 if (HasPortData(port_id) && --GetPortData(port_id).ref_count == 0) {
148 ClearPortData(port_id); 168 // Send via the RenderThread because the RenderView might be closing.
149 } 169 content::RenderThread::Get()->Send(
170 new ExtensionHostMsg_CloseChannel(port_id, std::string()));
171 ClearPortData(port_id);
150 } 172 }
173
151 return v8::Undefined(); 174 return v8::Undefined();
152 } 175 }
153 176
154 struct GCCallbackArgs { 177 struct GCCallbackArgs {
155 GCCallbackArgs(v8::Handle<v8::Object> object, 178 GCCallbackArgs(v8::Handle<v8::Object> object,
156 v8::Handle<v8::Function> callback) 179 v8::Handle<v8::Function> callback)
157 : object(object), callback(callback) {} 180 : object(object), callback(callback) {}
158 181
159 extensions::ScopedPersistent<v8::Object> object; 182 extensions::ScopedPersistent<v8::Object> object;
160 extensions::ScopedPersistent<v8::Function> callback; 183 extensions::ScopedPersistent<v8::Function> callback;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 251
229 v8::Handle<v8::Value> arguments[] = { 252 v8::Handle<v8::Value> arguments[] = {
230 v8::Integer::New(target_port_id), 253 v8::Integer::New(target_port_id),
231 v8::String::New(channel_name.c_str(), channel_name.size()), 254 v8::String::New(channel_name.c_str(), channel_name.size()),
232 tab, 255 tab,
233 v8::String::New(source_extension_id.c_str(), source_extension_id.size()), 256 v8::String::New(source_extension_id.c_str(), source_extension_id.size()),
234 v8::String::New(target_extension_id.c_str(), target_extension_id.size()), 257 v8::String::New(target_extension_id.c_str(), target_extension_id.size()),
235 v8::String::New(source_url_spec.c_str(), source_url_spec.size()) 258 v8::String::New(source_url_spec.c_str(), source_url_spec.size())
236 }; 259 };
237 260
238 v8::Handle<v8::Value> retval; 261 v8::Handle<v8::Value> retval = (*it)->module_system()->CallModuleMethod(
239 v8::TryCatch try_catch; 262 "miscellaneous_bindings",
240 if (!(*it)->CallChromeHiddenMethod("Port.dispatchOnConnect", 263 "dispatchOnConnect",
241 arraysize(arguments), arguments, 264 arraysize(arguments), arguments);
242 &retval)) {
243 continue;
244 }
245
246 if (try_catch.HasCaught()) {
247 LOG(ERROR) << "Exception caught when calling Port.dispatchOnConnect.";
248 continue;
249 }
250 265
251 if (retval.IsEmpty()) { 266 if (retval.IsEmpty()) {
252 LOG(ERROR) << "Empty return value from Port.dispatchOnConnect."; 267 LOG(ERROR) << "Empty return value from dispatchOnConnect.";
253 continue; 268 continue;
254 } 269 }
255 270
256 CHECK(retval->IsBoolean()); 271 CHECK(retval->IsBoolean());
257 if (retval->BooleanValue()) 272 port_created |= retval->BooleanValue();
258 port_created = true;
259 } 273 }
260 274
261 // If we didn't create a port, notify the other end of the channel (treat it 275 // If we didn't create a port, notify the other end of the channel (treat it
262 // as a disconnect). 276 // as a disconnect).
263 if (!port_created) { 277 if (!port_created) {
278 LOG(WARNING) << "Port wasn't created";
264 content::RenderThread::Get()->Send( 279 content::RenderThread::Get()->Send(
265 new ExtensionHostMsg_CloseChannel( 280 new ExtensionHostMsg_CloseChannel(
266 target_port_id, kReceivingEndDoesntExistError)); 281 target_port_id, kReceivingEndDoesntExistError));
267 } 282 }
268 } 283 }
269 284
270 // static 285 // static
271 void MiscellaneousBindings::DeliverMessage( 286 void MiscellaneousBindings::DeliverMessage(
272 const ChromeV8ContextSet::ContextSet& contexts, 287 const ChromeV8ContextSet::ContextSet& contexts,
273 int target_port_id, 288 int target_port_id,
274 const std::string& message, 289 const base::ListValue& message,
275 content::RenderView* restrict_to_render_view) { 290 content::RenderView* restrict_to_render_view) {
276 v8::HandleScope handle_scope; 291 v8::HandleScope handle_scope;
277 292
278 for (ChromeV8ContextSet::ContextSet::const_iterator it = contexts.begin(); 293 for (ChromeV8ContextSet::ContextSet::const_iterator it = contexts.begin();
279 it != contexts.end(); ++it) { 294 it != contexts.end(); ++it) {
280 if (restrict_to_render_view && 295 if (restrict_to_render_view &&
281 restrict_to_render_view != (*it)->GetRenderView()) { 296 restrict_to_render_view != (*it)->GetRenderView()) {
282 continue; 297 continue;
283 } 298 }
284 299
300 v8::Handle<v8::Context> context = (*it)->v8_context();
301 v8::Context::Scope context_scope(context);
302
285 // Check to see whether the context has this port before bothering to create 303 // Check to see whether the context has this port before bothering to create
286 // the message. 304 // the message.
287 v8::Handle<v8::Value> port_id_handle = v8::Integer::New(target_port_id); 305 v8::Handle<v8::Value> port_id_handle = v8::Integer::New(target_port_id);
288 v8::Handle<v8::Value> has_port; 306 v8::Handle<v8::Value> has_port = (*it)->module_system()->CallModuleMethod(
289 v8::TryCatch try_catch; 307 "miscellaneous_bindings",
290 if (!(*it)->CallChromeHiddenMethod("Port.hasPort", 1, &port_id_handle, 308 "hasPort",
291 &has_port)) { 309 1, &port_id_handle);
292 continue;
293 }
294
295 if (try_catch.HasCaught()) {
296 LOG(ERROR) << "Exception caught when calling Port.hasPort.";
297 continue;
298 }
299 310
300 CHECK(!has_port.IsEmpty()); 311 CHECK(!has_port.IsEmpty());
301 if (!has_port->BooleanValue()) 312 if (!has_port->BooleanValue())
302 continue; 313 continue;
303 314
304 std::vector<v8::Handle<v8::Value> > arguments; 315 std::vector<v8::Handle<v8::Value> > arguments;
305 arguments.push_back(v8::String::New(message.c_str(), message.size())); 316
317 // Convert the message to a v8 object; either a value or undefined.
318 // See PostMessage for more details.
319 if (message.empty()) {
320 arguments.push_back(v8::Undefined());
321 } else {
322 CHECK_EQ(1u, message.GetSize());
323 const base::Value* message_value = NULL;
324 message.Get(0, &message_value);
325 scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create());
326 arguments.push_back(converter->ToV8Value(message_value, context));
327 }
328
306 arguments.push_back(port_id_handle); 329 arguments.push_back(port_id_handle);
307 CHECK((*it)->CallChromeHiddenMethod("Port.dispatchOnMessage", 330 (*it)->module_system()->CallModuleMethod("miscellaneous_bindings",
308 arguments.size(), 331 "dispatchOnMessage",
309 &arguments[0], 332 &arguments);
310 NULL));
311 } 333 }
312 } 334 }
313 335
314 // static 336 // static
315 void MiscellaneousBindings::DispatchOnDisconnect( 337 void MiscellaneousBindings::DispatchOnDisconnect(
316 const ChromeV8ContextSet::ContextSet& contexts, 338 const ChromeV8ContextSet::ContextSet& contexts,
317 int port_id, 339 int port_id,
318 const std::string& error_message, 340 const std::string& error_message,
319 content::RenderView* restrict_to_render_view) { 341 content::RenderView* restrict_to_render_view) {
320 v8::HandleScope handle_scope; 342 v8::HandleScope handle_scope;
321 343
322 for (ChromeV8ContextSet::ContextSet::const_iterator it = contexts.begin(); 344 for (ChromeV8ContextSet::ContextSet::const_iterator it = contexts.begin();
323 it != contexts.end(); ++it) { 345 it != contexts.end(); ++it) {
324 if (restrict_to_render_view && 346 if (restrict_to_render_view &&
325 restrict_to_render_view != (*it)->GetRenderView()) { 347 restrict_to_render_view != (*it)->GetRenderView()) {
326 continue; 348 continue;
327 } 349 }
328 350
329 std::vector<v8::Handle<v8::Value> > arguments; 351 std::vector<v8::Handle<v8::Value> > arguments;
330 arguments.push_back(v8::Integer::New(port_id)); 352 arguments.push_back(v8::Integer::New(port_id));
331 if (!error_message.empty()) { 353 if (!error_message.empty()) {
332 arguments.push_back(v8::String::New(error_message.c_str())); 354 arguments.push_back(v8::String::New(error_message.c_str()));
333 } else { 355 } else {
334 arguments.push_back(v8::Null()); 356 arguments.push_back(v8::Null());
335 } 357 }
336 (*it)->CallChromeHiddenMethod("Port.dispatchOnDisconnect", 358 (*it)->module_system()->CallModuleMethod("miscellaneous_bindings",
337 arguments.size(), &arguments[0], 359 "dispatchOnDisconnect",
338 NULL); 360 &arguments);
339 } 361 }
340 } 362 }
341 363
342 } // namespace extensions 364 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/renderer/extensions/miscellaneous_bindings.h ('k') | chrome/renderer/extensions/module_system.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698