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/api_binding.h" | 5 #include "extensions/renderer/api_binding.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
125 CHECK(dict->GetDictionary("properties", &property_dict)); | 125 CHECK(dict->GetDictionary("properties", &property_dict)); |
126 DecorateTemplateWithProperties(isolate, property_template, | 126 DecorateTemplateWithProperties(isolate, property_template, |
127 *property_dict); | 127 *property_dict); |
128 object_template->Set(isolate, iter.key().c_str(), property_template); | 128 object_template->Set(isolate, iter.key().c_str(), property_template); |
129 } | 129 } |
130 } | 130 } |
131 } | 131 } |
132 | 132 |
133 } // namespace | 133 } // namespace |
134 | 134 |
135 APIBinding::Request::Request() {} | |
136 APIBinding::Request::~Request() {} | |
137 | |
138 struct APIBinding::MethodData { | 135 struct APIBinding::MethodData { |
139 MethodData(std::string full_name, | 136 MethodData(std::string full_name, |
140 const base::ListValue& method_signature) | 137 const base::ListValue& method_signature) |
141 : full_name(std::move(full_name)), | 138 : full_name(std::move(full_name)), |
142 signature(method_signature) {} | 139 signature(method_signature) {} |
143 | 140 |
144 // The fully-qualified name of this api (e.g. runtime.sendMessage instead of | 141 // The fully-qualified name of this api (e.g. runtime.sendMessage instead of |
145 // sendMessage). | 142 // sendMessage). |
146 std::string full_name; | 143 std::string full_name; |
147 // The expected API signature. | 144 // The expected API signature. |
(...skipping 19 matching lines...) Expand all Loading... |
167 // APIBinding, and both the APIBinding and APIEventHandler are owned by the | 164 // APIBinding, and both the APIBinding and APIEventHandler are owned by the |
168 // same object (the APIBindingsSystem). | 165 // same object (the APIBindingsSystem). |
169 APIEventHandler* event_handler; | 166 APIEventHandler* event_handler; |
170 }; | 167 }; |
171 | 168 |
172 APIBinding::APIBinding(const std::string& api_name, | 169 APIBinding::APIBinding(const std::string& api_name, |
173 const base::ListValue* function_definitions, | 170 const base::ListValue* function_definitions, |
174 const base::ListValue* type_definitions, | 171 const base::ListValue* type_definitions, |
175 const base::ListValue* event_definitions, | 172 const base::ListValue* event_definitions, |
176 const base::DictionaryValue* property_definitions, | 173 const base::DictionaryValue* property_definitions, |
177 const SendRequestMethod& callback, | |
178 std::unique_ptr<APIBindingHooks> binding_hooks, | 174 std::unique_ptr<APIBindingHooks> binding_hooks, |
179 APITypeReferenceMap* type_refs, | 175 APITypeReferenceMap* type_refs, |
180 APIRequestHandler* request_handler, | 176 APIRequestHandler* request_handler, |
181 APIEventHandler* event_handler) | 177 APIEventHandler* event_handler) |
182 : api_name_(api_name), | 178 : api_name_(api_name), |
183 property_definitions_(property_definitions), | 179 property_definitions_(property_definitions), |
184 method_callback_(callback), | |
185 binding_hooks_(std::move(binding_hooks)), | 180 binding_hooks_(std::move(binding_hooks)), |
186 type_refs_(type_refs), | 181 type_refs_(type_refs), |
187 request_handler_(request_handler), | 182 request_handler_(request_handler), |
188 weak_factory_(this) { | 183 weak_factory_(this) { |
189 DCHECK(!method_callback_.is_null()); | |
190 | |
191 // TODO(devlin): It might make sense to instantiate the object_template_ | 184 // TODO(devlin): It might make sense to instantiate the object_template_ |
192 // directly here, which would avoid the need to hold on to | 185 // directly here, which would avoid the need to hold on to |
193 // |property_definitions_| and |enums_|. However, there are *some* cases where | 186 // |property_definitions_| and |enums_|. However, there are *some* cases where |
194 // we don't immediately stamp out an API from the template following | 187 // we don't immediately stamp out an API from the template following |
195 // construction. | 188 // construction. |
196 | 189 |
197 if (function_definitions) { | 190 if (function_definitions) { |
198 for (const auto& func : *function_definitions) { | 191 for (const auto& func : *function_definitions) { |
199 const base::DictionaryValue* func_dict = nullptr; | 192 const base::DictionaryValue* func_dict = nullptr; |
200 CHECK(func->GetAsDictionary(&func_dict)); | 193 CHECK(func->GetAsDictionary(&func_dict)); |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 DCHECK(!converted_arguments); | 404 DCHECK(!converted_arguments); |
412 try_catch.ReThrow(); | 405 try_catch.ReThrow(); |
413 return; | 406 return; |
414 } | 407 } |
415 } | 408 } |
416 if (invalid_invocation) { | 409 if (invalid_invocation) { |
417 arguments->ThrowTypeError("Invalid invocation"); | 410 arguments->ThrowTypeError("Invalid invocation"); |
418 return; | 411 return; |
419 } | 412 } |
420 | 413 |
421 auto request = base::MakeUnique<Request>(); | 414 request_handler_->StartRequest(context, name, std::move(converted_arguments), |
422 if (!callback.IsEmpty()) { | 415 callback, custom_callback); |
423 // In the JS bindings, custom callbacks are called with the arguments of | |
424 // name, the full request object (see below), the original callback, and | |
425 // the responses from the API. The responses from the API are handled by the | |
426 // APIRequestHandler, but we need to curry in the other values. | |
427 std::vector<v8::Local<v8::Value>> callback_args; | |
428 if (!custom_callback.IsEmpty()) { | |
429 // TODO(devlin): The |request| object in the JS bindings includes | |
430 // properties for callback, callbackSchema, args, stack, id, and | |
431 // customCallback. Of those, it appears that we only use stack, args, and | |
432 // id (since callback is curried in separately). We may be able to update | |
433 // bindings to get away from some of those. For now, just pass in an empty | |
434 // object (most APIs don't rely on it). | |
435 v8::Local<v8::Object> request = v8::Object::New(isolate); | |
436 callback_args = { gin::StringToSymbol(isolate, name), request, callback }; | |
437 callback = custom_callback; | |
438 } | |
439 request->request_id = request_handler_->AddPendingRequest( | |
440 isolate, callback, context, callback_args); | |
441 request->has_callback = true; | |
442 } | |
443 request->has_user_gesture = | |
444 blink::WebUserGestureIndicator::isProcessingUserGestureThreadSafe(); | |
445 request->arguments = std::move(converted_arguments); | |
446 request->method_name = name; | |
447 | |
448 method_callback_.Run(std::move(request), context); | |
449 } | 416 } |
450 | 417 |
451 } // namespace extensions | 418 } // namespace extensions |
OLD | NEW |