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