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 "modules/payments/PaymentRequest.h" | 5 #include "modules/payments/PaymentRequest.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <utility> | 8 #include <utility> |
9 #include "bindings/core/v8/ExceptionState.h" | 9 #include "bindings/core/v8/ExceptionState.h" |
10 #include "bindings/core/v8/ScriptPromiseResolver.h" | 10 #include "bindings/core/v8/ScriptPromiseResolver.h" |
11 #include "bindings/core/v8/ScriptState.h" | 11 #include "bindings/core/v8/ScriptState.h" |
12 #include "bindings/core/v8/V8StringResource.h" | 12 #include "bindings/core/v8/V8StringResource.h" |
13 #include "bindings/modules/v8/V8AndroidPayMethodData.h" | 13 #include "bindings/modules/v8/V8AndroidPayMethodData.h" |
14 #include "bindings/modules/v8/V8BasicCardRequest.h" | 14 #include "bindings/modules/v8/V8BasicCardRequest.h" |
15 #include "bindings/modules/v8/V8PaymentDetailsUpdate.h" | 15 #include "bindings/modules/v8/V8PaymentDetails.h" |
16 #include "core/EventTypeNames.h" | 16 #include "core/EventTypeNames.h" |
17 #include "core/dom/DOMException.h" | 17 #include "core/dom/DOMException.h" |
18 #include "core/dom/Document.h" | 18 #include "core/dom/Document.h" |
19 #include "core/dom/ExceptionCode.h" | 19 #include "core/dom/ExceptionCode.h" |
20 #include "core/dom/TaskRunnerHelper.h" | 20 #include "core/dom/TaskRunnerHelper.h" |
21 #include "core/events/Event.h" | 21 #include "core/events/Event.h" |
22 #include "core/events/EventQueue.h" | 22 #include "core/events/EventQueue.h" |
23 #include "core/frame/FrameOwner.h" | 23 #include "core/frame/FrameOwner.h" |
24 #include "core/html/HTMLIFrameElement.h" | 24 #include "core/html/HTMLIFrameElement.h" |
25 #include "core/inspector/ConsoleMessage.h" | 25 #include "core/inspector/ConsoleMessage.h" |
26 #include "core/inspector/ConsoleTypes.h" | 26 #include "core/inspector/ConsoleTypes.h" |
27 #include "modules/EventTargetModulesNames.h" | 27 #include "modules/EventTargetModulesNames.h" |
28 #include "modules/payments/AndroidPayMethodData.h" | 28 #include "modules/payments/AndroidPayMethodData.h" |
29 #include "modules/payments/AndroidPayTokenization.h" | 29 #include "modules/payments/AndroidPayTokenization.h" |
30 #include "modules/payments/BasicCardRequest.h" | 30 #include "modules/payments/BasicCardRequest.h" |
31 #include "modules/payments/HTMLIFrameElementPayments.h" | 31 #include "modules/payments/HTMLIFrameElementPayments.h" |
32 #include "modules/payments/PaymentAddress.h" | 32 #include "modules/payments/PaymentAddress.h" |
33 #include "modules/payments/PaymentDetailsInit.h" | |
34 #include "modules/payments/PaymentDetailsUpdate.h" | |
35 #include "modules/payments/PaymentItem.h" | 33 #include "modules/payments/PaymentItem.h" |
36 #include "modules/payments/PaymentRequestUpdateEvent.h" | 34 #include "modules/payments/PaymentRequestUpdateEvent.h" |
37 #include "modules/payments/PaymentResponse.h" | 35 #include "modules/payments/PaymentResponse.h" |
38 #include "modules/payments/PaymentShippingOption.h" | 36 #include "modules/payments/PaymentShippingOption.h" |
39 #include "modules/payments/PaymentsValidators.h" | 37 #include "modules/payments/PaymentsValidators.h" |
40 #include "mojo/public/cpp/bindings/interface_request.h" | 38 #include "mojo/public/cpp/bindings/interface_request.h" |
41 #include "platform/RuntimeEnabledFeatures.h" | 39 #include "platform/RuntimeEnabledFeatures.h" |
42 #include "platform/mojo/MojoHelper.h" | 40 #include "platform/mojo/MojoHelper.h" |
43 #include "public/platform/InterfaceProvider.h" | 41 #include "public/platform/InterfaceProvider.h" |
44 #include "public/platform/Platform.h" | 42 #include "public/platform/Platform.h" |
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 String getSelectedShippingOption( | 465 String getSelectedShippingOption( |
468 const Vector<PaymentShippingOptionPtr>& shippingOptions) { | 466 const Vector<PaymentShippingOptionPtr>& shippingOptions) { |
469 String result; | 467 String result; |
470 for (const PaymentShippingOptionPtr& shippingOption : shippingOptions) { | 468 for (const PaymentShippingOptionPtr& shippingOption : shippingOptions) { |
471 if (shippingOption->selected) | 469 if (shippingOption->selected) |
472 result = shippingOption->id; | 470 result = shippingOption->id; |
473 } | 471 } |
474 return result; | 472 return result; |
475 } | 473 } |
476 | 474 |
477 void validateAndConvertPaymentDetailsBase(const PaymentDetailsBase& input, | 475 void validateAndConvertPaymentDetails(const PaymentDetails& input, |
478 bool requestShipping, | 476 bool requestShipping, |
479 PaymentDetailsPtr& output, | 477 PaymentDetailsPtr& output, |
480 String& shippingOptionOutput, | 478 String& shippingOptionOutput, |
481 ExecutionContext& executionContext, | 479 ExecutionContext& executionContext, |
482 ExceptionState& exceptionState) { | 480 ExceptionState& exceptionState) { |
| 481 if (!input.hasTotal()) { |
| 482 exceptionState.throwTypeError("Must specify total"); |
| 483 return; |
| 484 } |
| 485 |
| 486 validateAndConvertTotal(input.total(), output->total, exceptionState); |
| 487 if (exceptionState.hadException()) |
| 488 return; |
| 489 |
483 if (input.hasDisplayItems()) { | 490 if (input.hasDisplayItems()) { |
484 validateAndConvertDisplayItems(input.displayItems(), output->display_items, | 491 validateAndConvertDisplayItems(input.displayItems(), output->display_items, |
485 exceptionState); | 492 exceptionState); |
486 if (exceptionState.hadException()) | 493 if (exceptionState.hadException()) |
487 return; | 494 return; |
488 } | 495 } |
489 | 496 |
490 if (input.hasShippingOptions() && requestShipping) { | 497 if (input.hasShippingOptions() && requestShipping) { |
491 validateAndConvertShippingOptions(input.shippingOptions(), | 498 validateAndConvertShippingOptions(input.shippingOptions(), |
492 output->shipping_options, exceptionState); | 499 output->shipping_options, exceptionState); |
493 if (exceptionState.hadException()) | 500 if (exceptionState.hadException()) |
494 return; | 501 return; |
495 } | 502 } |
496 | 503 |
497 shippingOptionOutput = getSelectedShippingOption(output->shipping_options); | 504 shippingOptionOutput = getSelectedShippingOption(output->shipping_options); |
498 | 505 |
499 if (input.hasModifiers()) { | 506 if (input.hasModifiers()) { |
500 validateAndConvertPaymentDetailsModifiers( | 507 validateAndConvertPaymentDetailsModifiers( |
501 input.modifiers(), output->modifiers, executionContext, exceptionState); | 508 input.modifiers(), output->modifiers, executionContext, exceptionState); |
502 if (exceptionState.hadException()) | 509 if (exceptionState.hadException()) |
503 return; | 510 return; |
504 } | 511 } |
505 } | |
506 | |
507 void validateAndConvertPaymentDetailsInit(const PaymentDetailsInit& input, | |
508 bool requestShipping, | |
509 PaymentDetailsPtr& output, | |
510 String& shippingOptionOutput, | |
511 ExecutionContext& executionContext, | |
512 ExceptionState& exceptionState) { | |
513 validateAndConvertPaymentDetailsBase(input, requestShipping, output, | |
514 shippingOptionOutput, executionContext, | |
515 exceptionState); | |
516 if (exceptionState.hadException()) | |
517 return; | |
518 | |
519 if (!input.hasTotal()) { | |
520 exceptionState.throwTypeError("Must specify total"); | |
521 return; | |
522 } | |
523 | |
524 validateAndConvertTotal(input.total(), output->total, exceptionState); | |
525 } | |
526 | |
527 void validateAndConvertPaymentDetailsUpdate(const PaymentDetailsUpdate& input, | |
528 bool requestShipping, | |
529 PaymentDetailsPtr& output, | |
530 String& shippingOptionOutput, | |
531 ExecutionContext& executionContext, | |
532 ExceptionState& exceptionState) { | |
533 validateAndConvertPaymentDetailsBase(input, requestShipping, output, | |
534 shippingOptionOutput, executionContext, | |
535 exceptionState); | |
536 if (exceptionState.hadException()) | |
537 return; | |
538 | |
539 if (input.hasTotal()) { | |
540 validateAndConvertTotal(input.total(), output->total, exceptionState); | |
541 if (exceptionState.hadException()) | |
542 return; | |
543 } | |
544 | 512 |
545 if (input.hasError() && !input.error().isNull()) { | 513 if (input.hasError() && !input.error().isNull()) { |
546 String errorMessage; | 514 String errorMessage; |
547 if (!PaymentsValidators::isValidErrorMsgFormat(input.error(), | 515 if (!PaymentsValidators::isValidErrorMsgFormat(input.error(), |
548 &errorMessage)) { | 516 &errorMessage)) { |
549 exceptionState.throwTypeError(errorMessage); | 517 exceptionState.throwTypeError(errorMessage); |
550 return; | 518 return; |
551 } | 519 } |
552 output->error = input.error(); | 520 output->error = input.error(); |
553 } else { | 521 } else { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
653 // Otherwise, paymentrequest is not allowed. (If we reach here and this is | 621 // Otherwise, paymentrequest is not allowed. (If we reach here and this is |
654 // the main frame, then paymentrequest must have been disabled by FP.) | 622 // the main frame, then paymentrequest must have been disabled by FP.) |
655 return false; | 623 return false; |
656 } | 624 } |
657 | 625 |
658 } // namespace | 626 } // namespace |
659 | 627 |
660 PaymentRequest* PaymentRequest::create( | 628 PaymentRequest* PaymentRequest::create( |
661 ExecutionContext* executionContext, | 629 ExecutionContext* executionContext, |
662 const HeapVector<PaymentMethodData>& methodData, | 630 const HeapVector<PaymentMethodData>& methodData, |
663 const PaymentDetailsInit& details, | 631 const PaymentDetails& details, |
664 ExceptionState& exceptionState) { | 632 ExceptionState& exceptionState) { |
665 return new PaymentRequest(executionContext, methodData, details, | 633 return new PaymentRequest(executionContext, methodData, details, |
666 PaymentOptions(), exceptionState); | 634 PaymentOptions(), exceptionState); |
667 } | 635 } |
668 | 636 |
669 PaymentRequest* PaymentRequest::create( | 637 PaymentRequest* PaymentRequest::create( |
670 ExecutionContext* executionContext, | 638 ExecutionContext* executionContext, |
671 const HeapVector<PaymentMethodData>& methodData, | 639 const HeapVector<PaymentMethodData>& methodData, |
672 const PaymentDetailsInit& details, | 640 const PaymentDetails& details, |
673 const PaymentOptions& options, | 641 const PaymentOptions& options, |
674 ExceptionState& exceptionState) { | 642 ExceptionState& exceptionState) { |
675 return new PaymentRequest(executionContext, methodData, details, options, | 643 return new PaymentRequest(executionContext, methodData, details, options, |
676 exceptionState); | 644 exceptionState); |
677 } | 645 } |
678 | 646 |
679 PaymentRequest::~PaymentRequest() {} | 647 PaymentRequest::~PaymentRequest() {} |
680 | 648 |
681 ScriptPromise PaymentRequest::show(ScriptState* scriptState) { | 649 ScriptPromise PaymentRequest::show(ScriptState* scriptState) { |
682 if (!m_paymentProvider.is_bound() || m_showResolver) { | 650 if (!m_paymentProvider.is_bound() || m_showResolver) { |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
786 | 754 |
787 m_completeResolver = ScriptPromiseResolver::create(scriptState); | 755 m_completeResolver = ScriptPromiseResolver::create(scriptState); |
788 return m_completeResolver->promise(); | 756 return m_completeResolver->promise(); |
789 } | 757 } |
790 | 758 |
791 void PaymentRequest::onUpdatePaymentDetails( | 759 void PaymentRequest::onUpdatePaymentDetails( |
792 const ScriptValue& detailsScriptValue) { | 760 const ScriptValue& detailsScriptValue) { |
793 if (!m_showResolver || !m_paymentProvider) | 761 if (!m_showResolver || !m_paymentProvider) |
794 return; | 762 return; |
795 | 763 |
796 PaymentDetailsUpdate details; | 764 PaymentDetails details; |
797 ExceptionState exceptionState(v8::Isolate::GetCurrent(), | 765 ExceptionState exceptionState(v8::Isolate::GetCurrent(), |
798 ExceptionState::ConstructionContext, | 766 ExceptionState::ConstructionContext, |
799 "PaymentDetailsUpdate"); | 767 "PaymentDetails"); |
800 V8PaymentDetailsUpdate::toImpl(detailsScriptValue.isolate(), | 768 V8PaymentDetails::toImpl(detailsScriptValue.isolate(), |
801 detailsScriptValue.v8Value(), details, | 769 detailsScriptValue.v8Value(), details, |
802 exceptionState); | 770 exceptionState); |
803 if (exceptionState.hadException()) { | 771 if (exceptionState.hadException()) { |
804 m_showResolver->reject( | 772 m_showResolver->reject( |
805 DOMException::create(SyntaxError, exceptionState.message())); | 773 DOMException::create(SyntaxError, exceptionState.message())); |
806 clearResolversAndCloseMojoConnection(); | 774 clearResolversAndCloseMojoConnection(); |
807 return; | 775 return; |
808 } | 776 } |
809 | 777 |
810 PaymentDetailsPtr validatedDetails = | 778 PaymentDetailsPtr validatedDetails = |
811 payments::mojom::blink::PaymentDetails::New(); | 779 payments::mojom::blink::PaymentDetails::New(); |
812 validateAndConvertPaymentDetailsUpdate( | 780 validateAndConvertPaymentDetails(details, m_options.requestShipping(), |
813 details, m_options.requestShipping(), validatedDetails, m_shippingOption, | 781 validatedDetails, m_shippingOption, |
814 *getExecutionContext(), exceptionState); | 782 *getExecutionContext(), exceptionState); |
815 if (exceptionState.hadException()) { | 783 if (exceptionState.hadException()) { |
816 m_showResolver->reject( | 784 m_showResolver->reject( |
817 DOMException::create(SyntaxError, exceptionState.message())); | 785 DOMException::create(SyntaxError, exceptionState.message())); |
818 clearResolversAndCloseMojoConnection(); | 786 clearResolversAndCloseMojoConnection(); |
819 return; | 787 return; |
820 } | 788 } |
821 | 789 |
822 m_paymentProvider->UpdateWith(std::move(validatedDetails)); | 790 m_paymentProvider->UpdateWith(std::move(validatedDetails)); |
823 } | 791 } |
824 | 792 |
(...skipping 16 matching lines...) Expand all Loading... |
841 ContextLifecycleObserver::trace(visitor); | 809 ContextLifecycleObserver::trace(visitor); |
842 } | 810 } |
843 | 811 |
844 void PaymentRequest::onCompleteTimeoutForTesting() { | 812 void PaymentRequest::onCompleteTimeoutForTesting() { |
845 m_completeTimer.stop(); | 813 m_completeTimer.stop(); |
846 onCompleteTimeout(0); | 814 onCompleteTimeout(0); |
847 } | 815 } |
848 | 816 |
849 PaymentRequest::PaymentRequest(ExecutionContext* executionContext, | 817 PaymentRequest::PaymentRequest(ExecutionContext* executionContext, |
850 const HeapVector<PaymentMethodData>& methodData, | 818 const HeapVector<PaymentMethodData>& methodData, |
851 const PaymentDetailsInit& details, | 819 const PaymentDetails& details, |
852 const PaymentOptions& options, | 820 const PaymentOptions& options, |
853 ExceptionState& exceptionState) | 821 ExceptionState& exceptionState) |
854 : ContextLifecycleObserver(executionContext), | 822 : ContextLifecycleObserver(executionContext), |
855 m_options(options), | 823 m_options(options), |
856 m_clientBinding(this), | 824 m_clientBinding(this), |
857 m_completeTimer(TaskRunnerHelper::get(TaskType::MiscPlatformAPI, frame()), | 825 m_completeTimer(TaskRunnerHelper::get(TaskType::MiscPlatformAPI, frame()), |
858 this, | 826 this, |
859 &PaymentRequest::onCompleteTimeout) { | 827 &PaymentRequest::onCompleteTimeout) { |
860 Vector<payments::mojom::blink::PaymentMethodDataPtr> validatedMethodData; | 828 Vector<payments::mojom::blink::PaymentMethodDataPtr> validatedMethodData; |
861 validateAndConvertPaymentMethodData(methodData, validatedMethodData, | 829 validateAndConvertPaymentMethodData(methodData, validatedMethodData, |
862 *getExecutionContext(), exceptionState); | 830 *getExecutionContext(), exceptionState); |
863 if (exceptionState.hadException()) | 831 if (exceptionState.hadException()) |
864 return; | 832 return; |
865 | 833 |
866 if (!getExecutionContext()->isSecureContext()) { | 834 if (!getExecutionContext()->isSecureContext()) { |
867 exceptionState.throwSecurityError("Must be in a secure context"); | 835 exceptionState.throwSecurityError("Must be in a secure context"); |
868 return; | 836 return; |
869 } | 837 } |
870 | 838 |
871 if (!allowedToUsePaymentRequest(frame())) { | 839 if (!allowedToUsePaymentRequest(frame())) { |
872 exceptionState.throwSecurityError( | 840 exceptionState.throwSecurityError( |
873 "Must be in a top-level browsing context or an iframe needs to specify " | 841 "Must be in a top-level browsing context or an iframe needs to specify " |
874 "'allowpaymentrequest' explicitly"); | 842 "'allowpaymentrequest' explicitly"); |
875 return; | 843 return; |
876 } | 844 } |
877 | 845 |
878 PaymentDetailsPtr validatedDetails = | 846 PaymentDetailsPtr validatedDetails = |
879 payments::mojom::blink::PaymentDetails::New(); | 847 payments::mojom::blink::PaymentDetails::New(); |
880 validateAndConvertPaymentDetailsInit(details, m_options.requestShipping(), | 848 validateAndConvertPaymentDetails(details, m_options.requestShipping(), |
881 validatedDetails, m_shippingOption, | 849 validatedDetails, m_shippingOption, |
882 *getExecutionContext(), exceptionState); | 850 *getExecutionContext(), exceptionState); |
883 if (exceptionState.hadException()) | 851 if (exceptionState.hadException()) |
884 return; | 852 return; |
885 | 853 |
| 854 if (details.hasError()) { |
| 855 exceptionState.throwTypeError("Error message not allowed in constructor"); |
| 856 return; |
| 857 } |
| 858 |
886 if (m_options.requestShipping()) | 859 if (m_options.requestShipping()) |
887 m_shippingType = getValidShippingType(m_options.shippingType()); | 860 m_shippingType = getValidShippingType(m_options.shippingType()); |
888 | 861 |
889 frame()->interfaceProvider()->getInterface( | 862 frame()->interfaceProvider()->getInterface( |
890 mojo::MakeRequest(&m_paymentProvider)); | 863 mojo::MakeRequest(&m_paymentProvider)); |
891 m_paymentProvider.set_connection_error_handler(convertToBaseCallback( | 864 m_paymentProvider.set_connection_error_handler(convertToBaseCallback( |
892 WTF::bind(&PaymentRequest::OnError, wrapWeakPersistent(this), | 865 WTF::bind(&PaymentRequest::OnError, wrapWeakPersistent(this), |
893 PaymentErrorReason::UNKNOWN))); | 866 PaymentErrorReason::UNKNOWN))); |
894 m_paymentProvider->Init( | 867 m_paymentProvider->Init( |
895 m_clientBinding.CreateInterfacePtrAndBind(), | 868 m_clientBinding.CreateInterfacePtrAndBind(), |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1072 m_completeResolver.clear(); | 1045 m_completeResolver.clear(); |
1073 m_showResolver.clear(); | 1046 m_showResolver.clear(); |
1074 m_abortResolver.clear(); | 1047 m_abortResolver.clear(); |
1075 m_canMakePaymentResolver.clear(); | 1048 m_canMakePaymentResolver.clear(); |
1076 if (m_clientBinding.is_bound()) | 1049 if (m_clientBinding.is_bound()) |
1077 m_clientBinding.Close(); | 1050 m_clientBinding.Close(); |
1078 m_paymentProvider.reset(); | 1051 m_paymentProvider.reset(); |
1079 } | 1052 } |
1080 | 1053 |
1081 } // namespace blink | 1054 } // namespace blink |
OLD | NEW |