| Index: extensions/renderer/native_extension_bindings_system.cc
|
| diff --git a/extensions/renderer/native_extension_bindings_system.cc b/extensions/renderer/native_extension_bindings_system.cc
|
| index 0669c14dc3e52108856cc791769a6304f4a7f371..a67b01180d520099d04c81c1afe94ce949da339d 100644
|
| --- a/extensions/renderer/native_extension_bindings_system.cc
|
| +++ b/extensions/renderer/native_extension_bindings_system.cc
|
| @@ -81,6 +81,52 @@ void CallJsFunction(v8::Local<v8::Function> function,
|
| script_context->SafeCallFunction(function, argc, argv);
|
| }
|
|
|
| +// A helper class for calling JS function synchronously.
|
| +class CallJsSyncHelper {
|
| + public:
|
| + CallJsSyncHelper(v8::Isolate* isolate) : isolate_(isolate),
|
| + weak_factory_(this) {}
|
| + ~CallJsSyncHelper() {}
|
| +
|
| + ScriptInjectionCallback::CompleteCallback GetCallback() {
|
| + return base::Bind(&CallJsSyncHelper::OnJsComplete,
|
| + weak_factory_.GetWeakPtr());
|
| + }
|
| +
|
| + bool did_complete() const { return did_complete_; }
|
| + v8::Global<v8::Value> take_result() { return std::move(result_); }
|
| +
|
| + private:
|
| + void OnJsComplete(const std::vector<v8::Local<v8::Value>>& results) {
|
| + DCHECK_EQ(1u, results.size());
|
| + did_complete_ = true;
|
| + // The locals are released after the callback is executed, so we need to
|
| + // grab a persistent handle.
|
| + result_.Reset(isolate_, results[0]);
|
| + }
|
| +
|
| + bool did_complete_ = false;
|
| + v8::Isolate* isolate_;
|
| + v8::Global<v8::Value> result_;
|
| + base::WeakPtrFactory<CallJsSyncHelper> weak_factory_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(CallJsSyncHelper);
|
| +};
|
| +
|
| +v8::Global<v8::Value> CallJsFunctionSync(v8::Local<v8::Function> function,
|
| + v8::Local<v8::Context> context,
|
| + int argc,
|
| + v8::Local<v8::Value> argv[]) {
|
| + CallJsSyncHelper helper(context->GetIsolate());
|
| + ScriptContext* script_context =
|
| + ScriptContextSet::GetContextByV8Context(context);
|
| + CHECK(script_context);
|
| + script_context->SafeCallFunction(function, argc, argv, helper.GetCallback());
|
| + // If the JS did not, in fact, execute synchronously, there's a big problem.
|
| + CHECK(helper.did_complete());
|
| + return helper.take_result();
|
| +}
|
| +
|
| // Returns the API schema indicated by |api_name|.
|
| const base::DictionaryValue& GetAPISchema(const std::string& api_name) {
|
| const base::DictionaryValue* schema =
|
| @@ -102,6 +148,7 @@ NativeExtensionBindingsSystem::NativeExtensionBindingsSystem(
|
| const SendIPCMethod& send_ipc)
|
| : send_ipc_(send_ipc),
|
| api_system_(base::Bind(&CallJsFunction),
|
| + base::Bind(&CallJsFunctionSync),
|
| base::Bind(&GetAPISchema),
|
| base::Bind(&NativeExtensionBindingsSystem::SendRequest,
|
| base::Unretained(this))),
|
|
|