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/bindings/api_binding.h" | 5 #include "extensions/renderer/bindings/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 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 | 171 |
172 CreateCustomType create_custom_type; | 172 CreateCustomType create_custom_type; |
173 }; | 173 }; |
174 | 174 |
175 APIBinding::APIBinding(const std::string& api_name, | 175 APIBinding::APIBinding(const std::string& api_name, |
176 const base::ListValue* function_definitions, | 176 const base::ListValue* function_definitions, |
177 const base::ListValue* type_definitions, | 177 const base::ListValue* type_definitions, |
178 const base::ListValue* event_definitions, | 178 const base::ListValue* event_definitions, |
179 const base::DictionaryValue* property_definitions, | 179 const base::DictionaryValue* property_definitions, |
180 const CreateCustomType& create_custom_type, | 180 const CreateCustomType& create_custom_type, |
| 181 const OnSilentRequest& on_silent_request, |
181 std::unique_ptr<APIBindingHooks> binding_hooks, | 182 std::unique_ptr<APIBindingHooks> binding_hooks, |
182 APITypeReferenceMap* type_refs, | 183 APITypeReferenceMap* type_refs, |
183 APIRequestHandler* request_handler, | 184 APIRequestHandler* request_handler, |
184 APIEventHandler* event_handler, | 185 APIEventHandler* event_handler, |
185 BindingAccessChecker* access_checker) | 186 BindingAccessChecker* access_checker) |
186 : api_name_(api_name), | 187 : api_name_(api_name), |
187 property_definitions_(property_definitions), | 188 property_definitions_(property_definitions), |
188 create_custom_type_(create_custom_type), | 189 create_custom_type_(create_custom_type), |
| 190 on_silent_request_(on_silent_request), |
189 binding_hooks_(std::move(binding_hooks)), | 191 binding_hooks_(std::move(binding_hooks)), |
190 type_refs_(type_refs), | 192 type_refs_(type_refs), |
191 request_handler_(request_handler), | 193 request_handler_(request_handler), |
192 event_handler_(event_handler), | 194 event_handler_(event_handler), |
193 access_checker_(access_checker), | 195 access_checker_(access_checker), |
194 weak_factory_(this) { | 196 weak_factory_(this) { |
195 // TODO(devlin): It might make sense to instantiate the object_template_ | 197 // TODO(devlin): It might make sense to instantiate the object_template_ |
196 // directly here, which would avoid the need to hold on to | 198 // directly here, which would avoid the need to hold on to |
197 // |property_definitions_| and |enums_|. However, there are *some* cases where | 199 // |property_definitions_| and |enums_|. However, there are *some* cases where |
198 // we don't immediately stamp out an API from the template following | 200 // we don't immediately stamp out an API from the template following |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
545 // TODO(devlin): Do we need handle this for events as well? I'm not sure the | 547 // TODO(devlin): Do we need handle this for events as well? I'm not sure the |
546 // currrent system does (though perhaps it should). Investigate. | 548 // currrent system does (though perhaps it should). Investigate. |
547 return; | 549 return; |
548 } | 550 } |
549 | 551 |
550 std::vector<v8::Local<v8::Value>> argument_list = arguments->GetAll(); | 552 std::vector<v8::Local<v8::Value>> argument_list = arguments->GetAll(); |
551 | 553 |
552 bool invalid_invocation = false; | 554 bool invalid_invocation = false; |
553 v8::Local<v8::Function> custom_callback; | 555 v8::Local<v8::Function> custom_callback; |
554 bool updated_args = false; | 556 bool updated_args = false; |
| 557 int old_request_id = request_handler_->last_sent_request_id(); |
555 { | 558 { |
556 v8::TryCatch try_catch(isolate); | 559 v8::TryCatch try_catch(isolate); |
557 APIBindingHooks::RequestResult hooks_result = binding_hooks_->RunHooks( | 560 APIBindingHooks::RequestResult hooks_result = binding_hooks_->RunHooks( |
558 name, context, signature, &argument_list, *type_refs_); | 561 name, context, signature, &argument_list, *type_refs_); |
559 | 562 |
560 switch (hooks_result.code) { | 563 switch (hooks_result.code) { |
561 case APIBindingHooks::RequestResult::INVALID_INVOCATION: | 564 case APIBindingHooks::RequestResult::INVALID_INVOCATION: |
562 invalid_invocation = true; | 565 invalid_invocation = true; |
563 error = std::move(hooks_result.error); | 566 error = std::move(hooks_result.error); |
564 // Throw a type error below so that it's not caught by our try-catch. | 567 // Throw a type error below so that it's not caught by our try-catch. |
565 break; | 568 break; |
566 case APIBindingHooks::RequestResult::THROWN: | 569 case APIBindingHooks::RequestResult::THROWN: |
567 DCHECK(try_catch.HasCaught()); | 570 DCHECK(try_catch.HasCaught()); |
568 try_catch.ReThrow(); | 571 try_catch.ReThrow(); |
569 return; | 572 return; |
570 case APIBindingHooks::RequestResult::HANDLED: | 573 case APIBindingHooks::RequestResult::HANDLED: |
571 if (!hooks_result.return_value.IsEmpty()) | 574 if (!hooks_result.return_value.IsEmpty()) |
572 arguments->Return(hooks_result.return_value); | 575 arguments->Return(hooks_result.return_value); |
| 576 |
| 577 // TODO(devlin): This is a pretty simplistic implementation of this, |
| 578 // but it's similar to the current JS logic. If we wanted to be more |
| 579 // correct, we could create a RequestScope object that watches outgoing |
| 580 // requests. |
| 581 if (old_request_id == request_handler_->last_sent_request_id()) |
| 582 on_silent_request_.Run(context, name, argument_list); |
| 583 |
573 return; // Our work here is done. | 584 return; // Our work here is done. |
574 case APIBindingHooks::RequestResult::ARGUMENTS_UPDATED: | 585 case APIBindingHooks::RequestResult::ARGUMENTS_UPDATED: |
575 updated_args = true; // Intentional fall-through. | 586 updated_args = true; // Intentional fall-through. |
576 case APIBindingHooks::RequestResult::NOT_HANDLED: | 587 case APIBindingHooks::RequestResult::NOT_HANDLED: |
577 break; // Handle in the default manner. | 588 break; // Handle in the default manner. |
578 } | 589 } |
579 custom_callback = hooks_result.custom_callback; | 590 custom_callback = hooks_result.custom_callback; |
580 } | 591 } |
581 | 592 |
582 if (invalid_invocation) { | 593 if (invalid_invocation) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
622 arguments->ThrowTypeError(api_errors::InvocationError( | 633 arguments->ThrowTypeError(api_errors::InvocationError( |
623 name, signature->GetExpectedSignature(), error)); | 634 name, signature->GetExpectedSignature(), error)); |
624 return; | 635 return; |
625 } | 636 } |
626 | 637 |
627 request_handler_->StartRequest(context, name, std::move(converted_arguments), | 638 request_handler_->StartRequest(context, name, std::move(converted_arguments), |
628 callback, custom_callback, thread); | 639 callback, custom_callback, thread); |
629 } | 640 } |
630 | 641 |
631 } // namespace extensions | 642 } // namespace extensions |
OLD | NEW |