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

[PRImpl] Move SettingsAutofillAndPaymentsObserver to UIsManager

Changes:
* Move SettingsAutofillAndPaymentsObserver.Observer from PRImpl to
UIsManager, which includes these methods:
 - onMethodDataInitiated
 - onCreditCardDeleted
 - onCreditCardUpdated
 - onAddressDeleted
 - onAddressUpdated
* Create PRLifecycleObserver in CPRImpl
* Create PRParams and let PRImpl implement it.
* Since some methods depend on mMerchantSupportsAutofillCards, this CL
refactor the code that set merchantSupportsAutofillCards with
PRLifecycleObserver.onPaymentRequestParamsInitiated
* Change mCanUserAddCreditCard to boxed type so that we can assert
they are used after defined. mMerchantSupportsAutofillCards is not
changed to boxed type because an existing used-before-defined issue
crbug.com/1107039.

Bug: 1102522

Change-Id: Ib1354e9a3b53f2ce82ce760a70dfa00d46f80813
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2304772
Commit-Queue: Liquan (Max) Gu <maxlg@chromium.org>
Reviewed-by: default avatarRouslan Solomakhin <rouslan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#790463}
parent ccbe5802
......@@ -6,31 +6,20 @@ package org.chromium.chrome.browser.payments;
import org.chromium.components.autofill.Completable;
import org.chromium.components.payments.PaymentApp;
import org.chromium.components.payments.PaymentRequestParams;
import java.util.Comparator;
/** A comparator that is used to rank the payment apps to be listed in the payment sheet. */
/* package */ class PaymentAppComparator implements Comparator<PaymentApp> {
private final ParamsProvider mParamsProvider;
/** The provider of the parameters needed by this class. */
/* package */ interface ParamsProvider {
/** @return The requestShipping set by the merchant. */
boolean requestShipping();
/** @return The requestPayerName set by the merchant. */
boolean requestPayerName();
/** @return The requestPayerEmail set by the merchant. */
boolean requestPayerEmail();
/** @return The requestPayerPhone set by the merchant. */
boolean requestPayerPhone();
}
private final PaymentRequestParams mParams;
/**
* Create an instance of PaymentAppComparator.
* @param paramsProvider The provider of the params needed by this class.
* @param params The parameters of PaymentRequest specified by the merchant.
*/
/* package */ PaymentAppComparator(ParamsProvider paramsProvider) {
mParamsProvider = paramsProvider;
/* package */ PaymentAppComparator(PaymentRequestParams params) {
mParams = params;
}
/**
......@@ -89,7 +78,7 @@ import java.util.Comparator;
if (completeness != 0) return completeness;
// Payment apps which handle shipping address before others.
if (mParamsProvider.requestShipping()) {
if (mParams.requestShipping()) {
int canHandleShipping =
(b.handlesShippingAddress() ? 1 : 0) - (a.handlesShippingAddress() ? 1 : 0);
if (canHandleShipping != 0) return canHandleShipping;
......@@ -98,15 +87,15 @@ import java.util.Comparator;
// Payment apps which handle more contact information fields come first.
int aSupportedContactDelegationsNum = 0;
int bSupportedContactDelegationsNum = 0;
if (mParamsProvider.requestPayerName()) {
if (mParams.requestPayerName()) {
if (a.handlesPayerName()) aSupportedContactDelegationsNum++;
if (b.handlesPayerName()) bSupportedContactDelegationsNum++;
}
if (mParamsProvider.requestPayerEmail()) {
if (mParams.requestPayerEmail()) {
if (a.handlesPayerEmail()) aSupportedContactDelegationsNum++;
if (b.handlesPayerEmail()) bSupportedContactDelegationsNum++;
}
if (mParamsProvider.requestPayerPhone()) {
if (mParams.requestPayerPhone()) {
if (a.handlesPayerPhone()) aSupportedContactDelegationsNum++;
if (b.handlesPayerPhone()) bSupportedContactDelegationsNum++;
}
......
......@@ -4,29 +4,48 @@
package org.chromium.chrome.browser.payments.ui;
import androidx.annotation.Nullable;
import org.chromium.chrome.browser.autofill.PersonalDataManager.CreditCard;
import org.chromium.chrome.browser.payments.AddressEditor;
import org.chromium.chrome.browser.payments.AutofillAddress;
import org.chromium.chrome.browser.payments.AutofillPaymentAppCreator;
import org.chromium.chrome.browser.payments.AutofillPaymentAppFactory;
import org.chromium.chrome.browser.payments.CardEditor;
import org.chromium.chrome.browser.payments.PaymentRequestImpl;
import org.chromium.chrome.browser.payments.SettingsAutofillAndPaymentsObserver;
import org.chromium.components.payments.PaymentApp;
import org.chromium.components.payments.PaymentAppType;
import org.chromium.components.payments.PaymentFeatureList;
import org.chromium.components.payments.PaymentRequestLifecycleObserver;
import org.chromium.components.payments.PaymentRequestParams;
/**
* This class manages all of the UIs related to payment. The UI logic of {@link PaymentRequestImpl}
* should be moved into this class.
*/
public class PaymentUIsManager {
private PaymentRequestUI mPaymentRequestUI;
private PaymentUisShowStateReconciler mPaymentUisShowStateReconciler;
public class PaymentUIsManager
implements SettingsAutofillAndPaymentsObserver.Observer, PaymentRequestLifecycleObserver {
private final Delegate mDelegate;
private final AddressEditor mAddressEditor;
private final CardEditor mCardEditor;
private final PaymentUisShowStateReconciler mPaymentUisShowStateReconciler;
private PaymentRequestUI mPaymentRequestUI;
private boolean mMerchantSupportsAutofillCards;
private Boolean mMerchantSupportsAutofillCards;
private SectionInformation mPaymentMethodsSection;
private SectionInformation mShippingAddressesSection;
private ContactDetailsSection mContactSection;
private AutofillPaymentAppCreator mAutofillPaymentAppCreator;
private boolean mCanUserAddCreditCard;
private Boolean mCanUserAddCreditCard;
/** The delegate of this class. */
public interface Delegate {
/** Updates the modifiers for payment apps and order summary. */
void updateAppModifiedTotals();
}
/**
* This class is to coordinate the show state of a bottom sheet UI (either expandable payment
......@@ -84,10 +103,16 @@ public class PaymentUIsManager {
/**
* Create PaymentUIsManager.
* @param delegate The delegate of this class.
* @param addressEditor The AddressEditor of the PaymentRequest UI.
* @param cardEditor The CardEditor of the PaymentRequest UI.
*/
public PaymentUIsManager(AddressEditor addressEditor, CardEditor cardEditor) {
// TODO(crbug.com/1107102): AddressEditor and CardEditor should be initialized in this
// constructor instead of the caller of the constructor, once CardEditor's "ForTest" symbols
// have been removed from the production code.
public PaymentUIsManager(
Delegate delegate, AddressEditor addressEditor, CardEditor cardEditor) {
mDelegate = delegate;
mAddressEditor = addressEditor;
mCardEditor = cardEditor;
mPaymentUisShowStateReconciler = new PaymentUisShowStateReconciler();
......@@ -122,15 +147,13 @@ public class PaymentUIsManager {
}
/** @return Whether the merchant supports autofill cards. */
public boolean merchantSupportsAutofillCards() {
@Nullable
public Boolean merchantSupportsAutofillCards() {
// TODO(crbug.com/1107039): this value should be asserted not null to avoid being used
// before defined, after this bug is fixed.
return mMerchantSupportsAutofillCards;
}
/** Set whether the merchant supports autofill cards. */
public void setMerchantSupportsAutofillCards(boolean merchantSupportsAutofillCards) {
mMerchantSupportsAutofillCards = merchantSupportsAutofillCards;
}
/** @return Get the PaymentMethodsSection of the PaymentRequest UI. */
public SectionInformation getPaymentMethodsSection() {
return mPaymentMethodsSection;
......@@ -173,11 +196,97 @@ public class PaymentUIsManager {
/** @return Whether user can add credit card. */
public boolean canUserAddCreditCard() {
assert mCanUserAddCreditCard != null;
return mCanUserAddCreditCard;
}
/** Set whether user can add credit card. */
public void setCanUserAddCreditCard(boolean canUserAddCreditCard) {
mCanUserAddCreditCard = canUserAddCreditCard;
// Implement SettingsAutofillAndPaymentsObserver.Observer:
@Override
public void onAddressUpdated(AutofillAddress address) {
address.setShippingAddressLabelWithCountry();
mCardEditor.updateBillingAddressIfComplete(address);
if (mShippingAddressesSection != null) {
mShippingAddressesSection.addAndSelectOrUpdateItem(address);
mPaymentRequestUI.updateSection(
PaymentRequestUI.DataType.SHIPPING_ADDRESSES, mShippingAddressesSection);
}
if (mContactSection != null) {
mContactSection.addOrUpdateWithAutofillAddress(address);
mPaymentRequestUI.updateSection(
PaymentRequestUI.DataType.CONTACT_DETAILS, mContactSection);
}
}
// Implement SettingsAutofillAndPaymentsObserver.Observer:
@Override
public void onAddressDeleted(String guid) {
// TODO: Delete the address from getShippingAddressesSection() and
// getContactSection(). Note that we only displayed
// SUGGESTIONS_LIMIT addresses, so we may want to add back previously ignored addresses.
}
// Implement SettingsAutofillAndPaymentsObserver.Observer:
@Override
public void onCreditCardUpdated(CreditCard card) {
assert mMerchantSupportsAutofillCards != null;
if (!mMerchantSupportsAutofillCards || mPaymentMethodsSection == null
|| mAutofillPaymentAppCreator == null) {
return;
}
PaymentApp updatedAutofillCard = mAutofillPaymentAppCreator.createPaymentAppForCard(card);
// Can be null when the card added through settings does not match the requested card
// network or is invalid, because autofill settings do not perform the same level of
// validation as Basic Card implementation in Chrome.
if (updatedAutofillCard == null) return;
mPaymentMethodsSection.addAndSelectOrUpdateItem(updatedAutofillCard);
mDelegate.updateAppModifiedTotals();
if (mPaymentRequestUI != null) {
mPaymentRequestUI.updateSection(
PaymentRequestUI.DataType.PAYMENT_METHODS, mPaymentMethodsSection);
}
}
// Implement SettingsAutofillAndPaymentsObserver.Observer:
@Override
public void onCreditCardDeleted(String guid) {
assert mMerchantSupportsAutofillCards != null;
if (!mMerchantSupportsAutofillCards || mPaymentMethodsSection == null) return;
mPaymentMethodsSection.removeAndUnselectItem(guid);
mDelegate.updateAppModifiedTotals();
if (mPaymentRequestUI != null) {
mPaymentRequestUI.updateSection(
PaymentRequestUI.DataType.PAYMENT_METHODS, mPaymentMethodsSection);
}
}
// Implement PaymentRequestLifecycleObserver:
@Override
public void onPaymentRequestParamsInitiated(PaymentRequestParams params) {
// Checks whether the merchant supports autofill cards before show is called.
mMerchantSupportsAutofillCards =
AutofillPaymentAppFactory.merchantSupportsBasicCard(params.getMethodDataMap());
// If in strict mode, don't give user an option to add an autofill card during the checkout
// to avoid the "unhappy" basic-card flow.
mCanUserAddCreditCard = mMerchantSupportsAutofillCards
&& !PaymentFeatureList.isEnabledOrExperimentalFeaturesEnabled(
PaymentFeatureList.STRICT_HAS_ENROLLED_AUTOFILL_INSTRUMENT);
}
/** @return The selected payment app type. */
public @PaymentAppType int getSelectedPaymentAppType() {
return mPaymentMethodsSection != null && mPaymentMethodsSection.getSelectedItem() != null
? ((PaymentApp) mPaymentMethodsSection.getSelectedItem()).getPaymentAppType()
: PaymentAppType.UNDEFINED;
}
}
......@@ -90,6 +90,8 @@ android_library("java") {
"java/src/org/chromium/components/payments/PaymentManifestDownloader.java",
"java/src/org/chromium/components/payments/PaymentManifestParser.java",
"java/src/org/chromium/components/payments/PaymentManifestWebDataService.java",
"java/src/org/chromium/components/payments/PaymentRequestLifecycleObserver.java",
"java/src/org/chromium/components/payments/PaymentRequestParams.java",
"java/src/org/chromium/components/payments/PaymentRequestSpec.java",
"java/src/org/chromium/components/payments/PaymentRequestUpdateEventListener.java",
"java/src/org/chromium/components/payments/PaymentValidator.java",
......
......@@ -23,6 +23,7 @@ import org.chromium.payments.mojom.PaymentValidationErrors;
public class ComponentPaymentRequestImpl implements PaymentRequest {
private final ComponentPaymentRequestDelegate mDelegate;
private PaymentRequestClient mClient;
private PaymentRequestLifecycleObserver mPaymentRequestLifecycleObserver;
/**
* The delegate of {@link ComponentPaymentRequestImpl}.
......@@ -160,4 +161,18 @@ public class ComponentPaymentRequestImpl implements PaymentRequest {
if (mClient != null) mClient.close();
mClient = null;
}
/**
* Register an observer for the PaymentRequest lifecycle.
* @param paymentRequestLifecycleObserver The observer.
*/
public void registerPaymentRequestLifecycleObserver(
PaymentRequestLifecycleObserver paymentRequestLifecycleObserver) {
mPaymentRequestLifecycleObserver = paymentRequestLifecycleObserver;
}
/** @return The observer for the PaymentRequest lifecycle. */
public PaymentRequestLifecycleObserver getPaymentRequestLifecycleObserver() {
return mPaymentRequestLifecycleObserver;
}
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.components.payments;
/** Observe the lifecycle of the PaymentRequest. */
public interface PaymentRequestLifecycleObserver {
/**
* Called when all of the PaymentRequest parameters have been initiated and validated.
* @param params The parameters.
*/
void onPaymentRequestParamsInitiated(PaymentRequestParams params);
}
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.components.payments;
import org.chromium.payments.mojom.PaymentMethodData;
import java.util.Map;
/**
* The parameters of PaymentRequest specified by the merchant.
*/
public interface PaymentRequestParams {
/** @return The requestShipping set by the merchant. */
boolean requestShipping();
/** @return The requestPayerName set by the merchant. */
boolean requestPayerName();
/** @return The requestPayerEmail set by the merchant. */
boolean requestPayerEmail();
/** @return The requestPayerPhone set by the merchant. */
boolean requestPayerPhone();
/**
* @return The unmodifiable mapping of payment method identifier to the method-specific data in
* the payment request.
*/
Map<String, PaymentMethodData> getMethodDataMap();
}
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