Commit cdb475af authored by dfalcantara's avatar dfalcantara Committed by Commit bot

[Payments] Select and add buttons for incomplete sections

* Replaces the previous "Select shipping address" or "Select shipping option"
  prompts with gigantic [SELECT] and [ADD] buttons on the right of each
  incomplete section.

* Caches a copy of the SectionInformation in the relevant PaymentRequestSection
  instances so that we can determine if we need to prompt the user to SELECT
  or ADD new PaymentOptions.

* Buttons are enabled from top to bottom, with only one button enabled at a
  time.  This encourages users to move downward while filling out the form.
  When a button is visible for a section, the only way to interact with the
  section is via the button (no more clicking on incomplete sections to expand
  them).

* The shipping summary section, which combines both the shipping address and
  shipping option fields, can now display a button that shows either the
  button for the incomplete shipping address section or the incomplete shipping
  option section (prioritized in taht order).

* Get rid of and generalizes a bunch of unneeded strings.

* Because the logic is so complicated now, we consolidate most layout updates
  and view visibility checks to updateControlLayout().

* Updates the PaymentRequestDynamicShippingSingleAddressTest to account for the
  lack of summary text for incomplete sections.

* Edits the "select shipping address" string to add "and requirements" to the end.

Videos:
https://drive.google.com/open?id=0B7c8ZkXVwskDZDZWUkhDXzdvLUE
https://drive.google.com/open?id=0B7c8ZkXVwskDRm53UUhHUHZmeW8

BUG=603635

Review-Url: https://codereview.chromium.org/2170693002
Cr-Commit-Position: refs/heads/master@{#407289}
parent ffc181a2
...@@ -423,7 +423,7 @@ public class CardEditor extends EditorBase<AutofillPaymentInstrument> { ...@@ -423,7 +423,7 @@ public class CardEditor extends EditorBase<AutofillPaymentInstrument> {
private void addBillingAddressDropdown(EditorModel editor, final CreditCard card) { private void addBillingAddressDropdown(EditorModel editor, final CreditCard card) {
final List<DropdownKeyValue> billingAddresses = new ArrayList<>(); final List<DropdownKeyValue> billingAddresses = new ArrayList<>();
billingAddresses.add(new DropdownKeyValue(BILLING_ADDRESS_NONE, billingAddresses.add(new DropdownKeyValue(BILLING_ADDRESS_NONE,
mContext.getString(R.string.autofill_billing_address_select_prompt))); mContext.getString(R.string.select)));
// Re-read profiles every time, in case any of them have changed. This does not cause a disk // Re-read profiles every time, in case any of them have changed. This does not cause a disk
// read, because personal_data_manager.h holds a cache. // read, because personal_data_manager.h holds a cache.
......
...@@ -17,6 +17,7 @@ import android.view.LayoutInflater; ...@@ -17,6 +17,7 @@ import android.view.LayoutInflater;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.Button;
import android.widget.GridLayout; import android.widget.GridLayout;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView; import android.widget.ImageView;
...@@ -27,6 +28,7 @@ import android.widget.TextView; ...@@ -27,6 +28,7 @@ import android.widget.TextView;
import org.chromium.base.ApiCompatibilityUtils; import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.base.VisibleForTesting; import org.chromium.base.VisibleForTesting;
import org.chromium.chrome.R; import org.chromium.chrome.R;
import org.chromium.chrome.browser.widget.DualControlLayout;
import org.chromium.chrome.browser.widget.TintedDrawable; import org.chromium.chrome.browser.widget.TintedDrawable;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -39,11 +41,11 @@ import javax.annotation.Nullable; ...@@ -39,11 +41,11 @@ import javax.annotation.Nullable;
* *
* The row is broken up into three major, vertically-centered sections: * The row is broken up into three major, vertically-centered sections:
* ............................................................................................. * .............................................................................................
* . TITLE | | . * . TITLE | | CHEVRON .
* .................................................................| | . * .................................................................| | or .
* . LEFT SUMMARY TEXT | RIGHT SUMMARY TEXT | LOGO | CHEVRON . * . LEFT SUMMARY TEXT | RIGHT SUMMARY TEXT | LOGO | ADD .
* .................................................................| | . * .................................................................| | or .
* . MAIN SECTION CONTENT | | . * . MAIN SECTION CONTENT | | SELECT .
* ............................................................................................. * .............................................................................................
* *
* 1) MAIN CONTENT * 1) MAIN CONTENT
...@@ -55,19 +57,14 @@ import javax.annotation.Nullable; ...@@ -55,19 +57,14 @@ import javax.annotation.Nullable;
* Displays an optional logo (e.g. a credit card image) that floats to the right of the main * Displays an optional logo (e.g. a credit card image) that floats to the right of the main
* content. * content.
* *
* 3) CHEVRON * 3) CHEVRON or ADD or SELECT
* Drawn to indicate that the current section may be expanded. Displayed only when the view is * Drawn to indicate that the current section may be expanded. Displayed only when the view is
* in the {@link #DISPLAY_MODE_EXPANDABLE} state. * in the {@link #DISPLAY_MODE_EXPANDABLE} state and only if an ADD or SELECT button isn't shown.
* *
* There are three states that the UI may flip between; see {@link #DISPLAY_MODE_NORMAL}, * There are three states that the UI may flip between; see {@link #DISPLAY_MODE_NORMAL},
* {@link #DISPLAY_MODE_EXPANDABLE}, and {@link #DISPLAY_MODE_FOCUSED} for details. * {@link #DISPLAY_MODE_EXPANDABLE}, and {@link #DISPLAY_MODE_FOCUSED} for details.
*
* TODO(dfalcantara): Figure out what kind of Layout we should really be using here now that mocks
* have stabilized, somewhat. A RelativeLayout is gross because it doesn't
* automatically account for Views being removed, meaning we'd have to twiddle
* with each View's LayoutParams as their visibility was toggled.
*/ */
public abstract class PaymentRequestSection extends LinearLayout { public abstract class PaymentRequestSection extends LinearLayout implements View.OnClickListener {
public static final String TAG = "PaymentRequestUI"; public static final String TAG = "PaymentRequestUI";
/** Handles clicks on the widgets and providing data to the PaymentsRequestSection. */ /** Handles clicks on the widgets and providing data to the PaymentsRequestSection. */
...@@ -78,38 +75,54 @@ public abstract class PaymentRequestSection extends LinearLayout { ...@@ -78,38 +75,54 @@ public abstract class PaymentRequestSection extends LinearLayout {
* @param section Section that was changed. * @param section Section that was changed.
* @param option {@link PaymentOption} that was selected. * @param option {@link PaymentOption} that was selected.
*/ */
void onPaymentOptionChanged(OptionSection section, PaymentOption option); void onPaymentOptionChanged(PaymentRequestSection section, PaymentOption option);
/** Called when the user requests adding a new PaymentOption to a given section. */ /** Called when the user requests adding a new PaymentOption to a given section. */
void onAddPaymentOption(OptionSection section); void onAddPaymentOption(PaymentRequestSection section);
/** Checks whether or not the text should be formatted with a bold label. */ /** Checks whether or not the text should be formatted with a bold label. */
boolean isBoldLabelNeeded(OptionSection section); boolean isBoldLabelNeeded(PaymentRequestSection section);
/** Checks whether or not the user should be allowed to click on controls. */ /** Checks whether or not the user should be allowed to click on controls. */
boolean isAcceptingUserInput(); boolean isAcceptingUserInput();
/** Returns any additional text that needs to be displayed. */ /** Returns any additional text that needs to be displayed. */
@Nullable String getAdditionalText(OptionSection section); @Nullable String getAdditionalText(PaymentRequestSection section);
/** Returns true if the additional text should be stylized as a warning instead of info. */ /** Returns true if the additional text should be stylized as a warning instead of info. */
boolean isAdditionalTextDisplayingWarning(OptionSection section); boolean isAdditionalTextDisplayingWarning(PaymentRequestSection section);
/** Called when a section has been clicked. */
void onSectionClicked(PaymentRequestSection section);
} }
/** Edit button mode: Hide the button. */
public static final int EDIT_BUTTON_GONE = 0;
/** Edit button mode: Indicate that the section requires a selection. */
public static final int EDIT_BUTTON_SELECT = 1;
/** Edit button mode: Indicate that the section requires adding an option. */
public static final int EDIT_BUTTON_ADD = 2;
/** Normal mode: White background, displays the item assuming the user accepts it as is. */ /** Normal mode: White background, displays the item assuming the user accepts it as is. */
static final int DISPLAY_MODE_NORMAL = 0; static final int DISPLAY_MODE_NORMAL = 3;
/** Editable mode: White background, displays the item with an edit chevron. */ /** Editable mode: White background, displays the item with an edit chevron. */
static final int DISPLAY_MODE_EXPANDABLE = 1; static final int DISPLAY_MODE_EXPANDABLE = 4;
/** Focused mode: Gray background, more padding, no edit chevron. */ /** Focused mode: Gray background, more padding, no edit chevron. */
static final int DISPLAY_MODE_FOCUSED = 2; static final int DISPLAY_MODE_FOCUSED = 5;
/** Checking mode: Gray background, spinner overlay hides everything except the title. */ /** Checking mode: Gray background, spinner overlay hides everything except the title. */
static final int DISPLAY_MODE_CHECKING = 3; static final int DISPLAY_MODE_CHECKING = 6;
protected final SectionDelegate mDelegate; protected final SectionDelegate mDelegate;
protected final int mLargeSpacing; protected final int mLargeSpacing;
protected final Button mEditButtonView;
protected final boolean mIsLayoutInitialized;
protected int mDisplayMode = DISPLAY_MODE_NORMAL;
private final int mVerticalSpacing; private final int mVerticalSpacing;
private final int mFocusedBackgroundColor; private final int mFocusedBackgroundColor;
...@@ -123,7 +136,6 @@ public abstract class PaymentRequestSection extends LinearLayout { ...@@ -123,7 +136,6 @@ public abstract class PaymentRequestSection extends LinearLayout {
private TextView mSummaryRightTextView; private TextView mSummaryRightTextView;
private int mLogoResourceId; private int mLogoResourceId;
private int mDisplayMode;
private boolean mIsSummaryAllowed = true; private boolean mIsSummaryAllowed = true;
/** /**
...@@ -136,7 +148,6 @@ public abstract class PaymentRequestSection extends LinearLayout { ...@@ -136,7 +148,6 @@ public abstract class PaymentRequestSection extends LinearLayout {
private PaymentRequestSection(Context context, String sectionName, SectionDelegate delegate) { private PaymentRequestSection(Context context, String sectionName, SectionDelegate delegate) {
super(context); super(context);
mDelegate = delegate; mDelegate = delegate;
setId(R.id.payments_section);
setOnClickListener(delegate); setOnClickListener(delegate);
setOrientation(HORIZONTAL); setOrientation(HORIZONTAL);
setGravity(Gravity.CENTER_VERTICAL); setGravity(Gravity.CENTER_VERTICAL);
...@@ -153,7 +164,9 @@ public abstract class PaymentRequestSection extends LinearLayout { ...@@ -153,7 +164,9 @@ public abstract class PaymentRequestSection extends LinearLayout {
// Create the main content. // Create the main content.
mMainSection = prepareMainSection(sectionName); mMainSection = prepareMainSection(sectionName);
mLogoView = isLogoNecessary() ? createAndAddLogoView(this, 0, mLargeSpacing) : null; mLogoView = isLogoNecessary() ? createAndAddLogoView(this, 0, mLargeSpacing) : null;
mEditButtonView = createAndAddEditButton(this);
mChevronView = createAndAddChevron(this); mChevronView = createAndAddChevron(this);
mIsLayoutInitialized = true;
setDisplayMode(DISPLAY_MODE_NORMAL); setDisplayMode(DISPLAY_MODE_NORMAL);
} }
...@@ -166,7 +179,40 @@ public abstract class PaymentRequestSection extends LinearLayout { ...@@ -166,7 +179,40 @@ public abstract class PaymentRequestSection extends LinearLayout {
assert isLogoNecessary(); assert isLogoNecessary();
mLogoResourceId = resourceId; mLogoResourceId = resourceId;
mLogoView.setImageResource(resourceId); mLogoView.setImageResource(resourceId);
updateLogoVisibility(); }
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
// Allow touches to propagate to children only if the layout can be interacted with.
return !mDelegate.isAcceptingUserInput();
}
@Override
public final void onClick(View v) {
if (!mDelegate.isAcceptingUserInput()) return;
// Handle clicking on "ADD" or "SELECT".
if (v == mEditButtonView) {
if (getEditButtonState() == EDIT_BUTTON_ADD) {
mDelegate.onAddPaymentOption(this);
} else {
mDelegate.onSectionClicked(this);
}
return;
}
handleClick(v);
updateControlLayout();
}
/** Handles clicks on the PaymentRequestSection. */
protected void handleClick(View v) { }
/**
* Called when the UI is telling the section that it has either gained or lost focus.
*/
public void focusSection(boolean shouldFocus) {
setDisplayMode(shouldFocus ? DISPLAY_MODE_FOCUSED : DISPLAY_MODE_EXPANDABLE);
} }
/** /**
...@@ -176,20 +222,7 @@ public abstract class PaymentRequestSection extends LinearLayout { ...@@ -176,20 +222,7 @@ public abstract class PaymentRequestSection extends LinearLayout {
*/ */
public void setDisplayMode(int displayMode) { public void setDisplayMode(int displayMode) {
mDisplayMode = displayMode; mDisplayMode = displayMode;
boolean isExpanded = updateControlLayout();
displayMode == DISPLAY_MODE_FOCUSED || displayMode == DISPLAY_MODE_CHECKING;
setBackgroundColor(isExpanded ? mFocusedBackgroundColor : Color.WHITE);
updateLogoVisibility();
mChevronView.setVisibility(displayMode == DISPLAY_MODE_EXPANDABLE ? VISIBLE : GONE);
// The title gains extra spacing when there is another visible view in the main section.
int numVisibleMainViews = 0;
for (int i = 0; i < mMainSection.getChildCount(); i++) {
if (mMainSection.getChildAt(i).getVisibility() == VISIBLE) numVisibleMainViews += 1;
}
boolean isTitleMarginNecessary = numVisibleMainViews > 1 && isExpanded;
((ViewGroup.MarginLayoutParams) mTitleView.getLayoutParams()).bottomMargin =
isTitleMarginNecessary ? mVerticalSpacing : 0;
} }
/** /**
...@@ -203,7 +236,7 @@ public abstract class PaymentRequestSection extends LinearLayout { ...@@ -203,7 +236,7 @@ public abstract class PaymentRequestSection extends LinearLayout {
mSummaryLeftTextView.setText(leftText); mSummaryLeftTextView.setText(leftText);
mSummaryRightTextView.setText(rightText); mSummaryRightTextView.setText(rightText);
mSummaryRightTextView.setVisibility(TextUtils.isEmpty(rightText) ? GONE : VISIBLE); mSummaryRightTextView.setVisibility(TextUtils.isEmpty(rightText) ? GONE : VISIBLE);
updateSummaryVisibility(); updateControlLayout();
} }
/** /**
...@@ -228,14 +261,22 @@ public abstract class PaymentRequestSection extends LinearLayout { ...@@ -228,14 +261,22 @@ public abstract class PaymentRequestSection extends LinearLayout {
*/ */
protected abstract void createMainSectionContent(LinearLayout mainSectionLayout); protected abstract void createMainSectionContent(LinearLayout mainSectionLayout);
/**
* Sets whether the edit button may be interacted with.
*
* @param isEnabled Whether the button may be interacted with.
*/
public void setIsEditButtonEnabled(boolean isEnabled) {
mEditButtonView.setEnabled(isEnabled);
}
/** /**
* Sets whether the summary text can be displayed. * Sets whether the summary text can be displayed.
* *
* @param isAllowed Whether to display the summary text. * @param isAllowed Whether to display the summary text when needed.
*/ */
protected void setIsSummaryAllowed(boolean isAllowed) { protected void setIsSummaryAllowed(boolean isAllowed) {
mIsSummaryAllowed = isAllowed; mIsSummaryAllowed = isAllowed;
updateSummaryVisibility();
} }
/** @return Whether or not the logo should be displayed. */ /** @return Whether or not the logo should be displayed. */
...@@ -243,6 +284,15 @@ public abstract class PaymentRequestSection extends LinearLayout { ...@@ -243,6 +284,15 @@ public abstract class PaymentRequestSection extends LinearLayout {
return false; return false;
} }
/**
* Returns the state of the edit button, which is hidden by default.
*
* @return State of the edit button.
*/
public int getEditButtonState() {
return EDIT_BUTTON_GONE;
}
/** /**
* Creates the main section. Subclasses must call super#createMainSection() immediately to * Creates the main section. Subclasses must call super#createMainSection() immediately to
* guarantee that Views are added in the correct order. * guarantee that Views are added in the correct order.
...@@ -315,6 +365,19 @@ public abstract class PaymentRequestSection extends LinearLayout { ...@@ -315,6 +365,19 @@ public abstract class PaymentRequestSection extends LinearLayout {
return view; return view;
} }
private Button createAndAddEditButton(ViewGroup parent) {
Resources resources = parent.getResources();
Button view = DualControlLayout.createButtonForLayout(
parent.getContext(), true, resources.getString(R.string.select), this);
view.setId(R.id.payments_section);
LayoutParams params =
new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
ApiCompatibilityUtils.setMarginStart(params, mLargeSpacing);
parent.addView(view, params);
return view;
}
private ImageView createAndAddChevron(ViewGroup parent) { private ImageView createAndAddChevron(ViewGroup parent) {
Resources resources = parent.getResources(); Resources resources = parent.getResources();
TintedDrawable chevron = TintedDrawable.constructTintedDrawable( TintedDrawable chevron = TintedDrawable.constructTintedDrawable(
...@@ -331,30 +394,81 @@ public abstract class PaymentRequestSection extends LinearLayout { ...@@ -331,30 +394,81 @@ public abstract class PaymentRequestSection extends LinearLayout {
return view; return view;
} }
private void updateSummaryVisibility() { /**
boolean show = mIsSummaryAllowed && !TextUtils.isEmpty(mSummaryLeftTextView.getText()); * Called when the section's controls need to be updated after configuration changes.
mSummaryLayout.setVisibility(show ? VISIBLE : GONE); *
} * Because of the complicated special casing of what controls hide other controls, all calls to
* update just one of the controls causes the visibility logic to trigger for all of them.
*
* Subclasses should call the super method after they update their own controls.
*/
protected void updateControlLayout() {
if (!mIsLayoutInitialized) return;
private void updateLogoVisibility() { boolean isExpanded =
if (mLogoView == null) return; mDisplayMode == DISPLAY_MODE_FOCUSED || mDisplayMode == DISPLAY_MODE_CHECKING;
setBackgroundColor(isExpanded ? mFocusedBackgroundColor : Color.WHITE);
// Update whether the logo is displayed.
if (mLogoView != null) {
boolean show = mLogoResourceId != 0 && mDisplayMode != DISPLAY_MODE_FOCUSED; boolean show = mLogoResourceId != 0 && mDisplayMode != DISPLAY_MODE_FOCUSED;
mLogoView.setVisibility(show ? VISIBLE : GONE); mLogoView.setVisibility(show ? VISIBLE : GONE);
} }
// The button takes precedence over the summary text and the chevron.
int editButtonState = getEditButtonState();
if (editButtonState == EDIT_BUTTON_GONE) {
mEditButtonView.setVisibility(GONE);
mChevronView.setVisibility(
mDisplayMode == DISPLAY_MODE_EXPANDABLE ? VISIBLE : GONE);
// Update whether the summary is displayed.
boolean showSummary =
mIsSummaryAllowed && !TextUtils.isEmpty(mSummaryLeftTextView.getText());
mSummaryLayout.setVisibility(showSummary ? VISIBLE : GONE);
} else {
// Show the edit button and hide the chevron and the summary.
boolean isButtonAllowed = mDisplayMode == DISPLAY_MODE_EXPANDABLE
|| mDisplayMode == DISPLAY_MODE_NORMAL;
mSummaryLayout.setVisibility(GONE);
mChevronView.setVisibility(GONE);
mEditButtonView.setVisibility(isButtonAllowed ? VISIBLE : GONE);
mEditButtonView.setText(
editButtonState == EDIT_BUTTON_SELECT ? R.string.select : R.string.add);
}
// The title gains extra spacing when there is another visible view in the main section.
int numVisibleMainViews = 0;
for (int i = 0; i < mMainSection.getChildCount(); i++) {
if (mMainSection.getChildAt(i).getVisibility() == VISIBLE) numVisibleMainViews += 1;
}
boolean isTitleMarginNecessary = numVisibleMainViews > 1 && isExpanded;
int oldMargin =
((ViewGroup.MarginLayoutParams) mTitleView.getLayoutParams()).bottomMargin;
int newMargin = isTitleMarginNecessary ? mVerticalSpacing : 0;
if (oldMargin != newMargin) {
((ViewGroup.MarginLayoutParams) mTitleView.getLayoutParams()).bottomMargin =
newMargin;
requestLayout();
}
}
/** /**
* Section with a secondary TextView beneath the summary to show additional details. * Section with a secondary TextView beneath the summary to show additional details.
* *
* ............................................................................ * ............................................................................
* . TITLE | . * . TITLE | CHEVRON .
* .................................................................| . * .................................................................| or .
* . LEFT SUMMARY TEXT | RIGHT SUMMARY TEXT | CHEVRON . * . LEFT SUMMARY TEXT | RIGHT SUMMARY TEXT | ADD .
* .................................................................| . * .................................................................| or .
* . EXTRA TEXT | . * . EXTRA TEXT | SELECT .
* ............................................................................ * ............................................................................
*/ */
public static class ExtraTextSection extends PaymentRequestSection { public static class ExtraTextSection extends PaymentRequestSection {
private TextView mExtraTextView; private TextView mExtraTextView;
private int mEditButtonState = EDIT_BUTTON_GONE;
public ExtraTextSection(Context context, String sectionName, SectionDelegate delegate) { public ExtraTextSection(Context context, String sectionName, SectionDelegate delegate) {
super(context, sectionName, delegate); super(context, sectionName, delegate);
...@@ -381,6 +495,17 @@ public abstract class PaymentRequestSection extends LinearLayout { ...@@ -381,6 +495,17 @@ public abstract class PaymentRequestSection extends LinearLayout {
mExtraTextView.setText(text); mExtraTextView.setText(text);
mExtraTextView.setVisibility(TextUtils.isEmpty(text) ? GONE : VISIBLE); mExtraTextView.setVisibility(TextUtils.isEmpty(text) ? GONE : VISIBLE);
} }
/** Sets the state of the edit button. */
public void setEditButtonState(int state) {
mEditButtonState = state;
updateControlLayout();
}
@Override
public int getEditButtonState() {
return mEditButtonState;
}
} }
/** /**
...@@ -393,11 +518,11 @@ public abstract class PaymentRequestSection extends LinearLayout { ...@@ -393,11 +518,11 @@ public abstract class PaymentRequestSection extends LinearLayout {
* *
* ............................................................................ * ............................................................................
* . TITLE | . * . TITLE | .
* .................................................................| . * .................................................................| CHERVON .
* . LEFT SUMMARY TEXT | RIGHT SUMMARY TEXT | . * . LEFT SUMMARY TEXT | RIGHT SUMMARY TEXT | or .
* .................................................................| CHEVRON . * .................................................................| ADD .
* . | Line item 1 | $13.99 | . * . | Line item 1 | $13.99 | or .
* . | Line item 2 | $.99 | . * . | Line item 2 | $.99 | SELECT .
* . | Line item 3 | $2.99 | . * . | Line item 3 | $2.99 | .
* ............................................................................ * ............................................................................
*/ */
...@@ -495,9 +620,11 @@ public abstract class PaymentRequestSection extends LinearLayout { ...@@ -495,9 +620,11 @@ public abstract class PaymentRequestSection extends LinearLayout {
} }
@Override @Override
public void setDisplayMode(int displayMode) { protected void updateControlLayout() {
super.setDisplayMode(displayMode); if (!mIsLayoutInitialized) return;
mBreakdownLayout.setVisibility(displayMode == DISPLAY_MODE_FOCUSED ? VISIBLE : GONE);
mBreakdownLayout.setVisibility(mDisplayMode == DISPLAY_MODE_FOCUSED ? VISIBLE : GONE);
super.updateControlLayout();
} }
} }
...@@ -516,16 +643,16 @@ public abstract class PaymentRequestSection extends LinearLayout { ...@@ -516,16 +643,16 @@ public abstract class PaymentRequestSection extends LinearLayout {
* . TITLE | | . * . TITLE | | .
* .................................................................| | . * .................................................................| | .
* . LEFT SUMMARY TEXT | RIGHT SUMMARY TEXT | | . * . LEFT SUMMARY TEXT | RIGHT SUMMARY TEXT | | .
* .................................................................| | . * .................................................................| | CHEVRON .
* . Descriptive text that spans all three columns because it can. | | . * . Descriptive text that spans all three columns because it can. | | or .
* . ! Warning text that displays a big scary warning and icon. | LOGO | CHEVRON . * . ! Warning text that displays a big scary warning and icon. | LOGO | ADD .
* . O Option 1 ICON 1 | | . * . O Option 1 ICON 1 | | or .
* . O Option 2 ICON 2 | | . * . O Option 2 ICON 2 | | SELECT .
* . O Option 3 ICON 3 | | . * . O Option 3 ICON 3 | | .
* . + ADD THING | | . * . + ADD THING | | .
* ............................................................................................. * .............................................................................................
*/ */
public static class OptionSection extends PaymentRequestSection implements OnClickListener { public static class OptionSection extends PaymentRequestSection {
private static final int INVALID_OPTION_INDEX = -1; private static final int INVALID_OPTION_INDEX = -1;
...@@ -722,9 +849,6 @@ public abstract class PaymentRequestSection extends LinearLayout { ...@@ -722,9 +849,6 @@ public abstract class PaymentRequestSection extends LinearLayout {
} }
} }
/** Text to display in the summary when there is no selected option. */
private final CharSequence mEmptyLabel;
/** Top and bottom margins for each item. */ /** Top and bottom margins for each item. */
private final int mVerticalMargin; private final int mVerticalMargin;
...@@ -740,29 +864,27 @@ public abstract class PaymentRequestSection extends LinearLayout { ...@@ -740,29 +864,27 @@ public abstract class PaymentRequestSection extends LinearLayout {
/** A spinner to show when the user selection is being checked. */ /** A spinner to show when the user selection is being checked. */
private View mCheckingProgress; private View mCheckingProgress;
/** SectionInformation that is used to populate the views in this section. */
private SectionInformation mSectionInformation;
/** /**
* Constructs an OptionSection. * Constructs an OptionSection.
* *
* @param context Context to pull resources from. * @param context Context to pull resources from.
* @param sectionName Title of the section to display. * @param sectionName Title of the section to display.
* @param emptyLabel An optional string to display when no item is selected.
* @param delegate Delegate to alert when something changes in the dialog. * @param delegate Delegate to alert when something changes in the dialog.
*/ */
public OptionSection(Context context, String sectionName, @Nullable CharSequence emptyLabel, public OptionSection(Context context, String sectionName, SectionDelegate delegate) {
SectionDelegate delegate) {
super(context, sectionName, delegate); super(context, sectionName, delegate);
mVerticalMargin = context.getResources().getDimensionPixelSize( mVerticalMargin = context.getResources().getDimensionPixelSize(
R.dimen.payments_section_small_spacing); R.dimen.payments_section_small_spacing);
mEmptyLabel = emptyLabel;
mIconMaxWidth = context.getResources().getDimensionPixelSize( mIconMaxWidth = context.getResources().getDimensionPixelSize(
R.dimen.payments_section_logo_width); R.dimen.payments_section_logo_width);
setSummaryText(emptyLabel, null); setSummaryText(null, null);
} }
@Override @Override
public void onClick(View v) { public void handleClick(View v) {
if (!mDelegate.isAcceptingUserInput()) return;
// Handle click on the "ADD THING" button. // Handle click on the "ADD THING" button.
for (int i = 0; i < mOptionRows.size(); i++) { for (int i = 0; i < mOptionRows.size(); i++) {
OptionRow row = mOptionRows.get(i); OptionRow row = mOptionRows.get(i);
...@@ -782,9 +904,15 @@ public abstract class PaymentRequestSection extends LinearLayout { ...@@ -782,9 +904,15 @@ public abstract class PaymentRequestSection extends LinearLayout {
} }
@Override @Override
public boolean onInterceptTouchEvent(MotionEvent event) { public void focusSection(boolean shouldFocus) {
// Allow touches to propagate to children only if the layout can be interacted with. // Override expansion of the section if there's no options to show.
return !mDelegate.isAcceptingUserInput(); boolean mayFocus = mSectionInformation != null && mSectionInformation.getSize() > 0;
if (!mayFocus && shouldFocus) {
setDisplayMode(PaymentRequestSection.DISPLAY_MODE_NORMAL);
return;
}
super.focusSection(shouldFocus);
} }
@Override @Override
...@@ -810,9 +938,11 @@ public abstract class PaymentRequestSection extends LinearLayout { ...@@ -810,9 +938,11 @@ public abstract class PaymentRequestSection extends LinearLayout {
/** Updates the View to account for the new {@link SectionInformation} being passed in. */ /** Updates the View to account for the new {@link SectionInformation} being passed in. */
public void update(SectionInformation information) { public void update(SectionInformation information) {
mSectionInformation = information;
PaymentOption selectedItem = information.getSelectedItem(); PaymentOption selectedItem = information.getSelectedItem();
updateSelectedItem(selectedItem); updateSelectedItem(selectedItem);
updateOptionList(information, selectedItem); updateOptionList(information, selectedItem);
updateControlLayout();
} }
private View createLoadingSpinner() { private View createLoadingSpinner() {
...@@ -849,14 +979,14 @@ public abstract class PaymentRequestSection extends LinearLayout { ...@@ -849,14 +979,14 @@ public abstract class PaymentRequestSection extends LinearLayout {
} }
@Override @Override
public void setDisplayMode(int displayMode) { protected void updateControlLayout() {
super.setDisplayMode(displayMode); if (!mIsLayoutInitialized) return;
if (displayMode == DISPLAY_MODE_FOCUSED) { if (mDisplayMode == DISPLAY_MODE_FOCUSED) {
setIsSummaryAllowed(false); setIsSummaryAllowed(false);
mOptionLayout.setVisibility(VISIBLE); mOptionLayout.setVisibility(VISIBLE);
setSpinnerVisibility(false); setSpinnerVisibility(false);
} else if (displayMode == DISPLAY_MODE_CHECKING) { } else if (mDisplayMode == DISPLAY_MODE_CHECKING) {
setIsSummaryAllowed(false); setIsSummaryAllowed(false);
mOptionLayout.setVisibility(GONE); mOptionLayout.setVisibility(GONE);
setSpinnerVisibility(true); setSpinnerVisibility(true);
...@@ -865,20 +995,36 @@ public abstract class PaymentRequestSection extends LinearLayout { ...@@ -865,20 +995,36 @@ public abstract class PaymentRequestSection extends LinearLayout {
mOptionLayout.setVisibility(GONE); mOptionLayout.setVisibility(GONE);
setSpinnerVisibility(false); setSpinnerVisibility(false);
} }
super.updateControlLayout();
}
@Override
public int getEditButtonState() {
if (mSectionInformation == null) return EDIT_BUTTON_GONE;
if (mSectionInformation.getSize() == 0 && mCanAddItems) {
// There aren't any PaymentOptions. Ask the user to add a new one.
return EDIT_BUTTON_ADD;
} else if (mSectionInformation.getSelectedItem() == null) {
// The user hasn't selected any available PaymentOptions. Ask the user to pick one.
return EDIT_BUTTON_SELECT;
} else {
return EDIT_BUTTON_GONE;
}
} }
private void updateSelectedItem(PaymentOption selectedItem) { private void updateSelectedItem(PaymentOption selectedItem) {
if (selectedItem == null) { if (selectedItem == null) {
setLogoResource(0); setLogoResource(0);
if (TextUtils.isEmpty(mEmptyLabel)) {
setIsSummaryAllowed(false); setIsSummaryAllowed(false);
} else { setSummaryText(null, null);
setSummaryText(mEmptyLabel, null);
}
} else { } else {
setLogoResource(selectedItem.getDrawableIconId()); setLogoResource(selectedItem.getDrawableIconId());
setSummaryText(convertOptionToString(selectedItem, false), null); setSummaryText(convertOptionToString(selectedItem, false), null);
} }
updateControlLayout();
} }
private void updateOptionList(SectionInformation information, PaymentOption selectedItem) { private void updateOptionList(SectionInformation information, PaymentOption selectedItem) {
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
package org.chromium.chrome.browser.payments.ui; package org.chromium.chrome.browser.payments.ui;
import static org.chromium.chrome.browser.payments.ui.PaymentRequestSection.EDIT_BUTTON_GONE;
import android.animation.Animator; import android.animation.Animator;
import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet; import android.animation.AnimatorSet;
...@@ -262,7 +264,7 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View ...@@ -262,7 +264,7 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View
private OptionSection mPaymentMethodSection; private OptionSection mPaymentMethodSection;
private List<SectionSeparator> mSectionSeparators; private List<SectionSeparator> mSectionSeparators;
private ViewGroup mSelectedSection; private PaymentRequestSection mSelectedSection;
private boolean mIsShowingEditDialog; private boolean mIsShowingEditDialog;
private boolean mIsProcessingPayClicked; private boolean mIsProcessingPayClicked;
private boolean mIsClientClosing; private boolean mIsClientClosing;
...@@ -328,8 +330,7 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View ...@@ -328,8 +330,7 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View
} }
updateSection(TYPE_PAYMENT_METHODS, result.getPaymentMethods()); updateSection(TYPE_PAYMENT_METHODS, result.getPaymentMethods());
if (mShippingAddressSectionInformation.getSelectedItem() == null) { if (mShippingAddressSectionInformation.getSelectedItem() == null) {
mShippingAddressSection.setDisplayMode( expand(mShippingAddressSection);
PaymentRequestSection.DISPLAY_MODE_FOCUSED);
} else { } else {
expand(null); expand(null);
} }
...@@ -381,24 +382,26 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View ...@@ -381,24 +382,26 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View
String selectedShippingAddress = result.getSelectedShippingAddressLabel(); String selectedShippingAddress = result.getSelectedShippingAddressLabel();
String selectedShippingName = result.getSelectedShippingAddressSublabel(); String selectedShippingName = result.getSelectedShippingAddressSublabel();
String selectedShippingOptionLabel = result.getSelectedShippingOptionLabel(); String selectedShippingOptionLabel = result.getSelectedShippingOptionLabel();
if (selectedShippingAddress == null && selectedShippingOptionLabel == null) {
mShippingSummarySection.setSummaryText(mContext.getString( if (selectedShippingAddress == null || selectedShippingOptionLabel == null) {
R.string.payments_select_shipping_prompt), null); // Let the summary display a SELECT/ADD button for the first subsection
// that needs it.
mShippingSummarySection.setSummaryText(null, null);
mShippingSummarySection.setSummaryProperties(null, false, null, false); mShippingSummarySection.setSummaryProperties(null, false, null, false);
PaymentRequestSection section =
mShippingAddressSection.getEditButtonState() == EDIT_BUTTON_GONE
? mShippingOptionSection : mShippingAddressSection;
mShippingSummarySection.setEditButtonState(section.getEditButtonState());
} else { } else {
// Show the shipping address and the name in the summary section. // Show the shipping address and the name in the summary section.
mShippingSummarySection.setSummaryText(selectedShippingAddress == null mShippingSummarySection.setSummaryText(
? mContext.getString( selectedShippingAddress, selectedShippingName);
R.string.payments_select_shipping_address_prompt)
: selectedShippingAddress, selectedShippingName);
mShippingSummarySection.setSummaryProperties( mShippingSummarySection.setSummaryProperties(
TruncateAt.MIDDLE, true, null, true); TruncateAt.MIDDLE, true, null, true);
// Indicate the shipping option below the address. // Indicate the shipping option below the address.
mShippingSummarySection.setExtraText(selectedShippingOptionLabel == null mShippingSummarySection.setExtraText(selectedShippingOptionLabel);
? mContext.getString(
R.string.payments_select_shipping_option_prompt)
: selectedShippingOptionLabel);
} }
} }
...@@ -459,22 +462,21 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View ...@@ -459,22 +462,21 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View
mPaymentContainer = (ScrollView) mRequestView.findViewById(R.id.option_container); mPaymentContainer = (ScrollView) mRequestView.findViewById(R.id.option_container);
mPaymentContainerLayout = mPaymentContainerLayout =
(LinearLayout) mRequestView.findViewById(R.id.payment_container_layout); (LinearLayout) mRequestView.findViewById(R.id.payment_container_layout);
mOrderSummarySection = new LineItemBreakdownSection(activity, mOrderSummarySection = new LineItemBreakdownSection(
activity.getString(R.string.payments_order_summary_label), this); activity, activity.getString(R.string.payments_order_summary_label), this);
mShippingSummarySection = new ExtraTextSection(activity, mShippingSummarySection = new ExtraTextSection(
activity.getString(R.string.payments_shipping_summary_label), this); activity, activity.getString(R.string.payments_shipping_summary_label), this);
mShippingAddressSection = new OptionSection(activity, mShippingAddressSection = new OptionSection(
activity.getString(R.string.payments_shipping_address_label), activity, activity.getString(R.string.payments_shipping_address_label), this);
activity.getString(R.string.payments_select_shipping_address_prompt), this); mShippingOptionSection = new OptionSection(
mShippingOptionSection = new OptionSection(activity, activity, activity.getString(R.string.payments_shipping_option_label), this);
activity.getString(R.string.payments_shipping_option_label), mContactDetailsSection = new OptionSection(
activity.getString(R.string.payments_select_shipping_option_prompt), this); activity, activity.getString(R.string.payments_contact_details_label), this);
mContactDetailsSection = new OptionSection(activity, mPaymentMethodSection = new OptionSection(
activity.getString(R.string.payments_contact_details_label), activity, activity.getString(R.string.payments_method_of_payment_label), this);
activity.getString(R.string.payments_select_contact_details_prompt), this);
mPaymentMethodSection = new OptionSection(activity, // Some sections conditionally allow adding new options.
activity.getString(R.string.payments_method_of_payment_label), mShippingOptionSection.setCanAddItems(false);
activity.getString(R.string.payments_select_method_of_payment_prompt), this);
mPaymentMethodSection.setCanAddItems(canAddCards); mPaymentMethodSection.setCanAddItems(canAddCards);
// Add the necessary sections to the layout. // Add the necessary sections to the layout.
...@@ -594,12 +596,13 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View ...@@ -594,12 +596,13 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View
mPaymentMethodSection.update(section); mPaymentMethodSection.update(section);
} }
mIsEditingPaymentItem = false; mIsEditingPaymentItem = false;
updateSectionButtons();
notifyReadyToClose(); notifyReadyToClose();
updatePayButtonEnabled(); updatePayButtonEnabled();
} }
@Override @Override
public void onPaymentOptionChanged(final OptionSection section, PaymentOption option) { public void onPaymentOptionChanged(final PaymentRequestSection section, PaymentOption option) {
@SelectionResult int result = SELECTION_RESULT_NONE; @SelectionResult int result = SELECTION_RESULT_NONE;
if (section == mShippingAddressSection if (section == mShippingAddressSection
&& mShippingAddressSectionInformation.getSelectedItem() != option) { && mShippingAddressSectionInformation.getSelectedItem() != option) {
...@@ -621,9 +624,17 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View ...@@ -621,9 +624,17 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View
} }
@Override @Override
public void onAddPaymentOption(OptionSection section) { public void onAddPaymentOption(PaymentRequestSection section) {
assert section != mShippingOptionSection; assert section != mShippingOptionSection;
// There's no way to add new shipping options, so users adding an option via the shipping
// summary's button have to be adding an address. Expand the sheet when this happens so
// that the shipping address section properly appears afterward.
if (section == mShippingSummarySection) {
expand(null);
section = mShippingAddressSection;
}
@SelectionResult int result = SELECTION_RESULT_NONE; @SelectionResult int result = SELECTION_RESULT_NONE;
if (section == mShippingAddressSection) { if (section == mShippingAddressSection) {
result = mClient.onSectionAddOption(TYPE_SHIPPING_ADDRESSES, mUpdateSectionsCallback); result = mClient.onSectionAddOption(TYPE_SHIPPING_ADDRESSES, mUpdateSectionsCallback);
...@@ -636,12 +647,13 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View ...@@ -636,12 +647,13 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View
updateStateFromResult(section, result); updateStateFromResult(section, result);
} }
void updateStateFromResult(OptionSection section, @SelectionResult int result) { void updateStateFromResult(PaymentRequestSection section, @SelectionResult int result) {
mIsClientCheckingSelection = result == SELECTION_RESULT_ASYNCHRONOUS_VALIDATION; mIsClientCheckingSelection = result == SELECTION_RESULT_ASYNCHRONOUS_VALIDATION;
mIsEditingPaymentItem = result == SELECTION_RESULT_EDITOR_LAUNCH; mIsEditingPaymentItem = result == SELECTION_RESULT_EDITOR_LAUNCH;
if (mIsClientCheckingSelection) { if (mIsClientCheckingSelection) {
startSectionResizeAnimation(); mSelectedSection = section;
updateSectionVisibility();
section.setDisplayMode(PaymentRequestSection.DISPLAY_MODE_CHECKING); section.setDisplayMode(PaymentRequestSection.DISPLAY_MODE_CHECKING);
} else { } else {
expand(null); expand(null);
...@@ -651,7 +663,7 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View ...@@ -651,7 +663,7 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View
} }
@Override @Override
public boolean isBoldLabelNeeded(OptionSection section) { public boolean isBoldLabelNeeded(PaymentRequestSection section) {
return section == mShippingAddressSection; return section == mShippingAddressSection;
} }
...@@ -680,6 +692,12 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View ...@@ -680,6 +692,12 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View
if (!isAcceptingUserInput()) return; if (!isAcceptingUserInput()) return;
// Users can only expand incomplete sections by clicking on their edit buttons.
if (v instanceof PaymentRequestSection) {
PaymentRequestSection section = (PaymentRequestSection) v;
if (section.getEditButtonState() != EDIT_BUTTON_GONE) return;
}
if (v == mOrderSummarySection) { if (v == mOrderSummarySection) {
expand(mOrderSummarySection); expand(mOrderSummarySection);
} else if (v == mShippingSummarySection || v == mShippingAddressSection) { } else if (v == mShippingSummarySection || v == mShippingAddressSection) {
...@@ -815,7 +833,7 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View ...@@ -815,7 +833,7 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View
&& !mIsClientCheckingSelection; && !mIsClientCheckingSelection;
} }
private void expand(ViewGroup section) { private void expand(PaymentRequestSection section) {
if (!mIsShowingEditDialog) { if (!mIsShowingEditDialog) {
// Container now takes the full height of the screen, animating towards it. // Container now takes the full height of the screen, animating towards it.
mRequestView.getLayoutParams().height = LayoutParams.MATCH_PARENT; mRequestView.getLayoutParams().height = LayoutParams.MATCH_PARENT;
...@@ -850,6 +868,10 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View ...@@ -850,6 +868,10 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View
// Make the dialog take the whole screen. // Make the dialog take the whole screen.
mDialog.getWindow().setLayout( mDialog.getWindow().setLayout(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
// Disable all but the first button.
updateSectionButtons();
mIsShowingEditDialog = true; mIsShowingEditDialog = true;
} }
...@@ -891,25 +913,33 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View ...@@ -891,25 +913,33 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View
}; };
} }
/** Update the display status of each expandable section. */ /** Update the display status of each expandable section in the full dialog. */
private void updateSectionVisibility() { private void updateSectionVisibility() {
startSectionResizeAnimation(); startSectionResizeAnimation();
mOrderSummarySection.focusSection(mSelectedSection == mOrderSummarySection);
mShippingAddressSection.focusSection(mSelectedSection == mShippingAddressSection);
mShippingOptionSection.focusSection(mSelectedSection == mShippingOptionSection);
mContactDetailsSection.focusSection(mSelectedSection == mContactDetailsSection);
mPaymentMethodSection.focusSection(mSelectedSection == mPaymentMethodSection);
updateSectionButtons();
}
/**
* Updates the enabled/disbled state of each section's edit button.
*
* Only the top-most button is enabled -- the others are disabled so the user is directed
* through the form from top to bottom.
*/
private void updateSectionButtons() {
boolean mayEnableButton = true;
for (int i = 0; i < mPaymentContainerLayout.getChildCount(); i++) {
View child = mPaymentContainerLayout.getChildAt(i);
if (!(child instanceof PaymentRequestSection)) continue;
mOrderSummarySection.setDisplayMode(mSelectedSection == mOrderSummarySection PaymentRequestSection section = (PaymentRequestSection) child;
? PaymentRequestSection.DISPLAY_MODE_FOCUSED section.setIsEditButtonEnabled(mayEnableButton);
: PaymentRequestSection.DISPLAY_MODE_EXPANDABLE); if (section.getEditButtonState() != EDIT_BUTTON_GONE) mayEnableButton = false;
mShippingAddressSection.setDisplayMode(mSelectedSection == mShippingAddressSection }
? PaymentRequestSection.DISPLAY_MODE_FOCUSED
: PaymentRequestSection.DISPLAY_MODE_EXPANDABLE);
mShippingOptionSection.setDisplayMode(mSelectedSection == mShippingOptionSection
? PaymentRequestSection.DISPLAY_MODE_FOCUSED
: PaymentRequestSection.DISPLAY_MODE_EXPANDABLE);
mContactDetailsSection.setDisplayMode(mSelectedSection == mContactDetailsSection
? PaymentRequestSection.DISPLAY_MODE_FOCUSED
: PaymentRequestSection.DISPLAY_MODE_EXPANDABLE);
mPaymentMethodSection.setDisplayMode(mSelectedSection == mPaymentMethodSection
? PaymentRequestSection.DISPLAY_MODE_FOCUSED
: PaymentRequestSection.DISPLAY_MODE_EXPANDABLE);
} }
/** /**
...@@ -932,7 +962,7 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View ...@@ -932,7 +962,7 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View
} }
@Override @Override
public String getAdditionalText(OptionSection section) { public String getAdditionalText(PaymentRequestSection section) {
if (section == mShippingAddressSection) { if (section == mShippingAddressSection) {
int selectedItemIndex = mShippingAddressSectionInformation.getSelectedItemIndex(); int selectedItemIndex = mShippingAddressSectionInformation.getSelectedItemIndex();
boolean isNecessary = mClient.merchantNeedsShippingAddress() boolean isNecessary = mClient.merchantNeedsShippingAddress()
...@@ -948,13 +978,23 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View ...@@ -948,13 +978,23 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View
} }
@Override @Override
public boolean isAdditionalTextDisplayingWarning(OptionSection section) { public boolean isAdditionalTextDisplayingWarning(PaymentRequestSection section) {
return section == mShippingAddressSection return section == mShippingAddressSection
&& mShippingAddressSectionInformation != null && mShippingAddressSectionInformation != null
&& mShippingAddressSectionInformation.getSelectedItemIndex() && mShippingAddressSectionInformation.getSelectedItemIndex()
== SectionInformation.INVALID_SELECTION; == SectionInformation.INVALID_SELECTION;
} }
@Override
public void onSectionClicked(PaymentRequestSection section) {
if (section == mShippingSummarySection) {
// Clicking the summary section focuses one of its subsections.
section = mShippingAddressSection.getEditButtonState() == EDIT_BUTTON_GONE
? mShippingOptionSection : mShippingAddressSection;
}
expand(section);
}
/** /**
* Animates the different sections of the dialog expanding and contracting into their final * Animates the different sections of the dialog expanding and contracting into their final
* positions. * positions.
...@@ -1138,7 +1178,7 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View ...@@ -1138,7 +1178,7 @@ public class PaymentRequestUI implements DialogInterface.OnDismissListener, View
} }
@VisibleForTesting @VisibleForTesting
public ViewGroup getShippingSummarySectionForTest() { public PaymentRequestSection getShippingSummarySectionForTest() {
return mShippingSummarySection; return mShippingSummarySection;
} }
......
...@@ -38,8 +38,7 @@ abstract class AutofillCreditCardEditor extends AutofillEditorBase { ...@@ -38,8 +38,7 @@ abstract class AutofillCreditCardEditor extends AutofillEditorBase {
profilesAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); profilesAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
AutofillProfile noSelection = new AutofillProfile(); AutofillProfile noSelection = new AutofillProfile();
noSelection.setLabel( noSelection.setLabel(getActivity().getString(R.string.select));
getActivity().getString(R.string.autofill_billing_address_select_prompt));
profilesAdapter.add(noSelection); profilesAdapter.add(noSelection);
List<AutofillProfile> profiles = PersonalDataManager.getInstance().getProfilesForSettings(); List<AutofillProfile> profiles = PersonalDataManager.getInstance().getProfilesForSettings();
......
...@@ -195,6 +195,12 @@ CHAR-LIMIT guidelines: ...@@ -195,6 +195,12 @@ CHAR-LIMIT guidelines:
<message name="IDS_YESTERDAY" desc="Generic Label saying the date is yesterday."> <message name="IDS_YESTERDAY" desc="Generic Label saying the date is yesterday.">
Yesterday Yesterday
</message> </message>
<message name="IDS_SELECT" desc="Prompt for user to select something. [CHAR-LIMIT=20]">
Select
</message>
<message name="IDS_ADD" desc="Prompt for the user to add something, like a new address. [CHAR-LIMIT=20]">
Add
</message>
<!-- Main Preferences --> <!-- Main Preferences -->
<message name="IDS_PREFERENCES" desc="Title for Chrome's Settings."> <message name="IDS_PREFERENCES" desc="Title for Chrome's Settings.">
...@@ -290,9 +296,6 @@ CHAR-LIMIT guidelines: ...@@ -290,9 +296,6 @@ CHAR-LIMIT guidelines:
<message name="IDS_AUTOFILL_CREDIT_CARD_EDITOR_BILLING_ADDRESS" desc="Label for a spinner input field containing a list of billing addresses for a credit card. [CHAR-LIMIT=32]"> <message name="IDS_AUTOFILL_CREDIT_CARD_EDITOR_BILLING_ADDRESS" desc="Label for a spinner input field containing a list of billing addresses for a credit card. [CHAR-LIMIT=32]">
Billing address Billing address
</message> </message>
<message name="IDS_AUTOFILL_BILLING_ADDRESS_SELECT_PROMPT" desc="Prompt for user to select a billing address in autofill settings for a credit card. [CHAR-LIMIT=24]">
Select
</message>
<message name="IDS_AUTOFILL_DESCRIBE_LOCAL_COPY" desc="Text label that describes a Wallet credit card which has been copied to the local Chrome instance."> <message name="IDS_AUTOFILL_DESCRIBE_LOCAL_COPY" desc="Text label that describes a Wallet credit card which has been copied to the local Chrome instance.">
Copied to Chrome Copied to Chrome
</message> </message>
...@@ -1583,9 +1586,6 @@ You are signing in with a managed account and giving its administrator control o ...@@ -1583,9 +1586,6 @@ You are signing in with a managed account and giving its administrator control o
</message> </message>
<!-- Add to Home screen strings --> <!-- Add to Home screen strings -->
<message name="IDS_ADD" desc="Title for Add button [CHAR-LIMIT=20]">
Add
</message>
<message name="IDS_ADD_TO_HOMESCREEN_TITLE" desc="Edit text title for Add to Home screen dialog [CHAR-LIMIT=30]"> <message name="IDS_ADD_TO_HOMESCREEN_TITLE" desc="Edit text title for Add to Home screen dialog [CHAR-LIMIT=30]">
Title Title
</message> </message>
...@@ -2634,15 +2634,9 @@ You can control the Physical Web in Chrome Settings. ...@@ -2634,15 +2634,9 @@ You can control the Physical Web in Chrome Settings.
<message name="IDS_PAYMENTS_METHOD_OF_PAYMENT_LABEL" desc="The title for the section that lets the user select the method of payment."> <message name="IDS_PAYMENTS_METHOD_OF_PAYMENT_LABEL" desc="The title for the section that lets the user select the method of payment.">
Payment Payment
</message> </message>
<message name="IDS_PAYMENTS_SELECT_METHOD_OF_PAYMENT_PROMPT" desc="The label for the button that presents the user with the list of possible methods of payments, for example a list of their credit cards..">
Select payment method
</message>
<message name="IDS_PAYMENTS_CONTACT_DETAILS_LABEL" desc="The title for the section that lets the user select how they can be contacted."> <message name="IDS_PAYMENTS_CONTACT_DETAILS_LABEL" desc="The title for the section that lets the user select how they can be contacted.">
Contact info Contact info
</message> </message>
<message name="IDS_PAYMENTS_SELECT_CONTACT_DETAILS_PROMPT" desc="The label for the button that presents the user with the list of possible phone numbers and email addresses where the user can be reached.">
Select contact details
</message>
<message name="IDS_PAYMENTS_ADD_CONTACT_DETAILS_LABEL" desc="The title of the dialog for user to add new contact information, such as email address or phone number."> <message name="IDS_PAYMENTS_ADD_CONTACT_DETAILS_LABEL" desc="The title of the dialog for user to add new contact information, such as email address or phone number.">
Add contact info Add contact info
</message> </message>
...@@ -2658,15 +2652,6 @@ You can control the Physical Web in Chrome Settings. ...@@ -2658,15 +2652,6 @@ You can control the Physical Web in Chrome Settings.
<message name="IDS_PAYMENTS_SHIPPING_OPTION_LABEL" desc="The title for the section that lets the user select how the product should be shipped."> <message name="IDS_PAYMENTS_SHIPPING_OPTION_LABEL" desc="The title for the section that lets the user select how the product should be shipped.">
Shipping option Shipping option
</message> </message>
<message name="IDS_PAYMENTS_SELECT_SHIPPING_PROMPT" desc="The label for the button that presents the user with the list of possible shipping addresses and options.">
Select shipping
</message>
<message name="IDS_PAYMENTS_SELECT_SHIPPING_OPTION_PROMPT" desc="The label for the button that presents the user with the list of possible shipping options.">
Select shipping option
</message>
<message name="IDS_PAYMENTS_SELECT_SHIPPING_ADDRESS_PROMPT" desc="The label for the button that presents the user with the list of possible shipping addresses.">
Select shipping address
</message>
<message name="IDS_PAYMENTS_ORDER_SUMMARY_LABEL" desc="The title of the section that shows the summary of the order, including names and prices of individual line items, i.e. the bill."> <message name="IDS_PAYMENTS_ORDER_SUMMARY_LABEL" desc="The title of the section that shows the summary of the order, including names and prices of individual line items, i.e. the bill.">
Order summary Order summary
</message> </message>
...@@ -2707,7 +2692,7 @@ You can control the Physical Web in Chrome Settings. ...@@ -2707,7 +2692,7 @@ You can control the Physical Web in Chrome Settings.
Add contact info Add contact info
</message> </message>
<message name="IDS_PAYMENTS_SELECT_SHIPPING_ADDRESS_FOR_SHIPPING_METHODS" desc="Text implying that a user needs to pick a shipping address to see the shipping methods."> <message name="IDS_PAYMENTS_SELECT_SHIPPING_ADDRESS_FOR_SHIPPING_METHODS" desc="Text implying that a user needs to pick a shipping address to see the shipping methods.">
Select a shipping address to check shipping methods. Select a shipping address to check shipping methods and requirements.
</message> </message>
<message name="IDS_PAYMENTS_CHECKING_OPTION" desc="Text explaining that the option the user selected is being checked and verified."> <message name="IDS_PAYMENTS_CHECKING_OPTION" desc="Text explaining that the option the user selected is being checked and verified.">
Checking Checking
......
...@@ -15,6 +15,7 @@ import org.chromium.chrome.R; ...@@ -15,6 +15,7 @@ import org.chromium.chrome.R;
import org.chromium.chrome.browser.autofill.AutofillTestHelper; import org.chromium.chrome.browser.autofill.AutofillTestHelper;
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.CreditCard;
import org.chromium.chrome.browser.payments.ui.PaymentRequestSection;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
...@@ -47,7 +48,7 @@ public class PaymentRequestDynamicShippingSingleAddressTest extends PaymentReque ...@@ -47,7 +48,7 @@ public class PaymentRequestDynamicShippingSingleAddressTest extends PaymentReque
public void testAddressNotSelected() public void testAddressNotSelected()
throws InterruptedException, ExecutionException, TimeoutException { throws InterruptedException, ExecutionException, TimeoutException {
triggerUIAndWait(mReadyForInput); triggerUIAndWait(mReadyForInput);
assertEquals("Select shipping", getAddressSectionLabel()); assertEquals(PaymentRequestSection.EDIT_BUTTON_SELECT, getSummarySectionButtonState());
} }
/** Expand the shipping address section, select an address, and click "Pay." */ /** Expand the shipping address section, select an address, and click "Pay." */
......
...@@ -10,7 +10,6 @@ import android.view.ViewGroup; ...@@ -10,7 +10,6 @@ import android.view.ViewGroup;
import android.widget.CheckBox; import android.widget.CheckBox;
import android.widget.EditText; import android.widget.EditText;
import android.widget.Spinner; import android.widget.Spinner;
import android.widget.TextView;
import org.chromium.base.ThreadUtils; import org.chromium.base.ThreadUtils;
import org.chromium.base.test.util.UrlUtils; import org.chromium.base.test.util.UrlUtils;
...@@ -251,13 +250,12 @@ abstract class PaymentRequestTestBase extends ChromeActivityTestCaseBase<ChromeA ...@@ -251,13 +250,12 @@ abstract class PaymentRequestTestBase extends ChromeActivityTestCaseBase<ChromeA
helper.waitForCallback(callCount); helper.waitForCallback(callCount);
} }
/** Returns the left summary label of the "Shipping summary" section. */ /** Gets the button state for the shipping summary section. */
protected String getAddressSectionLabel() throws ExecutionException { protected int getSummarySectionButtonState() throws ExecutionException {
return ThreadUtils.runOnUiThreadBlocking(new Callable<String>() { return ThreadUtils.runOnUiThreadBlocking(new Callable<Integer>() {
@Override @Override
public String call() { public Integer call() {
return ((TextView) mUI.getShippingSummarySectionForTest().findViewById( return mUI.getShippingSummarySectionForTest().getEditButtonState();
R.id.payments_left_summary_label)).getText().toString();
} }
}); });
} }
......
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