Commit c401ae3b authored by Clemens Arbesser's avatar Clemens Arbesser Committed by Commit Bot

[Autofill Assistant] Add short-term support for right-aligned checkboxes to FormAction.

This CL adds support for right-aligned checkboxes to the ShowFormAction. Prior to this CL, checkboxes would be left-aligned rather than right-aligned.

This CL also adds support for an additional description line for counters and two additional description lines for checkboxes and radiobuttons.

This change is intended to be short-term for an upcoming experiment, and will be removed or refactored in the near future.

Bug: b/144402029
Change-Id: I679bf1273f13bd836b9cce69662fa60bd724a3d0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1917176
Commit-Queue: Clemens Arbesser <arbesser@google.com>
Reviewed-by: default avatarMathias Carlen <mcarlen@chromium.org>
Cr-Commit-Position: refs/heads/master@{#718219}
parent 27278f09
...@@ -210,6 +210,7 @@ android_library("test_java") { ...@@ -210,6 +210,7 @@ android_library("test_java") {
"javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantBottomsheetTest.java", "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantBottomsheetTest.java",
"javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDetailsUiTest.java", "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDetailsUiTest.java",
"javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandlerTest.java", "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantDirectActionHandlerTest.java",
"javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantFormActionTest.java",
"javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantHeaderUiTest.java", "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantHeaderUiTest.java",
"javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantInfoBoxUiTest.java", "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantInfoBoxUiTest.java",
"javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayUiTest.java", "javatests/src/org/chromium/chrome/browser/autofill_assistant/AutofillAssistantOverlayUiTest.java",
......
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2019 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. -->
<LinearLayout android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Identifiers in this file match those in autofill_assistant_form_checkbox.xml -->
<LinearLayout
android:id="@+id/descriptions"
android:layout_width="0dp"
android:layout_weight="1.0"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="fill_horizontal">
<TextView
android:id="@+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.BlackTitle2"/>
<TextView
android:id="@+id/description_line_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.BlackCaption"/>
<TextView
android:id="@+id/description_line_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.BlackCaption"/>
</LinearLayout>
<!-- TODO(806868) Remove the hard-coded padding and align properly. -->
<CheckBox
android:id="@+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingEnd="26.5dp"
android:layout_gravity="center_vertical"/>
</LinearLayout>
\ No newline at end of file
...@@ -22,13 +22,17 @@ ...@@ -22,13 +22,17 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.BlackTitle2"/> android:textAppearance="@style/TextAppearance.BlackTitle2"/>
<TextView <TextView
android:id="@+id/subtext" android:id="@+id/description_line_1"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.BlackCaption" android:textAppearance="@style/TextAppearance.BlackCaption"/>
android:visibility="gone"/> <TextView
android:id="@+id/description_line_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.BlackCaption"/>
</LinearLayout> </LinearLayout>
<ImageView <org.chromium.ui.widget.ChromeImageView
android:id="@+id/decrease_button" android:id="@+id/decrease_button"
android:layout_width="32dp" android:layout_width="32dp"
android:layout_height="32dp" android:layout_height="32dp"
...@@ -43,7 +47,7 @@ ...@@ -43,7 +47,7 @@
android:minWidth="20dp" android:minWidth="20dp"
android:gravity="center" android:gravity="center"
android:textAppearance="@style/TextAppearance.BlackTitle2"/> android:textAppearance="@style/TextAppearance.BlackTitle2"/>
<ImageView <org.chromium.ui.widget.ChromeImageView
android:id="@+id/increase_button" android:id="@+id/increase_button"
android:layout_width="32dp" android:layout_width="32dp"
android:layout_height="32dp" android:layout_height="32dp"
......
...@@ -36,11 +36,11 @@ ...@@ -36,11 +36,11 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.BlackCaption"/> android:textAppearance="@style/TextAppearance.BlackCaption"/>
<ImageView <org.chromium.ui.widget.ChromeImageView
android:id="@+id/chevron" android:id="@+id/chevron"
android:layout_width="16dp" android:layout_width="16dp"
android:layout_height="16dp" android:layout_height="16dp"
android:tint="@color/default_text_color_secondary_list" android:tint="@color/control_normal_color"
app:srcCompat="@drawable/ic_expand_more_black_24dp" app:srcCompat="@drawable/ic_expand_more_black_24dp"
tools:ignore="ContentDescription"/> tools:ignore="ContentDescription"/>
</LinearLayout> </LinearLayout>
......
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2019 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. -->
<!-- Identifiers in this file match those in autofill_assistant_form_radiobutton.xml -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/descriptions"
android:layout_width="0dp"
android:layout_weight="1.0"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="fill_horizontal">
<TextView
android:id="@+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.BlackTitle2"/>
<TextView
android:id="@+id/description_line_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.BlackCaption"/>
<TextView
android:id="@+id/description_line_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.BlackCaption"/>
</LinearLayout>
\ No newline at end of file
...@@ -3,11 +3,10 @@ ...@@ -3,11 +3,10 @@
Use of this source code is governed by a BSD-style license that can be Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. --> found in the LICENSE file. -->
<LinearLayout <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"> android:orientation="vertical">
<TextView <TextView
android:id="@+id/label" android:id="@+id/label"
...@@ -16,13 +15,23 @@ ...@@ -16,13 +15,23 @@
android:layout_marginBottom="4dp" android:layout_marginBottom="4dp"
android:textAppearance="@style/TextAppearance.BlackButtonText"/> android:textAppearance="@style/TextAppearance.BlackButtonText"/>
<LinearLayout
android:id="@+id/checkbox_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone">
<!-- Choices are created in code. -->
</LinearLayout>
<org.chromium.chrome.browser.autofill_assistant.user_data.AssistantChoiceList <org.chromium.chrome.browser.autofill_assistant.user_data.AssistantChoiceList
android:id="@+id/choice_list" android:id="@+id/radiobutton_list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:can_add_items="false" app:can_add_items="false"
app:row_spacing="0dp" app:row_spacing="0dp"
app:column_spacing="8dp"> app:column_spacing="8dp"
android:visibility="gone">
<!-- Choices are created in code. --> <!-- Choices are created in code. -->
</org.chromium.chrome.browser.autofill_assistant.user_data.AssistantChoiceList> </org.chromium.chrome.browser.autofill_assistant.user_data.AssistantChoiceList>
</LinearLayout> </LinearLayout>
...@@ -36,6 +36,7 @@ public class AssistantFormCoordinator { ...@@ -36,6 +36,7 @@ public class AssistantFormCoordinator {
mModel.getInputsModel().addObserver(new AbstractListObserver<Void>() { mModel.getInputsModel().addObserver(new AbstractListObserver<Void>() {
@Override @Override
public void onDataSetChanged() { public void onDataSetChanged() {
// TODO(b/144690738) This creates a new instance of the UI on every notification...
for (int i = 0; i < mView.getChildCount(); i++) { for (int i = 0; i < mView.getChildCount(); i++) {
mView.getChildAt(i).setVisibility(View.GONE); mView.getChildAt(i).setVisibility(View.GONE);
} }
......
...@@ -6,19 +6,25 @@ package org.chromium.chrome.browser.autofill_assistant.form; ...@@ -6,19 +6,25 @@ package org.chromium.chrome.browser.autofill_assistant.form;
abstract class AssistantFormCounter { abstract class AssistantFormCounter {
private final String mLabel; private final String mLabel;
private final String mSubtext; private final String mDescriptionLine1;
private final String mDescriptionLine2;
private AssistantFormCounter(String label, String subtext) { private AssistantFormCounter(String label, String descriptionLine1, String descriptionLine2) {
mLabel = label; mLabel = label;
mSubtext = subtext; mDescriptionLine1 = descriptionLine1;
mDescriptionLine2 = descriptionLine2;
} }
String getLabel() { String getLabel() {
return mLabel; return mLabel;
} }
String getSubtext() { String getDescriptionLine1() {
return mSubtext; return mDescriptionLine1;
}
String getDescriptionLine2() {
return mDescriptionLine2;
} }
abstract int getValue(); abstract int getValue();
...@@ -31,13 +37,16 @@ abstract class AssistantFormCounter { ...@@ -31,13 +37,16 @@ abstract class AssistantFormCounter {
abstract void increaseValue(); abstract void increaseValue();
static AssistantFormCounter create(String label, String subtext, int initialValue, int minValue, static AssistantFormCounter create(String label, String descriptionLine1,
int maxValue, int[] allowedValues) { String descriptionLine2, int initialValue, int minValue, int maxValue,
int[] allowedValues) {
if (allowedValues.length > 0) { if (allowedValues.length > 0) {
return new FiniteCounter(label, subtext, initialValue, allowedValues); return new FiniteCounter(
label, descriptionLine1, descriptionLine2, initialValue, allowedValues);
} }
return new BoundedCounter(label, subtext, initialValue, minValue, maxValue); return new BoundedCounter(
label, descriptionLine1, descriptionLine2, initialValue, minValue, maxValue);
} }
/** A counter whose value is limited by a min and max value. */ /** A counter whose value is limited by a min and max value. */
...@@ -46,9 +55,9 @@ abstract class AssistantFormCounter { ...@@ -46,9 +55,9 @@ abstract class AssistantFormCounter {
private final int mMaxValue; private final int mMaxValue;
private int mValue; private int mValue;
private BoundedCounter( private BoundedCounter(String label, String descriptionLine1, String descriptionLine2,
String label, String subtext, int initialValue, int minValue, int maxValue) { int initialValue, int minValue, int maxValue) {
super(label, subtext); super(label, descriptionLine1, descriptionLine2);
mMinValue = minValue; mMinValue = minValue;
mMaxValue = maxValue; mMaxValue = maxValue;
mValue = initialValue; mValue = initialValue;
...@@ -85,8 +94,9 @@ abstract class AssistantFormCounter { ...@@ -85,8 +94,9 @@ abstract class AssistantFormCounter {
private final int[] mAllowedValues; private final int[] mAllowedValues;
private int mValueIndex; private int mValueIndex;
private FiniteCounter(String label, String subtext, int initialValue, int[] allowedValues) { private FiniteCounter(String label, String descriptionLine1, String descriptionLine2,
super(label, subtext); int initialValue, int[] allowedValues) {
super(label, descriptionLine1, descriptionLine2);
mAllowedValues = allowedValues; mAllowedValues = allowedValues;
for (int i = 0; i < mAllowedValues.length; i++) { for (int i = 0; i < mAllowedValues.length; i++) {
......
...@@ -16,6 +16,7 @@ import android.view.ViewGroup; ...@@ -16,6 +16,7 @@ import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import org.chromium.chrome.autofill_assistant.R; import org.chromium.chrome.autofill_assistant.R;
import org.chromium.chrome.browser.autofill_assistant.AssistantTextUtils;
import org.chromium.chrome.browser.util.AccessibilityUtil; import org.chromium.chrome.browser.util.AccessibilityUtil;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -39,7 +40,8 @@ class AssistantFormCounterInput extends AssistantFormInput { ...@@ -39,7 +40,8 @@ class AssistantFormCounterInput extends AssistantFormInput {
private static class CounterViewHolder { private static class CounterViewHolder {
private final View mView; private final View mView;
private final TextView mLabelView; private final TextView mLabelView;
private final TextView mSubtextView; private final TextView mDescriptionLine1View;
private final TextView mDescriptionLine2View;
private final TextView mValueView; private final TextView mValueView;
private final View mDecreaseButtonView; private final View mDecreaseButtonView;
private final View mIncreaseButtonView; private final View mIncreaseButtonView;
...@@ -48,7 +50,8 @@ class AssistantFormCounterInput extends AssistantFormInput { ...@@ -48,7 +50,8 @@ class AssistantFormCounterInput extends AssistantFormInput {
mView = LayoutInflater.from(context).inflate( mView = LayoutInflater.from(context).inflate(
R.layout.autofill_assistant_form_counter, /*root= */ null); R.layout.autofill_assistant_form_counter, /*root= */ null);
mLabelView = mView.findViewById(R.id.label); mLabelView = mView.findViewById(R.id.label);
mSubtextView = mView.findViewById(R.id.subtext); mDescriptionLine1View = mView.findViewById(R.id.description_line_1);
mDescriptionLine2View = mView.findViewById(R.id.description_line_2);
mValueView = mView.findViewById(R.id.value); mValueView = mView.findViewById(R.id.value);
mDecreaseButtonView = mView.findViewById(R.id.decrease_button); mDecreaseButtonView = mView.findViewById(R.id.decrease_button);
mIncreaseButtonView = mView.findViewById(R.id.increase_button); mIncreaseButtonView = mView.findViewById(R.id.increase_button);
...@@ -191,10 +194,13 @@ class AssistantFormCounterInput extends AssistantFormInput { ...@@ -191,10 +194,13 @@ class AssistantFormCounterInput extends AssistantFormInput {
AssistantFormCounter counter = counters.get(i); AssistantFormCounter counter = counters.get(i);
CounterViewHolder view = views.get(i); CounterViewHolder view = views.get(i);
if (!counter.getSubtext().isEmpty()) { // TODO(b/144402029) Add support for text links.
view.mSubtextView.setVisibility(View.VISIBLE); AssistantTextUtils.applyVisualAppearanceTags(
view.mSubtextView.setText(counter.getSubtext()); view.mDescriptionLine1View, counter.getDescriptionLine1(), null);
} AssistantTextUtils.applyVisualAppearanceTags(
view.mDescriptionLine2View, counter.getDescriptionLine2(), null);
hideIfEmpty(view.mDescriptionLine1View);
hideIfEmpty(view.mDescriptionLine2View);
updateLabelAndValue(counter, view); updateLabelAndValue(counter, view);
...@@ -254,4 +260,8 @@ class AssistantFormCounterInput extends AssistantFormInput { ...@@ -254,4 +260,8 @@ class AssistantFormCounterInput extends AssistantFormInput {
mDelegate.onCounterChanged(counterIndex, counter.getValue()); mDelegate.onCounterChanged(counterIndex, counter.getValue());
} }
private void hideIfEmpty(TextView view) {
view.setVisibility(view.length() == 0 ? View.GONE : View.VISIBLE);
}
} }
...@@ -45,16 +45,18 @@ public abstract class AssistantFormInput { ...@@ -45,16 +45,18 @@ public abstract class AssistantFormInput {
} }
@CalledByNative @CalledByNative
private static AssistantFormCounter createCounter(String label, String subtext, private static AssistantFormCounter createCounter(String label, String descriptionLine1,
int initialValue, int minValue, int maxValue, int[] allowedValues) { String descriptionLine2, int initialValue, int minValue, int maxValue,
return AssistantFormCounter.create( int[] allowedValues) {
label, subtext, initialValue, minValue, maxValue, allowedValues); return AssistantFormCounter.create(label, descriptionLine1, descriptionLine2, initialValue,
minValue, maxValue, allowedValues);
} }
@CalledByNative @CalledByNative
private static AssistantFormSelectionChoice createChoice( private static AssistantFormSelectionChoice createChoice(String label, String descriptionLine1,
String label, boolean initiallySelected) { String descriptionLine2, boolean initiallySelected) {
return new AssistantFormSelectionChoice(label, initiallySelected); return new AssistantFormSelectionChoice(
label, descriptionLine1, descriptionLine2, initiallySelected);
} }
@CalledByNative @CalledByNative
......
...@@ -6,10 +6,15 @@ package org.chromium.chrome.browser.autofill_assistant.form; ...@@ -6,10 +6,15 @@ package org.chromium.chrome.browser.autofill_assistant.form;
class AssistantFormSelectionChoice { class AssistantFormSelectionChoice {
private final String mLabel; private final String mLabel;
private final String mDescriptionLine1;
private final String mDescriptionLine2;
private final boolean mIsInitiallySelected; private final boolean mIsInitiallySelected;
public AssistantFormSelectionChoice(String label, boolean isInitiallySelected) { public AssistantFormSelectionChoice(String label, String descriptionLine1,
String descriptionLine2, boolean isInitiallySelected) {
mLabel = label; mLabel = label;
mDescriptionLine1 = descriptionLine1;
mDescriptionLine2 = descriptionLine2;
mIsInitiallySelected = isInitiallySelected; mIsInitiallySelected = isInitiallySelected;
} }
...@@ -17,6 +22,14 @@ class AssistantFormSelectionChoice { ...@@ -17,6 +22,14 @@ class AssistantFormSelectionChoice {
return mLabel; return mLabel;
} }
public String getDescriptionLine1() {
return mDescriptionLine1;
}
public String getDescriptionLine2() {
return mDescriptionLine2;
}
public boolean isInitiallySelected() { public boolean isInitiallySelected() {
return mIsInitiallySelected; return mIsInitiallySelected;
} }
......
...@@ -5,14 +5,14 @@ ...@@ -5,14 +5,14 @@
package org.chromium.chrome.browser.autofill_assistant.form; package org.chromium.chrome.browser.autofill_assistant.form;
import android.content.Context; import android.content.Context;
import android.view.Gravity;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.TextView; import android.widget.TextView;
import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.chrome.autofill_assistant.R; import org.chromium.chrome.autofill_assistant.R;
import org.chromium.chrome.browser.autofill_assistant.AssistantTextUtils;
import org.chromium.chrome.browser.autofill_assistant.user_data.AssistantChoiceList; import org.chromium.chrome.browser.autofill_assistant.user_data.AssistantChoiceList;
import java.util.List; import java.util.List;
...@@ -38,7 +38,8 @@ class AssistantFormSelectionInput extends AssistantFormInput { ...@@ -38,7 +38,8 @@ class AssistantFormSelectionInput extends AssistantFormInput {
@Override @Override
public View createView(Context context, ViewGroup parent) { public View createView(Context context, ViewGroup parent) {
ViewGroup root = (ViewGroup) LayoutInflater.from(context).inflate( LayoutInflater inflater = LayoutInflater.from(context);
ViewGroup root = (ViewGroup) inflater.inflate(
R.layout.autofill_assistant_form_selection_input, parent, R.layout.autofill_assistant_form_selection_input, parent,
/* attachToRoot= */ false); /* attachToRoot= */ false);
TextView label = root.findViewById(org.chromium.chrome.autofill_assistant.R.id.label); TextView label = root.findViewById(org.chromium.chrome.autofill_assistant.R.id.label);
...@@ -48,25 +49,61 @@ class AssistantFormSelectionInput extends AssistantFormInput { ...@@ -48,25 +49,61 @@ class AssistantFormSelectionInput extends AssistantFormInput {
label.setText(mLabel); label.setText(mLabel);
} }
AssistantChoiceList choiceList = root.findViewById(R.id.choice_list); if (mChoices.isEmpty()) {
choiceList.setAllowMultipleChoices(mAllowMultipleChoices); return root;
}
ViewGroup checkboxList = root.findViewById(R.id.checkbox_list);
AssistantChoiceList radiobuttonList = root.findViewById(R.id.radiobutton_list);
for (int i = 0; i < mChoices.size(); i++) { for (int i = 0; i < mChoices.size(); i++) {
AssistantFormSelectionChoice choice = mChoices.get(i); AssistantFormSelectionChoice choice = mChoices.get(i);
TextView choiceView = new TextView(context);
ApiCompatibilityUtils.setTextAppearance(
choiceView, R.style.TextAppearance_BlackCaptionDefault);
choiceView.setGravity(Gravity.CENTER_VERTICAL);
choiceView.setText(choice.getLabel());
int index = i; // needed for the lambda. int index = i; // needed for the lambda.
choiceList.addItem(choiceView, /* hasEditButton= */ false, View choiceView;
(isChecked) if (mAllowMultipleChoices) {
-> mDelegate.onChoiceSelectionChanged(index, isChecked), choiceView =
/* itemEditedListener= */ null); inflater.inflate(R.layout.autofill_assistant_form_checkbox, checkboxList);
CheckBox checkBox = choiceView.findViewById(R.id.checkbox);
checkBox.setOnCheckedChangeListener(
(compoundButton,
isChecked) -> mDelegate.onChoiceSelectionChanged(index, isChecked));
choiceView.findViewById(R.id.descriptions)
.setOnClickListener(
unusedView -> checkBox.setChecked(!checkBox.isChecked()));
checkBox.setChecked(choice.isInitiallySelected());
} else {
choiceView = inflater.inflate(R.layout.autofill_assistant_form_radiobutton, null);
radiobuttonList.addItem(choiceView, /* hasEditButton= */ false,
(isChecked)
-> mDelegate.onChoiceSelectionChanged(index, isChecked),
/* itemEditedListener= */ null);
radiobuttonList.setChecked(choiceView, choice.isInitiallySelected());
}
choiceList.setChecked(choiceView, choice.isInitiallySelected()); TextView choiceLabel = choiceView.findViewById(R.id.label);
TextView descriptionLine1 = choiceView.findViewById(R.id.description_line_1);
TextView descriptionLine2 = choiceView.findViewById(R.id.description_line_2);
AssistantTextUtils.applyVisualAppearanceTags(choiceLabel, choice.getLabel(), null);
AssistantTextUtils.applyVisualAppearanceTags(
descriptionLine1, choice.getDescriptionLine1(), null);
AssistantTextUtils.applyVisualAppearanceTags(
descriptionLine2, choice.getDescriptionLine2(), null);
hideIfEmpty(choiceLabel);
hideIfEmpty(descriptionLine1);
hideIfEmpty(descriptionLine2);
}
if (mAllowMultipleChoices) {
checkboxList.setVisibility(View.VISIBLE);
} else {
radiobuttonList.setVisibility(View.VISIBLE);
} }
return root; return root;
} }
private void hideIfEmpty(TextView view) {
view.setVisibility(view.length() == 0 ? View.GONE : View.VISIBLE);
}
} }
// Copyright 2019 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;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant;
import static android.support.test.espresso.matcher.ViewMatchers.hasSibling;
import static android.support.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.isEnabled;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.startAutofillAssistant;
import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.waitUntilViewMatchesCondition;
import android.support.test.InstrumentationRegistry;
import android.support.test.filters.MediumTest;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.DisableIf;
import org.chromium.chrome.autofill_assistant.R;
import org.chromium.chrome.browser.ChromeSwitches;
import org.chromium.chrome.browser.autofill_assistant.proto.ActionProto;
import org.chromium.chrome.browser.autofill_assistant.proto.ChipProto;
import org.chromium.chrome.browser.autofill_assistant.proto.ChipType;
import org.chromium.chrome.browser.autofill_assistant.proto.CounterInputProto;
import org.chromium.chrome.browser.autofill_assistant.proto.FormInputProto;
import org.chromium.chrome.browser.autofill_assistant.proto.FormProto;
import org.chromium.chrome.browser.autofill_assistant.proto.PromptProto;
import org.chromium.chrome.browser.autofill_assistant.proto.PromptProto.Choice;
import org.chromium.chrome.browser.autofill_assistant.proto.SelectionInputProto;
import org.chromium.chrome.browser.autofill_assistant.proto.ShowFormProto;
import org.chromium.chrome.browser.autofill_assistant.proto.SupportedScriptProto;
import org.chromium.chrome.browser.autofill_assistant.proto.SupportedScriptProto.PresentationProto;
import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
import org.chromium.chrome.browser.customtabs.CustomTabsTestUtils;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import java.util.ArrayList;
import java.util.Collections;
/**
* Tests autofill assistant bottomsheet.
*/
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
@RunWith(ChromeJUnit4ClassRunner.class)
public class AutofillAssistantFormActionTest {
@Rule
public CustomTabActivityTestRule mTestRule = new CustomTabActivityTestRule();
private static final String TEST_PAGE = "/components/test/data/autofill_assistant/html/"
+ "autofill_assistant_target_website.html";
@Before
public void setUp() {
AutofillAssistantPreferencesUtil.setInitialPreferences(true);
mTestRule.startCustomTabActivityWithIntent(CustomTabsTestUtils.createMinimalCustomTabIntent(
InstrumentationRegistry.getTargetContext(),
mTestRule.getTestServer().getURL(TEST_PAGE)));
mTestRule.getActivity().getScrim().disableAnimationForTesting(true);
}
@Test
@MediumTest
@DisableIf.Build(sdk_is_less_than = 21)
public void testFormAction() {
ArrayList<ActionProto> list = new ArrayList<>();
// FromProto.Builder, extracted to avoid excessive line widths.
FormProto.Builder formProto =
FormProto.newBuilder()
.addInputs(FormInputProto.newBuilder().setCounter(
CounterInputProto.newBuilder()
.addCounters(CounterInputProto.Counter.newBuilder()
.setMinValue(1)
.setMaxValue(9)
.setLabel("Counter 1")
.setDescriptionLine1("$34.00 per tick")
.setDescriptionLine2(
"<link1>Details</link1>"))
.addCounters(
CounterInputProto.Counter.newBuilder()
.setMinValue(1)
.setMaxValue(9)
.setLabel("Counter 2")
.setDescriptionLine1("$387.00 per tick"))
.setMinimizedCount(1)
.setMinCountersSum(2)
.setMinimizeText("Minimize")
.setExpandText("Expand")))
.addInputs(FormInputProto.newBuilder().setSelection(
SelectionInputProto.newBuilder()
.addChoices(
SelectionInputProto.Choice.newBuilder()
.setLabel("Choice 1")
.setDescriptionLine1("$10.00 per choice")
.setDescriptionLine2(
"<link1>Details</link1>"))
.setAllowMultiple(true)))
.addInputs(FormInputProto.newBuilder().setCounter(
CounterInputProto.newBuilder().addCounters(
CounterInputProto.Counter.newBuilder()
.setMinValue(1)
.setMaxValue(9)
.setLabel("Counter 3")
.setDescriptionLine1("$20.00 per tick")
.setDescriptionLine2("<link1>Details</link1>"))));
// FormAction.
list.add((ActionProto) ActionProto.newBuilder()
.setShowForm(ShowFormProto.newBuilder()
.setChip(ChipProto.newBuilder()
.setType(ChipType.HIGHLIGHTED_ACTION)
.setText("Continue"))
.setForm(formProto))
.build());
// Prompt.
list.add((ActionProto) ActionProto.newBuilder()
.setPrompt(PromptProto.newBuilder()
.setMessage("Finished")
.addChoices(Choice.newBuilder().setChip(
ChipProto.newBuilder()
.setType(ChipType.DONE_ACTION)
.setText("End"))))
.build());
AutofillAssistantTestScript script = new AutofillAssistantTestScript(
(SupportedScriptProto) SupportedScriptProto.newBuilder()
.setPath("autofill_assistant_target_website.html")
.setPresentation(PresentationProto.newBuilder().setAutostart(true).setChip(
ChipProto.newBuilder().setText("Autostart")))
.build(),
list);
AutofillAssistantTestService testService =
new AutofillAssistantTestService(Collections.singletonList(script));
startAutofillAssistant(mTestRule.getActivity(), testService);
waitUntilViewMatchesCondition(withText("Continue"), isCompletelyDisplayed());
// TODO(b/144690738) Remove the isDisplayed() condition.
onView(allOf(isDisplayed(), withId(R.id.increase_button),
hasSibling(hasDescendant(withText("Counter 1")))))
.perform(click());
onView(allOf(isDisplayed(), withId(R.id.expand_label))).perform(click());
onView(allOf(isDisplayed(), withId(R.id.increase_button),
hasSibling(hasDescendant(withText("Counter 3")))))
.perform(click());
onView(allOf(isDisplayed(), withId(R.id.checkbox),
hasSibling(hasDescendant(withText("Choice 1")))))
.perform(click());
onView(allOf(isDisplayed(), withId(R.id.increase_button),
hasSibling(hasDescendant(withText("Counter 2")))))
.perform(click());
waitUntilViewMatchesCondition(withText("Continue"), isEnabled());
onView(withText("Continue")).perform(click());
waitUntilViewMatchesCondition(withText("End"), isCompletelyDisplayed());
// TODO(806868): check that the values were correctly received by the native delegate.
}
}
...@@ -1051,8 +1051,10 @@ void UiControllerAndroid::OnFormChanged(const FormProto* form) { ...@@ -1051,8 +1051,10 @@ void UiControllerAndroid::OnFormChanged(const FormProto* form) {
Java_AssistantFormInput_createCounter( Java_AssistantFormInput_createCounter(
env, env,
base::android::ConvertUTF8ToJavaString(env, counter.label()), base::android::ConvertUTF8ToJavaString(env, counter.label()),
base::android::ConvertUTF8ToJavaString(env, base::android::ConvertUTF8ToJavaString(
counter.subtext()), env, counter.description_line_1()),
base::android::ConvertUTF8ToJavaString(
env, counter.description_line_2()),
counter.initial_value(), counter.min_value(), counter.initial_value(), counter.min_value(),
counter.max_value(), counter.max_value(),
base::android::ToJavaIntArray(env, allowed_values))); base::android::ToJavaIntArray(env, allowed_values)));
...@@ -1085,6 +1087,10 @@ void UiControllerAndroid::OnFormChanged(const FormProto* form) { ...@@ -1085,6 +1087,10 @@ void UiControllerAndroid::OnFormChanged(const FormProto* form) {
Java_AssistantFormInput_createChoice( Java_AssistantFormInput_createChoice(
env, env,
base::android::ConvertUTF8ToJavaString(env, choice.label()), base::android::ConvertUTF8ToJavaString(env, choice.label()),
base::android::ConvertUTF8ToJavaString(
env, choice.description_line_1()),
base::android::ConvertUTF8ToJavaString(
env, choice.description_line_2()),
choice.selected())); choice.selected()));
} }
......
...@@ -1695,7 +1695,10 @@ message CounterInputProto { ...@@ -1695,7 +1695,10 @@ message CounterInputProto {
optional string label = 1; optional string label = 1;
// Text shown below the label. Optional. // Text shown below the label. Optional.
optional string subtext = 5; optional string description_line_1 = 5;
// Text shown below |description_line_2|. Optional.
optional string description_line_2 = 8;
// The possible values this counter can have. If empty, the possible values // The possible values this counter can have. If empty, the possible values
// will be all integer values between |min_value| and |max_value|. // will be all integer values between |min_value| and |max_value|.
...@@ -1827,6 +1830,12 @@ message SelectionInputProto { ...@@ -1827,6 +1830,12 @@ message SelectionInputProto {
// The label of this choice. // The label of this choice.
optional string label = 1; optional string label = 1;
// Text shown below the label. Optional.
optional string description_line_1 = 3;
// Text shown below |description_line_2|. Optional.
optional string description_line_2 = 4;
// Whether this choice is selected by default. If |allow_multiple| is false, // Whether this choice is selected by default. If |allow_multiple| is false,
// then maximum 1 Choice can have this set to true, otherwise the associated // then maximum 1 Choice can have this set to true, otherwise the associated
// FormAction will fail. // FormAction will fail.
......
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