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

Side by Side Diff: extensions/renderer/messaging_bindings.cc

Issue 327953002: Make MessagingBindings use ScriptContextSet::ForEach (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: ForEach shortcuts Created 6 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
« no previous file with comments | « extensions/renderer/messaging_bindings.h ('k') | extensions/renderer/resources/messaging.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "extensions/renderer/messaging_bindings.h" 5 #include "extensions/renderer/messaging_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 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 CHECK(args.Length() == 2 && args[0]->IsObject() && args[1]->IsFunction()); 230 CHECK(args.Length() == 2 && args[0]->IsObject() && args[1]->IsFunction());
231 GCCallback::Bind(args[0].As<v8::Object>(), 231 GCCallback::Bind(args[0].As<v8::Object>(),
232 args[1].As<v8::Function>(), 232 args[1].As<v8::Function>(),
233 args.GetIsolate()); 233 args.GetIsolate());
234 } 234 }
235 235
236 // Dispatcher handle. Not owned. 236 // Dispatcher handle. Not owned.
237 Dispatcher* dispatcher_; 237 Dispatcher* dispatcher_;
238 }; 238 };
239 239
240 void DispatchOnConnectToScriptContext(
241 int target_port_id,
242 const std::string& channel_name,
243 const base::DictionaryValue* source_tab,
244 const ExtensionMsg_ExternalConnectionInfo& info,
245 const std::string& tls_channel_id,
246 bool* port_created,
247 ScriptContext* script_context) {
248 v8::Isolate* isolate = script_context->isolate();
249 v8::HandleScope handle_scope(isolate);
250
251 scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create());
252
253 const std::string& source_url_spec = info.source_url.spec();
254 std::string target_extension_id = script_context->GetExtensionID();
255 const Extension* extension = script_context->extension();
256
257 v8::Handle<v8::Value> tab = v8::Null(isolate);
258 v8::Handle<v8::Value> tls_channel_id_value = v8::Undefined(isolate);
259
260 if (extension) {
261 if (!source_tab->empty() && !extension->is_platform_app())
262 tab = converter->ToV8Value(source_tab, script_context->v8_context());
263
264 ExternallyConnectableInfo* externally_connectable =
265 ExternallyConnectableInfo::Get(extension);
266 if (externally_connectable &&
267 externally_connectable->accepts_tls_channel_id) {
268 tls_channel_id_value = v8::String::NewFromUtf8(isolate,
269 tls_channel_id.c_str(),
270 v8::String::kNormalString,
271 tls_channel_id.size());
272 }
273 }
274
275 v8::Handle<v8::Value> arguments[] = {
276 // portId
277 v8::Integer::New(isolate, target_port_id),
278 // channelName
279 v8::String::NewFromUtf8(isolate,
280 channel_name.c_str(),
281 v8::String::kNormalString,
282 channel_name.size()),
283 // sourceTab
284 tab,
285 // sourceExtensionId
286 v8::String::NewFromUtf8(isolate,
287 info.source_id.c_str(),
288 v8::String::kNormalString,
289 info.source_id.size()),
290 // targetExtensionId
291 v8::String::NewFromUtf8(isolate,
292 target_extension_id.c_str(),
293 v8::String::kNormalString,
294 target_extension_id.size()),
295 // sourceUrl
296 v8::String::NewFromUtf8(isolate,
297 source_url_spec.c_str(),
298 v8::String::kNormalString,
299 source_url_spec.size()),
300 // tlsChannelId
301 tls_channel_id_value,
302 };
303
304 v8::Handle<v8::Value> retval =
305 script_context->module_system()->CallModuleMethod(
306 "messaging", "dispatchOnConnect", arraysize(arguments), arguments);
307
308 if (!retval.IsEmpty()) {
309 CHECK(retval->IsBoolean());
310 *port_created |= retval->BooleanValue();
311 } else {
312 LOG(ERROR) << "Empty return value from dispatchOnConnect.";
313 }
314 }
315
316 void DeliverMessageToScriptContext(const std::string& message_data,
317 int target_port_id,
318 ScriptContext* script_context) {
319 v8::Isolate* isolate = v8::Isolate::GetCurrent();
320 v8::HandleScope handle_scope(isolate);
321
322 // Check to see whether the context has this port before bothering to create
323 // the message.
324 v8::Handle<v8::Value> port_id_handle =
325 v8::Integer::New(isolate, target_port_id);
326 v8::Handle<v8::Value> has_port =
327 script_context->module_system()->CallModuleMethod(
328 "messaging", "hasPort", 1, &port_id_handle);
329
330 CHECK(!has_port.IsEmpty());
331 if (!has_port->BooleanValue())
332 return;
333
334 std::vector<v8::Handle<v8::Value> > arguments;
335 arguments.push_back(v8::String::NewFromUtf8(isolate,
336 message_data.c_str(),
337 v8::String::kNormalString,
338 message_data.size()));
339 arguments.push_back(port_id_handle);
340 script_context->module_system()->CallModuleMethod(
341 "messaging", "dispatchOnMessage", &arguments);
342 }
343
344 void DispatchOnDisconnectToScriptContext(int port_id,
345 const std::string& error_message,
346 ScriptContext* script_context) {
347 v8::Isolate* isolate = script_context->isolate();
348 v8::HandleScope handle_scope(isolate);
349
350 std::vector<v8::Handle<v8::Value> > arguments;
351 arguments.push_back(v8::Integer::New(isolate, port_id));
352 if (!error_message.empty()) {
353 arguments.push_back(
354 v8::String::NewFromUtf8(isolate, error_message.c_str()));
355 } else {
356 arguments.push_back(v8::Null(isolate));
357 }
358
359 script_context->module_system()->CallModuleMethod(
360 "messaging", "dispatchOnDisconnect", &arguments);
361 }
362
240 } // namespace 363 } // namespace
241 364
242 ObjectBackedNativeHandler* MessagingBindings::Get(Dispatcher* dispatcher, 365 ObjectBackedNativeHandler* MessagingBindings::Get(Dispatcher* dispatcher,
243 ScriptContext* context) { 366 ScriptContext* context) {
244 return new ExtensionImpl(dispatcher, context); 367 return new ExtensionImpl(dispatcher, context);
245 } 368 }
246 369
247 // static 370 // static
248 void MessagingBindings::DispatchOnConnect( 371 void MessagingBindings::DispatchOnConnect(
249 const ScriptContextSet::ContextSet& contexts, 372 const ScriptContextSet& context_set,
250 int target_port_id, 373 int target_port_id,
251 const std::string& channel_name, 374 const std::string& channel_name,
252 const base::DictionaryValue& source_tab, 375 const base::DictionaryValue& source_tab,
253 const std::string& source_extension_id, 376 const ExtensionMsg_ExternalConnectionInfo& info,
254 const std::string& target_extension_id,
255 const GURL& source_url,
256 const std::string& tls_channel_id, 377 const std::string& tls_channel_id,
257 content::RenderView* restrict_to_render_view) { 378 content::RenderView* restrict_to_render_view) {
258 v8::Isolate* isolate = v8::Isolate::GetCurrent();
259 v8::HandleScope handle_scope(isolate);
260
261 scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create());
262
263 bool port_created = false; 379 bool port_created = false;
264 std::string source_url_spec = source_url.spec(); 380 context_set.ForEach(info.target_id,
265 381 restrict_to_render_view,
266 // TODO(kalman): pass in the full ScriptContextSet; call ForEach. 382 base::Bind(&DispatchOnConnectToScriptContext,
267 for (ScriptContextSet::ContextSet::const_iterator it = contexts.begin(); 383 target_port_id,
268 it != contexts.end(); 384 channel_name,
269 ++it) { 385 &source_tab,
270 if (restrict_to_render_view && 386 info,
271 restrict_to_render_view != (*it)->GetRenderView()) { 387 tls_channel_id,
272 continue; 388 &port_created));
273 }
274
275 // TODO(kalman): remove when ContextSet::ForEach is available.
276 if ((*it)->v8_context().IsEmpty())
277 continue;
278
279 v8::Handle<v8::Value> tab = v8::Null(isolate);
280 v8::Handle<v8::Value> tls_channel_id_value = v8::Undefined(isolate);
281 const Extension* extension = (*it)->extension();
282 if (extension) {
283 if (!source_tab.empty() && !extension->is_platform_app())
284 tab = converter->ToV8Value(&source_tab, (*it)->v8_context());
285
286 ExternallyConnectableInfo* externally_connectable =
287 ExternallyConnectableInfo::Get(extension);
288 if (externally_connectable &&
289 externally_connectable->accepts_tls_channel_id) {
290 tls_channel_id_value =
291 v8::String::NewFromUtf8(isolate,
292 tls_channel_id.c_str(),
293 v8::String::kNormalString,
294 tls_channel_id.size());
295 }
296 }
297
298 v8::Handle<v8::Value> arguments[] = {
299 // portId
300 v8::Integer::New(isolate, target_port_id),
301 // channelName
302 v8::String::NewFromUtf8(isolate,
303 channel_name.c_str(),
304 v8::String::kNormalString,
305 channel_name.size()),
306 // sourceTab
307 tab,
308 // sourceExtensionId
309 v8::String::NewFromUtf8(isolate,
310 source_extension_id.c_str(),
311 v8::String::kNormalString,
312 source_extension_id.size()),
313 // targetExtensionId
314 v8::String::NewFromUtf8(isolate,
315 target_extension_id.c_str(),
316 v8::String::kNormalString,
317 target_extension_id.size()),
318 // sourceUrl
319 v8::String::NewFromUtf8(isolate,
320 source_url_spec.c_str(),
321 v8::String::kNormalString,
322 source_url_spec.size()),
323 // tlsChannelId
324 tls_channel_id_value,
325 };
326
327 v8::Handle<v8::Value> retval = (*it)->module_system()->CallModuleMethod(
328 "messaging", "dispatchOnConnect", arraysize(arguments), arguments);
329
330 if (retval.IsEmpty()) {
331 LOG(ERROR) << "Empty return value from dispatchOnConnect.";
332 continue;
333 }
334
335 CHECK(retval->IsBoolean());
336 port_created |= retval->BooleanValue();
337 }
338 389
339 // If we didn't create a port, notify the other end of the channel (treat it 390 // If we didn't create a port, notify the other end of the channel (treat it
340 // as a disconnect). 391 // as a disconnect).
341 if (!port_created) { 392 if (!port_created) {
342 content::RenderThread::Get()->Send(new ExtensionHostMsg_CloseChannel( 393 content::RenderThread::Get()->Send(new ExtensionHostMsg_CloseChannel(
343 target_port_id, kReceivingEndDoesntExistError)); 394 target_port_id, kReceivingEndDoesntExistError));
344 } 395 }
345 } 396 }
346 397
347 // static 398 // static
348 void MessagingBindings::DeliverMessage( 399 void MessagingBindings::DeliverMessage(
349 const ScriptContextSet::ContextSet& contexts, 400 const ScriptContextSet& context_set,
350 int target_port_id, 401 int target_port_id,
351 const Message& message, 402 const Message& message,
352 content::RenderView* restrict_to_render_view) { 403 content::RenderView* restrict_to_render_view) {
353 scoped_ptr<blink::WebScopedUserGesture> web_user_gesture; 404 scoped_ptr<blink::WebScopedUserGesture> web_user_gesture;
354 scoped_ptr<blink::WebScopedWindowFocusAllowedIndicator> allow_window_focus; 405 scoped_ptr<blink::WebScopedWindowFocusAllowedIndicator> allow_window_focus;
355 if (message.user_gesture) { 406 if (message.user_gesture) {
356 web_user_gesture.reset(new blink::WebScopedUserGesture); 407 web_user_gesture.reset(new blink::WebScopedUserGesture);
357 allow_window_focus.reset(new blink::WebScopedWindowFocusAllowedIndicator); 408 allow_window_focus.reset(new blink::WebScopedWindowFocusAllowedIndicator);
358 } 409 }
359 410
360 v8::Isolate* isolate = v8::Isolate::GetCurrent(); 411 context_set.ForEach(
361 v8::HandleScope handle_scope(isolate); 412 restrict_to_render_view,
362 413 base::Bind(&DeliverMessageToScriptContext, message.data, target_port_id));
363 // TODO(kalman): pass in the full ScriptContextSet; call ForEach.
364 for (ScriptContextSet::ContextSet::const_iterator it = contexts.begin();
365 it != contexts.end();
366 ++it) {
367 if (restrict_to_render_view &&
368 restrict_to_render_view != (*it)->GetRenderView()) {
369 continue;
370 }
371
372 // TODO(kalman): remove when ContextSet::ForEach is available.
373 if ((*it)->v8_context().IsEmpty())
374 continue;
375
376 // Check to see whether the context has this port before bothering to create
377 // the message.
378 v8::Handle<v8::Value> port_id_handle =
379 v8::Integer::New(isolate, target_port_id);
380 v8::Handle<v8::Value> has_port = (*it)->module_system()->CallModuleMethod(
381 "messaging", "hasPort", 1, &port_id_handle);
382
383 CHECK(!has_port.IsEmpty());
384 if (!has_port->BooleanValue())
385 continue;
386
387 std::vector<v8::Handle<v8::Value> > arguments;
388 arguments.push_back(v8::String::NewFromUtf8(isolate,
389 message.data.c_str(),
390 v8::String::kNormalString,
391 message.data.size()));
392 arguments.push_back(port_id_handle);
393 (*it)->module_system()->CallModuleMethod(
394 "messaging", "dispatchOnMessage", &arguments);
395 }
396 } 414 }
397 415
398 // static 416 // static
399 void MessagingBindings::DispatchOnDisconnect( 417 void MessagingBindings::DispatchOnDisconnect(
400 const ScriptContextSet::ContextSet& contexts, 418 const ScriptContextSet& context_set,
401 int port_id, 419 int port_id,
402 const std::string& error_message, 420 const std::string& error_message,
403 content::RenderView* restrict_to_render_view) { 421 content::RenderView* restrict_to_render_view) {
404 v8::Isolate* isolate = v8::Isolate::GetCurrent(); 422 context_set.ForEach(
405 v8::HandleScope handle_scope(isolate); 423 restrict_to_render_view,
406 424 base::Bind(&DispatchOnDisconnectToScriptContext, port_id, error_message));
407 // TODO(kalman): pass in the full ScriptContextSet; call ForEach.
408 for (ScriptContextSet::ContextSet::const_iterator it = contexts.begin();
409 it != contexts.end();
410 ++it) {
411 if (restrict_to_render_view &&
412 restrict_to_render_view != (*it)->GetRenderView()) {
413 continue;
414 }
415
416 // TODO(kalman): remove when ContextSet::ForEach is available.
417 if ((*it)->v8_context().IsEmpty())
418 continue;
419
420 std::vector<v8::Handle<v8::Value> > arguments;
421 arguments.push_back(v8::Integer::New(isolate, port_id));
422 if (!error_message.empty()) {
423 arguments.push_back(
424 v8::String::NewFromUtf8(isolate, error_message.c_str()));
425 } else {
426 arguments.push_back(v8::Null(isolate));
427 }
428 (*it)->module_system()->CallModuleMethod(
429 "messaging", "dispatchOnDisconnect", &arguments);
430 }
431 } 425 }
432 426
433 } // namespace extensions 427 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/renderer/messaging_bindings.h ('k') | extensions/renderer/resources/messaging.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698