OLD | NEW |
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 "content/public/common/content_switches.h" | 8 #include "content/public/common/content_switches.h" |
9 #include "extensions/common/constants.h" | 9 #include "extensions/common/constants.h" |
10 #include "extensions/common/extension_api.h" | 10 #include "extensions/common/extension_api.h" |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 void CallJsFunction(v8::Local<v8::Function> function, | 74 void CallJsFunction(v8::Local<v8::Function> function, |
75 v8::Local<v8::Context> context, | 75 v8::Local<v8::Context> context, |
76 int argc, | 76 int argc, |
77 v8::Local<v8::Value> argv[]) { | 77 v8::Local<v8::Value> argv[]) { |
78 ScriptContext* script_context = | 78 ScriptContext* script_context = |
79 ScriptContextSet::GetContextByV8Context(context); | 79 ScriptContextSet::GetContextByV8Context(context); |
80 CHECK(script_context); | 80 CHECK(script_context); |
81 script_context->SafeCallFunction(function, argc, argv); | 81 script_context->SafeCallFunction(function, argc, argv); |
82 } | 82 } |
83 | 83 |
| 84 // A helper class for calling JS function synchronously. |
| 85 class CallJsSyncHelper { |
| 86 public: |
| 87 CallJsSyncHelper(v8::Isolate* isolate) : isolate_(isolate), |
| 88 weak_factory_(this) {} |
| 89 ~CallJsSyncHelper() {} |
| 90 |
| 91 ScriptInjectionCallback::CompleteCallback GetCallback() { |
| 92 return base::Bind(&CallJsSyncHelper::OnJsComplete, |
| 93 weak_factory_.GetWeakPtr()); |
| 94 } |
| 95 |
| 96 bool did_complete() const { return did_complete_; } |
| 97 v8::Global<v8::Value> take_result() { return std::move(result_); } |
| 98 |
| 99 private: |
| 100 void OnJsComplete(const std::vector<v8::Local<v8::Value>>& results) { |
| 101 DCHECK_EQ(1u, results.size()); |
| 102 did_complete_ = true; |
| 103 // The locals are released after the callback is executed, so we need to |
| 104 // grab a persistent handle. |
| 105 result_.Reset(isolate_, results[0]); |
| 106 } |
| 107 |
| 108 bool did_complete_ = false; |
| 109 v8::Isolate* isolate_; |
| 110 v8::Global<v8::Value> result_; |
| 111 base::WeakPtrFactory<CallJsSyncHelper> weak_factory_; |
| 112 |
| 113 DISALLOW_COPY_AND_ASSIGN(CallJsSyncHelper); |
| 114 }; |
| 115 |
| 116 v8::Global<v8::Value> CallJsFunctionSync(v8::Local<v8::Function> function, |
| 117 v8::Local<v8::Context> context, |
| 118 int argc, |
| 119 v8::Local<v8::Value> argv[]) { |
| 120 CallJsSyncHelper helper(context->GetIsolate()); |
| 121 ScriptContext* script_context = |
| 122 ScriptContextSet::GetContextByV8Context(context); |
| 123 CHECK(script_context); |
| 124 script_context->SafeCallFunction(function, argc, argv, helper.GetCallback()); |
| 125 // If the JS did not, in fact, execute synchronously, there's a big problem. |
| 126 CHECK(helper.did_complete()); |
| 127 return helper.take_result(); |
| 128 } |
| 129 |
84 // Returns the API schema indicated by |api_name|. | 130 // Returns the API schema indicated by |api_name|. |
85 const base::DictionaryValue& GetAPISchema(const std::string& api_name) { | 131 const base::DictionaryValue& GetAPISchema(const std::string& api_name) { |
86 const base::DictionaryValue* schema = | 132 const base::DictionaryValue* schema = |
87 ExtensionAPI::GetSharedInstance()->GetSchema(api_name); | 133 ExtensionAPI::GetSharedInstance()->GetSchema(api_name); |
88 CHECK(schema); | 134 CHECK(schema); |
89 return *schema; | 135 return *schema; |
90 } | 136 } |
91 | 137 |
92 // Returns true if the method specified by |method_name| is available to the | 138 // Returns true if the method specified by |method_name| is available to the |
93 // given |context|. | 139 // given |context|. |
94 bool IsAPIMethodAvailable(ScriptContext* context, | 140 bool IsAPIMethodAvailable(ScriptContext* context, |
95 const std::string& method_name) { | 141 const std::string& method_name) { |
96 return context->GetAvailability(method_name).is_available(); | 142 return context->GetAvailability(method_name).is_available(); |
97 } | 143 } |
98 | 144 |
99 } // namespace | 145 } // namespace |
100 | 146 |
101 NativeExtensionBindingsSystem::NativeExtensionBindingsSystem( | 147 NativeExtensionBindingsSystem::NativeExtensionBindingsSystem( |
102 const SendIPCMethod& send_ipc) | 148 const SendIPCMethod& send_ipc) |
103 : send_ipc_(send_ipc), | 149 : send_ipc_(send_ipc), |
104 api_system_(base::Bind(&CallJsFunction), | 150 api_system_(base::Bind(&CallJsFunction), |
| 151 base::Bind(&CallJsFunctionSync), |
105 base::Bind(&GetAPISchema), | 152 base::Bind(&GetAPISchema), |
106 base::Bind(&NativeExtensionBindingsSystem::SendRequest, | 153 base::Bind(&NativeExtensionBindingsSystem::SendRequest, |
107 base::Unretained(this))), | 154 base::Unretained(this))), |
108 weak_factory_(this) {} | 155 weak_factory_(this) {} |
109 | 156 |
110 NativeExtensionBindingsSystem::~NativeExtensionBindingsSystem() {} | 157 NativeExtensionBindingsSystem::~NativeExtensionBindingsSystem() {} |
111 | 158 |
112 void NativeExtensionBindingsSystem::DidCreateScriptContext( | 159 void NativeExtensionBindingsSystem::DidCreateScriptContext( |
113 ScriptContext* context) {} | 160 ScriptContext* context) {} |
114 | 161 |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 params.has_callback = request->has_callback; | 336 params.has_callback = request->has_callback; |
290 params.user_gesture = request->has_user_gesture; | 337 params.user_gesture = request->has_user_gesture; |
291 // TODO(devlin): Make this work in ServiceWorkers. | 338 // TODO(devlin): Make this work in ServiceWorkers. |
292 params.worker_thread_id = -1; | 339 params.worker_thread_id = -1; |
293 params.service_worker_version_id = kInvalidServiceWorkerVersionId; | 340 params.service_worker_version_id = kInvalidServiceWorkerVersionId; |
294 | 341 |
295 send_ipc_.Run(script_context, params); | 342 send_ipc_.Run(script_context, params); |
296 } | 343 } |
297 | 344 |
298 } // namespace extensions | 345 } // namespace extensions |
OLD | NEW |