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; ...@@ -6,31 +6,20 @@ package org.chromium.chrome.browser.payments;
import org.chromium.components.autofill.Completable; import org.chromium.components.autofill.Completable;
import org.chromium.components.payments.PaymentApp; import org.chromium.components.payments.PaymentApp;
import org.chromium.components.payments.PaymentRequestParams;
import java.util.Comparator; import java.util.Comparator;
/** A comparator that is used to rank the payment apps to be listed in the payment sheet. */ /** A comparator that is used to rank the payment apps to be listed in the payment sheet. */
/* package */ class PaymentAppComparator implements Comparator<PaymentApp> { /* package */ class PaymentAppComparator implements Comparator<PaymentApp> {
private final ParamsProvider mParamsProvider; private final PaymentRequestParams mParams;
/** 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();
}
/** /**
* Create an instance of PaymentAppComparator. * 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) { /* package */ PaymentAppComparator(PaymentRequestParams params) {
mParamsProvider = paramsProvider; mParams = params;
} }
/** /**
...@@ -89,7 +78,7 @@ import java.util.Comparator; ...@@ -89,7 +78,7 @@ import java.util.Comparator;
if (completeness != 0) return completeness; if (completeness != 0) return completeness;
// Payment apps which handle shipping address before others. // Payment apps which handle shipping address before others.
if (mParamsProvider.requestShipping()) { if (mParams.requestShipping()) {
int canHandleShipping = int canHandleShipping =
(b.handlesShippingAddress() ? 1 : 0) - (a.handlesShippingAddress() ? 1 : 0); (b.handlesShippingAddress() ? 1 : 0) - (a.handlesShippingAddress() ? 1 : 0);
if (canHandleShipping != 0) return canHandleShipping; if (canHandleShipping != 0) return canHandleShipping;
...@@ -98,15 +87,15 @@ import java.util.Comparator; ...@@ -98,15 +87,15 @@ import java.util.Comparator;
// Payment apps which handle more contact information fields come first. // Payment apps which handle more contact information fields come first.
int aSupportedContactDelegationsNum = 0; int aSupportedContactDelegationsNum = 0;
int bSupportedContactDelegationsNum = 0; int bSupportedContactDelegationsNum = 0;
if (mParamsProvider.requestPayerName()) { if (mParams.requestPayerName()) {
if (a.handlesPayerName()) aSupportedContactDelegationsNum++; if (a.handlesPayerName()) aSupportedContactDelegationsNum++;
if (b.handlesPayerName()) bSupportedContactDelegationsNum++; if (b.handlesPayerName()) bSupportedContactDelegationsNum++;
} }
if (mParamsProvider.requestPayerEmail()) { if (mParams.requestPayerEmail()) {
if (a.handlesPayerEmail()) aSupportedContactDelegationsNum++; if (a.handlesPayerEmail()) aSupportedContactDelegationsNum++;
if (b.handlesPayerEmail()) bSupportedContactDelegationsNum++; if (b.handlesPayerEmail()) bSupportedContactDelegationsNum++;
} }
if (mParamsProvider.requestPayerPhone()) { if (mParams.requestPayerPhone()) {
if (a.handlesPayerPhone()) aSupportedContactDelegationsNum++; if (a.handlesPayerPhone()) aSupportedContactDelegationsNum++;
if (b.handlesPayerPhone()) bSupportedContactDelegationsNum++; if (b.handlesPayerPhone()) bSupportedContactDelegationsNum++;
} }
......
...@@ -22,7 +22,6 @@ import org.chromium.chrome.browser.ChromeActivity; ...@@ -22,7 +22,6 @@ import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.ChromeTabbedActivity; import org.chromium.chrome.browser.ChromeTabbedActivity;
import org.chromium.chrome.browser.autofill.PersonalDataManager; import org.chromium.chrome.browser.autofill.PersonalDataManager;
import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile;
import org.chromium.chrome.browser.autofill.PersonalDataManager.CreditCard;
import org.chromium.chrome.browser.autofill.PersonalDataManager.NormalizedAddressRequestDelegate; import org.chromium.chrome.browser.autofill.PersonalDataManager.NormalizedAddressRequestDelegate;
import org.chromium.chrome.browser.compositor.layouts.EmptyOverviewModeObserver; import org.chromium.chrome.browser.compositor.layouts.EmptyOverviewModeObserver;
import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior; import org.chromium.chrome.browser.compositor.layouts.OverviewModeBehavior;
...@@ -76,6 +75,7 @@ import org.chromium.components.payments.PaymentDetailsConverter; ...@@ -76,6 +75,7 @@ import org.chromium.components.payments.PaymentDetailsConverter;
import org.chromium.components.payments.PaymentDetailsUpdateServiceHelper; import org.chromium.components.payments.PaymentDetailsUpdateServiceHelper;
import org.chromium.components.payments.PaymentFeatureList; import org.chromium.components.payments.PaymentFeatureList;
import org.chromium.components.payments.PaymentHandlerHost; import org.chromium.components.payments.PaymentHandlerHost;
import org.chromium.components.payments.PaymentRequestParams;
import org.chromium.components.payments.PaymentRequestSpec; import org.chromium.components.payments.PaymentRequestSpec;
import org.chromium.components.payments.PaymentRequestUpdateEventListener; import org.chromium.components.payments.PaymentRequestUpdateEventListener;
import org.chromium.components.payments.PaymentValidator; import org.chromium.components.payments.PaymentValidator;
...@@ -133,9 +133,8 @@ public class PaymentRequestImpl ...@@ -133,9 +133,8 @@ public class PaymentRequestImpl
PaymentRequestUpdateEventListener, PaymentApp.AbortCallback, PaymentRequestUpdateEventListener, PaymentApp.AbortCallback,
PaymentApp.InstrumentDetailsCallback, PaymentApp.InstrumentDetailsCallback,
PaymentResponseHelper.PaymentResponseRequesterDelegate, FocusChangedObserver, PaymentResponseHelper.PaymentResponseRequesterDelegate, FocusChangedObserver,
NormalizedAddressRequestDelegate, SettingsAutofillAndPaymentsObserver.Observer, NormalizedAddressRequestDelegate, PaymentDetailsConverter.MethodChecker,
PaymentDetailsConverter.MethodChecker, PaymentHandlerUiObserver, PaymentHandlerUiObserver, PaymentRequestParams, PaymentUIsManager.Delegate {
PaymentAppComparator.ParamsProvider {
/** /**
* A delegate to ask questions about the system, that allows tests to inject behaviour without * A delegate to ask questions about the system, that allows tests to inject behaviour without
* having to modify the entire system. This partially mirrors a similar C++ * having to modify the entire system. This partially mirrors a similar C++
...@@ -505,8 +504,8 @@ public class PaymentRequestImpl ...@@ -505,8 +504,8 @@ public class PaymentRequestImpl
mSkipUiForNonUrlPaymentMethodIdentifiers = mDelegate.skipUiForBasicCard(); mSkipUiForNonUrlPaymentMethodIdentifiers = mDelegate.skipUiForBasicCard();
if (sObserverForTest != null) sObserverForTest.onPaymentRequestCreated(this); if (sObserverForTest != null) sObserverForTest.onPaymentRequestCreated(this);
mPaymentUIsManager = new PaymentUIsManager(addressEditor, cardEditor); mPaymentUIsManager = new PaymentUIsManager(/*delegate=*/this, addressEditor, cardEditor);
mPaymentAppComparator = new PaymentAppComparator(/*paramsProvider=*/this); mPaymentAppComparator = new PaymentAppComparator(/*params=*/this);
} }
// Implement ComponentPaymentRequestDelegate: // Implement ComponentPaymentRequestDelegate:
...@@ -527,6 +526,7 @@ public class PaymentRequestImpl ...@@ -527,6 +526,7 @@ public class PaymentRequestImpl
boolean googlePayBridgeEligible) { boolean googlePayBridgeEligible) {
assert getClient() != null; assert getClient() != null;
mMethodData = new HashMap<>(); mMethodData = new HashMap<>();
mComponentPaymentRequestImpl.registerPaymentRequestLifecycleObserver(mPaymentUIsManager);
if (!OriginSecurityChecker.isOriginSecure(mWebContents.getLastCommittedUrl())) { if (!OriginSecurityChecker.isOriginSecure(mWebContents.getLastCommittedUrl())) {
mJourneyLogger.setAborted(AbortReason.INVALID_DATA_FROM_RENDERER); mJourneyLogger.setAborted(AbortReason.INVALID_DATA_FROM_RENDERER);
...@@ -609,15 +609,12 @@ public class PaymentRequestImpl ...@@ -609,15 +609,12 @@ public class PaymentRequestImpl
} }
mId = details.id; mId = details.id;
// Checks whether the merchant supports autofill cards before show is called. // The first time initializations and validation of all of the parameters of {@link
boolean merchantSupportsAutofillCards = // PaymentRequestParams} should be done before {@link
AutofillPaymentAppFactory.merchantSupportsBasicCard(mMethodData); // PaymentRequestLifeCycleObserver#onPaymentRequestParamsInitiated}.
// If in strict mode, don't give user an option to add an autofill card during the checkout mComponentPaymentRequestImpl.getPaymentRequestLifecycleObserver()
// to avoid the "unhappy" basic-card flow. .onPaymentRequestParamsInitiated(
mPaymentUIsManager.setCanUserAddCreditCard(merchantSupportsAutofillCards /*params=*/this);
&& !PaymentFeatureList.isEnabledOrExperimentalFeaturesEnabled(
PaymentFeatureList.STRICT_HAS_ENROLLED_AUTOFILL_INSTRUMENT));
mPaymentUIsManager.setMerchantSupportsAutofillCards(merchantSupportsAutofillCards);
if (mRequestShipping || mRequestPayerName || mRequestPayerPhone || mRequestPayerEmail) { if (mRequestShipping || mRequestPayerName || mRequestPayerPhone || mRequestPayerEmail) {
mAutofillProfiles = Collections.unmodifiableList( mAutofillProfiles = Collections.unmodifiableList(
...@@ -660,7 +657,7 @@ public class PaymentRequestImpl ...@@ -660,7 +657,7 @@ public class PaymentRequestImpl
// Log the various types of payment methods that were requested by the merchant. // Log the various types of payment methods that were requested by the merchant.
boolean requestedMethodGoogle = false; boolean requestedMethodGoogle = false;
// Not to record requestedMethodBasicCard because JourneyLogger ignore the case where the // Not to record requestedMethodBasicCard because JourneyLogger ignore the case where the
// specified networks are unsupported. mPaymentUIsManager.isMerchantSupportsAutofillCards() // specified networks are unsupported. mPaymentUIsManager.merchantSupportsAutofillCards()
// better captures this group of interest than requestedMethodBasicCard. // better captures this group of interest than requestedMethodBasicCard.
boolean requestedMethodOther = false; boolean requestedMethodOther = false;
mURLPaymentMethodIdentifiersSupported = false; mURLPaymentMethodIdentifiersSupported = false;
...@@ -673,7 +670,7 @@ public class PaymentRequestImpl ...@@ -673,7 +670,7 @@ public class PaymentRequestImpl
break; break;
case MethodStrings.BASIC_CARD: case MethodStrings.BASIC_CARD:
// Not to record requestedMethodBasicCard because // Not to record requestedMethodBasicCard because
// mPaymentUIsManager.isMerchantSupportsAutofillCards() is used instead. // mPaymentUIsManager.merchantSupportsAutofillCards() is used instead.
break; break;
default: default:
// "Other" includes https url, http url(when certifate check is bypassed) and // "Other" includes https url, http url(when certifate check is bypassed) and
...@@ -1245,25 +1242,31 @@ public class PaymentRequestImpl ...@@ -1245,25 +1242,31 @@ public class PaymentRequestImpl
return true; return true;
} }
// Implement PaymentAppComparator.ParamsProvider: // Implement PaymentRequestParams:
@Override
public Map<String, PaymentMethodData> getMethodDataMap() {
return getMethodData();
}
// Implement PaymentRequestParams:
@Override @Override
public boolean requestShipping() { public boolean requestShipping() {
return mRequestShipping; return mRequestShipping;
} }
// Implement PaymentAppComparator.ParamsProvider: // Implement PaymentRequestParams:
@Override @Override
public boolean requestPayerName() { public boolean requestPayerName() {
return mRequestPayerName; return mRequestPayerName;
} }
// Implement PaymentAppComparator.ParamsProvider: // Implement PaymentRequestParams:
@Override @Override
public boolean requestPayerEmail() { public boolean requestPayerEmail() {
return mRequestPayerEmail; return mRequestPayerEmail;
} }
// Implement PaymentAppComparator.ParamsProvider: // Implement PaymentRequestParams:
@Override @Override
public boolean requestPayerPhone() { public boolean requestPayerPhone() {
return mRequestPayerPhone; return mRequestPayerPhone;
...@@ -1534,8 +1537,9 @@ public class PaymentRequestImpl ...@@ -1534,8 +1537,9 @@ public class PaymentRequestImpl
return true; return true;
} }
/** Updates the modifiers for payment apps and order summary. */ // Implement PaymentUIsManager.Delegate:
private void updateAppModifiedTotals() { @Override
public void updateAppModifiedTotals() {
if (!PaymentFeatureList.isEnabled(PaymentFeatureList.WEB_PAYMENTS_MODIFIERS)) return; if (!PaymentFeatureList.isEnabled(PaymentFeatureList.WEB_PAYMENTS_MODIFIERS)) return;
if (mModifiers == null) return; if (mModifiers == null) return;
if (mPaymentUIsManager.getPaymentMethodsSection() == null) return; if (mPaymentUIsManager.getPaymentMethodsSection() == null) return;
...@@ -1721,7 +1725,8 @@ public class PaymentRequestImpl ...@@ -1721,7 +1725,8 @@ public class PaymentRequestImpl
// origin completely. // origin completely.
mPaymentUIsManager.getPaymentMethodsSection() mPaymentUIsManager.getPaymentMethodsSection()
.setDisplaySelectedItemSummaryInSingleLineInNormalMode( .setDisplaySelectedItemSummaryInSingleLineInNormalMode(
getSelectedPaymentAppType() != PaymentAppType.SERVICE_WORKER_APP); mPaymentUIsManager.getSelectedPaymentAppType()
!= PaymentAppType.SERVICE_WORKER_APP);
mPaymentInformationCallback.onResult(new PaymentInformation(mUiShoppingCart, mPaymentInformationCallback.onResult(new PaymentInformation(mUiShoppingCart,
mPaymentUIsManager.getShippingAddressesSection(), mUiShippingOptions, mPaymentUIsManager.getShippingAddressesSection(), mUiShippingOptions,
mPaymentUIsManager.getContactSection(), mPaymentUIsManager.getContactSection(),
...@@ -2067,19 +2072,11 @@ public class PaymentRequestImpl ...@@ -2067,19 +2072,11 @@ public class PaymentRequestImpl
return; return;
} }
assert getSelectedPaymentAppType() == PaymentAppType.AUTOFILL; assert mPaymentUIsManager.getSelectedPaymentAppType() == PaymentAppType.AUTOFILL;
mPaymentUIsManager.getPaymentRequestUI().showProcessingMessage(); mPaymentUIsManager.getPaymentRequestUI().showProcessingMessage();
} }
private @PaymentAppType int getSelectedPaymentAppType() {
return mPaymentUIsManager.getPaymentMethodsSection() != null
&& mPaymentUIsManager.getPaymentMethodsSection().getSelectedItem() != null
? ((PaymentApp) mPaymentUIsManager.getPaymentMethodsSection().getSelectedItem())
.getPaymentAppType()
: PaymentAppType.UNDEFINED;
}
@Override @Override
public boolean onPayClicked(EditableOption selectedShippingAddress, public boolean onPayClicked(EditableOption selectedShippingAddress,
EditableOption selectedShippingOption, EditableOption selectedPaymentMethod) { EditableOption selectedShippingOption, EditableOption selectedPaymentMethod) {
...@@ -2353,83 +2350,6 @@ public class PaymentRequestImpl ...@@ -2353,83 +2350,6 @@ public class PaymentRequestImpl
settingsLauncher.launchSettingsActivity(context); settingsLauncher.launchSettingsActivity(context);
} }
@Override
public void onAddressUpdated(AutofillAddress address) {
if (getClient() == null) return;
address.setShippingAddressLabelWithCountry();
mPaymentUIsManager.getCardEditor().updateBillingAddressIfComplete(address);
if (mPaymentUIsManager.getShippingAddressesSection() != null) {
mPaymentUIsManager.getShippingAddressesSection().addAndSelectOrUpdateItem(address);
mPaymentUIsManager.getPaymentRequestUI().updateSection(
PaymentRequestUI.DataType.SHIPPING_ADDRESSES,
mPaymentUIsManager.getShippingAddressesSection());
}
if (mPaymentUIsManager.getContactSection() != null) {
mPaymentUIsManager.getContactSection().addOrUpdateWithAutofillAddress(address);
mPaymentUIsManager.getPaymentRequestUI().updateSection(
PaymentRequestUI.DataType.CONTACT_DETAILS,
mPaymentUIsManager.getContactSection());
}
}
@Override
public void onAddressDeleted(String guid) {
if (getClient() == null) return;
// TODO: Delete the address from mPaymentUIsManager.getShippingAddressesSection() and
// mPaymentUIsManager.getContactSection(). Note that we only displayed SUGGESTIONS_LIMIT
// addresses, so we may want to add back previously ignored addresses.
}
@Override
public void onCreditCardUpdated(CreditCard card) {
if (getClient() == null || !mPaymentUIsManager.merchantSupportsAutofillCards()
|| mPaymentUIsManager.getPaymentMethodsSection() == null
|| mPaymentUIsManager.getAutofillPaymentAppCreator() == null) {
return;
}
PaymentApp updatedAutofillCard =
mPaymentUIsManager.getAutofillPaymentAppCreator().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;
mPaymentUIsManager.getPaymentMethodsSection().addAndSelectOrUpdateItem(updatedAutofillCard);
updateAppModifiedTotals();
if (mPaymentUIsManager.getPaymentRequestUI() != null) {
mPaymentUIsManager.getPaymentRequestUI().updateSection(
PaymentRequestUI.DataType.PAYMENT_METHODS,
mPaymentUIsManager.getPaymentMethodsSection());
}
}
@Override
public void onCreditCardDeleted(String guid) {
if (getClient() == null) return;
if (!mPaymentUIsManager.merchantSupportsAutofillCards()
|| mPaymentUIsManager.getPaymentMethodsSection() == null) {
return;
}
mPaymentUIsManager.getPaymentMethodsSection().removeAndUnselectItem(guid);
updateAppModifiedTotals();
if (mPaymentUIsManager.getPaymentRequestUI() != null) {
mPaymentUIsManager.getPaymentRequestUI().updateSection(
PaymentRequestUI.DataType.PAYMENT_METHODS,
mPaymentUIsManager.getPaymentMethodsSection());
}
}
// Implement ComponentPaymentRequestDelegate: // Implement ComponentPaymentRequestDelegate:
/** Called by the merchant website to check if the user has complete payment apps. */ /** Called by the merchant website to check if the user has complete payment apps. */
@Override @Override
...@@ -2759,7 +2679,11 @@ public class PaymentRequestImpl ...@@ -2759,7 +2679,11 @@ public class PaymentRequestImpl
int missingFields = 0; int missingFields = 0;
if (mPendingApps.isEmpty()) { if (mPendingApps.isEmpty()) {
if (mPaymentUIsManager.merchantSupportsAutofillCards()) { // TODO(crbug.com/1107039): This value could be null when this method is entered from
// PaymentRequest#init. We should turn it into boolean after correcting this bug.
Boolean merchantSupportsAutofillCards =
mPaymentUIsManager.merchantSupportsAutofillCards();
if (merchantSupportsAutofillCards != null && 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
| AutofillPaymentInstrument.CompletionStatus.CREDIT_CARD_NO_CARDHOLDER | AutofillPaymentInstrument.CompletionStatus.CREDIT_CARD_NO_CARDHOLDER
...@@ -2778,7 +2702,7 @@ public class PaymentRequestImpl ...@@ -2778,7 +2702,7 @@ public class PaymentRequestImpl
updateAppModifiedTotals(); updateAppModifiedTotals();
SettingsAutofillAndPaymentsObserver.getInstance().registerObserver(this); SettingsAutofillAndPaymentsObserver.getInstance().registerObserver(mPaymentUIsManager);
if (mIsCurrentPaymentRequestShowing) { if (mIsCurrentPaymentRequestShowing) {
// 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.
...@@ -3065,7 +2989,7 @@ public class PaymentRequestImpl ...@@ -3065,7 +2989,7 @@ public class PaymentRequestImpl
mOverviewModeBehavior = null; mOverviewModeBehavior = null;
} }
SettingsAutofillAndPaymentsObserver.getInstance().unregisterObserver(this); SettingsAutofillAndPaymentsObserver.getInstance().unregisterObserver(mPaymentUIsManager);
// Destroy native objects. // Destroy native objects.
for (CurrencyFormatter formatter : mCurrencyFormatterMap.values()) { for (CurrencyFormatter formatter : mCurrencyFormatterMap.values()) {
......
...@@ -4,29 +4,48 @@ ...@@ -4,29 +4,48 @@
package org.chromium.chrome.browser.payments.ui; 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.AddressEditor;
import org.chromium.chrome.browser.payments.AutofillAddress;
import org.chromium.chrome.browser.payments.AutofillPaymentAppCreator; 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.CardEditor;
import org.chromium.chrome.browser.payments.PaymentRequestImpl; 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} * This class manages all of the UIs related to payment. The UI logic of {@link PaymentRequestImpl}
* should be moved into this class. * should be moved into this class.
*/ */
public class PaymentUIsManager { public class PaymentUIsManager
private PaymentRequestUI mPaymentRequestUI; implements SettingsAutofillAndPaymentsObserver.Observer, PaymentRequestLifecycleObserver {
private PaymentUisShowStateReconciler mPaymentUisShowStateReconciler; private final Delegate mDelegate;
private final AddressEditor mAddressEditor; private final AddressEditor mAddressEditor;
private final CardEditor mCardEditor; private final CardEditor mCardEditor;
private final PaymentUisShowStateReconciler mPaymentUisShowStateReconciler;
private PaymentRequestUI mPaymentRequestUI;
private boolean mMerchantSupportsAutofillCards; private Boolean mMerchantSupportsAutofillCards;
private SectionInformation mPaymentMethodsSection; private SectionInformation mPaymentMethodsSection;
private SectionInformation mShippingAddressesSection; private SectionInformation mShippingAddressesSection;
private ContactDetailsSection mContactSection; private ContactDetailsSection mContactSection;
private AutofillPaymentAppCreator mAutofillPaymentAppCreator; 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 * This class is to coordinate the show state of a bottom sheet UI (either expandable payment
...@@ -84,10 +103,16 @@ public class PaymentUIsManager { ...@@ -84,10 +103,16 @@ public class PaymentUIsManager {
/** /**
* Create PaymentUIsManager. * Create PaymentUIsManager.
* @param delegate The delegate of this class.
* @param addressEditor The AddressEditor of the PaymentRequest UI. * @param addressEditor The AddressEditor of the PaymentRequest UI.
* @param cardEditor The CardEditor 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; mAddressEditor = addressEditor;
mCardEditor = cardEditor; mCardEditor = cardEditor;
mPaymentUisShowStateReconciler = new PaymentUisShowStateReconciler(); mPaymentUisShowStateReconciler = new PaymentUisShowStateReconciler();
...@@ -122,15 +147,13 @@ public class PaymentUIsManager { ...@@ -122,15 +147,13 @@ public class PaymentUIsManager {
} }
/** @return Whether the merchant supports autofill cards. */ /** @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; return mMerchantSupportsAutofillCards;
} }
/** Set whether the merchant supports autofill cards. */
public void setMerchantSupportsAutofillCards(boolean merchantSupportsAutofillCards) {
mMerchantSupportsAutofillCards = merchantSupportsAutofillCards;
}
/** @return Get the PaymentMethodsSection of the PaymentRequest UI. */ /** @return Get the PaymentMethodsSection of the PaymentRequest UI. */
public SectionInformation getPaymentMethodsSection() { public SectionInformation getPaymentMethodsSection() {
return mPaymentMethodsSection; return mPaymentMethodsSection;
...@@ -173,11 +196,97 @@ public class PaymentUIsManager { ...@@ -173,11 +196,97 @@ public class PaymentUIsManager {
/** @return Whether user can add credit card. */ /** @return Whether user can add credit card. */
public boolean canUserAddCreditCard() { public boolean canUserAddCreditCard() {
assert mCanUserAddCreditCard != null;
return mCanUserAddCreditCard; return mCanUserAddCreditCard;
} }
/** Set whether user can add credit card. */ // Implement SettingsAutofillAndPaymentsObserver.Observer:
public void setCanUserAddCreditCard(boolean canUserAddCreditCard) { @Override
mCanUserAddCreditCard = canUserAddCreditCard; 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") { ...@@ -90,6 +90,8 @@ android_library("java") {
"java/src/org/chromium/components/payments/PaymentManifestDownloader.java", "java/src/org/chromium/components/payments/PaymentManifestDownloader.java",
"java/src/org/chromium/components/payments/PaymentManifestParser.java", "java/src/org/chromium/components/payments/PaymentManifestParser.java",
"java/src/org/chromium/components/payments/PaymentManifestWebDataService.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/PaymentRequestSpec.java",
"java/src/org/chromium/components/payments/PaymentRequestUpdateEventListener.java", "java/src/org/chromium/components/payments/PaymentRequestUpdateEventListener.java",
"java/src/org/chromium/components/payments/PaymentValidator.java", "java/src/org/chromium/components/payments/PaymentValidator.java",
......
...@@ -23,6 +23,7 @@ import org.chromium.payments.mojom.PaymentValidationErrors; ...@@ -23,6 +23,7 @@ import org.chromium.payments.mojom.PaymentValidationErrors;
public class ComponentPaymentRequestImpl implements PaymentRequest { public class ComponentPaymentRequestImpl implements PaymentRequest {
private final ComponentPaymentRequestDelegate mDelegate; private final ComponentPaymentRequestDelegate mDelegate;
private PaymentRequestClient mClient; private PaymentRequestClient mClient;
private PaymentRequestLifecycleObserver mPaymentRequestLifecycleObserver;
/** /**
* The delegate of {@link ComponentPaymentRequestImpl}. * The delegate of {@link ComponentPaymentRequestImpl}.
...@@ -160,4 +161,18 @@ public class ComponentPaymentRequestImpl implements PaymentRequest { ...@@ -160,4 +161,18 @@ public class ComponentPaymentRequestImpl implements PaymentRequest {
if (mClient != null) mClient.close(); if (mClient != null) mClient.close();
mClient = null; 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