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

[WebLayer] Hide PaymentMethodsSection behind PaymentUiService

Changes:
* Hides the PaymentMethodsSection getter and setter in CPRService
  behind PaymentUiService and replace them with getPaymentApps. This
  is because "PaymentMethodsSection" is a UI term and "payment app" is
  an PaymentRequest API term.
* Encapsulates the logic of "loading apps into app selector" behind
  PaymentUiService#loadPaymentApps().

Bug: 1025619

Change-Id: I310dffa9d926be853bda9d138c622d8d27b52706
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2553310
Commit-Queue: Liquan (Max) Gu <maxlg@chromium.org>
Reviewed-by: default avatarRouslan Solomakhin <rouslan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#830627}
parent 08dd69a0
...@@ -14,7 +14,6 @@ import org.chromium.chrome.R; ...@@ -14,7 +14,6 @@ import org.chromium.chrome.R;
import org.chromium.chrome.browser.app.ChromeActivity; import org.chromium.chrome.browser.app.ChromeActivity;
import org.chromium.chrome.browser.autofill.PersonalDataManager; import org.chromium.chrome.browser.autofill.PersonalDataManager;
import org.chromium.chrome.browser.payments.handler.PaymentHandlerCoordinator; import org.chromium.chrome.browser.payments.handler.PaymentHandlerCoordinator;
import org.chromium.chrome.browser.payments.ui.PaymentRequestUI;
import org.chromium.chrome.browser.payments.ui.PaymentUiService; import org.chromium.chrome.browser.payments.ui.PaymentUiService;
import org.chromium.chrome.browser.payments.ui.SectionInformation; import org.chromium.chrome.browser.payments.ui.SectionInformation;
import org.chromium.components.autofill.EditableOption; import org.chromium.components.autofill.EditableOption;
...@@ -37,7 +36,6 @@ import org.chromium.components.payments.PaymentRequestService; ...@@ -37,7 +36,6 @@ import org.chromium.components.payments.PaymentRequestService;
import org.chromium.components.payments.PaymentRequestServiceUtil; import org.chromium.components.payments.PaymentRequestServiceUtil;
import org.chromium.components.payments.PaymentRequestSpec; import org.chromium.components.payments.PaymentRequestSpec;
import org.chromium.components.payments.PaymentResponseHelperInterface; import org.chromium.components.payments.PaymentResponseHelperInterface;
import org.chromium.components.payments.Section;
import org.chromium.components.payments.SkipToGPayHelper; import org.chromium.components.payments.SkipToGPayHelper;
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;
...@@ -220,7 +218,7 @@ public class ChromePaymentRequestService ...@@ -220,7 +218,7 @@ public class ChromePaymentRequestService
// Send AppListReady signal when all apps are created and request.show() is called. // Send AppListReady signal when all apps are created and request.show() is called.
if (PaymentRequestService.getNativeObserverForTest() != null) { if (PaymentRequestService.getNativeObserverForTest() != null) {
PaymentRequestService.getNativeObserverForTest().onAppListReady( PaymentRequestService.getNativeObserverForTest().onAppListReady(
mPaymentUiService.getPaymentMethodsSection().getItems(), total); mPaymentUiService.getPaymentApps(), total);
} }
// 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.
...@@ -262,7 +260,7 @@ public class ChromePaymentRequestService ...@@ -262,7 +260,7 @@ public class ChromePaymentRequestService
// If we are skipping showing the Payment Request UI, we should call into the payment app // If we are skipping showing the Payment Request UI, we should call into the payment app
// immediately after we determine the apps are ready and UI is shown. // immediately after we determine the apps are ready and UI is shown.
if ((mPaymentUiService.shouldSkipShowingPaymentRequestUi() || mSkipToGPayHelper != null)) { if ((mPaymentUiService.shouldSkipShowingPaymentRequestUi() || mSkipToGPayHelper != null)) {
assert !mPaymentUiService.getPaymentMethodsSection().isEmpty(); assert !mPaymentUiService.getPaymentApps().isEmpty();
assert mPaymentUiService.getPaymentRequestUI() != null; assert mPaymentUiService.getPaymentRequestUI() != null;
if (isMinimalUiApplicable(isUserGestureShow)) { if (isMinimalUiApplicable(isUserGestureShow)) {
...@@ -282,9 +280,8 @@ public class ChromePaymentRequestService ...@@ -282,9 +280,8 @@ public class ChromePaymentRequestService
} }
} }
assert !mPaymentUiService.getPaymentMethodsSection().isEmpty(); assert !mPaymentUiService.getPaymentApps().isEmpty();
PaymentApp selectedApp = PaymentApp selectedApp = (PaymentApp) mPaymentUiService.getSelectedPaymentApp();
(PaymentApp) mPaymentUiService.getPaymentMethodsSection().getSelectedItem();
dimBackgroundIfNotBottomSheetPaymentHandler(selectedApp); dimBackgroundIfNotBottomSheetPaymentHandler(selectedApp);
mDidRecordShowEvent = true; mDidRecordShowEvent = true;
mJourneyLogger.setEventOccurred(Event.SKIPPED_SHOW); mJourneyLogger.setEventOccurred(Event.SKIPPED_SHOW);
...@@ -304,13 +301,12 @@ public class ChromePaymentRequestService ...@@ -304,13 +301,12 @@ public class ChromePaymentRequestService
* @return Whether the minimal UI should be shown. * @return Whether the minimal UI should be shown.
*/ */
private boolean isMinimalUiApplicable(boolean isUserGestureShow) { private boolean isMinimalUiApplicable(boolean isUserGestureShow) {
if (!isUserGestureShow || mPaymentUiService.getPaymentMethodsSection() == null if (!isUserGestureShow || mPaymentUiService.getPaymentApps().isEmpty()
|| mPaymentUiService.getPaymentMethodsSection().getSize() != 1) { || mPaymentUiService.getPaymentApps().size() != 1) {
return false; return false;
} }
PaymentApp app = PaymentApp app = (PaymentApp) mPaymentUiService.getSelectedPaymentApp();
(PaymentApp) mPaymentUiService.getPaymentMethodsSection().getSelectedItem();
if (app == null || !app.isReadyForMinimalUI() || TextUtils.isEmpty(app.accountBalance())) { if (app == null || !app.isReadyForMinimalUI() || TextUtils.isEmpty(app.accountBalance())) {
return false; return false;
} }
...@@ -610,25 +606,10 @@ public class ChromePaymentRequestService ...@@ -610,25 +606,10 @@ public class ChromePaymentRequestService
} }
} }
mPaymentUiService.rankPaymentAppsForPaymentRequestUI(pendingApps); mPaymentUiService.setPaymentApps(pendingApps);
// Possibly pre-select the first app on the list.
int selection = !pendingApps.isEmpty() && pendingApps.get(0).canPreselect()
? 0
: SectionInformation.NO_SELECTION;
// The list of payment apps is ready to display.
mPaymentUiService.setPaymentMethodsSection(
new SectionInformation(PaymentRequestUI.DataType.PAYMENT_METHODS, selection,
new ArrayList<>(pendingApps)));
// Record the number suggested payment methods and whether at least one of them was
// complete.
mJourneyLogger.setNumberOfSuggestionsShown(Section.PAYMENT_METHOD, pendingApps.size(),
!pendingApps.isEmpty() && pendingApps.get(0).isComplete());
int missingFields = 0; int missingFields = 0;
if (pendingApps.isEmpty()) { if (mPaymentUiService.getPaymentApps().isEmpty()) {
if (mPaymentUiService.merchantSupportsAutofillCards()) { if (mPaymentUiService.merchantSupportsAutofillCards()) {
// Record all fields if basic-card is supported but no card exists. // Record all fields if basic-card is supported but no card exists.
missingFields = AutofillPaymentInstrument.CompletionStatus.CREDIT_CARD_EXPIRED missingFields = AutofillPaymentInstrument.CompletionStatus.CREDIT_CARD_EXPIRED
...@@ -636,16 +617,17 @@ public class ChromePaymentRequestService ...@@ -636,16 +617,17 @@ public class ChromePaymentRequestService
| AutofillPaymentInstrument.CompletionStatus.CREDIT_CARD_NO_NUMBER | AutofillPaymentInstrument.CompletionStatus.CREDIT_CARD_NO_NUMBER
| AutofillPaymentInstrument.CompletionStatus.CREDIT_CARD_NO_BILLING_ADDRESS; | AutofillPaymentInstrument.CompletionStatus.CREDIT_CARD_NO_BILLING_ADDRESS;
} }
} else if (pendingApps.get(0).isAutofillInstrument()) { } else {
missingFields = ((AutofillPaymentInstrument) (pendingApps.get(0))).getMissingFields(); PaymentApp firstApp = (PaymentApp) mPaymentUiService.getPaymentApps().get(0);
if (firstApp.isAutofillInstrument()) {
missingFields = ((AutofillPaymentInstrument) (firstApp)).getMissingFields();
}
} }
if (missingFields != 0) { if (missingFields != 0) {
RecordHistogram.recordSparseHistogram( RecordHistogram.recordSparseHistogram(
"PaymentRequest.MissingPaymentFields", missingFields); "PaymentRequest.MissingPaymentFields", missingFields);
} }
mPaymentUiService.updateAppModifiedTotals();
SettingsAutofillAndPaymentsObserver.getInstance().registerObserver(mPaymentUiService); SettingsAutofillAndPaymentsObserver.getInstance().registerObserver(mPaymentUiService);
} }
...@@ -665,8 +647,7 @@ public class ChromePaymentRequestService ...@@ -665,8 +647,7 @@ public class ChromePaymentRequestService
@Override @Override
public void onInstrumentDetailsReady() { public void onInstrumentDetailsReady() {
// If the payment method was an Autofill credit card with an identifier, record its use. // If the payment method was an Autofill credit card with an identifier, record its use.
PaymentApp selectedPaymentMethod = PaymentApp selectedPaymentMethod = (PaymentApp) mPaymentUiService.getSelectedPaymentApp();
(PaymentApp) mPaymentUiService.getPaymentMethodsSection().getSelectedItem();
if (selectedPaymentMethod != null if (selectedPaymentMethod != null
&& selectedPaymentMethod.getPaymentAppType() == PaymentAppType.AUTOFILL && selectedPaymentMethod.getPaymentAppType() == PaymentAppType.AUTOFILL
&& !selectedPaymentMethod.getIdentifier().isEmpty()) { && !selectedPaymentMethod.getIdentifier().isEmpty()) {
......
...@@ -344,14 +344,42 @@ public class PaymentUiService implements SettingsAutofillAndPaymentsObserver.Obs ...@@ -344,14 +344,42 @@ public class PaymentUiService implements SettingsAutofillAndPaymentsObserver.Obs
return mMerchantSupportsAutofillCards; return mMerchantSupportsAutofillCards;
} }
/** @return Get the PaymentMethodsSection of the PaymentRequest UI. */ /** @return Get the payment apps of the PaymentRequest UI. */
public SectionInformation getPaymentMethodsSection() { public List<EditableOption> getPaymentApps() {
return mPaymentMethodsSection; return mPaymentMethodsSection.getItems();
} }
/** Set the PaymentMethodsSection of the PaymentRequest UI. */ /**
public void setPaymentMethodsSection(SectionInformation paymentMethodsSection) { * Returns the selected payment app, if any.
mPaymentMethodsSection = paymentMethodsSection; * @return The selected payment app or null if none selected.
*/
@Nullable
public EditableOption getSelectedPaymentApp() {
return mPaymentMethodsSection.getSelectedItem();
}
/**
* Loads the payment apps into the app selector UI (aka, PaymentRequest UI).
* @param apps The payment apps to be loaded into the app selector UI.
*/
public void setPaymentApps(List<PaymentApp> apps) {
Collections.sort(apps, mPaymentAppComparator);
// Possibly pre-select the first app on the list.
int selection =
!apps.isEmpty() && apps.get(0).canPreselect() ? 0 : SectionInformation.NO_SELECTION;
// The list of payment apps is ready to display.
mPaymentMethodsSection = new SectionInformation(
PaymentRequestUI.DataType.PAYMENT_METHODS, selection, new ArrayList<>(apps));
// Record the number suggested payment methods and whether at least one of them was
// complete.
// TODO(crbug.com/1152498): move this into PaymentRequestService because the WebLayer
// payment request needs to record this as well.
mJourneyLogger.setNumberOfSuggestionsShown(
Section.PAYMENT_METHOD, apps.size(), !apps.isEmpty() && apps.get(0).isComplete());
updateAppModifiedTotals();
} }
/** Get the ShippingAddressesSection of the PaymentRequest UI. */ /** Get the ShippingAddressesSection of the PaymentRequest UI. */
...@@ -1258,14 +1286,6 @@ public class PaymentUiService implements SettingsAutofillAndPaymentsObserver.Obs ...@@ -1258,14 +1286,6 @@ public class PaymentUiService implements SettingsAutofillAndPaymentsObserver.Obs
PaymentRequestUI.DataType.SHIPPING_ADDRESSES, firstCompleteAddressIndex, addresses); PaymentRequestUI.DataType.SHIPPING_ADDRESSES, firstCompleteAddressIndex, addresses);
} }
/**
* Rank the payment apps for PaymentRequest UI.
* @param paymentApps A list of payment apps to be ranked in place.
*/
public void rankPaymentAppsForPaymentRequestUI(List<PaymentApp> paymentApps) {
Collections.sort(paymentApps, mPaymentAppComparator);
}
/** /**
* Edit the credit cards on the PaymentRequest UI. * Edit the credit cards on the PaymentRequest UI.
* @param toEdit The AutofillPaymentInstrument whose credit card is to replace those on the UI, * @param toEdit The AutofillPaymentInstrument whose credit card is to replace those on the UI,
......
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