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

[WebLayer] Move PaymentAppFactoryDelegate and PaymentAppFactoryParams

Changes:
* PRService takes over PaymentAppFactoryDelegate,
  PaymentAppFactoryParams from CPRService. These two interfaces need
  to be moved together, otherwise it would be subjected to the
  use-after-close issue of CL[1].
* Removed @Nullable from PRService#mPaymentOptions because it's not
  possible to be null[2].
* Wrapped canUserAddCreditCard in supportPaymentSheetBasedPaymentApp,
  because "whether users can add credit card" is not at the same
  semantic level as other methods of PaymentRequestService.
  PRService knows about basic-card payment app, and CPR knows about
  whether users can add credit card on the basic card payment app.

[1] https://chromium-review.googlesource.com/c/chromium/src/+/2519759
[2] https://source.chromium.org/chromium/chromium/src/+/master:components/payments/content/android/java/src/org/chromium/components/payments/PaymentRequestService.java;l=259;drc=df872ce8fcce25af51aa6b0f9fe8b1135b687524

Bug: 1146049, 1146051, 1145803
Change-Id: Ib02f9d15b4e0777e55d63770ec6f2b68b9fe6b3c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2520277
Commit-Queue: Liquan (Max) Gu <maxlg@chromium.org>
Reviewed-by: default avatarRouslan Solomakhin <rouslan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#824590}
parent 0f8a4ac4
......@@ -33,9 +33,6 @@ import org.chromium.components.payments.NotShownReason;
import org.chromium.components.payments.PackageManagerDelegate;
import org.chromium.components.payments.PayerData;
import org.chromium.components.payments.PaymentApp;
import org.chromium.components.payments.PaymentAppFactoryDelegate;
import org.chromium.components.payments.PaymentAppFactoryInterface;
import org.chromium.components.payments.PaymentAppFactoryParams;
import org.chromium.components.payments.PaymentAppService;
import org.chromium.components.payments.PaymentAppType;
import org.chromium.components.payments.PaymentDetailsConverter;
......@@ -57,9 +54,7 @@ import org.chromium.payments.mojom.PayerDetail;
import org.chromium.payments.mojom.PaymentAddress;
import org.chromium.payments.mojom.PaymentComplete;
import org.chromium.payments.mojom.PaymentDetails;
import org.chromium.payments.mojom.PaymentDetailsModifier;
import org.chromium.payments.mojom.PaymentErrorReason;
import org.chromium.payments.mojom.PaymentItem;
import org.chromium.payments.mojom.PaymentMethodData;
import org.chromium.payments.mojom.PaymentOptions;
import org.chromium.payments.mojom.PaymentRequest;
......@@ -70,7 +65,6 @@ import org.chromium.url.GURL;
import org.chromium.url.Origin;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
......@@ -81,9 +75,8 @@ import java.util.Set;
* living in {@link PaymentRequestService}.
*/
public class ChromePaymentRequestService
implements BrowserPaymentRequest, PaymentAppFactoryDelegate, PaymentAppFactoryParams,
PaymentRequestUpdateEventListener, PaymentApp.AbortCallback,
PaymentApp.InstrumentDetailsCallback,
implements BrowserPaymentRequest, PaymentRequestUpdateEventListener,
PaymentApp.AbortCallback, PaymentApp.InstrumentDetailsCallback,
PaymentResponseHelper.PaymentResponseRequesterDelegate,
PaymentDetailsConverter.MethodChecker, PaymentUiService.Delegate,
PaymentUIsObserver {
......@@ -113,8 +106,6 @@ public class ChromePaymentRequestService
private final boolean mIsOffTheRecord;
private final PaymentUiService mPaymentUiService;
@Nullable
private final PaymentOptions mPaymentOptions;
private final boolean mRequestShipping;
private boolean mWasRetryCalled;
......@@ -189,7 +180,8 @@ public class ChromePaymentRequestService
mPaymentRequestService = paymentRequestService;
mPaymentUiService = new PaymentUiService(/*delegate=*/this,
/*params=*/this, mWebContents, mIsOffTheRecord, mJourneyLogger, mTopLevelOrigin,
/*params=*/mPaymentRequestService, mWebContents, mIsOffTheRecord, mJourneyLogger,
mTopLevelOrigin,
/*observer=*/this);
}
......@@ -294,16 +286,11 @@ public class ChromePaymentRequestService
}
if (AutofillPaymentAppFactory.canMakePayments(mSpec.getMethodData())) {
mPaymentUiService.setAutofillPaymentAppCreator(
AutofillPaymentAppFactory.createAppCreator(/*delegate=*/this));
AutofillPaymentAppFactory.createAppCreator(
/*delegate=*/mPaymentRequestService));
}
}
// Implements BrowserPaymentRequest:
@Override
public PaymentAppFactoryDelegate getPaymentAppFactoryDelegate() {
return this;
}
/** @return Whether the UI was built. */
private boolean buildUI(ChromeActivity activity) {
String error = mPaymentUiService.buildPaymentRequestUI(activity,
......@@ -1083,149 +1070,11 @@ public class ChromePaymentRequestService
closeUIAndDestroyNativeObjects();
}
// PaymentAppFactoryParams implementation.
@Override
public WebContents getWebContents() {
return mWebContents;
}
// PaymentAppFactoryParams implementation.
@Override
public RenderFrameHost getRenderFrameHost() {
return mRenderFrameHost;
}
// PaymentAppFactoryParams implementation.
@Override
public boolean hasClosed() {
return mHasClosed;
}
// PaymentAppFactoryParams implementation.
@Override
public Map<String, PaymentMethodData> getMethodData() {
// GetMethodData should not get called after PR is closed.
assert !mHasClosed;
assert !mSpec.isDestroyed();
return mSpec.getMethodData();
}
// PaymentAppFactoryParams implementation.
@Override
public String getId() {
assert !mHasClosed;
assert !mSpec.isDestroyed();
return mSpec.getId();
}
// PaymentAppFactoryParams implementation.
@Override
public String getTopLevelOrigin() {
return mTopLevelOrigin;
}
// PaymentAppFactoryParams implementation.
@Override
public String getPaymentRequestOrigin() {
return mPaymentRequestOrigin;
}
// PaymentAppFactoryParams implementation.
@Override
public Origin getPaymentRequestSecurityOrigin() {
return mPaymentRequestSecurityOrigin;
}
// PaymentAppFactoryParams implementation.
@Override
@Nullable
public byte[][] getCertificateChain() {
return mCertificateChain;
}
// PaymentAppFactoryParams implementation.
@Override
public Map<String, PaymentDetailsModifier> getUnmodifiableModifiers() {
assert !mHasClosed;
assert !mSpec.isDestroyed();
return Collections.unmodifiableMap(mSpec.getModifiers());
}
// PaymentAppFactoryParams implementation.
@Override
public PaymentItem getRawTotal() {
assert !mHasClosed;
assert !mSpec.isDestroyed();
return mSpec.getRawTotal();
}
// PaymentAppFactoryParams implementation.
@Override
public boolean getMayCrawl() {
return !mPaymentUiService.canUserAddCreditCard()
|| PaymentFeatureList.isEnabledOrExperimentalFeaturesEnabled(
PaymentFeatureList.WEB_PAYMENTS_ALWAYS_ALLOW_JUST_IN_TIME_PAYMENT_APP);
}
// PaymentAppFactoryParams implementation.
@Override
public PaymentRequestUpdateEventListener getPaymentRequestUpdateEventListener() {
return this;
}
// PaymentAppFactoryParams implementation.
@Override
public PaymentOptions getPaymentOptions() {
return mPaymentOptions;
}
// PaymentAppFactoryParams implementation.
@Override
public PaymentRequestSpec getSpec() {
return mSpec;
}
// PaymentAppFactoryParams implementation.
@Override
@Nullable
public String getTwaPackageName() {
return mDelegate.getTwaPackageName();
}
// PaymentAppFactoryDelegate implementation.
@Override
public PaymentAppFactoryParams getParams() {
return this;
}
// PaymentAppFactoryDelegate implementation.
@Override
public void onCanMakePaymentCalculated(boolean canMakePayment) {
if (mPaymentRequestService == null) return;
mPaymentRequestService.onCanMakePaymentCalculated(canMakePayment);
}
// PaymentAppFactoryDelegate implementation.
// Implements BrowserPaymentRequest:
@Override
public void onPaymentAppCreated(PaymentApp paymentApp) {
if (mPaymentRequestService == null) return;
mHideServerAutofillCards |= paymentApp.isServerAutofillInstrumentReplacement();
paymentApp.setHaveRequestedAutofillData(mPaymentUiService.haveRequestedAutofillData());
mPaymentRequestService.onPaymentAppCreated(paymentApp);
}
// PaymentAppFactoryDelegate implementation.
@Override
public void onPaymentAppCreationError(String errorMessage) {
if (TextUtils.isEmpty(mRejectShowErrorMessage)) mRejectShowErrorMessage = errorMessage;
}
// PaymentAppFactoryDelegate implementation.
@Override
public void onDoneCreatingPaymentApps(PaymentAppFactoryInterface factory /* Unused */) {
if (mPaymentRequestService == null) return;
mPaymentRequestService.onDoneCreatingPaymentApps();
}
// Implements BrowserPaymentRequest:
......@@ -1299,12 +1148,30 @@ public class ChromePaymentRequestService
return mPaymentUiService.hasAvailableApps();
}
// Implements BrowserPaymentRequest:
@Override
public PaymentRequestUpdateEventListener getPaymentRequestUpdateEventListener() {
return this;
}
// Implements BrowserPaymentRequest:
@Override
public boolean isPaymentSheetBasedPaymentAppSupported() {
return mPaymentUiService.canUserAddCreditCard();
}
// Implements BrowserPaymentRequest:
@Override
public String getRejectShowErrorMessage() {
return mRejectShowErrorMessage;
}
// Implements BrowserPaymentRequest:
@Override
public void setRejectShowErrorMessage(String errorMessage) {
mRejectShowErrorMessage = errorMessage;
}
// Implements BrowserPaymentRequest:
@Override
public boolean disconnectForStrictShow(boolean isUserGestureShow) {
......
......@@ -118,9 +118,6 @@ public interface BrowserPaymentRequest {
*/
void addPaymentAppFactories(PaymentAppService service);
/** @return A PaymentAppFactoryDelegate to be used with the PaymentAppService. */
PaymentAppFactoryDelegate getPaymentAppFactoryDelegate();
default void onWhetherGooglePayBridgeEligible(boolean googlePayBridgeEligible,
WebContents webContents, PaymentMethodData[] rawMethodData) {}
......@@ -165,4 +162,33 @@ public interface BrowserPaymentRequest {
default String getRejectShowErrorMessage() {
return "";
}
/**
* Called when a new payment app is created.
* @param paymentApp The new payment app.
*/
default void onPaymentAppCreated(PaymentApp paymentApp) {}
// TODO(crbug.com/1144527): this method will be removed once PaymentRequestService has taken
// over PaymentRequestUpdateEventListener.
/** @return An instance of PaymentRequestUpdateEventListener. */
default PaymentRequestUpdateEventListener getPaymentRequestUpdateEventListener() {
return null;
}
/**
* @return Whether payment sheet based payment app is supported, e.g., user entering credit
* cards on payment sheet.
*/
default boolean isPaymentSheetBasedPaymentAppSupported() {
return false;
}
// TODO(crbug.com/1144527): this method will be removed once PaymentRequestService has taken
// over mRejectShowErrorMessage.
/**
* Set the error message for show rejection.
* @param errorMessage The error message for show rejection.
*/
default void setRejectShowErrorMessage(String errorMessage) {}
}
......@@ -57,7 +57,7 @@ import java.util.Map;
* class need to close them with
* {@link PaymentRequestService#close()}, after which no usage is allowed.
*/
public class PaymentRequestService {
public class PaymentRequestService implements PaymentAppFactoryDelegate, PaymentAppFactoryParams {
private static final String TAG = "PaymentRequestServ";
private static PaymentRequestServiceObserverForTest sObserverForTest;
private static NativeObserverForTest sNativeObserverForTest;
......@@ -73,7 +73,6 @@ public class PaymentRequestService {
@Nullable
private final byte[][] mCertificateChain;
private final boolean mIsOffTheRecord;
@Nullable
private final PaymentOptions mPaymentOptions;
private final boolean mRequestShipping;
private final boolean mRequestPayerName;
......@@ -91,9 +90,11 @@ public class PaymentRequestService {
private boolean mIsUserGestureShow;
// mClient is null only when it has closed.
@Nullable
private PaymentRequestClient mClient;
// mBrowserPaymentRequest is null when it has closed or is uninitiated.
@Nullable
private BrowserPaymentRequest mBrowserPaymentRequest;
/**
* A mapping of the payment method names to the corresponding payment method specific data. If
......@@ -332,7 +333,7 @@ public class PaymentRequestService {
private void startPaymentAppService() {
PaymentAppService service = PaymentAppService.getInstance();
mBrowserPaymentRequest.addPaymentAppFactories(service);
service.create(/*delegate=*/mBrowserPaymentRequest.getPaymentAppFactoryDelegate());
service.create(/*delegate=*/this);
}
/** Abort the request, used before this class's instantiation. */
......@@ -528,8 +529,10 @@ public class PaymentRequestService {
}
}
/** Called when the payment app service has done creating all payment apps. */
public void onDoneCreatingPaymentApps() {
// Implements PaymentAppFactoryDelegate:
@Override
public void onDoneCreatingPaymentApps(PaymentAppFactoryInterface factory /* Unused */) {
if (mBrowserPaymentRequest == null) return;
mIsFinishedQueryingPaymentApps = true;
if (disconnectIfNoPaymentMethodsSupported(mBrowserPaymentRequest.hasAvailableApps())) {
......@@ -645,11 +648,17 @@ public class PaymentRequestService {
sIsLocalHasEnrolledInstrumentQueryQuotaEnforcedForTest = true;
}
/**
* Called when a payment app is created.
* @param paymentApp The created payment app.
*/
// Implements PaymentAppFactoryDelegate:
@Override
public PaymentAppFactoryParams getParams() {
return this;
}
// Implements PaymentAppFactoryDelegate:
@Override
public void onPaymentAppCreated(PaymentApp paymentApp) {
if (mBrowserPaymentRequest == null) return;
mBrowserPaymentRequest.onPaymentAppCreated(paymentApp);
mHasEnrolledInstrument |= paymentApp.canMakePayment();
mHasNonAutofillApp |= !paymentApp.isAutofillInstrument();
......@@ -667,8 +676,7 @@ public class PaymentRequestService {
/** Responds to the CanMakePayment query from the merchant page. */
public void respondCanMakePaymentQuery() {
// Every caller should stop referencing this class once close() is called.
assert mClient != null;
if (mClient == null) return;
mIsCanMakePaymentResponsePending = false;
......@@ -688,6 +696,7 @@ public class PaymentRequestService {
/** Responds to the HasEnrolledInstrument query from the merchant page. */
public void respondHasEnrolledInstrumentQuery() {
if (mClient == null) return;
boolean response = mHasEnrolledInstrument;
mIsHasEnrolledInstrumentResponsePending = false;
......@@ -732,11 +741,10 @@ public class PaymentRequestService {
return mHasEnrolledInstrument;
}
/**
* Called when the response of the CanMakePayment query is calculated.
* @param canMakePayment Whether any payment app support the requested payment.
*/
// Implements PaymentAppFactoryDelegate:
@Override
public void onCanMakePaymentCalculated(boolean canMakePayment) {
if (mBrowserPaymentRequest == null) return;
mCanMakePayment = canMakePayment;
if (!mIsCanMakePaymentResponsePending) return;
// canMakePayment doesn't need to wait for all apps to be queried because it only needs to
......@@ -744,6 +752,15 @@ public class PaymentRequestService {
respondCanMakePaymentQuery();
}
// Implements PaymentAppFactoryDelegate:
@Override
public void onPaymentAppCreationError(String errorMessage) {
if (mBrowserPaymentRequest != null
&& TextUtils.isEmpty(mBrowserPaymentRequest.getRejectShowErrorMessage())) {
mBrowserPaymentRequest.setRejectShowErrorMessage(errorMessage);
}
}
/** @return Whether the created payment apps includes any autofill payment app. */
public boolean getHasNonAutofillApp() {
return mHasNonAutofillApp;
......@@ -1020,64 +1037,132 @@ public class PaymentRequestService {
return mJourneyLogger;
}
/** @return The WebContents of the merchant's page, cannot be null. */
/** @return Whether the WebContents is currently showing an off-the-record tab. */
public boolean isOffTheRecord() {
return mIsOffTheRecord;
}
/**
* Redact shipping address before exposing it in ShippingAddressChangeEvent.
* https://w3c.github.io/payment-request/#shipping-address-changed-algorithm
* @param shippingAddress The shipping address to redact in place.
*/
private static void redactShippingAddress(PaymentAddress shippingAddress) {
if (PaymentFeatureList.isEnabledOrExperimentalFeaturesEnabled(
PaymentFeatureList.WEB_PAYMENTS_REDACT_SHIPPING_ADDRESS)) {
shippingAddress.organization = "";
shippingAddress.phone = "";
shippingAddress.recipient = "";
shippingAddress.addressLine = new String[0];
}
}
// PaymentAppFactoryParams implementation.
@Override
public WebContents getWebContents() {
return mWebContents;
}
/** @return Whether the WebContents is currently showing an off-the-record tab. */
public boolean isOffTheRecord() {
return mIsOffTheRecord;
// PaymentAppFactoryParams implementation.
@Override
public RenderFrameHost getRenderFrameHost() {
return mRenderFrameHost;
}
/** @return The certificate chain from the merchant page's WebContents, can be null. */
@Nullable
public byte[][] getCertificateChain() {
return mCertificateChain;
// PaymentAppFactoryParams implementation.
@Override
public boolean hasClosed() {
return mHasClosed;
}
/** @return The origin of the page at which the PaymentRequest is created. */
public String getPaymentRequestOrigin() {
return mPaymentRequestOrigin;
// PaymentAppFactoryParams implementation.
@Override
public Map<String, PaymentMethodData> getMethodData() {
// GetMethodData should not get called after PR is closed.
assert !mHasClosed;
assert !mSpec.isDestroyed();
return mSpec.getMethodData();
}
// PaymentAppFactoryParams implementation.
@Override
public String getId() {
assert !mHasClosed;
assert !mSpec.isDestroyed();
return mSpec.getId();
}
/** @return The origin of the top level frame of the merchant page. */
// PaymentAppFactoryParams implementation.
@Override
public String getTopLevelOrigin() {
return mTopLevelOrigin;
}
/** @return The payment options requested by the merchant, can be null. */
// PaymentAppFactoryParams implementation.
@Override
public String getPaymentRequestOrigin() {
return mPaymentRequestOrigin;
}
// PaymentAppFactoryParams implementation.
@Override
public Origin getPaymentRequestSecurityOrigin() {
return mPaymentRequestSecurityOrigin;
}
// PaymentAppFactoryParams implementation.
@Override
@Nullable
public PaymentOptions getPaymentOptions() {
return mPaymentOptions;
public byte[][] getCertificateChain() {
return mCertificateChain;
}
/** @return The RendererFrameHost of the merchant page. */
public RenderFrameHost getRenderFrameHost() {
return mRenderFrameHost;
// PaymentAppFactoryParams implementation.
@Override
public Map<String, PaymentDetailsModifier> getUnmodifiableModifiers() {
assert !mHasClosed;
assert !mSpec.isDestroyed();
return Collections.unmodifiableMap(mSpec.getModifiers());
}
/**
* @return The origin of the iframe that invoked the PaymentRequest API. Can be opaque. Used by
* security features like 'Sec-Fetch-Site' and 'Cross-Origin-Resource-Policy'. Should not be
* null.
*/
public Origin getPaymentRequestSecurityOrigin() {
return mPaymentRequestSecurityOrigin;
// PaymentAppFactoryParams implementation.
@Override
public PaymentItem getRawTotal() {
assert !mHasClosed;
assert !mSpec.isDestroyed();
return mSpec.getRawTotal();
}
/**
* Redact shipping address before exposing it in ShippingAddressChangeEvent.
* https://w3c.github.io/payment-request/#shipping-address-changed-algorithm
* @param shippingAddress The shipping address to redact in place.
*/
private static void redactShippingAddress(PaymentAddress shippingAddress) {
if (PaymentFeatureList.isEnabledOrExperimentalFeaturesEnabled(
PaymentFeatureList.WEB_PAYMENTS_REDACT_SHIPPING_ADDRESS)) {
shippingAddress.organization = "";
shippingAddress.phone = "";
shippingAddress.recipient = "";
shippingAddress.addressLine = new String[0];
}
// PaymentAppFactoryParams implementation.
@Override
public boolean getMayCrawl() {
return !mBrowserPaymentRequest.isPaymentSheetBasedPaymentAppSupported()
|| PaymentFeatureList.isEnabledOrExperimentalFeaturesEnabled(
PaymentFeatureList.WEB_PAYMENTS_ALWAYS_ALLOW_JUST_IN_TIME_PAYMENT_APP);
}
// PaymentAppFactoryParams implementation.
@Override
public PaymentRequestUpdateEventListener getPaymentRequestUpdateEventListener() {
return mBrowserPaymentRequest.getPaymentRequestUpdateEventListener();
}
// PaymentAppFactoryParams implementation.
@Override
public PaymentOptions getPaymentOptions() {
return mPaymentOptions;
}
// PaymentAppFactoryParams implementation.
@Override
public PaymentRequestSpec getSpec() {
return mSpec;
}
// PaymentAppFactoryParams implementation.
@Override
@Nullable
public String getTwaPackageName() {
return mDelegate.getTwaPackageName();
}
}
......@@ -5,7 +5,6 @@
package org.chromium.weblayer_private.payments;
import org.chromium.components.payments.BrowserPaymentRequest;
import org.chromium.components.payments.PaymentAppFactoryDelegate;
import org.chromium.components.payments.PaymentAppService;
import org.chromium.components.payments.PaymentRequestService;
import org.chromium.components.payments.PaymentRequestService.Delegate;
......@@ -69,9 +68,4 @@ public class WebLayerPaymentRequestService implements BrowserPaymentRequest {
assert false : "Not implemented yet";
}
@Override
public PaymentAppFactoryDelegate getPaymentAppFactoryDelegate() {
assert false : "Not implemented yet";
return null;
}
}
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