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

[WebLayer] Move shouldSkipShowingPaymentRequestUi()

This CL moved shouldSkipShowingPaymentRequestUi() from PaymentUiService
to PRService so that WebLayer and Chrome can share the logic.

Bug: 1025619

Change-Id: If69054ad42b29541e5892998113c7174b0c45bdc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2555560Reviewed-by: default avatarJinsuk Kim <jinsukkim@chromium.org>
Reviewed-by: default avatarRouslan Solomakhin <rouslan@chromium.org>
Commit-Queue: Liquan (Max) Gu <maxlg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#830966}
parent 13b51aed
...@@ -237,11 +237,12 @@ public class ChromePaymentRequestService ...@@ -237,11 +237,12 @@ public class ChromePaymentRequestService
if (error != null) return error; if (error != null) return error;
// Calculate skip ui and build ui only after all payment apps are ready and // Calculate skip ui and build ui only after all payment apps are ready and
// request.show() is called. // request.show() is called.
mShouldSkipShowingPaymentRequestUi = PaymentUiService.shouldSkipShowingPaymentRequestUi( mShouldSkipShowingPaymentRequestUi =
isUserGestureShow, mDelegate.skipUiForBasicCard(), mSpec.getPaymentOptions(), PaymentRequestService.shouldSkipShowingPaymentRequestUi(isUserGestureShow,
mSpec.getMethodData().keySet(), mDelegate.skipUiForBasicCard(), mSpec.getPaymentOptions(),
(PaymentApp) mPaymentUiService.getSelectedPaymentApp(), mSpec.getMethodData().keySet(),
mPaymentUiService.getPaymentAppsInPaymentAppList()); (PaymentApp) mPaymentUiService.getSelectedPaymentApp(),
mPaymentUiService.getPaymentAppsInPaymentAppList());
if (!mShouldSkipShowingPaymentRequestUi && mSkipToGPayHelper == null) { if (!mShouldSkipShowingPaymentRequestUi && mSkipToGPayHelper == null) {
mPaymentUiService.getPaymentRequestUI().show(isShowWaitingForUpdatedDetails); mPaymentUiService.getPaymentRequestUI().show(isShowWaitingForUpdatedDetails);
} }
......
...@@ -52,7 +52,6 @@ import org.chromium.chrome.browser.ui.favicon.FaviconHelper; ...@@ -52,7 +52,6 @@ import org.chromium.chrome.browser.ui.favicon.FaviconHelper;
import org.chromium.components.autofill.Completable; import org.chromium.components.autofill.Completable;
import org.chromium.components.autofill.EditableOption; import org.chromium.components.autofill.EditableOption;
import org.chromium.components.browser_ui.bottomsheet.BottomSheetControllerProvider; import org.chromium.components.browser_ui.bottomsheet.BottomSheetControllerProvider;
import org.chromium.components.embedder_support.util.UrlConstants;
import org.chromium.components.payments.AbortReason; import org.chromium.components.payments.AbortReason;
import org.chromium.components.payments.BasicCardUtils; import org.chromium.components.payments.BasicCardUtils;
import org.chromium.components.payments.CurrencyFormatter; import org.chromium.components.payments.CurrencyFormatter;
...@@ -1425,35 +1424,6 @@ public class PaymentUiService implements SettingsAutofillAndPaymentsObserver.Obs ...@@ -1425,35 +1424,6 @@ public class PaymentUiService implements SettingsAutofillAndPaymentsObserver.Obs
mPaymentRequestUI.setShippingAddressSectionFocusChangedObserver(this); mPaymentRequestUI.setShippingAddressSectionFocusChangedObserver(this);
} }
/**
* @param options The payment options specified in the payment request.
* @param allApps All available payment apps.
* @return true when there is exactly one available payment app which can provide all requested
* information including shipping address and payer's contact information whenever needed.
*/
private static boolean onlySingleAppCanProvideAllRequiredInformation(
PaymentOptions options, List<PaymentApp> allApps) {
if (!PaymentOptionsUtils.requestAnyInformation(options)) {
return allApps.size() == 1 && !((PaymentApp) allApps.get(0)).isAutofillInstrument();
}
boolean anAppCanProvideAllInfo = false;
for (int i = 0; i < allApps.size(); i++) {
PaymentApp app = (PaymentApp) allApps.get(i);
if ((!options.requestShipping || app.handlesShippingAddress())
&& (!options.requestPayerName || app.handlesPayerName())
&& (!options.requestPayerPhone || app.handlesPayerPhone())
&& (!options.requestPayerEmail || app.handlesPayerEmail())) {
// There is more than one available app that can provide all merchant requested
// information information.
if (anAppCanProvideAllInfo) return false;
anAppCanProvideAllInfo = true;
}
}
return anAppCanProvideAllInfo;
}
/** /**
* Update the details related fields on the PaymentRequest UI. * Update the details related fields on the PaymentRequest UI.
* @param details The details whose information is used for the update. * @param details The details whose information is used for the update.
...@@ -1479,54 +1449,6 @@ public class PaymentUiService implements SettingsAutofillAndPaymentsObserver.Obs ...@@ -1479,54 +1449,6 @@ public class PaymentUiService implements SettingsAutofillAndPaymentsObserver.Obs
updateAppModifiedTotals(); updateAppModifiedTotals();
} }
/**
* @param methods The payment methods supported by the payment request.
* @return True when at least one url payment method identifier is specified in payment
* request.
*/
private static boolean isUrlPaymentMethodIdentifiersSupported(Set<String> methods) {
for (String methodName : methods) {
if (methodName.startsWith(UrlConstants.HTTPS_URL_PREFIX)
|| methodName.startsWith(UrlConstants.HTTP_URL_PREFIX)) {
return true;
}
}
return false;
}
/**
* @param isUserGestureShow Whether the PaymentRequest.show() is triggered by user gesture.
* @param skipUiForNonUrlPaymentMethodIdentifiers True when skip UI is available for non-url
* based payment method identifiers (e.g., basic-card).
* @param options The payment options specified in the payment request.
* @param paymentMethods The payment methods supported by this request.
* @param selectedApp The selected payment apps.
* @param allApps All available payment apps.
* @return Whether the browser payment sheet should be skipped directly into the payment app.
*/
public static boolean shouldSkipShowingPaymentRequestUi(boolean isUserGestureShow,
boolean skipUiForNonUrlPaymentMethodIdentifiers, PaymentOptions options,
Set<String> paymentMethods, PaymentApp selectedApp, List<PaymentApp> allApps) {
boolean urlPaymentMethodIdentifiersSupported =
isUrlPaymentMethodIdentifiersSupported(paymentMethods);
// If there is only a single payment app which can provide all merchant requested
// information, we can safely go directly to the payment app instead of showing Payment
// Request UI.
return PaymentFeatureList.isEnabled(PaymentFeatureList.WEB_PAYMENTS_SINGLE_APP_UI_SKIP)
// Only allowing payment apps that own their own UIs.
// This excludes AutofillPaymentInstrument as its UI is rendered inline in
// the payment request UI, thus can't be skipped.
&& (urlPaymentMethodIdentifiersSupported || skipUiForNonUrlPaymentMethodIdentifiers)
&& allApps.size() >= 1
&& onlySingleAppCanProvideAllRequiredInformation(options, allApps)
// Skip to payment app only if it can be pre-selected.
&& selectedApp != null
// Skip to payment app only if user gesture is provided when it is required to
// skip-UI.
&& (isUserGestureShow || !selectedApp.isUserGestureRequiredToSkipUi());
}
/** Removes all of the observers that observe users leaving the tab. */ /** Removes all of the observers that observe users leaving the tab. */
public void removeLeavingTabObservers() { public void removeLeavingTabObservers() {
if (mObservedTabModelSelector != null) { if (mObservedTabModelSelector != null) {
......
...@@ -153,6 +153,7 @@ android_library("all_java") { ...@@ -153,6 +153,7 @@ android_library("all_java") {
"//base:base_java", "//base:base_java",
"//base:jni_java", "//base:jni_java",
"//components/autofill/android:autofill_java", "//components/autofill/android:autofill_java",
"//components/embedder_support/android:util_java",
"//components/page_info/android:java", "//components/page_info/android:java",
"//components/payments/mojom:mojom_java", "//components/payments/mojom:mojom_java",
"//components/url_formatter/android:url_formatter_java", "//components/url_formatter/android:url_formatter_java",
......
include_rules = [ include_rules = [
"+components/embedder_support/android",
"+components/payments/content/android/jni_headers", "+components/payments/content/android/jni_headers",
"+mojo/public/java", "+mojo/public/java",
"+services/network/public/cpp", "+services/network/public/cpp",
......
...@@ -13,6 +13,7 @@ import androidx.collection.ArrayMap; ...@@ -13,6 +13,7 @@ import androidx.collection.ArrayMap;
import org.chromium.base.LocaleUtils; import org.chromium.base.LocaleUtils;
import org.chromium.base.Log; import org.chromium.base.Log;
import org.chromium.components.autofill.EditableOption; import org.chromium.components.autofill.EditableOption;
import org.chromium.components.embedder_support.util.UrlConstants;
import org.chromium.components.page_info.CertificateChainHelper; import org.chromium.components.page_info.CertificateChainHelper;
import org.chromium.components.payments.BrowserPaymentRequest.Factory; import org.chromium.components.payments.BrowserPaymentRequest.Factory;
import org.chromium.components.url_formatter.UrlFormatter; import org.chromium.components.url_formatter.UrlFormatter;
...@@ -45,6 +46,7 @@ import java.util.Collections; ...@@ -45,6 +46,7 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
/** /**
* {@link PaymentRequestService}, {@link MojoPaymentRequestGateKeeper} and * {@link PaymentRequestService}, {@link MojoPaymentRequestGateKeeper} and
...@@ -976,6 +978,83 @@ public class PaymentRequestService ...@@ -976,6 +978,83 @@ public class PaymentRequestService
return mBrowserPaymentRequest.triggerPaymentAppUiSkipIfApplicable(mIsUserGestureShow); return mBrowserPaymentRequest.triggerPaymentAppUiSkipIfApplicable(mIsUserGestureShow);
} }
/**
* @param options The payment options specified in the payment request.
* @param allApps All available payment apps.
* @return true when there is exactly one available payment app which can provide all requested
* information including shipping address and payer's contact information whenever needed.
*/
private static boolean onlySingleAppCanProvideAllRequiredInformation(
PaymentOptions options, List<PaymentApp> allApps) {
if (!PaymentOptionsUtils.requestAnyInformation(options)) {
return allApps.size() == 1 && !((PaymentApp) allApps.get(0)).isAutofillInstrument();
}
boolean anAppCanProvideAllInfo = false;
for (int i = 0; i < allApps.size(); i++) {
PaymentApp app = (PaymentApp) allApps.get(i);
if ((!options.requestShipping || app.handlesShippingAddress())
&& (!options.requestPayerName || app.handlesPayerName())
&& (!options.requestPayerPhone || app.handlesPayerPhone())
&& (!options.requestPayerEmail || app.handlesPayerEmail())) {
// There is more than one available app that can provide all merchant requested
// information information.
if (anAppCanProvideAllInfo) return false;
anAppCanProvideAllInfo = true;
}
}
return anAppCanProvideAllInfo;
}
/**
* @param methods The payment methods supported by the payment request.
* @return True when at least one url payment method identifier is specified in payment
* request.
*/
private static boolean isUrlPaymentMethodIdentifiersSupported(Set<String> methods) {
for (String methodName : methods) {
if (methodName.startsWith(UrlConstants.HTTPS_URL_PREFIX)
|| methodName.startsWith(UrlConstants.HTTP_URL_PREFIX)) {
return true;
}
}
return false;
}
/**
* @param isUserGestureShow Whether the PaymentRequest.show() is triggered by user gesture.
* @param skipUiForNonUrlPaymentMethodIdentifiers True when skip UI is available for non-url
* based payment method identifiers (e.g., basic-card).
* @param options The payment options specified in the payment request.
* @param paymentMethods The payment methods supported by this request.
* @param selectedApp The selected payment apps.
* @param allApps All available payment apps.
* @return Whether the browser payment sheet should be skipped directly into the payment app.
*/
public static boolean shouldSkipShowingPaymentRequestUi(boolean isUserGestureShow,
boolean skipUiForNonUrlPaymentMethodIdentifiers, PaymentOptions options,
Set<String> paymentMethods, PaymentApp selectedApp, List<PaymentApp> allApps) {
boolean urlPaymentMethodIdentifiersSupported =
isUrlPaymentMethodIdentifiersSupported(paymentMethods);
// If there is only a single payment app which can provide all merchant requested
// information, we can safely go directly to the payment app instead of showing Payment
// Request UI.
return PaymentFeatureList.isEnabled(PaymentFeatureList.WEB_PAYMENTS_SINGLE_APP_UI_SKIP)
// Only allowing payment apps that own their own UIs.
// This excludes AutofillPaymentInstrument as its UI is rendered inline in
// the payment request UI, thus can't be skipped.
&& (urlPaymentMethodIdentifiersSupported || skipUiForNonUrlPaymentMethodIdentifiers)
&& allApps.size() >= 1
&& onlySingleAppCanProvideAllRequiredInformation(options, allApps)
// Skip to payment app only if it can be pre-selected.
&& selectedApp != null
// Skip to payment app only if user gesture is provided when it is required to
// skip-UI.
&& (isUserGestureShow || !selectedApp.isUserGestureRequiredToSkipUi());
}
// Implements PaymentDetailsConverter.MethodChecker: // Implements PaymentDetailsConverter.MethodChecker:
@Override @Override
public boolean isInvokedInstrumentValidForPaymentMethodIdentifier( public boolean isInvokedInstrumentValidForPaymentMethodIdentifier(
......
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