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

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

Issue 2657613005: [Extensions Bindings] Add chrome.runtime.lastError support (Closed)
Patch Set: rebase Created 3 years, 10 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
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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/native_extension_bindings_system.h" 5 #include "extensions/renderer/native_extension_bindings_system.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/memory/ptr_util.h" 8 #include "base/memory/ptr_util.h"
9 #include "content/public/common/content_switches.h" 9 #include "content/public/common/content_switches.h"
10 #include "extensions/common/constants.h" 10 #include "extensions/common/constants.h"
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 const SendEventListenerIPCMethod& send_event_listener_ipc) 319 const SendEventListenerIPCMethod& send_event_listener_ipc)
320 : send_request_ipc_(send_request_ipc), 320 : send_request_ipc_(send_request_ipc),
321 send_event_listener_ipc_(send_event_listener_ipc), 321 send_event_listener_ipc_(send_event_listener_ipc),
322 api_system_( 322 api_system_(
323 base::Bind(&CallJsFunction), 323 base::Bind(&CallJsFunction),
324 base::Bind(&CallJsFunctionSync), 324 base::Bind(&CallJsFunctionSync),
325 base::Bind(&GetAPISchema), 325 base::Bind(&GetAPISchema),
326 base::Bind(&NativeExtensionBindingsSystem::SendRequest, 326 base::Bind(&NativeExtensionBindingsSystem::SendRequest,
327 base::Unretained(this)), 327 base::Unretained(this)),
328 base::Bind(&NativeExtensionBindingsSystem::OnEventListenerChanged, 328 base::Bind(&NativeExtensionBindingsSystem::OnEventListenerChanged,
329 base::Unretained(this))), 329 base::Unretained(this)),
330 APILastError(base::Bind(&GetRuntime))),
330 weak_factory_(this) {} 331 weak_factory_(this) {}
331 332
332 NativeExtensionBindingsSystem::~NativeExtensionBindingsSystem() {} 333 NativeExtensionBindingsSystem::~NativeExtensionBindingsSystem() {}
333 334
334 void NativeExtensionBindingsSystem::DidCreateScriptContext( 335 void NativeExtensionBindingsSystem::DidCreateScriptContext(
335 ScriptContext* context) {} 336 ScriptContext* context) {}
336 337
337 void NativeExtensionBindingsSystem::WillReleaseScriptContext( 338 void NativeExtensionBindingsSystem::WillReleaseScriptContext(
338 ScriptContext* context) {} 339 ScriptContext* context) {}
339 340
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 // expose this under the name of the feature (e.g., 'tabs'), but in some 397 // expose this under the name of the feature (e.g., 'tabs'), but in some
397 // cases, this will be a prefixed API, such as 'app.runtime'. Find what the 398 // cases, this will be a prefixed API, such as 'app.runtime'. Find what the
398 // property on the chrome object is named, and use that. So in the case of 399 // property on the chrome object is named, and use that. So in the case of
399 // 'app.runtime', we surface a getter for simply 'app'. 400 // 'app.runtime', we surface a getter for simply 'app'.
400 base::StringPiece accessor_name = 401 base::StringPiece accessor_name =
401 GetFirstDifferentAPIName(map_entry.first, base::StringPiece()); 402 GetFirstDifferentAPIName(map_entry.first, base::StringPiece());
402 last_accessor = accessor_name; 403 last_accessor = accessor_name;
403 v8::Local<v8::String> api_name = 404 v8::Local<v8::String> api_name =
404 gin::StringToSymbol(v8_context->GetIsolate(), accessor_name); 405 gin::StringToSymbol(v8_context->GetIsolate(), accessor_name);
405 v8::Maybe<bool> success = chrome->SetAccessor( 406 v8::Maybe<bool> success = chrome->SetAccessor(
406 v8_context, api_name, &GetAPIHelper, nullptr, api_name); 407 v8_context, api_name, &BindingAccessor, nullptr, api_name);
407 if (!success.IsJust() || !success.FromJust()) { 408 if (!success.IsJust() || !success.FromJust()) {
408 LOG(ERROR) << "Failed to create API on Chrome object."; 409 LOG(ERROR) << "Failed to create API on Chrome object.";
409 return; 410 return;
410 } 411 }
411 } 412 }
412 } 413 }
413 414
414 void NativeExtensionBindingsSystem::DispatchEventInContext( 415 void NativeExtensionBindingsSystem::DispatchEventInContext(
415 const std::string& event_name, 416 const std::string& event_name,
416 const base::ListValue* event_args, 417 const base::ListValue* event_args,
417 const base::DictionaryValue* filtering_info, 418 const base::DictionaryValue* filtering_info,
418 ScriptContext* context) { 419 ScriptContext* context) {
419 v8::HandleScope handle_scope(context->isolate()); 420 v8::HandleScope handle_scope(context->isolate());
420 v8::Context::Scope context_scope(context->v8_context()); 421 v8::Context::Scope context_scope(context->v8_context());
421 // TODO(devlin): Take into account |filtering_info|. 422 // TODO(devlin): Take into account |filtering_info|.
422 api_system_.FireEventInContext(event_name, context->v8_context(), 423 api_system_.FireEventInContext(event_name, context->v8_context(),
423 *event_args); 424 *event_args);
424 } 425 }
425 426
426 void NativeExtensionBindingsSystem::HandleResponse( 427 void NativeExtensionBindingsSystem::HandleResponse(
427 int request_id, 428 int request_id,
428 bool success, 429 bool success,
429 const base::ListValue& response, 430 const base::ListValue& response,
430 const std::string& error) { 431 const std::string& error) {
431 api_system_.CompleteRequest(request_id, response); 432 api_system_.CompleteRequest(request_id, response, error);
432 } 433 }
433 434
434 RequestSender* NativeExtensionBindingsSystem::GetRequestSender() { 435 RequestSender* NativeExtensionBindingsSystem::GetRequestSender() {
435 return nullptr; 436 return nullptr;
436 } 437 }
437 438
438 // static 439 void NativeExtensionBindingsSystem::BindingAccessor(
439 void NativeExtensionBindingsSystem::GetAPIHelper(
440 v8::Local<v8::Name> name, 440 v8::Local<v8::Name> name,
441 const v8::PropertyCallbackInfo<v8::Value>& info) { 441 const v8::PropertyCallbackInfo<v8::Value>& info) {
442 v8::Isolate* isolate = info.GetIsolate(); 442 v8::Isolate* isolate = info.GetIsolate();
443 v8::HandleScope handle_scope(isolate); 443 v8::HandleScope handle_scope(isolate);
444 v8::Local<v8::Context> context = info.Holder()->CreationContext(); 444 v8::Local<v8::Context> context = info.Holder()->CreationContext();
445
446 // We use info.Data() to store a real name here instead of using the provided
447 // one to handle any weirdness from the caller (non-existent strings, etc).
448 v8::Local<v8::String> api_name = info.Data().As<v8::String>();
449 v8::Local<v8::Object> binding = GetAPIHelper(context, api_name);
450 if (!binding.IsEmpty())
451 info.GetReturnValue().Set(binding);
452 }
453
454 // static
455 v8::Local<v8::Object> NativeExtensionBindingsSystem::GetAPIHelper(
456 v8::Local<v8::Context> context,
457 v8::Local<v8::String> api_name) {
445 BindingsSystemPerContextData* data = GetBindingsDataFromContext(context); 458 BindingsSystemPerContextData* data = GetBindingsDataFromContext(context);
446 if (!data) 459 if (!data)
447 return; 460 return v8::Local<v8::Object>();
448 461
462 v8::Isolate* isolate = context->GetIsolate();
449 v8::Local<v8::Object> apis; 463 v8::Local<v8::Object> apis;
450 if (data->api_object.IsEmpty()) { 464 if (data->api_object.IsEmpty()) {
451 apis = v8::Object::New(isolate); 465 apis = v8::Object::New(isolate);
452 data->api_object = v8::Global<v8::Object>(isolate, apis); 466 data->api_object = v8::Global<v8::Object>(isolate, apis);
453 if (data->bindings_system->get_internal_api_.IsEmpty()) { 467 if (data->bindings_system->get_internal_api_.IsEmpty()) {
454 data->bindings_system->get_internal_api_.Set( 468 data->bindings_system->get_internal_api_.Set(
455 isolate, v8::FunctionTemplate::New( 469 isolate, v8::FunctionTemplate::New(
456 isolate, &NativeExtensionBindingsSystem::GetInternalAPI, 470 isolate, &NativeExtensionBindingsSystem::GetInternalAPI,
457 v8::Local<v8::Value>(), v8::Local<v8::Signature>(), 0, 471 v8::Local<v8::Value>(), v8::Local<v8::Signature>(), 0,
458 v8::ConstructorBehavior::kThrow)); 472 v8::ConstructorBehavior::kThrow));
459 } 473 }
460 } else { 474 } else {
461 apis = data->api_object.Get(isolate); 475 apis = data->api_object.Get(isolate);
462 } 476 }
463 v8::Local<v8::Function> get_internal_api = 477 v8::Local<v8::Function> get_internal_api =
464 data->bindings_system->get_internal_api_.Get(isolate) 478 data->bindings_system->get_internal_api_.Get(isolate)
465 ->GetFunction(context) 479 ->GetFunction(context)
466 .ToLocalChecked(); 480 .ToLocalChecked();
467 481
468 // We use info.Data() to store a real name here instead of using the provided 482 v8::Local<v8::Object> result;
jbroman 2017/02/13 19:41:27 nit: Does this variable still need to exist? Looks
Devlin 2017/02/14 04:57:08 Done.
469 // one to handle any weirdness from the caller (non-existent strings, etc).
470 v8::Local<v8::String> api_name = info.Data().As<v8::String>();
471 v8::Local<v8::Value> result;
472 v8::Maybe<bool> has_property = apis->HasRealNamedProperty(context, api_name); 483 v8::Maybe<bool> has_property = apis->HasRealNamedProperty(context, api_name);
473 if (!has_property.IsJust()) 484 if (!has_property.IsJust())
474 return; 485 return v8::Local<v8::Object>();
475 486
476 if (has_property.FromJust()) { 487 if (has_property.FromJust()) {
477 result = apis->GetRealNamedProperty(context, api_name).ToLocalChecked(); 488 v8::Local<v8::Value> value =
489 apis->GetRealNamedProperty(context, api_name).ToLocalChecked();
490 DCHECK(value->IsObject());
491 result = value.As<v8::Object>();
478 } else { 492 } else {
479 ScriptContext* script_context = 493 ScriptContext* script_context =
480 ScriptContextSet::GetContextByV8Context(context); 494 ScriptContextSet::GetContextByV8Context(context);
481 std::string api_name_string; 495 std::string api_name_string;
482 CHECK(gin::Converter<std::string>::FromV8(isolate, api_name, 496 CHECK(gin::Converter<std::string>::FromV8(isolate, api_name,
483 &api_name_string)); 497 &api_name_string));
484 498
485 v8::Local<v8::Object> root_binding = CreateFullBinding( 499 v8::Local<v8::Object> root_binding = CreateFullBinding(
486 context, script_context, &data->bindings_system->api_system_, 500 context, script_context, &data->bindings_system->api_system_,
487 FeatureProvider::GetAPIFeatures(), api_name_string, get_internal_api); 501 FeatureProvider::GetAPIFeatures(), api_name_string, get_internal_api);
488 if (root_binding.IsEmpty()) 502 if (root_binding.IsEmpty())
489 return; 503 return v8::Local<v8::Object>();
490 504
491 v8::Maybe<bool> success = 505 v8::Maybe<bool> success =
492 apis->CreateDataProperty(context, api_name, root_binding); 506 apis->CreateDataProperty(context, api_name, root_binding);
493 if (!success.IsJust() || !success.FromJust()) 507 if (!success.IsJust() || !success.FromJust())
494 return; 508 return v8::Local<v8::Object>();
495 509
496 result = root_binding; 510 result = root_binding;
497 } 511 }
498 512
499 info.GetReturnValue().Set(result); 513 return result;
514 }
515
516 v8::Local<v8::Object> NativeExtensionBindingsSystem::GetRuntime(
517 v8::Local<v8::Context> context) {
518 return GetAPIHelper(context,
519 gin::StringToSymbol(context->GetIsolate(), "runtime"));
500 } 520 }
501 521
502 // static 522 // static
503 void NativeExtensionBindingsSystem::GetInternalAPI( 523 void NativeExtensionBindingsSystem::GetInternalAPI(
504 const v8::FunctionCallbackInfo<v8::Value>& info) { 524 const v8::FunctionCallbackInfo<v8::Value>& info) {
505 CHECK_EQ(1, info.Length()); 525 CHECK_EQ(1, info.Length());
506 CHECK(info[0]->IsString()); 526 CHECK(info[0]->IsString());
507 527
508 v8::Isolate* isolate = info.GetIsolate(); 528 v8::Isolate* isolate = info.GetIsolate();
509 v8::HandleScope handle_scope(isolate); 529 v8::HandleScope handle_scope(isolate);
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 625
606 void NativeExtensionBindingsSystem::OnEventListenerChanged( 626 void NativeExtensionBindingsSystem::OnEventListenerChanged(
607 const std::string& event_name, 627 const std::string& event_name,
608 binding::EventListenersChanged change, 628 binding::EventListenersChanged change,
609 v8::Local<v8::Context> context) { 629 v8::Local<v8::Context> context) {
610 send_event_listener_ipc_.Run( 630 send_event_listener_ipc_.Run(
611 change, ScriptContextSet::GetContextByV8Context(context), event_name); 631 change, ScriptContextSet::GetContextByV8Context(context), event_name);
612 } 632 }
613 633
614 } // namespace extensions 634 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698