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 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 | 186 |
187 CreateCustomType create_custom_type; | 187 CreateCustomType create_custom_type; |
188 }; | 188 }; |
189 | 189 |
190 APIBinding::APIBinding(const std::string& api_name, | 190 APIBinding::APIBinding(const std::string& api_name, |
191 const base::ListValue* function_definitions, | 191 const base::ListValue* function_definitions, |
192 const base::ListValue* type_definitions, | 192 const base::ListValue* type_definitions, |
193 const base::ListValue* event_definitions, | 193 const base::ListValue* event_definitions, |
194 const base::DictionaryValue* property_definitions, | 194 const base::DictionaryValue* property_definitions, |
195 const CreateCustomType& create_custom_type, | 195 const CreateCustomType& create_custom_type, |
| 196 const OnSilentRequest& on_silent_request, |
196 std::unique_ptr<APIBindingHooks> binding_hooks, | 197 std::unique_ptr<APIBindingHooks> binding_hooks, |
197 APITypeReferenceMap* type_refs, | 198 APITypeReferenceMap* type_refs, |
198 APIRequestHandler* request_handler, | 199 APIRequestHandler* request_handler, |
199 APIEventHandler* event_handler, | 200 APIEventHandler* event_handler, |
200 BindingAccessChecker* access_checker) | 201 BindingAccessChecker* access_checker) |
201 : api_name_(api_name), | 202 : api_name_(api_name), |
202 property_definitions_(property_definitions), | 203 property_definitions_(property_definitions), |
203 create_custom_type_(create_custom_type), | 204 create_custom_type_(create_custom_type), |
| 205 on_silent_request_(on_silent_request), |
204 binding_hooks_(std::move(binding_hooks)), | 206 binding_hooks_(std::move(binding_hooks)), |
205 type_refs_(type_refs), | 207 type_refs_(type_refs), |
206 request_handler_(request_handler), | 208 request_handler_(request_handler), |
207 event_handler_(event_handler), | 209 event_handler_(event_handler), |
208 access_checker_(access_checker), | 210 access_checker_(access_checker), |
209 weak_factory_(this) { | 211 weak_factory_(this) { |
210 // TODO(devlin): It might make sense to instantiate the object_template_ | 212 // TODO(devlin): It might make sense to instantiate the object_template_ |
211 // directly here, which would avoid the need to hold on to | 213 // directly here, which would avoid the need to hold on to |
212 // |property_definitions_| and |enums_|. However, there are *some* cases where | 214 // |property_definitions_| and |enums_|. However, there are *some* cases where |
213 // we don't immediately stamp out an API from the template following | 215 // we don't immediately stamp out an API from the template following |
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
577 // TODO(devlin): Do we need handle this for events as well? I'm not sure the | 579 // TODO(devlin): Do we need handle this for events as well? I'm not sure the |
578 // currrent system does (though perhaps it should). Investigate. | 580 // currrent system does (though perhaps it should). Investigate. |
579 return; | 581 return; |
580 } | 582 } |
581 | 583 |
582 std::vector<v8::Local<v8::Value>> argument_list = arguments->GetAll(); | 584 std::vector<v8::Local<v8::Value>> argument_list = arguments->GetAll(); |
583 | 585 |
584 bool invalid_invocation = false; | 586 bool invalid_invocation = false; |
585 v8::Local<v8::Function> custom_callback; | 587 v8::Local<v8::Function> custom_callback; |
586 bool updated_args = false; | 588 bool updated_args = false; |
| 589 int old_request_id = request_handler_->last_sent_request_id(); |
587 { | 590 { |
588 v8::TryCatch try_catch(isolate); | 591 v8::TryCatch try_catch(isolate); |
589 APIBindingHooks::RequestResult hooks_result = binding_hooks_->RunHooks( | 592 APIBindingHooks::RequestResult hooks_result = binding_hooks_->RunHooks( |
590 name, context, signature, &argument_list, *type_refs_); | 593 name, context, signature, &argument_list, *type_refs_); |
591 | 594 |
592 switch (hooks_result.code) { | 595 switch (hooks_result.code) { |
593 case APIBindingHooks::RequestResult::INVALID_INVOCATION: | 596 case APIBindingHooks::RequestResult::INVALID_INVOCATION: |
594 invalid_invocation = true; | 597 invalid_invocation = true; |
595 error = std::move(hooks_result.error); | 598 error = std::move(hooks_result.error); |
596 // Throw a type error below so that it's not caught by our try-catch. | 599 // Throw a type error below so that it's not caught by our try-catch. |
597 break; | 600 break; |
598 case APIBindingHooks::RequestResult::THROWN: | 601 case APIBindingHooks::RequestResult::THROWN: |
599 DCHECK(try_catch.HasCaught()); | 602 DCHECK(try_catch.HasCaught()); |
600 try_catch.ReThrow(); | 603 try_catch.ReThrow(); |
601 return; | 604 return; |
602 case APIBindingHooks::RequestResult::HANDLED: | 605 case APIBindingHooks::RequestResult::HANDLED: |
603 if (!hooks_result.return_value.IsEmpty()) | 606 if (!hooks_result.return_value.IsEmpty()) |
604 arguments->Return(hooks_result.return_value); | 607 arguments->Return(hooks_result.return_value); |
| 608 |
| 609 // TODO(devlin): This is a pretty simplistic implementation of this, |
| 610 // but it's similar to the current JS logic. If we wanted to be more |
| 611 // correct, we could create a RequestScope object that watches outgoing |
| 612 // requests. |
| 613 if (old_request_id == request_handler_->last_sent_request_id()) |
| 614 on_silent_request_.Run(context, name, argument_list); |
| 615 |
605 return; // Our work here is done. | 616 return; // Our work here is done. |
606 case APIBindingHooks::RequestResult::ARGUMENTS_UPDATED: | 617 case APIBindingHooks::RequestResult::ARGUMENTS_UPDATED: |
607 updated_args = true; // Intentional fall-through. | 618 updated_args = true; // Intentional fall-through. |
608 case APIBindingHooks::RequestResult::NOT_HANDLED: | 619 case APIBindingHooks::RequestResult::NOT_HANDLED: |
609 break; // Handle in the default manner. | 620 break; // Handle in the default manner. |
610 } | 621 } |
611 custom_callback = hooks_result.custom_callback; | 622 custom_callback = hooks_result.custom_callback; |
612 } | 623 } |
613 | 624 |
614 if (invalid_invocation) { | 625 if (invalid_invocation) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 arguments->ThrowTypeError(api_errors::InvocationError( | 665 arguments->ThrowTypeError(api_errors::InvocationError( |
655 name, signature->GetExpectedSignature(), error)); | 666 name, signature->GetExpectedSignature(), error)); |
656 return; | 667 return; |
657 } | 668 } |
658 | 669 |
659 request_handler_->StartRequest(context, name, std::move(converted_arguments), | 670 request_handler_->StartRequest(context, name, std::move(converted_arguments), |
660 callback, custom_callback, thread); | 671 callback, custom_callback, thread); |
661 } | 672 } |
662 | 673 |
663 } // namespace extensions | 674 } // namespace extensions |
OLD | NEW |