Commit cf391422 authored by Liquan (Max) Gu's avatar Liquan (Max) Gu Committed by Commit Bot

[WebLayer] Refactors CPRService#updateWith

Changes:
* Replaced `mPaymentUiService.getPaymentRequestUI() == null` with
  `mIsCurrentPaymentRequestShowing` as the way to check for 'update-
  without-show".
* Renamed "parseAndValidateDetailsForSkipToGPayHelper" as
  "parseAndValidateDetailsFurtherIfNeeded" because PRService needs to
  call it, and PRService does not know about skip-to-gpay.
* Moved the main logic of CPRService#updateWith into PRService, with
  the remaining part called onPaymentDetailsUpdated() left in
  CPRService.
* Since "invokedPaymentApp.updateWith()" is moved into PRService,
  PRService delegates the dependency MethodChecker.

Bug: 1131059

Change-Id: If305338491240b16d230e3ab6b43d0c64c256de7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2530312
Commit-Queue: Liquan (Max) Gu <maxlg@chromium.org>
Reviewed-by: default avatarRouslan Solomakhin <rouslan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#826326}
parent caa82f8f
......@@ -31,6 +31,7 @@ import org.chromium.components.payments.PaymentApp;
import org.chromium.components.payments.PaymentAppService;
import org.chromium.components.payments.PaymentAppType;
import org.chromium.components.payments.PaymentDetailsConverter;
import org.chromium.components.payments.PaymentDetailsConverter.MethodChecker;
import org.chromium.components.payments.PaymentDetailsUpdateServiceHelper;
import org.chromium.components.payments.PaymentFeatureList;
import org.chromium.components.payments.PaymentHandlerHost;
......@@ -214,7 +215,7 @@ public class ChromePaymentRequestService implements BrowserPaymentRequest,
mSkipToGPayHelper = new SkipToGPayHelper(options, data.gpayBridgeData);
}
if (!parseAndValidateDetailsForSkipToGPayHelper(details)) {
if (!parseAndValidateDetailsFurtherIfNeeded(details)) {
mJourneyLogger.setAborted(AbortReason.INVALID_DATA_FROM_RENDERER);
disconnectFromClientWithDebugMessage(ErrorStrings.INVALID_PAYMENT_DETAILS);
return true;
......@@ -484,57 +485,23 @@ public class ChromePaymentRequestService implements BrowserPaymentRequest,
}
// Implement BrowserPaymentRequest:
/**
* Called by merchant to update the shipping options and line items after the user has selected
* their shipping address or shipping option.
*/
@Override
public void updateWith(PaymentDetails details) {
public MethodChecker getMethodChecker() {
return this;
}
// Implement BrowserPaymentRequest:
@Override
public void onPaymentDetailsUpdated(
PaymentDetails details, boolean hasNotifiedInvokedPaymentApp) {
if (mPaymentRequestService == null) return;
// mSpec.updateWith() can be used only when mSpec has not been destroyed.
assert !mSpec.isDestroyed();
if (mPaymentRequestService.isShowWaitingForUpdatedDetails()) {
// Under this condition, updateWith() is called in response to the resolution of
// show()'s PaymentDetailsUpdate promise.
continueShow(details);
return;
}
if (mPaymentUiService.getPaymentRequestUI() == null) {
mJourneyLogger.setAborted(AbortReason.INVALID_DATA_FROM_RENDERER);
disconnectFromClientWithDebugMessage(ErrorStrings.CANNOT_UPDATE_WITHOUT_SHOW);
return;
}
PaymentApp invokedPaymentApp = mPaymentRequestService.getInvokedPaymentApp();
if (!PaymentOptionsUtils.requestAnyInformation(mPaymentOptions)
&& (invokedPaymentApp == null
|| !invokedPaymentApp.isWaitingForPaymentDetailsUpdate())) {
mJourneyLogger.setAborted(AbortReason.INVALID_DATA_FROM_RENDERER);
disconnectFromClientWithDebugMessage(ErrorStrings.INVALID_STATE);
return;
}
if (!PaymentValidator.validatePaymentDetails(details)
|| !parseAndValidateDetailsForSkipToGPayHelper(details)) {
mJourneyLogger.setAborted(AbortReason.INVALID_DATA_FROM_RENDERER);
disconnectFromClientWithDebugMessage(ErrorStrings.INVALID_PAYMENT_DETAILS);
return;
}
mSpec.updateWith(details);
mPaymentUiService.updateDetailsOnPaymentRequestUI(
mSpec.getPaymentDetails(), mSpec.getRawTotal(), mSpec.getRawLineItems());
if (invokedPaymentApp != null && invokedPaymentApp.isWaitingForPaymentDetailsUpdate()) {
// After a payment app has been invoked, all of the merchant's calls to update the price
// via updateWith() should be forwarded to the invoked app, so it can reflect the
// updated price in its UI.
invokedPaymentApp.updateWith(
PaymentDetailsConverter.convertToPaymentRequestDetailsUpdate(details,
/*methodChecker=*/this, invokedPaymentApp));
return;
}
if (hasNotifiedInvokedPaymentApp) return;
if (mPaymentUiService.shouldShowShippingSection()
&& (mPaymentUiService.getUiShippingOptions().isEmpty()
......@@ -551,7 +518,9 @@ public class ChromePaymentRequestService implements BrowserPaymentRequest,
if (providedInformationToPaymentRequestUI) recordShowEventAndTransactionAmount();
}
private void continueShow(PaymentDetails details) {
// Implements BrowserPaymentRequest:
@Override
public void continueShow(PaymentDetails details) {
assert mPaymentRequestService.isShowWaitingForUpdatedDetails();
// mSpec.updateWith() can be used only when mSpec has not been destroyed.
assert !mSpec.isDestroyed();
......@@ -564,7 +533,7 @@ public class ChromePaymentRequestService implements BrowserPaymentRequest,
}
if (!PaymentValidator.validatePaymentDetails(details)
|| !parseAndValidateDetailsForSkipToGPayHelper(details)) {
|| !parseAndValidateDetailsFurtherIfNeeded(details)) {
mJourneyLogger.setAborted(AbortReason.INVALID_DATA_FROM_RENDERER);
disconnectFromClientWithDebugMessage(ErrorStrings.INVALID_PAYMENT_DETAILS);
return;
......@@ -651,13 +620,9 @@ public class ChromePaymentRequestService implements BrowserPaymentRequest,
if (providedInformationToPaymentRequestUI) recordShowEventAndTransactionAmount();
}
/**
* If executing on the skip-to-gpay flow, do the flow's specific validation for details. If
* valid, set shipping options for SkipToGPayHelper.
* @param details The details specified by the merchant.
* @return True if skip-to-gpay parameters are valid or when skip-to-gpay does not apply.
*/
private boolean parseAndValidateDetailsForSkipToGPayHelper(PaymentDetails details) {
// Implements BrowserPaymentRequest:
@Override
public boolean parseAndValidateDetailsFurtherIfNeeded(PaymentDetails details) {
return mSkipToGPayHelper == null || mSkipToGPayHelper.setShippingOptionIfValid(details);
}
......
......@@ -6,6 +6,7 @@ package org.chromium.components.payments;
import androidx.annotation.Nullable;
import org.chromium.components.payments.PaymentDetailsConverter.MethodChecker;
import org.chromium.content_public.browser.WebContents;
import org.chromium.payments.mojom.PaymentDetails;
import org.chromium.payments.mojom.PaymentMethodData;
......@@ -36,10 +37,13 @@ public interface BrowserPaymentRequest {
}
/**
* The browser part of the {@link PaymentRequest#updateWith} implementation.
* The client of the interface calls this when it has received the payment details update
* from the merchant and has updated the PaymentRequestSpec.
* @param details The details that the merchant provides to update the payment request.
* @param hasNotifiedInvokedPaymentApp Whether the client has notified the invoked
* payment app of the updated details.
*/
void updateWith(PaymentDetails details);
void onPaymentDetailsUpdated(PaymentDetails details, boolean hasNotifiedInvokedPaymentApp);
/** The browser part of the {@link PaymentRequest#onPaymentDetailsNotUpdated} implementation. */
void onPaymentDetailsNotUpdated();
......@@ -187,4 +191,28 @@ public interface BrowserPaymentRequest {
default boolean isShowingUi() {
return false;
}
/**
* Continues the unfinished part of show() that was blocked for the payment details that was
* pending to be updated.
* @param details The updated payment details that show() is waiting for.
*/
default void continueShow(PaymentDetails details) {}
/**
* If needed, do extra parsing and validation for details.
* @param details The details specified by the merchant.
* @return True if the validation pass.
*/
default boolean parseAndValidateDetailsFurtherIfNeeded(PaymentDetails details) {
return true;
}
/**
* @return The {@link MethodChecker} that can check whether the invoked payment app is valid for
* the given payment method identifier.
*/
default MethodChecker getMethodChecker() {
return null;
}
}
......@@ -941,7 +941,50 @@ public class PaymentRequestService
*/
/* package */ void updateWith(PaymentDetails details) {
if (mBrowserPaymentRequest == null) return;
mBrowserPaymentRequest.updateWith(details);
if (mIsShowWaitingForUpdatedDetails) {
// Under this condition, updateWith() is called in response to the resolution of
// show()'s PaymentDetailsUpdate promise.
mBrowserPaymentRequest.continueShow(details);
return;
}
if (!mIsCurrentPaymentRequestShowing) {
mJourneyLogger.setAborted(AbortReason.INVALID_DATA_FROM_RENDERER);
disconnectFromClientWithDebugMessage(
ErrorStrings.CANNOT_UPDATE_WITHOUT_SHOW, PaymentErrorReason.USER_CANCEL);
return;
}
if (!PaymentOptionsUtils.requestAnyInformation(mPaymentOptions)
&& (mInvokedPaymentApp == null
|| !mInvokedPaymentApp.isWaitingForPaymentDetailsUpdate())) {
mJourneyLogger.setAborted(AbortReason.INVALID_DATA_FROM_RENDERER);
disconnectFromClientWithDebugMessage(
ErrorStrings.INVALID_STATE, PaymentErrorReason.USER_CANCEL);
return;
}
if (!PaymentValidator.validatePaymentDetails(details)
|| !mBrowserPaymentRequest.parseAndValidateDetailsFurtherIfNeeded(details)) {
mJourneyLogger.setAborted(AbortReason.INVALID_DATA_FROM_RENDERER);
disconnectFromClientWithDebugMessage(
ErrorStrings.INVALID_PAYMENT_DETAILS, PaymentErrorReason.USER_CANCEL);
return;
}
mSpec.updateWith(details);
boolean hasNotifiedInvokedPaymentApp =
mInvokedPaymentApp != null && mInvokedPaymentApp.isWaitingForPaymentDetailsUpdate();
if (hasNotifiedInvokedPaymentApp) {
// After a payment app has been invoked, all of the merchant's calls to update the price
// via updateWith() should be forwarded to the invoked app, so it can reflect the
// updated price in its UI.
mInvokedPaymentApp.updateWith(
PaymentDetailsConverter.convertToPaymentRequestDetailsUpdate(details,
/*methodChecker=*/mBrowserPaymentRequest.getMethodChecker(),
mInvokedPaymentApp));
}
mBrowserPaymentRequest.onPaymentDetailsUpdated(details, hasNotifiedInvokedPaymentApp);
}
/**
......
......@@ -24,7 +24,8 @@ public class WebLayerPaymentRequestService implements BrowserPaymentRequest {
}
@Override
public void updateWith(PaymentDetails details) {
public void onPaymentDetailsUpdated(
PaymentDetails details, boolean hasNotifiedInvokedPaymentApp) {
assert false : "Not implemented yet";
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment