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