Chromium Code Reviews| 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 f04aa91a2ccedfef21a1bdb069684ec3ca22283b..46d09a09959daad77479237ccc59b3728237cc93 100644 |
| --- a/extensions/renderer/native_extension_bindings_system.cc |
| +++ b/extensions/renderer/native_extension_bindings_system.cc |
| @@ -82,6 +82,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) { |
| + did_complete_ = true; |
| + // The locals are released after the callback is executed, so we need to |
| + // grab a persistent handle. |
| + if (!results.empty() && !results[0].IsEmpty()) |
| + 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()); |
|
jbroman
2017/01/02 19:46:38
WDYT of this, which seems to do the same but be so
Devlin
2017/01/04 17:57:02
I like it. Done.
I've also added a TODO to expre
|
| + // 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 = |
| @@ -103,6 +149,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))), |