blob: ef14834652b82bbf12a138826bc036373b2f63fd [file] [log] [blame]
// Copyright 2018 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.chrome.browser.autofill_assistant.user_data;
import android.app.Activity;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.Nullable;
import org.chromium.base.task.PostTask;
import org.chromium.chrome.browser.ChromeVersionInfo;
import org.chromium.chrome.browser.autofill.prefeditor.EditorDialog;
import org.chromium.chrome.browser.autofill_assistant.generic_ui.AssistantValue;
import org.chromium.chrome.browser.autofill_assistant.user_data.additional_sections.AssistantAdditionalSection.Delegate;
import org.chromium.chrome.browser.autofill_assistant.user_data.additional_sections.AssistantAdditionalSectionContainer;
import org.chromium.chrome.browser.payments.AddressEditor;
import org.chromium.chrome.browser.payments.AutofillAddress;
import org.chromium.chrome.browser.payments.AutofillContact;
import org.chromium.chrome.browser.payments.AutofillPaymentInstrument;
import org.chromium.chrome.browser.payments.BasicCardUtils;
import org.chromium.chrome.browser.payments.CardEditor;
import org.chromium.chrome.browser.payments.ContactEditor;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.components.payments.MethodStrings;
import org.chromium.content_public.browser.UiThreadTaskTraits;
import org.chromium.content_public.browser.WebContents;
import org.chromium.payments.mojom.PaymentMethodData;
import org.chromium.ui.modelutil.PropertyKey;
import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* This class is responsible for pushing updates to the Autofill Assistant UI for requesting user
* data. These updates are pulled from the {@link AssistantCollectUserDataModel} when a notification
* of an update is received.
*/
class AssistantCollectUserDataBinder
implements PropertyModelChangeProcessor.ViewBinder<AssistantCollectUserDataModel,
AssistantCollectUserDataBinder.ViewHolder, PropertyKey> {
/**
* A wrapper class that holds the different views of the CollectUserData request.
*/
static class ViewHolder {
private final View mRootView;
private final AssistantVerticalExpanderAccordion mPaymentRequestExpanderAccordion;
private final int mSectionToSectionPadding;
private final AssistantLoginSection mLoginSection;
private final AssistantContactDetailsSection mContactDetailsSection;
private final AssistantDateSection mDateRangeStartSection;
private final AssistantDateSection mDateRangeEndSection;
private final AssistantPaymentMethodSection mPaymentMethodSection;
private final AssistantShippingAddressSection mShippingAddressSection;
private final AssistantTermsSection mTermsSection;
private final AssistantTermsSection mTermsAsCheckboxSection;
private final AssistantInfoSection mInfoSection;
private final AssistantAdditionalSectionContainer mPrependedSections;
private final AssistantAdditionalSectionContainer mAppendedSections;
private final ViewGroup mGenericUserInterfaceContainerPrepended;
private final ViewGroup mGenericUserInterfaceContainerAppended;
private final Object mDividerTag;
private final Activity mActivity;
public ViewHolder(View rootView, AssistantVerticalExpanderAccordion accordion,
int sectionPadding, AssistantLoginSection loginSection,
AssistantContactDetailsSection contactDetailsSection,
AssistantDateSection dateRangeStartSection,
AssistantDateSection dateRangeEndSection,
AssistantPaymentMethodSection paymentMethodSection,
AssistantShippingAddressSection shippingAddressSection,
AssistantTermsSection termsSection, AssistantTermsSection termsAsCheckboxSection,
AssistantInfoSection infoSection,
AssistantAdditionalSectionContainer prependedSections,
AssistantAdditionalSectionContainer appendedSections,
ViewGroup genericUserInterfaceContainerPrepended,
ViewGroup genericUserInterfaceContainerAppended, Object dividerTag,
Activity activity) {
mRootView = rootView;
mPaymentRequestExpanderAccordion = accordion;
mSectionToSectionPadding = sectionPadding;
mLoginSection = loginSection;
mContactDetailsSection = contactDetailsSection;
mDateRangeStartSection = dateRangeStartSection;
mDateRangeEndSection = dateRangeEndSection;
mPaymentMethodSection = paymentMethodSection;
mShippingAddressSection = shippingAddressSection;
mTermsSection = termsSection;
mTermsAsCheckboxSection = termsAsCheckboxSection;
mInfoSection = infoSection;
mPrependedSections = prependedSections;
mAppendedSections = appendedSections;
mGenericUserInterfaceContainerPrepended = genericUserInterfaceContainerPrepended;
mGenericUserInterfaceContainerAppended = genericUserInterfaceContainerAppended;
mDividerTag = dividerTag;
mActivity = activity;
}
}
@Override
public void bind(
AssistantCollectUserDataModel model, ViewHolder view, PropertyKey propertyKey) {
boolean handled = updateEditors(model, propertyKey, view);
handled = updateRootVisibility(model, propertyKey, view) || handled;
handled = updateSectionVisibility(model, propertyKey, view) || handled;
handled = updateSectionTitles(model, propertyKey, view) || handled;
handled = updateSectionContents(model, propertyKey, view) || handled;
handled = updateSectionSelectedItem(model, propertyKey, view) || handled;
/* Update section paddings *after* updating section visibility. */
handled = updateSectionPaddings(model, propertyKey, view) || handled;
if (propertyKey == AssistantCollectUserDataModel.DELEGATE) {
AssistantCollectUserDataDelegate collectUserDataDelegate =
model.get(AssistantCollectUserDataModel.DELEGATE);
AssistantTermsSection.Delegate termsDelegate =
collectUserDataDelegate == null ? null : new AssistantTermsSection.Delegate() {
@Override
public void onStateChanged(@AssistantTermsAndConditionsState int state) {
collectUserDataDelegate.onTermsAndConditionsChanged(state);
}
@Override
public void onLinkClicked(int link) {
// TODO(b/143128544) refactor to do this the right way.
PostTask.postTask(UiThreadTaskTraits.DEFAULT, () -> {
view.mTermsSection.setTermsStatus(
AssistantTermsAndConditionsState.NOT_SELECTED);
view.mTermsAsCheckboxSection.setTermsStatus(
AssistantTermsAndConditionsState.NOT_SELECTED);
});
collectUserDataDelegate.onTextLinkClicked(link);
}
};
AssistantDateSection.Delegate dateStartDelegate =
collectUserDataDelegate == null ? null : new AssistantDateSection.Delegate() {
@Override
public void onDateChanged(@Nullable AssistantDateTime date) {
collectUserDataDelegate.onDateTimeRangeStartDateChanged(date);
// Set new start date as calendar fallback for the end date.
view.mDateRangeEndSection.setCalendarFallbackDate(date);
}
@Override
public void onTimeSlotChanged(@Nullable Integer index) {
collectUserDataDelegate.onDateTimeRangeStartTimeSlotChanged(index);
}
};
AssistantDateSection.Delegate dateEndDelegate =
collectUserDataDelegate == null ? null : new AssistantDateSection.Delegate() {
@Override
public void onDateChanged(@Nullable AssistantDateTime date) {
collectUserDataDelegate.onDateTimeRangeEndDateChanged(date);
// Set new end date as calendar fallback for the start date.
view.mDateRangeStartSection.setCalendarFallbackDate(date);
}
@Override
public void onTimeSlotChanged(@Nullable Integer index) {
collectUserDataDelegate.onDateTimeRangeEndTimeSlotChanged(index);
}
};
view.mTermsSection.setDelegate(termsDelegate);
view.mTermsAsCheckboxSection.setDelegate(termsDelegate);
view.mInfoSection.setListener(collectUserDataDelegate != null
? collectUserDataDelegate::onTextLinkClicked
: null);
view.mContactDetailsSection.setListener(collectUserDataDelegate != null
? collectUserDataDelegate::onContactInfoChanged
: null);
view.mPaymentMethodSection.setListener(collectUserDataDelegate != null
? collectUserDataDelegate::onPaymentMethodChanged
: null);
view.mShippingAddressSection.setListener(collectUserDataDelegate != null
? collectUserDataDelegate::onShippingAddressChanged
: null);
view.mLoginSection.setListener(collectUserDataDelegate != null
? collectUserDataDelegate::onLoginChoiceChanged
: null);
view.mDateRangeStartSection.setDelegate(dateStartDelegate);
view.mDateRangeEndSection.setDelegate(dateEndDelegate);
view.mPrependedSections.setDelegate(collectUserDataDelegate != null
? getAdditionalSectionsDelegate(collectUserDataDelegate)
: null);
view.mAppendedSections.setDelegate(collectUserDataDelegate != null
? getAdditionalSectionsDelegate(collectUserDataDelegate)
: null);
} else {
assert handled : "Unhandled property detected in AssistantCollectUserDataBinder!";
}
}
private Delegate getAdditionalSectionsDelegate(
AssistantCollectUserDataDelegate collectUserDataDelegate) {
return new Delegate() {
@Override
public void onValueChanged(String key, AssistantValue value) {
collectUserDataDelegate.onKeyValueChanged(key, value);
}
@Override
public void onTextFocusLost() {
collectUserDataDelegate.onTextFocusLost();
}
};
}
private boolean shouldShowContactDetails(AssistantCollectUserDataModel model) {
return model.get(AssistantCollectUserDataModel.REQUEST_NAME)
|| model.get(AssistantCollectUserDataModel.REQUEST_PHONE)
|| model.get(AssistantCollectUserDataModel.REQUEST_EMAIL);
}
private boolean updateSectionTitles(
AssistantCollectUserDataModel model, PropertyKey propertyKey, ViewHolder view) {
if (propertyKey == AssistantCollectUserDataModel.CONTACT_SECTION_TITLE) {
view.mContactDetailsSection.setTitle(
model.get(AssistantCollectUserDataModel.CONTACT_SECTION_TITLE));
return true;
} else if (propertyKey == AssistantCollectUserDataModel.LOGIN_SECTION_TITLE) {
view.mLoginSection.setTitle(
model.get(AssistantCollectUserDataModel.LOGIN_SECTION_TITLE));
return true;
} else if (propertyKey == AssistantCollectUserDataModel.SHIPPING_SECTION_TITLE) {
view.mShippingAddressSection.setTitle(
model.get(AssistantCollectUserDataModel.SHIPPING_SECTION_TITLE));
return true;
} else if (propertyKey == AssistantCollectUserDataModel.DATE_RANGE_START_DATE_LABEL) {
view.mDateRangeStartSection.setDateTitle(
model.get(AssistantCollectUserDataModel.DATE_RANGE_START_DATE_LABEL));
return true;
} else if (propertyKey == AssistantCollectUserDataModel.DATE_RANGE_START_TIME_LABEL) {
view.mDateRangeStartSection.setTimeTitle(
model.get(AssistantCollectUserDataModel.DATE_RANGE_START_TIME_LABEL));
return true;
} else if (propertyKey == AssistantCollectUserDataModel.DATE_RANGE_END_DATE_LABEL) {
view.mDateRangeEndSection.setDateTitle(
model.get(AssistantCollectUserDataModel.DATE_RANGE_END_DATE_LABEL));
return true;
} else if (propertyKey == AssistantCollectUserDataModel.DATE_RANGE_END_TIME_LABEL) {
view.mDateRangeEndSection.setTimeTitle(
model.get(AssistantCollectUserDataModel.DATE_RANGE_END_TIME_LABEL));
return true;
}
return false;
}
/**
* Updates the available items for each PR section.
* @return whether the property key was handled.
*/
private boolean updateSectionContents(
AssistantCollectUserDataModel model, PropertyKey propertyKey, ViewHolder view) {
if (propertyKey == AssistantCollectUserDataModel.AVAILABLE_PAYMENT_INSTRUMENTS
|| propertyKey == AssistantCollectUserDataModel.WEB_CONTENTS) {
if (model.get(AssistantCollectUserDataModel.REQUEST_PAYMENT)) {
List<AutofillPaymentInstrument> paymentInstruments;
if (model.get(AssistantCollectUserDataModel.WEB_CONTENTS) == null) {
paymentInstruments = Collections.emptyList();
} else {
paymentInstruments =
model.get(AssistantCollectUserDataModel.AVAILABLE_PAYMENT_INSTRUMENTS);
}
view.mPaymentMethodSection.onAvailablePaymentMethodsChanged(paymentInstruments);
}
return true;
} else if (propertyKey == AssistantCollectUserDataModel.AVAILABLE_CONTACTS) {
if (shouldShowContactDetails(model)) {
view.mContactDetailsSection.onContactsChanged(
model.get(AssistantCollectUserDataModel.AVAILABLE_CONTACTS));
}
return true;
} else if (propertyKey == AssistantCollectUserDataModel.AVAILABLE_SHIPPING_ADDRESSES) {
if (model.get(AssistantCollectUserDataModel.REQUEST_SHIPPING_ADDRESS)) {
view.mShippingAddressSection.onAddressesChanged(
model.get(AssistantCollectUserDataModel.AVAILABLE_SHIPPING_ADDRESSES));
}
return true;
} else if (propertyKey == AssistantCollectUserDataModel.AVAILABLE_BILLING_ADDRESSES) {
if (model.get(AssistantCollectUserDataModel.REQUEST_PAYMENT)) {
view.mPaymentMethodSection.onAddressesChanged(
model.get(AssistantCollectUserDataModel.AVAILABLE_BILLING_ADDRESSES));
}
return true;
} else if (propertyKey == AssistantCollectUserDataModel.REQUIRE_BILLING_POSTAL_CODE
|| propertyKey == AssistantCollectUserDataModel.BILLING_POSTAL_CODE_MISSING_TEXT) {
view.mPaymentMethodSection.setRequiresBillingPostalCode(
model.get(AssistantCollectUserDataModel.REQUIRE_BILLING_POSTAL_CODE));
view.mPaymentMethodSection.setBillingPostalCodeMissingText(
model.get(AssistantCollectUserDataModel.BILLING_POSTAL_CODE_MISSING_TEXT));
return true;
} else if (propertyKey == AssistantCollectUserDataModel.CREDIT_CARD_EXPIRED_TEXT) {
view.mPaymentMethodSection.setCreditCardExpiredText(
model.get(AssistantCollectUserDataModel.CREDIT_CARD_EXPIRED_TEXT));
return true;
} else if (propertyKey == AssistantCollectUserDataModel.AVAILABLE_LOGINS) {
if (model.get(AssistantCollectUserDataModel.REQUEST_LOGIN_CHOICE)) {
view.mLoginSection.onLoginsChanged(
model.get(AssistantCollectUserDataModel.AVAILABLE_LOGINS));
}
return true;
} else if (propertyKey == AssistantCollectUserDataModel.DATE_RANGE_START_OPTIONS) {
view.mDateRangeStartSection.setDateChoiceOptions(
model.get(AssistantCollectUserDataModel.DATE_RANGE_START_OPTIONS));
return true;
} else if (propertyKey == AssistantCollectUserDataModel.DATE_RANGE_START_DATE) {
view.mDateRangeStartSection.setCurrentDate(
model.get(AssistantCollectUserDataModel.DATE_RANGE_START_DATE));
return true;
} else if (propertyKey == AssistantCollectUserDataModel.DATE_RANGE_START_TIMESLOT) {
view.mDateRangeStartSection.setCurrentTimeSlot(
model.get(AssistantCollectUserDataModel.DATE_RANGE_START_TIMESLOT));
return true;
} else if (propertyKey == AssistantCollectUserDataModel.DATE_RANGE_END_OPTIONS) {
view.mDateRangeEndSection.setDateChoiceOptions(
model.get(AssistantCollectUserDataModel.DATE_RANGE_END_OPTIONS));
return true;
} else if (propertyKey == AssistantCollectUserDataModel.DATE_RANGE_END_DATE) {
view.mDateRangeEndSection.setCurrentDate(
model.get(AssistantCollectUserDataModel.DATE_RANGE_END_DATE));
return true;
} else if (propertyKey == AssistantCollectUserDataModel.DATE_RANGE_END_TIMESLOT) {
view.mDateRangeEndSection.setCurrentTimeSlot(
model.get(AssistantCollectUserDataModel.DATE_RANGE_END_TIMESLOT));
return true;
} else if (propertyKey
== AssistantCollectUserDataModel.DATE_RANGE_DATE_NOT_SET_ERROR_MESSAGE) {
view.mDateRangeStartSection.setDateNotSetErrorMessage(
model.get(AssistantCollectUserDataModel.DATE_RANGE_DATE_NOT_SET_ERROR_MESSAGE));
view.mDateRangeEndSection.setDateNotSetErrorMessage(
model.get(AssistantCollectUserDataModel.DATE_RANGE_DATE_NOT_SET_ERROR_MESSAGE));
return true;
} else if (propertyKey
== AssistantCollectUserDataModel.DATE_RANGE_TIME_NOT_SET_ERROR_MESSAGE) {
view.mDateRangeStartSection.setTimeNotSetErrorMessage(
model.get(AssistantCollectUserDataModel.DATE_RANGE_TIME_NOT_SET_ERROR_MESSAGE));
view.mDateRangeEndSection.setTimeNotSetErrorMessage(
model.get(AssistantCollectUserDataModel.DATE_RANGE_TIME_NOT_SET_ERROR_MESSAGE));
return true;
} else if (propertyKey == AssistantCollectUserDataModel.PREPENDED_SECTIONS) {
view.mPrependedSections.setSections(
model.get(AssistantCollectUserDataModel.PREPENDED_SECTIONS));
return true;
} else if (propertyKey == AssistantCollectUserDataModel.APPENDED_SECTIONS) {
view.mAppendedSections.setSections(
model.get(AssistantCollectUserDataModel.APPENDED_SECTIONS));
return true;
} else if (propertyKey == AssistantCollectUserDataModel.ACCEPT_TERMS_AND_CONDITIONS_TEXT) {
view.mTermsSection.setAcceptTermsAndConditionsText(
model.get(AssistantCollectUserDataModel.ACCEPT_TERMS_AND_CONDITIONS_TEXT));
view.mTermsAsCheckboxSection.setAcceptTermsAndConditionsText(
model.get(AssistantCollectUserDataModel.ACCEPT_TERMS_AND_CONDITIONS_TEXT));
return true;
} else if (propertyKey == AssistantCollectUserDataModel.TERMS_REQUIRE_REVIEW_TEXT) {
view.mTermsSection.setTermsRequireReviewText(
model.get(AssistantCollectUserDataModel.TERMS_REQUIRE_REVIEW_TEXT));
view.mTermsAsCheckboxSection.setTermsRequireReviewText(
model.get(AssistantCollectUserDataModel.TERMS_REQUIRE_REVIEW_TEXT));
return true;
} else if (propertyKey == AssistantCollectUserDataModel.INFO_SECTION_TEXT) {
view.mInfoSection.setText(model.get(AssistantCollectUserDataModel.INFO_SECTION_TEXT));
return true;
} else if (propertyKey == AssistantCollectUserDataModel.INFO_SECTION_TEXT_CENTER) {
view.mInfoSection.setCenter(
model.get(AssistantCollectUserDataModel.INFO_SECTION_TEXT_CENTER));
return true;
} else if (propertyKey == AssistantCollectUserDataModel.PRIVACY_NOTICE_TEXT) {
view.mTermsSection.setPrivacyNoticeText(
model.get(AssistantCollectUserDataModel.PRIVACY_NOTICE_TEXT));
view.mTermsAsCheckboxSection.setPrivacyNoticeText(
model.get(AssistantCollectUserDataModel.PRIVACY_NOTICE_TEXT));
return true;
} else if (propertyKey == AssistantCollectUserDataModel.GENERIC_USER_INTERFACE_PREPENDED) {
view.mGenericUserInterfaceContainerPrepended.removeAllViews();
if (model.get(AssistantCollectUserDataModel.GENERIC_USER_INTERFACE_PREPENDED) != null) {
view.mGenericUserInterfaceContainerPrepended.addView(
model.get(AssistantCollectUserDataModel.GENERIC_USER_INTERFACE_PREPENDED));
}
return true;
} else if (propertyKey == AssistantCollectUserDataModel.GENERIC_USER_INTERFACE_APPENDED) {
view.mGenericUserInterfaceContainerAppended.removeAllViews();
if (model.get(AssistantCollectUserDataModel.GENERIC_USER_INTERFACE_APPENDED) != null) {
view.mGenericUserInterfaceContainerAppended.addView(
model.get(AssistantCollectUserDataModel.GENERIC_USER_INTERFACE_APPENDED));
}
return true;
} else if (propertyKey
== AssistantCollectUserDataModel.CONTACT_SUMMARY_DESCRIPTION_OPTIONS) {
view.mContactDetailsSection.setContactSummaryOptions(
model.get(AssistantCollectUserDataModel.CONTACT_SUMMARY_DESCRIPTION_OPTIONS));
return true;
} else if (propertyKey == AssistantCollectUserDataModel.CONTACT_FULL_DESCRIPTION_OPTIONS) {
view.mContactDetailsSection.setContactFullOptions(
model.get(AssistantCollectUserDataModel.CONTACT_FULL_DESCRIPTION_OPTIONS));
return true;
}
return false;
}
/**
* Updates visibility of PR sections.
* @return whether the property key was handled.
*/
private boolean updateSectionVisibility(
AssistantCollectUserDataModel model, PropertyKey propertyKey, ViewHolder view) {
if ((propertyKey == AssistantCollectUserDataModel.REQUEST_NAME)
|| (propertyKey == AssistantCollectUserDataModel.REQUEST_EMAIL)
|| (propertyKey == AssistantCollectUserDataModel.REQUEST_PHONE)) {
view.mContactDetailsSection.setVisible(shouldShowContactDetails(model));
return true;
} else if (propertyKey == AssistantCollectUserDataModel.REQUEST_SHIPPING_ADDRESS) {
view.mShippingAddressSection.setVisible(
model.get(AssistantCollectUserDataModel.REQUEST_SHIPPING_ADDRESS));
return true;
} else if (propertyKey == AssistantCollectUserDataModel.REQUEST_PAYMENT) {
view.mPaymentMethodSection.setVisible(
(model.get(AssistantCollectUserDataModel.REQUEST_PAYMENT)));
return true;
} else if (propertyKey == AssistantCollectUserDataModel.SHOW_TERMS_AS_CHECKBOX) {
if (model.get(AssistantCollectUserDataModel.SHOW_TERMS_AS_CHECKBOX)) {
view.mTermsSection.getView().setVisibility(View.GONE);
view.mTermsAsCheckboxSection.getView().setVisibility(View.VISIBLE);
} else {
view.mTermsSection.getView().setVisibility(View.VISIBLE);
view.mTermsAsCheckboxSection.getView().setVisibility(View.GONE);
}
return true;
} else if (propertyKey == AssistantCollectUserDataModel.REQUEST_LOGIN_CHOICE) {
view.mLoginSection.setVisible(
model.get(AssistantCollectUserDataModel.REQUEST_LOGIN_CHOICE));
return true;
} else if (propertyKey == AssistantCollectUserDataModel.REQUEST_DATE_RANGE) {
boolean requestDateRange = model.get(AssistantCollectUserDataModel.REQUEST_DATE_RANGE);
view.mDateRangeStartSection.setVisible(requestDateRange);
view.mDateRangeEndSection.setVisible(requestDateRange);
return true;
}
return false;
}
/**
* Updates visibility of the root widget.
* @return whether the property key was handled.
*/
private boolean updateRootVisibility(
AssistantCollectUserDataModel model, PropertyKey propertyKey, ViewHolder view) {
if (propertyKey != AssistantCollectUserDataModel.VISIBLE) {
return false;
}
int visibility =
model.get(AssistantCollectUserDataModel.VISIBLE) ? View.VISIBLE : View.GONE;
if (view.mRootView.getVisibility() != visibility) {
view.mRootView.setVisibility(visibility);
}
return true;
}
/**
* Updates the currently selected item in each PR section.
* @return whether the property key was handled.
*/
private boolean updateSectionSelectedItem(
AssistantCollectUserDataModel model, PropertyKey propertyKey, ViewHolder view) {
if (propertyKey == AssistantCollectUserDataModel.SELECTED_SHIPPING_ADDRESS) {
if (model.get(AssistantCollectUserDataModel.REQUEST_SHIPPING_ADDRESS)) {
AutofillAddress shippingAddress =
model.get(AssistantCollectUserDataModel.SELECTED_SHIPPING_ADDRESS);
if (shippingAddress != null) {
view.mShippingAddressSection.addOrUpdateItem(
shippingAddress, /* select= */ true);
}
// No need to reset selection if null, this will be handled by setItems().
}
return true;
} else if (propertyKey == AssistantCollectUserDataModel.SELECTED_PAYMENT_INSTRUMENT) {
if (model.get(AssistantCollectUserDataModel.REQUEST_PAYMENT)) {
AutofillPaymentInstrument paymentInstrument =
model.get(AssistantCollectUserDataModel.SELECTED_PAYMENT_INSTRUMENT);
if (paymentInstrument != null) {
view.mPaymentMethodSection.addOrUpdateItem(
paymentInstrument, /* select= */ true);
}
// No need to reset selection if null, this will be handled by setItems().
}
return true;
} else if (propertyKey == AssistantCollectUserDataModel.SELECTED_CONTACT_DETAILS) {
if (shouldShowContactDetails(model)) {
AutofillContact contact =
model.get(AssistantCollectUserDataModel.SELECTED_CONTACT_DETAILS);
if (contact != null) {
view.mContactDetailsSection.addOrUpdateItem(contact, /* select= */ true);
}
// No need to reset selection if null, this will be handled by setItems().
}
return true;
} else if (propertyKey == AssistantCollectUserDataModel.TERMS_STATUS) {
int termsStatus = model.get(AssistantCollectUserDataModel.TERMS_STATUS);
view.mTermsSection.setTermsStatus(termsStatus);
view.mTermsAsCheckboxSection.setTermsStatus(termsStatus);
return true;
} else if (propertyKey == AssistantCollectUserDataModel.SELECTED_LOGIN) {
view.mLoginSection.addOrUpdateItem(
model.get(AssistantCollectUserDataModel.SELECTED_LOGIN), true);
return true;
}
return false;
}
/**
* Updates the paddings between sections and section dividers.
* @return whether the property key was handled.
*/
private boolean updateSectionPaddings(
AssistantCollectUserDataModel model, PropertyKey propertyKey, ViewHolder view) {
if ((propertyKey != AssistantCollectUserDataModel.REQUEST_SHIPPING_ADDRESS)
&& (propertyKey != AssistantCollectUserDataModel.REQUEST_NAME)
&& (propertyKey != AssistantCollectUserDataModel.REQUEST_EMAIL)
&& (propertyKey != AssistantCollectUserDataModel.REQUEST_PHONE)
&& (propertyKey != AssistantCollectUserDataModel.REQUEST_PAYMENT)
&& (propertyKey != AssistantCollectUserDataModel.REQUEST_LOGIN_CHOICE)
&& (propertyKey != AssistantCollectUserDataModel.REQUEST_DATE_RANGE)
&& (propertyKey != AssistantCollectUserDataModel.EXPANDED_SECTION)
&& (propertyKey != AssistantCollectUserDataModel.PREPENDED_SECTIONS)
&& (propertyKey != AssistantCollectUserDataModel.APPENDED_SECTIONS)) {
return false;
}
// Update section paddings such that the first and last section are flush to the top/bottom,
// and all other sections have the same amount of padding in-between them.
if (!model.get(AssistantCollectUserDataModel.PREPENDED_SECTIONS).isEmpty()) {
view.mPrependedSections.setPaddings(
0, view.mSectionToSectionPadding, view.mSectionToSectionPadding);
view.mLoginSection.setPaddings(
view.mSectionToSectionPadding, view.mSectionToSectionPadding);
view.mContactDetailsSection.setPaddings(
view.mSectionToSectionPadding, view.mSectionToSectionPadding);
view.mDateRangeStartSection.setPaddings(
view.mSectionToSectionPadding, view.mSectionToSectionPadding);
view.mDateRangeEndSection.setPaddings(
view.mSectionToSectionPadding, view.mSectionToSectionPadding);
view.mPaymentMethodSection.setPaddings(
view.mSectionToSectionPadding, view.mSectionToSectionPadding);
view.mShippingAddressSection.setPaddings(
view.mSectionToSectionPadding, view.mSectionToSectionPadding);
view.mAppendedSections.setPaddings(view.mSectionToSectionPadding,
view.mSectionToSectionPadding, view.mSectionToSectionPadding);
} else if (model.get(AssistantCollectUserDataModel.REQUEST_LOGIN_CHOICE)) {
view.mLoginSection.setPaddings(0, view.mSectionToSectionPadding);
view.mContactDetailsSection.setPaddings(
view.mSectionToSectionPadding, view.mSectionToSectionPadding);
view.mDateRangeStartSection.setPaddings(
view.mSectionToSectionPadding, view.mSectionToSectionPadding);
view.mDateRangeEndSection.setPaddings(
view.mSectionToSectionPadding, view.mSectionToSectionPadding);
view.mPaymentMethodSection.setPaddings(
view.mSectionToSectionPadding, view.mSectionToSectionPadding);
view.mShippingAddressSection.setPaddings(
view.mSectionToSectionPadding, view.mSectionToSectionPadding);
view.mAppendedSections.setPaddings(view.mSectionToSectionPadding,
view.mSectionToSectionPadding, view.mSectionToSectionPadding);
} else if (shouldShowContactDetails(model)) {
view.mContactDetailsSection.setPaddings(0, view.mSectionToSectionPadding);
view.mDateRangeStartSection.setPaddings(
view.mSectionToSectionPadding, view.mSectionToSectionPadding);
view.mDateRangeEndSection.setPaddings(
view.mSectionToSectionPadding, view.mSectionToSectionPadding);
view.mPaymentMethodSection.setPaddings(
view.mSectionToSectionPadding, view.mSectionToSectionPadding);
view.mShippingAddressSection.setPaddings(
view.mSectionToSectionPadding, view.mSectionToSectionPadding);
view.mAppendedSections.setPaddings(view.mSectionToSectionPadding,
view.mSectionToSectionPadding, view.mSectionToSectionPadding);
} else if (model.get(AssistantCollectUserDataModel.REQUEST_DATE_RANGE)) {
view.mDateRangeStartSection.setPaddings(0, view.mSectionToSectionPadding);
view.mDateRangeEndSection.setPaddings(
view.mSectionToSectionPadding, view.mSectionToSectionPadding);
view.mPaymentMethodSection.setPaddings(
view.mSectionToSectionPadding, view.mSectionToSectionPadding);
view.mShippingAddressSection.setPaddings(
view.mSectionToSectionPadding, view.mSectionToSectionPadding);
view.mAppendedSections.setPaddings(view.mSectionToSectionPadding,
view.mSectionToSectionPadding, view.mSectionToSectionPadding);
} else if (model.get(AssistantCollectUserDataModel.REQUEST_PAYMENT)) {
view.mPaymentMethodSection.setPaddings(0, view.mSectionToSectionPadding);
view.mShippingAddressSection.setPaddings(
view.mSectionToSectionPadding, view.mSectionToSectionPadding);
view.mAppendedSections.setPaddings(view.mSectionToSectionPadding,
view.mSectionToSectionPadding, view.mSectionToSectionPadding);
} else if (model.get(AssistantCollectUserDataModel.REQUEST_SHIPPING_ADDRESS)) {
view.mShippingAddressSection.setPaddings(0, view.mSectionToSectionPadding);
view.mAppendedSections.setPaddings(view.mSectionToSectionPadding,
view.mSectionToSectionPadding, view.mSectionToSectionPadding);
} else if (!model.get(AssistantCollectUserDataModel.APPENDED_SECTIONS).isEmpty()) {
view.mAppendedSections.setPaddings(
0, view.mSectionToSectionPadding, view.mSectionToSectionPadding);
}
view.mTermsSection.setPaddings(view.mSectionToSectionPadding, 0);
// Do not set padding to the view.mTermsAsCheckboxSection, it already has "padding" from
// its checkbox (that coincidentally matches the padding of mSectionToSectionPadding).
view.mInfoSection.setPaddings(view.mSectionToSectionPadding, 0);
// Hide dividers for currently invisible sections and after the expanded section, if any.
boolean prevSectionIsExpandedOrInvisible = false;
for (int i = 0; i < view.mPaymentRequestExpanderAccordion.getChildCount(); i++) {
View child = view.mPaymentRequestExpanderAccordion.getChildAt(i);
if (child instanceof AssistantVerticalExpander
|| child == view.mDateRangeStartSection.getView()
|| child == view.mDateRangeEndSection.getView()) {
prevSectionIsExpandedOrInvisible = child.getVisibility() != View.VISIBLE
|| (child instanceof AssistantVerticalExpander
&& ((AssistantVerticalExpander) child).isExpanded());
} else if (child.getTag() == view.mDividerTag) {
child.setVisibility(prevSectionIsExpandedOrInvisible ? View.GONE : View.VISIBLE);
} else {
prevSectionIsExpandedOrInvisible = false;
}
}
return true;
}
/**
* Updates/recreates section editors.
* @return whether the property key was handled.
*/
private boolean updateEditors(
AssistantCollectUserDataModel model, PropertyKey propertyKey, ViewHolder view) {
if ((propertyKey != AssistantCollectUserDataModel.WEB_CONTENTS)
&& (propertyKey != AssistantCollectUserDataModel.REQUEST_NAME)
&& (propertyKey != AssistantCollectUserDataModel.REQUEST_EMAIL)
&& (propertyKey != AssistantCollectUserDataModel.REQUEST_PHONE)
&& (propertyKey != AssistantCollectUserDataModel.SUPPORTED_BASIC_CARD_NETWORKS)) {
return false;
}
WebContents webContents = model.get(AssistantCollectUserDataModel.WEB_CONTENTS);
if (webContents == null) {
view.mContactDetailsSection.setEditor(null);
view.mPaymentMethodSection.setEditor(null);
view.mShippingAddressSection.setEditor(null);
return true;
}
Profile profile = Profile.fromWebContents(webContents);
if (shouldShowContactDetails(model)) {
ContactEditor contactEditor =
new ContactEditor(model.get(AssistantCollectUserDataModel.REQUEST_NAME),
model.get(AssistantCollectUserDataModel.REQUEST_PHONE),
model.get(AssistantCollectUserDataModel.REQUEST_EMAIL),
!webContents.isIncognito());
contactEditor.setEditorDialog(new EditorDialog(view.mActivity,
/*deleteRunnable =*/null, profile));
view.mContactDetailsSection.setEditor(contactEditor);
}
AddressEditor addressEditor = new AddressEditor(AddressEditor.Purpose.PAYMENT_REQUEST,
/* saveToDisk= */ !webContents.isIncognito());
addressEditor.setEditorDialog(new EditorDialog(view.mActivity,
/*deleteRunnable =*/null, profile));
CardEditor cardEditor = new CardEditor(webContents, addressEditor,
/* includeOrgLabel= */ false, /* observerForTest= */ null);
List<String> supportedCardNetworks =
model.get(AssistantCollectUserDataModel.SUPPORTED_BASIC_CARD_NETWORKS);
if (supportedCardNetworks != null) {
cardEditor.addAcceptedPaymentMethodIfRecognized(
getPaymentMethodDataFromNetworks(supportedCardNetworks));
}
EditorDialog cardEditorDialog = new EditorDialog(view.mActivity,
/*deleteRunnable =*/null, profile);
if (ChromeVersionInfo.isBetaBuild() || ChromeVersionInfo.isStableBuild()) {
cardEditorDialog.disableScreenshots();
}
cardEditor.setEditorDialog(cardEditorDialog);
view.mShippingAddressSection.setEditor(addressEditor);
view.mPaymentMethodSection.setEditor(cardEditor);
return true;
}
private PaymentMethodData getPaymentMethodDataFromNetworks(List<String> supportedCardNetworks) {
// Only enable 'basic-card' payment method.
PaymentMethodData methodData = new PaymentMethodData();
methodData.supportedMethod = MethodStrings.BASIC_CARD;
// Apply basic-card filter if specified
if (supportedCardNetworks != null && supportedCardNetworks.size() > 0) {
ArrayList<Integer> filteredNetworks = new ArrayList<>();
Map<String, Integer> networks = BasicCardUtils.getNetworkIdentifiers();
for (String network : supportedCardNetworks) {
assert networks.containsKey(network);
if (networks.containsKey(network)) {
filteredNetworks.add(networks.get(network));
}
}
methodData.supportedNetworks = new int[filteredNetworks.size()];
for (int i = 0; i < filteredNetworks.size(); ++i) {
methodData.supportedNetworks[i] = filteredNetworks.get(i);
}
}
return methodData;
}
}