Commit c4abc80d authored by Liquan (Max) Gu's avatar Liquan (Max) Gu Committed by Chromium LUCI CQ

[WebLayer] Simplify PRService's init logic

Context:
This CL is to simplify the PRService's init logic and the dependency
relationship.

Before the CL,
* PRService creates MojoPRGateKeeper (in a static method) and
  MojoPRGateKeeper creates PRService (constructor). It formed a
  circular dependency loop.
* PRService's init procedure is over complicated as it includes
  multiple similar methods which confused code readers as to where to
  put certain validation codes. The init procedure includes:
 - createPaymentRequest
 - createIfParamsValid
 - PaymentRequestService's constructor
 - initAndValidate

After the CL,
* CPRFactory & WLPRFactory creates MojoPRGateKeeper, and
  MojoPRGateKeeper creates PRService. PaymentRequestService delegates
  CPRFactory/WLPRFactory to create CPRServic/WLPRService. The
  dependency relationship becomes more clear.
* PRService's init procedure get simplified, as it includes:
 - PaymentRequestService's constructor
 - init
 - initAndValidate (will be combined into init in follow-up CL)

Bug: 1157847
Change-Id: I083e0e162085e27736577d433caf952c59592207
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2592190Reviewed-by: default avatarRouslan Solomakhin <rouslan@chromium.org>
Commit-Queue: Liquan (Max) Gu <maxlg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#837184}
parent 00b03a17
...@@ -10,7 +10,9 @@ import androidx.annotation.VisibleForTesting; ...@@ -10,7 +10,9 @@ import androidx.annotation.VisibleForTesting;
import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.app.ChromeActivity;
import org.chromium.chrome.browser.preferences.Pref; import org.chromium.chrome.browser.preferences.Pref;
import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.components.payments.BrowserPaymentRequest;
import org.chromium.components.payments.InvalidPaymentRequest; import org.chromium.components.payments.InvalidPaymentRequest;
import org.chromium.components.payments.MojoPaymentRequestGateKeeper;
import org.chromium.components.payments.OriginSecurityChecker; import org.chromium.components.payments.OriginSecurityChecker;
import org.chromium.components.payments.PaymentFeatureList; import org.chromium.components.payments.PaymentFeatureList;
import org.chromium.components.payments.PaymentRequestService; import org.chromium.components.payments.PaymentRequestService;
...@@ -64,6 +66,12 @@ public class ChromePaymentRequestFactory implements InterfaceFactory<PaymentRequ ...@@ -64,6 +66,12 @@ public class ChromePaymentRequestFactory implements InterfaceFactory<PaymentRequ
mRenderFrameHost = renderFrameHost; mRenderFrameHost = renderFrameHost;
} }
@Override
public BrowserPaymentRequest createBrowserPaymentRequest(
PaymentRequestService paymentRequestService) {
return new ChromePaymentRequestService(paymentRequestService, this);
}
@Override @Override
public boolean isOffTheRecord() { public boolean isOffTheRecord() {
WebContents liveWebContents = WebContents liveWebContents =
...@@ -162,8 +170,8 @@ public class ChromePaymentRequestFactory implements InterfaceFactory<PaymentRequ ...@@ -162,8 +170,8 @@ public class ChromePaymentRequestFactory implements InterfaceFactory<PaymentRequ
WebContents webContents = WebContentsStatics.fromRenderFrameHost(mRenderFrameHost); WebContents webContents = WebContentsStatics.fromRenderFrameHost(mRenderFrameHost);
if (webContents == null || webContents.isDestroyed()) return new InvalidPaymentRequest(); if (webContents == null || webContents.isDestroyed()) return new InvalidPaymentRequest();
return PaymentRequestService.createPaymentRequest(mRenderFrameHost, delegate, return new MojoPaymentRequestGateKeeper(
(paymentRequestService) (client, onClosed)
-> new ChromePaymentRequestService(paymentRequestService, delegate)); -> new PaymentRequestService(mRenderFrameHost, client, onClosed, delegate));
} }
} }
...@@ -14,6 +14,7 @@ import org.chromium.base.annotations.JNINamespace; ...@@ -14,6 +14,7 @@ import org.chromium.base.annotations.JNINamespace;
import org.chromium.chrome.browser.payments.ChromePaymentRequestFactory; import org.chromium.chrome.browser.payments.ChromePaymentRequestFactory;
import org.chromium.chrome.browser.payments.ChromePaymentRequestService; import org.chromium.chrome.browser.payments.ChromePaymentRequestService;
import org.chromium.components.autofill.EditableOption; import org.chromium.components.autofill.EditableOption;
import org.chromium.components.payments.BrowserPaymentRequest;
import org.chromium.components.payments.PaymentApp; import org.chromium.components.payments.PaymentApp;
import org.chromium.components.payments.PaymentRequestService; import org.chromium.components.payments.PaymentRequestService;
import org.chromium.components.payments.PaymentRequestService.NativeObserverForTest; import org.chromium.components.payments.PaymentRequestService.NativeObserverForTest;
...@@ -49,6 +50,12 @@ public class PaymentRequestTestBridge { ...@@ -49,6 +50,12 @@ public class PaymentRequestTestBridge {
public boolean skipUiForBasicCard() { public boolean skipUiForBasicCard() {
return mSkipUiForBasicCard; return mSkipUiForBasicCard;
} }
@Override
public BrowserPaymentRequest createBrowserPaymentRequest(
PaymentRequestService paymentRequestService) {
return new ChromePaymentRequestService(paymentRequestService, this);
}
} }
/** /**
...@@ -56,7 +63,8 @@ public class PaymentRequestTestBridge { ...@@ -56,7 +63,8 @@ public class PaymentRequestTestBridge {
* answers about the state of the system, in order to control which paths should be tested in * answers about the state of the system, in order to control which paths should be tested in
* the ChromePaymentRequestService. * the ChromePaymentRequestService.
*/ */
private static class PaymentRequestDelegateForTest implements PaymentRequestService.Delegate { private abstract static class PaymentRequestDelegateForTest
implements PaymentRequestService.Delegate {
private final boolean mIsOffTheRecord; private final boolean mIsOffTheRecord;
private final boolean mIsValidSsl; private final boolean mIsValidSsl;
private final boolean mPrefsCanMakePayment; private final boolean mPrefsCanMakePayment;
......
...@@ -25,18 +25,6 @@ import java.util.Map; ...@@ -25,18 +25,6 @@ import java.util.Map;
* Android Chrome browser or the WebLayer "browser". * Android Chrome browser or the WebLayer "browser".
*/ */
public interface BrowserPaymentRequest { public interface BrowserPaymentRequest {
/** The factory that creates an instance of {@link BrowserPaymentRequest}. */
interface Factory {
/**
* Create an instance of {@link BrowserPaymentRequest}.
* @param paymentRequestService The PaymentRequestService to work together with
* the BrowserPaymentRequest instance, cannot be null.
* @return An instance of BrowserPaymentRequest, cannot be null.
*/
BrowserPaymentRequest createBrowserPaymentRequest(
PaymentRequestService paymentRequestService);
}
/** /**
* The client of the interface calls this when it has received the payment details update * The client of the interface calls this when it has received the payment details update
* from the merchant and has updated the PaymentRequestSpec. * from the merchant and has updated the PaymentRequestSpec.
......
...@@ -16,39 +16,29 @@ import org.chromium.payments.mojom.PaymentValidationErrors; ...@@ -16,39 +16,29 @@ import org.chromium.payments.mojom.PaymentValidationErrors;
* Guards against invalid mojo parameters and enforces correct call sequence from mojo IPC in the * Guards against invalid mojo parameters and enforces correct call sequence from mojo IPC in the
* untrusted renderer, so PaymentRequestService does not have to. * untrusted renderer, so PaymentRequestService does not have to.
*/ */
/* package */ class MojoPaymentRequestGateKeeper implements PaymentRequest { public class MojoPaymentRequestGateKeeper implements PaymentRequest {
private final PaymentRequestServiceCreator mPaymentRequestServiceCreator; private final Delegate mDelegate;
private PaymentRequestService mPaymentRequestService; private PaymentRequestService mPaymentRequestService;
/** The creator of PaymentRequestService. */ /** The delegate of the class. */
/* package */ interface PaymentRequestServiceCreator { public interface Delegate {
/** /**
* Create an instance of PaymentRequestService if the parameters are valid. * Create an instance of PaymentRequestService.
* @param client The client of the renderer PaymentRequest, need validation before usage. * @param client The client of the renderer PaymentRequest, need validation before usage.
* @param methodData The supported methods specified by the merchant, need validation before
* usage.
* @param details The payment details specified by the merchant, need validation before
* usage.
* @param options The payment options specified by the merchant, need validation before
* usage.
* @param googlePayBridgeEligible True when the renderer process deems the current request
* eligible for the skip-to-GPay experimental flow. It is ultimately up to the
* browser process to determine whether to trigger it.
* @param onClosedListener The listener that's invoked when PaymentRequestService has * @param onClosedListener The listener that's invoked when PaymentRequestService has
* just closed. * just closed.
* @return The created instance, if the parameters are valid; otherwise, null. * @return The created instance, if the parameters are valid; otherwise, null.
*/ */
PaymentRequestService createPaymentRequestServiceIfParamsValid(PaymentRequestClient client, PaymentRequestService createPaymentRequestService(
PaymentMethodData[] methodData, PaymentDetails details, PaymentOptions options, PaymentRequestClient client, Runnable onClosedListener);
boolean googlePayBridgeEligible, Runnable onClosedListener);
} }
/** /**
* Create an instance of MojoPaymentRequestGateKeeper. * Create an instance of MojoPaymentRequestGateKeeper.
* @param creator The creator of PaymentRequestService. * @param delegate The delegate of the instance.
*/ */
/* package */ MojoPaymentRequestGateKeeper(PaymentRequestServiceCreator creator) { public MojoPaymentRequestGateKeeper(Delegate delegate) {
mPaymentRequestServiceCreator = creator; mDelegate = delegate;
} }
// Implement PaymentRequest: // Implement PaymentRequest:
...@@ -62,11 +52,10 @@ import org.chromium.payments.mojom.PaymentValidationErrors; ...@@ -62,11 +52,10 @@ import org.chromium.payments.mojom.PaymentValidationErrors;
return; return;
} }
// Note that a null value would be assigned when the params are invalid. PaymentRequestService service =
mPaymentRequestService = mDelegate.createPaymentRequestService(client, this::onPaymentRequestServiceClosed);
mPaymentRequestServiceCreator.createPaymentRequestServiceIfParamsValid(client, if (!service.init(methodData, details, options, googlePayBridgeEligible)) return;
methodData, details, options, googlePayBridgeEligible, mPaymentRequestService = service;
this::onPaymentRequestServiceClosed);
} }
private void onPaymentRequestServiceClosed() { private void onPaymentRequestServiceClosed() {
......
...@@ -8,7 +8,6 @@ import androidx.annotation.Nullable; ...@@ -8,7 +8,6 @@ import androidx.annotation.Nullable;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.chromium.components.payments.BrowserPaymentRequest.Factory;
import org.chromium.components.payments.PaymentRequestService.Delegate; import org.chromium.components.payments.PaymentRequestService.Delegate;
import org.chromium.content_public.browser.RenderFrameHost; import org.chromium.content_public.browser.RenderFrameHost;
import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.WebContents;
...@@ -31,7 +30,7 @@ public class PaymentRequestServiceBuilder implements PaymentRequestService.Deleg ...@@ -31,7 +30,7 @@ public class PaymentRequestServiceBuilder implements PaymentRequestService.Deleg
private final RenderFrameHost mRenderFrameHost; private final RenderFrameHost mRenderFrameHost;
private final Runnable mOnClosedListener; private final Runnable mOnClosedListener;
private final PaymentAppService mPaymentAppService; private final PaymentAppService mPaymentAppService;
private final Factory mBrowserPaymentRequestFactory; private final BrowserPaymentRequest mBrowserPaymentRequest;
private WebContents mWebContents; private WebContents mWebContents;
private boolean mIsOffTheRecord = true; private boolean mIsOffTheRecord = true;
private PaymentRequestClient mClient; private PaymentRequestClient mClient;
...@@ -84,12 +83,18 @@ public class PaymentRequestServiceBuilder implements PaymentRequestService.Deleg ...@@ -84,12 +83,18 @@ public class PaymentRequestServiceBuilder implements PaymentRequestService.Deleg
Mockito.doReturn(total).when(mSpec).getRawTotal(); Mockito.doReturn(total).when(mSpec).getRawTotal();
Map<String, PaymentMethodData> methodDataMap = new HashMap<>(); Map<String, PaymentMethodData> methodDataMap = new HashMap<>();
Mockito.doReturn(methodDataMap).when(mSpec).getMethodData(); Mockito.doReturn(methodDataMap).when(mSpec).getMethodData();
mBrowserPaymentRequestFactory = (paymentRequestService) -> browserPaymentRequest; mBrowserPaymentRequest = browserPaymentRequest;
mOnClosedListener = onClosedListener; mOnClosedListener = onClosedListener;
mClient = client; mClient = client;
mPaymentAppService = appService; mPaymentAppService = appService;
} }
@Override
public BrowserPaymentRequest createBrowserPaymentRequest(
PaymentRequestService paymentRequestService) {
return mBrowserPaymentRequest;
}
@Override @Override
public boolean isOffTheRecord() { public boolean isOffTheRecord() {
return mIsOffTheRecord; return mIsOffTheRecord;
...@@ -258,8 +263,9 @@ public class PaymentRequestServiceBuilder implements PaymentRequestService.Deleg ...@@ -258,8 +263,9 @@ public class PaymentRequestServiceBuilder implements PaymentRequestService.Deleg
} }
/* package */ PaymentRequestService build() { /* package */ PaymentRequestService build() {
return PaymentRequestService.createIfParamsValid(mRenderFrameHost, PaymentRequestService service =
mBrowserPaymentRequestFactory, mClient, mMethodData, mDetails, mOptions, new PaymentRequestService(mRenderFrameHost, mClient, mOnClosedListener, mDelegate);
mGooglePayBridgeEligible, mOnClosedListener, mDelegate); boolean success = service.init(mMethodData, mDetails, mOptions, mGooglePayBridgeEligible);
return success ? service : null;
} }
} }
...@@ -7,7 +7,9 @@ package org.chromium.weblayer_private.payments; ...@@ -7,7 +7,9 @@ package org.chromium.weblayer_private.payments;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import org.chromium.components.embedder_support.browser_context.BrowserContextHandle; import org.chromium.components.embedder_support.browser_context.BrowserContextHandle;
import org.chromium.components.payments.BrowserPaymentRequest;
import org.chromium.components.payments.InvalidPaymentRequest; import org.chromium.components.payments.InvalidPaymentRequest;
import org.chromium.components.payments.MojoPaymentRequestGateKeeper;
import org.chromium.components.payments.OriginSecurityChecker; import org.chromium.components.payments.OriginSecurityChecker;
import org.chromium.components.payments.PaymentFeatureList; import org.chromium.components.payments.PaymentFeatureList;
import org.chromium.components.payments.PaymentRequestService; import org.chromium.components.payments.PaymentRequestService;
...@@ -42,6 +44,12 @@ public class WebLayerPaymentRequestFactory implements InterfaceFactory<PaymentRe ...@@ -42,6 +44,12 @@ public class WebLayerPaymentRequestFactory implements InterfaceFactory<PaymentRe
mRenderFrameHost = renderFrameHost; mRenderFrameHost = renderFrameHost;
} }
@Override
public BrowserPaymentRequest createBrowserPaymentRequest(
PaymentRequestService paymentRequestService) {
return new WebLayerPaymentRequestService(paymentRequestService, this);
}
@Override @Override
public boolean isOffTheRecord() { public boolean isOffTheRecord() {
ProfileImpl profile = getProfile(); ProfileImpl profile = getProfile();
...@@ -112,9 +120,8 @@ public class WebLayerPaymentRequestFactory implements InterfaceFactory<PaymentRe ...@@ -112,9 +120,8 @@ public class WebLayerPaymentRequestFactory implements InterfaceFactory<PaymentRe
WebContents webContents = WebContentsStatics.fromRenderFrameHost(mRenderFrameHost); WebContents webContents = WebContentsStatics.fromRenderFrameHost(mRenderFrameHost);
if (webContents == null || webContents.isDestroyed()) return new InvalidPaymentRequest(); if (webContents == null || webContents.isDestroyed()) return new InvalidPaymentRequest();
return new MojoPaymentRequestGateKeeper(
return PaymentRequestService.createPaymentRequest(mRenderFrameHost, delegate, (client, onClosed)
(paymentRequestService) -> new PaymentRequestService(mRenderFrameHost, client, onClosed, delegate));
-> new WebLayerPaymentRequestService(paymentRequestService, delegate));
} }
} }
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