Commit 9ecb4387 authored by csashi's avatar csashi Committed by Commit bot

Expanded Autofill Credit Card Popup Layout Experiment in Android.

Assets are yet to be added to this change.
BUG=664367

Review-Url: https://codereview.chromium.org/2531223003
Cr-Commit-Position: refs/heads/master@{#437960}
parent 9ed7b561
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
package org.chromium.android_webview; package org.chromium.android_webview;
import android.graphics.Color;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
...@@ -64,7 +65,8 @@ public class AwAutofillClient { ...@@ -64,7 +65,8 @@ public class AwAutofillClient {
public void deleteSuggestion(int listIndex) { } public void deleteSuggestion(int listIndex) { }
}); });
} }
mAutofillPopup.filterAndShow(suggestions, isRtl); mAutofillPopup.filterAndShow(suggestions, isRtl, Color.TRANSPARENT /* backgroundColor */,
Color.TRANSPARENT /* dividerColor */, 0 /* dropdownItemHeight */);
} }
@CalledByNative @CalledByNative
...@@ -89,8 +91,9 @@ public class AwAutofillClient { ...@@ -89,8 +91,9 @@ public class AwAutofillClient {
@CalledByNative @CalledByNative
private static void addToAutofillSuggestionArray(AutofillSuggestion[] array, int index, private static void addToAutofillSuggestionArray(AutofillSuggestion[] array, int index,
String name, String label, int uniqueId) { String name, String label, int uniqueId) {
array[index] = array[index] = new AutofillSuggestion(name, label, DropdownItem.NO_ICON,
new AutofillSuggestion(name, label, DropdownItem.NO_ICON, uniqueId, false, false); false /* isIconAtLeft */, uniqueId, false /* isDeletable */,
false /* isMultilineLabel */, false /* isBoldLabel */);
} }
private native void nativeDismissed(long nativeAwAutofillClient); private native void nativeDismissed(long nativeAwAutofillClient);
......
...@@ -144,13 +144,15 @@ public class AutofillKeyboardAccessoryBridge ...@@ -144,13 +144,15 @@ public class AutofillKeyboardAccessoryBridge
* empty too. * empty too.
* @param iconId The resource ID for the icon associated with the suggestion, or 0 for no icon. * @param iconId The resource ID for the icon associated with the suggestion, or 0 for no icon.
* @param suggestionId Identifier for the suggestion type. * @param suggestionId Identifier for the suggestion type.
* @param isDeletable Whether the item can be deleted by the user.
*/ */
@CalledByNative @CalledByNative
private static void addToAutofillSuggestionArray(AutofillSuggestion[] array, int index, private static void addToAutofillSuggestionArray(AutofillSuggestion[] array, int index,
String label, String sublabel, int iconId, int suggestionId, boolean deletable) { String label, String sublabel, int iconId, int suggestionId, boolean isDeletable) {
int drawableId = iconId == 0 ? DropdownItem.NO_ICON : ResourceId.mapToDrawableId(iconId); int drawableId = iconId == 0 ? DropdownItem.NO_ICON : ResourceId.mapToDrawableId(iconId);
array[index] = array[index] = new AutofillSuggestion(label, sublabel, drawableId,
new AutofillSuggestion(label, sublabel, drawableId, suggestionId, deletable, false); false /* isIconAtStart */, suggestionId, isDeletable, false /* isMultilineLabel */,
false /* isBoldLabel */);
} }
private native void nativeViewDismissed(long nativeAutofillKeyboardAccessoryView); private native void nativeViewDismissed(long nativeAutofillKeyboardAccessoryView);
......
...@@ -92,10 +92,19 @@ public class AutofillPopupBridge implements AutofillDelegate, DialogInterface.On ...@@ -92,10 +92,19 @@ public class AutofillPopupBridge implements AutofillDelegate, DialogInterface.On
/** /**
* Shows an Autofill popup with specified suggestions. * Shows an Autofill popup with specified suggestions.
* @param suggestions Autofill suggestions to be displayed. * @param suggestions Autofill suggestions to be displayed.
* @param isRtl @code true if right-to-left text.
* @param backgroundColor popup background color, or {@code Color.TRANSPARENT} if not specified
* in experiment.
* @param dividerColor color for divider between popup items, or {@code Color.TRANSPARENT} if
* not specified in experiment.
* @param dropdownItemHeight height of each dropdown item in dimension independent pixel units,
* 0 if not specified in experiment.
*/ */
@CalledByNative @CalledByNative
private void show(AutofillSuggestion[] suggestions, boolean isRtl) { private void show(AutofillSuggestion[] suggestions, boolean isRtl, int backgroundColor,
if (mAutofillPopup != null) mAutofillPopup.filterAndShow(suggestions, isRtl); int dividerColor, int dropdownItemHeight) {
if (mAutofillPopup != null) mAutofillPopup.filterAndShow(suggestions, isRtl,
backgroundColor, dividerColor, dropdownItemHeight);
} }
@CalledByNative @CalledByNative
...@@ -122,17 +131,20 @@ public class AutofillPopupBridge implements AutofillDelegate, DialogInterface.On ...@@ -122,17 +131,20 @@ public class AutofillPopupBridge implements AutofillDelegate, DialogInterface.On
* @param label First line of the suggestion. * @param label First line of the suggestion.
* @param sublabel Second line of the suggestion. * @param sublabel Second line of the suggestion.
* @param iconId The resource ID for the icon associated with the suggestion, or 0 for no icon. * @param iconId The resource ID for the icon associated with the suggestion, or 0 for no icon.
* @param isIconAtStart {@code true} if {@param iconId} is displayed before {@param label}.
* @param suggestionId Identifier for the suggestion type. * @param suggestionId Identifier for the suggestion type.
* @param deletable Whether this item is deletable. * @param isDeletable Whether the item can be deleted by the user.
* @param isLabelMultiline Whether the label should be should over multiple lines. * @param isLabelMultiline Whether the label should be should over multiple lines.
* @param isLabelBold true if {@param label} should be displayed in {@code Typeface.BOLD},
* false if {@param label} should be displayed in {@code Typeface.NORMAL}.
*/ */
@CalledByNative @CalledByNative
private static void addToAutofillSuggestionArray(AutofillSuggestion[] array, int index, private static void addToAutofillSuggestionArray(AutofillSuggestion[] array, int index,
String label, String sublabel, int iconId, int suggestionId, boolean deletable, String label, String sublabel, int iconId, boolean isIconAtStart,
boolean isLabelMultiline) { int suggestionId, boolean isDeletable, boolean isLabelMultiline, boolean isLabelBold) {
int drawableId = iconId == 0 ? DropdownItem.NO_ICON : ResourceId.mapToDrawableId(iconId); int drawableId = iconId == 0 ? DropdownItem.NO_ICON : ResourceId.mapToDrawableId(iconId);
array[index] = new AutofillSuggestion( array[index] = new AutofillSuggestion(label, sublabel, drawableId, isIconAtStart,
label, sublabel, drawableId, suggestionId, deletable, isLabelMultiline); suggestionId, isDeletable, isLabelMultiline, isLabelBold);
} }
private native void nativeSuggestionSelected(long nativeAutofillPopupViewAndroid, private native void nativeSuggestionSelected(long nativeAutofillPopupViewAndroid,
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
package org.chromium.chrome.browser.autofill; package org.chromium.chrome.browser.autofill;
import android.graphics.Color;
import android.test.suitebuilder.annotation.SmallTest; import android.test.suitebuilder.annotation.SmallTest;
import android.view.View; import android.view.View;
...@@ -67,7 +68,9 @@ public class AutofillTest extends ChromeActivityTestCaseBase<ChromeActivity> { ...@@ -67,7 +68,9 @@ public class AutofillTest extends ChromeActivityTestCaseBase<ChromeActivity> {
mWindowAndroid = new ActivityWindowAndroid(activity); mWindowAndroid = new ActivityWindowAndroid(activity);
mAutofillPopup = new AutofillPopup(activity, anchorView, mMockAutofillCallback); mAutofillPopup = new AutofillPopup(activity, anchorView, mMockAutofillCallback);
mAutofillPopup.filterAndShow(new AutofillSuggestion[0], false); mAutofillPopup.filterAndShow(new AutofillSuggestion[0], false /* isRtl */,
Color.TRANSPARENT /* backgroundColor */,
Color.TRANSPARENT /* dividerColor */, 0 /* dropdownItemHeight */);
} }
}); });
} }
...@@ -107,21 +110,24 @@ public class AutofillTest extends ChromeActivityTestCaseBase<ChromeActivity> { ...@@ -107,21 +110,24 @@ public class AutofillTest extends ChromeActivityTestCaseBase<ChromeActivity> {
private AutofillSuggestion[] createTwoAutofillSuggestionArray() { private AutofillSuggestion[] createTwoAutofillSuggestionArray() {
return new AutofillSuggestion[] { return new AutofillSuggestion[] {
new AutofillSuggestion("Sherlock Holmes", "221B Baker Street", DropdownItem.NO_ICON, new AutofillSuggestion("Sherlock Holmes", "221B Baker Street", DropdownItem.NO_ICON,
42, false, false), false, 42, false, false, false),
new AutofillSuggestion( new AutofillSuggestion("Arthur Dent", "West Country", DropdownItem.NO_ICON,
"Arthur Dent", "West Country", DropdownItem.NO_ICON, 43, false, false), false, 43, false, false, false),
}; };
} }
private AutofillSuggestion[] createFiveAutofillSuggestionArray() { private AutofillSuggestion[] createFiveAutofillSuggestionArray() {
return new AutofillSuggestion[] { return new AutofillSuggestion[] {
new AutofillSuggestion("Sherlock Holmes", "221B Baker Street", DropdownItem.NO_ICON, new AutofillSuggestion("Sherlock Holmes", "221B Baker Street", DropdownItem.NO_ICON,
42, false, false), false, 42, false, false, false),
new AutofillSuggestion( new AutofillSuggestion("Arthur Dent", "West Country", DropdownItem.NO_ICON,
"Arthur Dent", "West Country", DropdownItem.NO_ICON, 43, false, false), false, 43, false, false, false),
new AutofillSuggestion("Arthos", "France", DropdownItem.NO_ICON, 44, false, false), new AutofillSuggestion("Arthos", "France", DropdownItem.NO_ICON,
new AutofillSuggestion("Porthos", "France", DropdownItem.NO_ICON, 45, false, false), false, 44, false, false, false),
new AutofillSuggestion("Aramis", "France", DropdownItem.NO_ICON, 46, false, false), new AutofillSuggestion("Porthos", "France", DropdownItem.NO_ICON,
false, 45, false, false, false),
new AutofillSuggestion("Aramis", "France", DropdownItem.NO_ICON,
false, 46, false, false, false),
}; };
} }
...@@ -130,7 +136,9 @@ public class AutofillTest extends ChromeActivityTestCaseBase<ChromeActivity> { ...@@ -130,7 +136,9 @@ public class AutofillTest extends ChromeActivityTestCaseBase<ChromeActivity> {
ThreadUtils.runOnUiThreadBlocking(new Runnable() { ThreadUtils.runOnUiThreadBlocking(new Runnable() {
@Override @Override
public void run() { public void run() {
mAutofillPopup.filterAndShow(suggestions, false); mAutofillPopup.filterAndShow(suggestions, false /* isRtl */,
Color.TRANSPARENT /* backgroundColor */,
Color.TRANSPARENT /* dividerColor */, 0 /* dropdownItemHeight */);
} }
}); });
CriteriaHelper.pollInstrumentationThread(new Criteria() { CriteriaHelper.pollInstrumentationThread(new Criteria() {
......
...@@ -94,7 +94,7 @@ void AutofillPopupViewAndroid::UpdateBoundsAndRedrawPopup() { ...@@ -94,7 +94,7 @@ void AutofillPopupViewAndroid::UpdateBoundsAndRedrawPopup() {
controller_->layout_model().GetIconResourceID(suggestion.icon)); controller_->layout_model().GetIconResourceID(suggestion.icon));
} }
bool deletable = bool is_deletable =
controller_->GetRemovalConfirmationText(i, nullptr, nullptr); controller_->GetRemovalConfirmationText(i, nullptr, nullptr);
bool is_label_multiline = bool is_label_multiline =
suggestion.frontend_id == suggestion.frontend_id ==
...@@ -102,11 +102,16 @@ void AutofillPopupViewAndroid::UpdateBoundsAndRedrawPopup() { ...@@ -102,11 +102,16 @@ void AutofillPopupViewAndroid::UpdateBoundsAndRedrawPopup() {
suggestion.frontend_id == POPUP_ITEM_ID_CREDIT_CARD_SIGNIN_PROMO; suggestion.frontend_id == POPUP_ITEM_ID_CREDIT_CARD_SIGNIN_PROMO;
Java_AutofillPopupBridge_addToAutofillSuggestionArray( Java_AutofillPopupBridge_addToAutofillSuggestionArray(
env, data_array, i, value, label, android_icon_id, env, data_array, i, value, label, android_icon_id,
suggestion.frontend_id, deletable, is_label_multiline); controller_->layout_model().IsIconAtStart(suggestion.frontend_id),
suggestion.frontend_id, is_deletable, is_label_multiline,
suggestion.is_value_bold);
} }
Java_AutofillPopupBridge_show(env, java_object_, data_array, Java_AutofillPopupBridge_show(
controller_->IsRTL()); env, java_object_, data_array, controller_->IsRTL(),
controller_->layout_model().GetBackgroundColor(),
controller_->layout_model().GetDividerColor(),
controller_->layout_model().GetDropdownItemHeight());
} }
void AutofillPopupViewAndroid::SuggestionSelected( void AutofillPopupViewAndroid::SuggestionSelected(
......
...@@ -70,7 +70,7 @@ AutofillPopupControllerImpl::AutofillPopupControllerImpl( ...@@ -70,7 +70,7 @@ AutofillPopupControllerImpl::AutofillPopupControllerImpl(
container_view, container_view,
web_contents)), web_contents)),
view_(NULL), view_(NULL),
layout_model_(this), layout_model_(this, delegate->IsCreditCardPopup()),
delegate_(delegate), delegate_(delegate),
weak_ptr_factory_(this) { weak_ptr_factory_(this) {
ClearState(); ClearState();
......
...@@ -10,10 +10,12 @@ ...@@ -10,10 +10,12 @@
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "chrome/browser/ui/autofill/autofill_popup_view.h" #include "chrome/browser/ui/autofill/autofill_popup_view.h"
#include "chrome/browser/ui/autofill/popup_constants.h" #include "chrome/browser/ui/autofill/popup_constants.h"
#include "components/autofill/core/browser/autofill_experiments.h"
#include "components/autofill/core/browser/popup_item_ids.h" #include "components/autofill/core/browser/popup_item_ids.h"
#include "components/autofill/core/browser/suggestion.h" #include "components/autofill/core/browser/suggestion.h"
#include "components/autofill/core/common/autofill_util.h" #include "components/autofill/core/common/autofill_util.h"
#include "components/grit/components_scaled_resources.h" #include "components/grit/components_scaled_resources.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/resource/resource_bundle.h" #include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/color_palette.h" #include "ui/gfx/color_palette.h"
#include "ui/gfx/color_utils.h" #include "ui/gfx/color_utils.h"
...@@ -70,8 +72,8 @@ int GetRowHeightFromId(int identifier) { ...@@ -70,8 +72,8 @@ int GetRowHeightFromId(int identifier) {
} // namespace } // namespace
AutofillPopupLayoutModel::AutofillPopupLayoutModel( AutofillPopupLayoutModel::AutofillPopupLayoutModel(
AutofillPopupViewDelegate* delegate) AutofillPopupViewDelegate* delegate, bool is_credit_card_popup)
: delegate_(delegate) { : delegate_(delegate), is_credit_card_popup_(is_credit_card_popup) {
#if !defined(OS_ANDROID) #if !defined(OS_ANDROID)
smaller_font_list_ = smaller_font_list_ =
normal_font_list_.DeriveWithSizeDelta(kSmallerFontSizeDelta); normal_font_list_.DeriveWithSizeDelta(kSmallerFontSizeDelta);
...@@ -282,4 +284,28 @@ const gfx::Rect AutofillPopupLayoutModel::RoundedElementBounds() const { ...@@ -282,4 +284,28 @@ const gfx::Rect AutofillPopupLayoutModel::RoundedElementBounds() const {
return gfx::ToEnclosingRect(delegate_->element_bounds()); return gfx::ToEnclosingRect(delegate_->element_bounds());
} }
bool AutofillPopupLayoutModel::IsPopupLayoutExperimentEnabled() const {
return is_credit_card_popup_ &&
IsAutofillCreditCardPopupLayoutExperimentEnabled();
}
SkColor AutofillPopupLayoutModel::GetBackgroundColor() const {
return is_credit_card_popup_ ?
GetCreditCardPopupBackgroundColor() : SK_ColorTRANSPARENT;
}
SkColor AutofillPopupLayoutModel::GetDividerColor() const {
return is_credit_card_popup_ ?
GetCreditCardPopupDividerColor() : SK_ColorTRANSPARENT;
}
unsigned int AutofillPopupLayoutModel::GetDropdownItemHeight() const {
return GetPopupDropdownItemHeight();
}
bool AutofillPopupLayoutModel::IsIconAtStart(int frontend_id) const {
return frontend_id == POPUP_ITEM_ID_HTTP_NOT_SECURE_WARNING_MESSAGE ||
(is_credit_card_popup_ && IsIconInCreditCardPopupAtStart());
}
} // namespace autofill } // namespace autofill
...@@ -25,7 +25,9 @@ namespace autofill { ...@@ -25,7 +25,9 @@ namespace autofill {
// TODO(mathp): investigate moving ownership of this class to the view. // TODO(mathp): investigate moving ownership of this class to the view.
class AutofillPopupLayoutModel { class AutofillPopupLayoutModel {
public: public:
explicit AutofillPopupLayoutModel(AutofillPopupViewDelegate* delegate); AutofillPopupLayoutModel(AutofillPopupViewDelegate* delegate,
bool is_credit_card_popup);
~AutofillPopupLayoutModel(); ~AutofillPopupLayoutModel();
// The minimum amount of padding between the Autofill name and subtext, // The minimum amount of padding between the Autofill name and subtext,
...@@ -92,6 +94,27 @@ class AutofillPopupLayoutModel { ...@@ -92,6 +94,27 @@ class AutofillPopupLayoutModel {
// resource isn't recognized. // resource isn't recognized.
int GetIconResourceID(const base::string16& resource_name) const; int GetIconResourceID(const base::string16& resource_name) const;
// Returns whether |GetBackgroundColor, GetDividerColor| returns a custom
// color configured in an experiment to tweak autofill popup layout.
bool IsPopupLayoutExperimentEnabled() const;
// Returns the background color for the autofill popup, or
// |SK_ColorTRANSPARENT| if not in an experiment to tweak autofill popup
// layout.
SkColor GetBackgroundColor() const;
// Returns the divider color for the autofill popup, or
// |SK_ColorTRANSPARENT| if not in an experiment to tweak autofill popup
// layout.
SkColor GetDividerColor() const;
// Returns the dropdown item height, or 0 if the dropdown item height isn't
// configured in an experiment to tweak autofill popup layout.
unsigned int GetDropdownItemHeight() const;
// Returns true if suggestion icon must be displayed before suggestion text.
bool IsIconAtStart(int frontend_id) const;
private: private:
// Returns the enclosing rectangle for the element_bounds. // Returns the enclosing rectangle for the element_bounds.
const gfx::Rect RoundedElementBounds() const; const gfx::Rect RoundedElementBounds() const;
...@@ -116,6 +139,8 @@ class AutofillPopupLayoutModel { ...@@ -116,6 +139,8 @@ class AutofillPopupLayoutModel {
AutofillPopupViewDelegate* delegate_; // Weak reference. AutofillPopupViewDelegate* delegate_; // Weak reference.
const bool is_credit_card_popup_;
DISALLOW_COPY_AND_ASSIGN(AutofillPopupLayoutModel); DISALLOW_COPY_AND_ASSIGN(AutofillPopupLayoutModel);
}; };
......
...@@ -74,7 +74,8 @@ class AutofillPopupLayoutModelTest : public ChromeRenderViewHostTestHarness { ...@@ -74,7 +74,8 @@ class AutofillPopupLayoutModelTest : public ChromeRenderViewHostTestHarness {
ChromeRenderViewHostTestHarness::SetUp(); ChromeRenderViewHostTestHarness::SetUp();
delegate_.reset(new TestAutofillPopupViewDelegate(web_contents())); delegate_.reset(new TestAutofillPopupViewDelegate(web_contents()));
layout_model_.reset(new AutofillPopupLayoutModel(delegate_.get())); layout_model_.reset(new AutofillPopupLayoutModel(
delegate_.get(), false /* is_credit_card_field */));
} }
AutofillPopupLayoutModel* layout_model() { return layout_model_.get(); } AutofillPopupLayoutModel* layout_model() { return layout_model_.get(); }
......
...@@ -4,6 +4,7 @@ include_rules = [ ...@@ -4,6 +4,7 @@ include_rules = [
"+grit", # For generated headers "+grit", # For generated headers
"+jni", "+jni",
"+net", "+net",
"+third_party/skia",
"+third_party/zlib/google", "+third_party/zlib/google",
"+ui", "+ui",
......
...@@ -6,6 +6,7 @@ package org.chromium.components.autofill; ...@@ -6,6 +6,7 @@ package org.chromium.components.autofill;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.graphics.Color;
import android.view.View; import android.view.View;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.PopupWindow; import android.widget.PopupWindow;
...@@ -28,7 +29,8 @@ public class AutofillPopup extends DropdownPopupWindow implements AdapterView.On ...@@ -28,7 +29,8 @@ public class AutofillPopup extends DropdownPopupWindow implements AdapterView.On
/** /**
* The constant used to specify a separator in a list of Autofill suggestions. * The constant used to specify a separator in a list of Autofill suggestions.
* Has to be kept in sync with enum in WebAutofillClient.h * Has to be kept in sync with {@code POPUP_ITEM_ID_SEPARATOR} enum in
* components/autofill/core/browser/popup_item_ids.h
*/ */
private static final int ITEM_ID_SEPARATOR_ENTRY = -3; private static final int ITEM_ID_SEPARATOR_ENTRY = -3;
...@@ -57,9 +59,18 @@ public class AutofillPopup extends DropdownPopupWindow implements AdapterView.On ...@@ -57,9 +59,18 @@ public class AutofillPopup extends DropdownPopupWindow implements AdapterView.On
/** /**
* Filters the Autofill suggestions to the ones that we support and shows the popup. * Filters the Autofill suggestions to the ones that we support and shows the popup.
* @param suggestions Autofill suggestion data. * @param suggestions Autofill suggestion data.
* @param isRtl @code true if right-to-left text.
* @param backgroundColor popup background color, or {@code Color.TRANSPARENT} if unspecified.
* @param dividerColor color for divider between popup items, or {@code Color.TRANSPARENT} if
* unspecified.
* @param isBoldLabel true if suggestion label's type face is {@code Typeface.BOLD}, false if
* suggestion label's type face is {@code Typeface.NORMAL}.
* @param dropdownItemHeight height of each dropdown item in dimension independent pixel units,
* 0 if unspecified.
*/ */
@SuppressLint("InlinedApi") @SuppressLint("InlinedApi")
public void filterAndShow(AutofillSuggestion[] suggestions, boolean isRtl) { public void filterAndShow(AutofillSuggestion[] suggestions, boolean isRtl,
int backgroundColor, int dividerColor, int dropdownItemHeight) {
mSuggestions = new ArrayList<AutofillSuggestion>(Arrays.asList(suggestions)); mSuggestions = new ArrayList<AutofillSuggestion>(Arrays.asList(suggestions));
// Remove the AutofillSuggestions with IDs that are not supported by Android // Remove the AutofillSuggestions with IDs that are not supported by Android
ArrayList<DropdownItem> cleanedData = new ArrayList<DropdownItem>(); ArrayList<DropdownItem> cleanedData = new ArrayList<DropdownItem>();
...@@ -73,7 +84,10 @@ public class AutofillPopup extends DropdownPopupWindow implements AdapterView.On ...@@ -73,7 +84,10 @@ public class AutofillPopup extends DropdownPopupWindow implements AdapterView.On
} }
} }
setAdapter(new DropdownAdapter(mContext, cleanedData, separators)); setAdapter(new DropdownAdapter(mContext, cleanedData, separators,
backgroundColor == Color.TRANSPARENT ? null : backgroundColor,
dividerColor == Color.TRANSPARENT ? null : dividerColor,
dropdownItemHeight == 0 ? null : dropdownItemHeight));
setRtl(isRtl); setRtl(isRtl);
show(); show();
getListView().setOnItemLongClickListener(this); getListView().setOnItemLongClickListener(this);
......
...@@ -12,34 +12,42 @@ import org.chromium.ui.DropdownItemBase; ...@@ -12,34 +12,42 @@ import org.chromium.ui.DropdownItemBase;
public class AutofillSuggestion extends DropdownItemBase { public class AutofillSuggestion extends DropdownItemBase {
/** /**
* The constant used to specify a http warning message in a list of Autofill suggestions. * The constant used to specify a http warning message in a list of Autofill suggestions.
* Has to be kept in sync with enum in popup_item_ids.h * Has to be kept in sync with {@code POPUP_ITEM_ID_SEPARATOR} enum in
* TODO(crbug.com/666529): Generate java constants from C++ enum. * components/autofill/core/browser/popup_item_ids.h
*/ */
private static final int ITEM_ID_HTTP_NOT_SECURE_WARNING_MESSAGE = -10; private static final int ITEM_ID_HTTP_NOT_SECURE_WARNING_MESSAGE = -10;
private final String mLabel; private final String mLabel;
private final String mSublabel; private final String mSublabel;
private final int mIconId; private final int mIconId;
private final boolean mIsIconAtStart;
private final int mSuggestionId; private final int mSuggestionId;
private final boolean mDeletable; private final boolean mIsDeletable;
private final boolean mIsMultilineLabel; private final boolean mIsMultilineLabel;
private final boolean mIsBoldLabel;
/** /**
* Constructs a Autofill suggestion container. * Constructs a Autofill suggestion container.
* @param label The main label of the Autofill suggestion. * @param label The main label of the Autofill suggestion.
* @param sublabel The describing sublabel of the Autofill suggestion. * @param sublabel The describing sublabel of the Autofill suggestion.
* @param iconId The resource ID for the icon associated with the suggestion, or
* {@code DropdownItem.NO_ICON} for no icon.
* @param isIconAtStart {@code true} if {@param iconId} is displayed before {@param label}.
* @param suggestionId The type of suggestion. * @param suggestionId The type of suggestion.
* @param deletable Whether the item can be deleted by the user. * @param isDeletable Whether the item can be deleted by the user.
* @param multilineLabel Whether the label is displayed over multiple lines. * @param isMultilineLabel Whether the label is displayed over multiple lines.
* @param isBoldLabel Whether the label is displayed in {@code Typeface.BOLD}.
*/ */
public AutofillSuggestion(String label, String sublabel, int iconId, int suggestionId, public AutofillSuggestion(String label, String sublabel, int iconId, boolean isIconAtStart,
boolean deletable, boolean multilineLabel) { int suggestionId, boolean isDeletable, boolean isMultilineLabel, boolean isBoldLabel) {
mLabel = label; mLabel = label;
mSublabel = sublabel; mSublabel = sublabel;
mIconId = iconId; mIconId = iconId;
mIsIconAtStart = isIconAtStart;
mSuggestionId = suggestionId; mSuggestionId = suggestionId;
mDeletable = deletable; mIsDeletable = isDeletable;
mIsMultilineLabel = multilineLabel; mIsMultilineLabel = isMultilineLabel;
mIsBoldLabel = isBoldLabel;
} }
@Override @Override
...@@ -62,6 +70,11 @@ public class AutofillSuggestion extends DropdownItemBase { ...@@ -62,6 +70,11 @@ public class AutofillSuggestion extends DropdownItemBase {
return mIsMultilineLabel; return mIsMultilineLabel;
} }
@Override
public boolean isBoldLabel() {
return mIsBoldLabel;
}
@Override @Override
public int getLabelFontColorResId() { public int getLabelFontColorResId() {
if (mSuggestionId == ITEM_ID_HTTP_NOT_SECURE_WARNING_MESSAGE) { if (mSuggestionId == ITEM_ID_HTTP_NOT_SECURE_WARNING_MESSAGE) {
...@@ -88,7 +101,7 @@ public class AutofillSuggestion extends DropdownItemBase { ...@@ -88,7 +101,7 @@ public class AutofillSuggestion extends DropdownItemBase {
@Override @Override
public boolean isIconAtStart() { public boolean isIconAtStart() {
if (mSuggestionId == ITEM_ID_HTTP_NOT_SECURE_WARNING_MESSAGE) { if (mIsIconAtStart) {
return true; return true;
} }
return super.isIconAtStart(); return super.isIconAtStart();
...@@ -99,7 +112,7 @@ public class AutofillSuggestion extends DropdownItemBase { ...@@ -99,7 +112,7 @@ public class AutofillSuggestion extends DropdownItemBase {
} }
public boolean isDeletable() { public boolean isDeletable() {
return mDeletable; return mIsDeletable;
} }
public boolean isFillable() { public boolean isFillable() {
......
...@@ -7,9 +7,12 @@ ...@@ -7,9 +7,12 @@
#include "base/command_line.h" #include "base/command_line.h"
#include "base/feature_list.h" #include "base/feature_list.h"
#include "base/metrics/field_trial.h" #include "base/metrics/field_trial.h"
#include "base/strings/string16.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "components/autofill/core/browser/suggestion.h"
#include "components/autofill/core/common/autofill_pref_names.h" #include "components/autofill/core/common/autofill_pref_names.h"
#include "components/autofill/core/common/autofill_switches.h" #include "components/autofill/core/common/autofill_switches.h"
#include "components/prefs/pref_service.h" #include "components/prefs/pref_service.h"
...@@ -17,6 +20,8 @@ ...@@ -17,6 +20,8 @@
#include "components/sync/driver/sync_service.h" #include "components/sync/driver/sync_service.h"
#include "components/variations/variations_associated_data.h" #include "components/variations/variations_associated_data.h"
#include "google_apis/gaia/gaia_auth_util.h" #include "google_apis/gaia/gaia_auth_util.h"
#include "grit/components_strings.h"
#include "ui/base/l10n/l10n_util.h"
namespace autofill { namespace autofill {
...@@ -28,7 +33,34 @@ const base::Feature kAutofillProfileCleanup{"AutofillProfileCleanup", ...@@ -28,7 +33,34 @@ const base::Feature kAutofillProfileCleanup{"AutofillProfileCleanup",
base::FEATURE_DISABLED_BY_DEFAULT}; base::FEATURE_DISABLED_BY_DEFAULT};
const base::Feature kAutofillScanCardholderName{ const base::Feature kAutofillScanCardholderName{
"AutofillScanCardholderName", base::FEATURE_DISABLED_BY_DEFAULT}; "AutofillScanCardholderName", base::FEATURE_DISABLED_BY_DEFAULT};
const base::Feature kAutofillCreditCardPopupLayout{
"AutofillCreditCardPopupLayout", base::FEATURE_DISABLED_BY_DEFAULT};
const char kCreditCardSigninPromoImpressionLimitParamKey[] = "impression_limit"; const char kCreditCardSigninPromoImpressionLimitParamKey[] = "impression_limit";
const char kAutofillCreditCardPopupBackgroundColorKey[] = "background_color";
const char kAutofillCreditCardPopupDividerColorKey[] = "dropdown_divider_color";
const char kAutofillCreditCardPopupValueBoldKey[] = "is_value_bold";
const char kAutofillCreditCardPopupIsValueAndLabelInSingleLineKey[] =
"is_value_and_label_in_single_line";
const char kAutofillPopupDropdownItemHeightKey[] =
"dropdown_item_height";
const char kAutofillCreditCardPopupIsIconAtStartKey[] =
"is_credit_card_icon_at_start";
namespace {
// Returns parameter value in |kAutofillCreditCardPopupLayout| feature, or 0 if
// parameter is not specified.
unsigned int GetCreditCardPopupParameterUintValue(
const std::string& param_name) {
unsigned int value;
const std::string param_value = variations::GetVariationParamValueByFeature(
kAutofillCreditCardPopupLayout, param_name);
if (!param_value.empty() && base::StringToUint(param_value, &value))
return value;
return 0;
}
} // namespace
bool IsAutofillEnabled(const PrefService* pref_service) { bool IsAutofillEnabled(const PrefService* pref_service) {
return pref_service->GetBoolean(prefs::kAutofillEnabled); return pref_service->GetBoolean(prefs::kAutofillEnabled);
...@@ -67,6 +99,60 @@ int GetCreditCardSigninPromoImpressionLimit() { ...@@ -67,6 +99,60 @@ int GetCreditCardSigninPromoImpressionLimit() {
return 0; return 0;
} }
bool IsAutofillCreditCardPopupLayoutExperimentEnabled() {
return base::FeatureList::IsEnabled(kAutofillCreditCardPopupLayout);
}
// |GetCreditCardPopupParameterUintValue| returns 0 if experiment parameter is
// not specified. 0 == |SK_ColorTRANSPARENT|.
SkColor GetCreditCardPopupBackgroundColor() {
return GetCreditCardPopupParameterUintValue(
kAutofillCreditCardPopupBackgroundColorKey);
}
SkColor GetCreditCardPopupDividerColor() {
return GetCreditCardPopupParameterUintValue(
kAutofillCreditCardPopupDividerColorKey);
}
bool IsCreditCardPopupValueBold() {
const std::string param_value = variations::GetVariationParamValueByFeature(
kAutofillCreditCardPopupLayout, kAutofillCreditCardPopupValueBoldKey);
return param_value == "true";
}
unsigned int GetPopupDropdownItemHeight() {
return GetCreditCardPopupParameterUintValue(
kAutofillPopupDropdownItemHeightKey);
}
bool IsIconInCreditCardPopupAtStart() {
const std::string param_value = variations::GetVariationParamValueByFeature(
kAutofillCreditCardPopupLayout, kAutofillCreditCardPopupIsIconAtStartKey);
return param_value == "true";
}
// Modifies |suggestion| as follows if experiment to display value and label in
// a single line is enabled.
// Say, |value| is 'Visa ....1111' and |label| is '01/18' (expiration date).
// Modifies |value| to 'Visa ....1111, exp 01/18' and clears |label|.
void ModifyAutofillCreditCardSuggestion(Suggestion* suggestion) {
DCHECK(IsAutofillCreditCardPopupLayoutExperimentEnabled());
const std::string param_value = variations::GetVariationParamValueByFeature(
kAutofillCreditCardPopupLayout,
kAutofillCreditCardPopupIsValueAndLabelInSingleLineKey);
if (param_value == "true") {
const base::string16 format_string = l10n_util::GetStringUTF16(
IDS_AUTOFILL_CREDIT_CARD_EXPIRATION_DATE_LABEL_AND_ABBR);
if (!format_string.empty()) {
suggestion->value.append(l10n_util::GetStringFUTF16(
IDS_AUTOFILL_CREDIT_CARD_EXPIRATION_DATE_LABEL_AND_ABBR,
suggestion->label));
}
suggestion->label.clear();
}
}
bool OfferStoreUnmaskedCards() { bool OfferStoreUnmaskedCards() {
#if defined(OS_LINUX) && !defined(OS_CHROMEOS) #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
// The checkbox can be forced on with a flag, but by default we don't store // The checkbox can be forced on with a flag, but by default we don't store
......
...@@ -7,6 +7,9 @@ ...@@ -7,6 +7,9 @@
#include <string> #include <string>
#include "base/strings/string16.h"
#include "third_party/skia/include/core/SkColor.h"
class PrefService; class PrefService;
namespace base { namespace base {
...@@ -19,11 +22,15 @@ class SyncService; ...@@ -19,11 +22,15 @@ class SyncService;
namespace autofill { namespace autofill {
struct Suggestion;
extern const base::Feature kAutofillCreditCardAssist; extern const base::Feature kAutofillCreditCardAssist;
extern const base::Feature kAutofillCreditCardSigninPromo; extern const base::Feature kAutofillCreditCardSigninPromo;
extern const base::Feature kAutofillProfileCleanup; extern const base::Feature kAutofillProfileCleanup;
extern const base::Feature kAutofillScanCardholderName; extern const base::Feature kAutofillScanCardholderName;
extern const base::Feature kAutofillCreditCardPopupLayout;
extern const char kCreditCardSigninPromoImpressionLimitParamKey[]; extern const char kCreditCardSigninPromoImpressionLimitParamKey[];
extern const char kAutofillCreditCardPopupSettingsSuggestionValueKey[];
// Returns true if autofill should be enabled. See also // Returns true if autofill should be enabled. See also
// IsInAutofillSuggestionsDisabledExperiment below. // IsInAutofillSuggestionsDisabledExperiment below.
...@@ -64,6 +71,37 @@ bool IsCreditCardUploadEnabled(const PrefService* pref_service, ...@@ -64,6 +71,37 @@ bool IsCreditCardUploadEnabled(const PrefService* pref_service,
// in the autofill dropdown when credit card fields are on an HTTP page. // in the autofill dropdown when credit card fields are on an HTTP page.
bool IsCreditCardAutofillHttpWarningEnabled(); bool IsCreditCardAutofillHttpWarningEnabled();
// Returns whether the new Autofill credit card popup layout experiment is
// enabled.
bool IsAutofillCreditCardPopupLayoutExperimentEnabled();
// Returns the background color for credit card autofill popup, or
// |SK_ColorTRANSPARENT| if the new credit card autofill popup layout experiment
// is not enabled.
SkColor GetCreditCardPopupBackgroundColor();
// Returns the divider color for credit card autofill popup, or
// |SK_ColorTRANSPARENT| if the new credit card autofill popup layout experiment
// is not enabled.
SkColor GetCreditCardPopupDividerColor();
// Returns true if the credit card autofill popup suggestion value is displayed
// in bold type face.
bool IsCreditCardPopupValueBold();
// Returns the dropdown item height for autofill popup, returning 0 if the
// dropdown item height isn't configured in an experiment to tweak autofill
// popup layout.
unsigned int GetPopupDropdownItemHeight();
// Returns true if the icon in the credit card autofill popup must be displayed
// before the credit card value or any other suggestion text.
bool IsIconInCreditCardPopupAtStart();
// Modifies the suggestion value and label if the new credit card autofill popup
// experiment is enabled to tweak the display of the value and label.
void ModifyAutofillCreditCardSuggestion(struct Suggestion* suggestion);
} // namespace autofill } // namespace autofill
#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_EXPERIMENTS_H_ #endif // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_EXPERIMENTS_H_
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "build/build_config.h" #include "build/build_config.h"
#include "components/autofill/core/browser/autocomplete_history_manager.h" #include "components/autofill/core/browser/autocomplete_history_manager.h"
#include "components/autofill/core/browser/autofill_driver.h" #include "components/autofill/core/browser/autofill_driver.h"
#include "components/autofill/core/browser/autofill_experiments.h"
#include "components/autofill/core/browser/autofill_manager.h" #include "components/autofill/core/browser/autofill_manager.h"
#include "components/autofill/core/browser/autofill_metrics.h" #include "components/autofill/core/browser/autofill_metrics.h"
#include "components/autofill/core/browser/popup_item_ids.h" #include "components/autofill/core/browser/popup_item_ids.h"
...@@ -48,6 +49,7 @@ AutofillExternalDelegate::AutofillExternalDelegate(AutofillManager* manager, ...@@ -48,6 +49,7 @@ AutofillExternalDelegate::AutofillExternalDelegate(AutofillManager* manager,
has_autofill_suggestions_(false), has_autofill_suggestions_(false),
has_shown_popup_for_current_edit_(false), has_shown_popup_for_current_edit_(false),
should_show_scan_credit_card_(false), should_show_scan_credit_card_(false),
is_credit_card_popup_(false),
should_show_cc_signin_promo_(false), should_show_cc_signin_promo_(false),
has_shown_address_book_prompt(false), has_shown_address_book_prompt(false),
weak_ptr_factory_(this) { weak_ptr_factory_(this) {
...@@ -69,6 +71,8 @@ void AutofillExternalDelegate::OnQuery(int query_id, ...@@ -69,6 +71,8 @@ void AutofillExternalDelegate::OnQuery(int query_id,
element_bounds_ = element_bounds; element_bounds_ = element_bounds;
should_show_scan_credit_card_ = should_show_scan_credit_card_ =
manager_->ShouldShowScanCreditCard(query_form_, query_field_); manager_->ShouldShowScanCreditCard(query_form_, query_field_);
is_credit_card_popup_ =
manager_->IsCreditCardPopup(query_form_, query_field_);
should_show_cc_signin_promo_ = should_show_cc_signin_promo_ =
manager_->ShouldShowCreditCardSigninPromo(query_form_, query_field_); manager_->ShouldShowCreditCardSigninPromo(query_form_, query_field_);
} }
...@@ -275,6 +279,10 @@ void AutofillExternalDelegate::ClearPreviewedForm() { ...@@ -275,6 +279,10 @@ void AutofillExternalDelegate::ClearPreviewedForm() {
driver_->RendererShouldClearPreviewedForm(); driver_->RendererShouldClearPreviewedForm();
} }
bool AutofillExternalDelegate::IsCreditCardPopup() {
return is_credit_card_popup_;
}
void AutofillExternalDelegate::Reset() { void AutofillExternalDelegate::Reset() {
manager_->client()->HideAutofillPopup(); manager_->client()->HideAutofillPopup();
} }
...@@ -325,8 +333,6 @@ void AutofillExternalDelegate::ApplyAutofillOptions( ...@@ -325,8 +333,6 @@ void AutofillExternalDelegate::ApplyAutofillOptions(
if (query_field_.is_autofilled) { if (query_field_.is_autofilled) {
base::string16 value = base::string16 value =
l10n_util::GetStringUTF16(IDS_AUTOFILL_CLEAR_FORM_MENU_ITEM); l10n_util::GetStringUTF16(IDS_AUTOFILL_CLEAR_FORM_MENU_ITEM);
// TODO(rouslan): Remove manual upper-casing when keyboard accessory becomes
// default on Android.
if (IsKeyboardAccessoryEnabled()) if (IsKeyboardAccessoryEnabled())
value = base::i18n::ToUpper(value); value = base::i18n::ToUpper(value);
...@@ -334,12 +340,9 @@ void AutofillExternalDelegate::ApplyAutofillOptions( ...@@ -334,12 +340,9 @@ void AutofillExternalDelegate::ApplyAutofillOptions(
suggestions->back().frontend_id = POPUP_ITEM_ID_CLEAR_FORM; suggestions->back().frontend_id = POPUP_ITEM_ID_CLEAR_FORM;
} }
// Append the 'Chrome Autofill options' menu item; // Append the 'Chrome Autofill options' menu item, or the menu item specified
// TODO(rouslan): Switch on the platform in the GRD file when keyboard // in the popup layout experiment.
// accessory becomes default on Android. suggestions->push_back(Suggestion(GetSettingsSuggestionValue()));
suggestions->push_back(Suggestion(l10n_util::GetStringUTF16(
IsKeyboardAccessoryEnabled() ? IDS_AUTOFILL_OPTIONS_CONTENT_DESCRIPTION
: IDS_AUTOFILL_OPTIONS_POPUP)));
suggestions->back().frontend_id = POPUP_ITEM_ID_AUTOFILL_OPTIONS; suggestions->back().frontend_id = POPUP_ITEM_ID_AUTOFILL_OPTIONS;
if (IsKeyboardAccessoryEnabled()) if (IsKeyboardAccessoryEnabled())
suggestions->back().icon = base::ASCIIToUTF16("settings"); suggestions->back().icon = base::ASCIIToUTF16("settings");
...@@ -382,4 +385,14 @@ void AutofillExternalDelegate::InsertDataListValues( ...@@ -382,4 +385,14 @@ void AutofillExternalDelegate::InsertDataListValues(
} }
} }
base::string16 AutofillExternalDelegate::GetSettingsSuggestionValue()
const {
if (IsKeyboardAccessoryEnabled()) {
return l10n_util::GetStringUTF16(IDS_AUTOFILL_OPTIONS_CONTENT_DESCRIPTION);
}
return l10n_util::GetStringUTF16(is_credit_card_popup_ ?
IDS_AUTOFILL_CREDIT_CARD_OPTIONS_POPUP :
IDS_AUTOFILL_OPTIONS_POPUP);
}
} // namespace autofill } // namespace autofill
...@@ -51,6 +51,9 @@ class AutofillExternalDelegate : public AutofillPopupDelegate { ...@@ -51,6 +51,9 @@ class AutofillExternalDelegate : public AutofillPopupDelegate {
base::string16* body) override; base::string16* body) override;
bool RemoveSuggestion(const base::string16& value, int identifier) override; bool RemoveSuggestion(const base::string16& value, int identifier) override;
void ClearPreviewedForm() override; void ClearPreviewedForm() override;
// Returns false for all popups prior to |onQuery|, true for credit card
// popups after call to |onQuery|.
bool IsCreditCardPopup() override;
// Records and associates a query_id with web form data. Called // Records and associates a query_id with web form data. Called
// when the renderer posts an Autofill query to the browser. |bounds| // when the renderer posts an Autofill query to the browser. |bounds|
...@@ -115,6 +118,9 @@ class AutofillExternalDelegate : public AutofillPopupDelegate { ...@@ -115,6 +118,9 @@ class AutofillExternalDelegate : public AutofillPopupDelegate {
// version. // version.
void InsertDataListValues(std::vector<Suggestion>* suggestions); void InsertDataListValues(std::vector<Suggestion>* suggestions);
// Returns the text (i.e. |Suggestion| value) for Chrome autofill options.
base::string16 GetSettingsSuggestionValue() const;
AutofillManager* manager_; // weak. AutofillManager* manager_; // weak.
// Provides driver-level context to the shared code of the component. Must // Provides driver-level context to the shared code of the component. Must
...@@ -139,8 +145,8 @@ class AutofillExternalDelegate : public AutofillPopupDelegate { ...@@ -139,8 +145,8 @@ class AutofillExternalDelegate : public AutofillPopupDelegate {
// currently editing? Used to keep track of state for metrics logging. // currently editing? Used to keep track of state for metrics logging.
bool has_shown_popup_for_current_edit_; bool has_shown_popup_for_current_edit_;
// FIXME
bool should_show_scan_credit_card_; bool should_show_scan_credit_card_;
bool is_credit_card_popup_;
// Whether the credit card signin promo should be shown to the user. // Whether the credit card signin promo should be shown to the user.
bool should_show_cc_signin_promo_; bool should_show_cc_signin_promo_;
......
...@@ -308,6 +308,12 @@ bool AutofillManager::ShouldShowScanCreditCard(const FormData& form, ...@@ -308,6 +308,12 @@ bool AutofillManager::ShouldShowScanCreditCard(const FormData& form,
return field.value.size() <= kShowScanCreditCardMaxValueLength; return field.value.size() <= kShowScanCreditCardMaxValueLength;
} }
bool AutofillManager::IsCreditCardPopup(const FormData& form,
const FormFieldData& field) {
AutofillField* autofill_field = GetAutofillField(form, field);
return autofill_field && autofill_field->Type().group() == CREDIT_CARD;
}
bool AutofillManager::ShouldShowCreditCardSigninPromo( bool AutofillManager::ShouldShowCreditCardSigninPromo(
const FormData& form, const FormData& form,
const FormFieldData& field) { const FormFieldData& field) {
...@@ -528,8 +534,6 @@ void AutofillManager::OnQueryFormFieldAutofill(int query_id, ...@@ -528,8 +534,6 @@ void AutofillManager::OnQueryFormFieldAutofill(int query_id,
if (!IsValidFormData(form) || !IsValidFormFieldData(field)) if (!IsValidFormData(form) || !IsValidFormFieldData(field))
return; return;
std::vector<Suggestion> suggestions;
gfx::RectF transformed_box = gfx::RectF transformed_box =
driver_->TransformBoundingBoxToViewportCoordinates(bounding_box); driver_->TransformBoundingBoxToViewportCoordinates(bounding_box);
external_delegate_->OnQuery(query_id, form, field, transformed_box); external_delegate_->OnQuery(query_id, form, field, transformed_box);
...@@ -554,6 +558,8 @@ void AutofillManager::OnQueryFormFieldAutofill(int query_id, ...@@ -554,6 +558,8 @@ void AutofillManager::OnQueryFormFieldAutofill(int query_id,
} }
} }
std::vector<Suggestion> suggestions;
if (is_autofill_possible && if (is_autofill_possible &&
driver_->RendererIsAvailable() && driver_->RendererIsAvailable() &&
got_autofillable_form) { got_autofillable_form) {
...@@ -1790,6 +1796,7 @@ std::vector<Suggestion> AutofillManager::GetCreditCardSuggestions( ...@@ -1790,6 +1796,7 @@ std::vector<Suggestion> AutofillManager::GetCreditCardSuggestions(
for (size_t i = 0; i < suggestions.size(); i++) { for (size_t i = 0; i < suggestions.size(); i++) {
suggestions[i].frontend_id = suggestions[i].frontend_id =
MakeFrontendID(suggestions[i].backend_id, std::string()); MakeFrontendID(suggestions[i].backend_id, std::string());
suggestions[i].is_value_bold = IsCreditCardPopupValueBold();
} }
return suggestions; return suggestions;
} }
......
...@@ -96,6 +96,10 @@ class AutofillManager : public AutofillDownloadManager::Observer, ...@@ -96,6 +96,10 @@ class AutofillManager : public AutofillDownloadManager::Observer,
virtual bool ShouldShowScanCreditCard(const FormData& form, virtual bool ShouldShowScanCreditCard(const FormData& form,
const FormFieldData& field); const FormFieldData& field);
// Whether the |field| belongs to CREDIT_CARD |FieldTypeGroup|.
virtual bool IsCreditCardPopup(const FormData& form,
const FormFieldData& field);
// Whether we should show the signin promo, based on the triggered |field| // Whether we should show the signin promo, based on the triggered |field|
// inside the |form|. // inside the |form|.
virtual bool ShouldShowCreditCardSigninPromo(const FormData& form, virtual bool ShouldShowCreditCardSigninPromo(const FormData& form,
......
...@@ -43,6 +43,9 @@ class AutofillPopupDelegate { ...@@ -43,6 +43,9 @@ class AutofillPopupDelegate {
// Informs the delegate that the Autofill previewed form should be cleared. // Informs the delegate that the Autofill previewed form should be cleared.
virtual void ClearPreviewedForm() = 0; virtual void ClearPreviewedForm() = 0;
// Returns true if popup is for credit card.
virtual bool IsCreditCardPopup() = 0;
}; };
} // namespace autofill } // namespace autofill
......
...@@ -1626,6 +1626,8 @@ std::vector<Suggestion> PersonalDataManager::GetSuggestionsForCards( ...@@ -1626,6 +1626,8 @@ std::vector<Suggestion> PersonalDataManager::GetSuggestionsForCards(
suggestion->value = credit_card->TypeAndLastFourDigits(); suggestion->value = credit_card->TypeAndLastFourDigits();
suggestion->label = credit_card->GetInfo( suggestion->label = credit_card->GetInfo(
AutofillType(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR), app_locale_); AutofillType(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR), app_locale_);
if (IsAutofillCreditCardPopupLayoutExperimentEnabled())
ModifyAutofillCreditCardSuggestion(suggestion);
} else if (credit_card->number().empty()) { } else if (credit_card->number().empty()) {
if (type.GetStorableType() != CREDIT_CARD_NAME_FULL) { if (type.GetStorableType() != CREDIT_CARD_NAME_FULL) {
suggestion->label = credit_card->GetInfo( suggestion->label = credit_card->GetInfo(
......
...@@ -10,7 +10,8 @@ namespace autofill { ...@@ -10,7 +10,8 @@ namespace autofill {
Suggestion::Suggestion() Suggestion::Suggestion()
: frontend_id(0), : frontend_id(0),
match(PREFIX_MATCH) { match(PREFIX_MATCH),
is_value_bold(false) {
} }
Suggestion::Suggestion(const Suggestion& other) Suggestion::Suggestion(const Suggestion& other)
...@@ -19,13 +20,15 @@ Suggestion::Suggestion(const Suggestion& other) ...@@ -19,13 +20,15 @@ Suggestion::Suggestion(const Suggestion& other)
value(other.value), value(other.value),
label(other.label), label(other.label),
icon(other.icon), icon(other.icon),
match(other.match) { match(other.match),
is_value_bold(other.is_value_bold) {
} }
Suggestion::Suggestion(const base::string16& v) Suggestion::Suggestion(const base::string16& v)
: frontend_id(0), : frontend_id(0),
value(v), value(v),
match(PREFIX_MATCH) { match(PREFIX_MATCH),
is_value_bold(false) {
} }
Suggestion::Suggestion(const std::string& v, Suggestion::Suggestion(const std::string& v,
...@@ -36,7 +39,8 @@ Suggestion::Suggestion(const std::string& v, ...@@ -36,7 +39,8 @@ Suggestion::Suggestion(const std::string& v,
value(base::UTF8ToUTF16(v)), value(base::UTF8ToUTF16(v)),
label(base::UTF8ToUTF16(l)), label(base::UTF8ToUTF16(l)),
icon(base::UTF8ToUTF16(i)), icon(base::UTF8ToUTF16(i)),
match(PREFIX_MATCH) { match(PREFIX_MATCH),
is_value_bold(false) {
} }
Suggestion::~Suggestion() { Suggestion::~Suggestion() {
......
...@@ -47,6 +47,7 @@ struct Suggestion { ...@@ -47,6 +47,7 @@ struct Suggestion {
base::string16 label; base::string16 label;
base::string16 icon; base::string16 icon;
MatchMode match; MatchMode match;
bool is_value_bold; // true if |value| should be displayed in bold type face.
}; };
} // namespace autofill } // namespace autofill
......
...@@ -157,6 +157,17 @@ ...@@ -157,6 +157,17 @@
</message> </message>
</if> </if>
<if expr="_google_chrome">
<message name="IDS_AUTOFILL_CREDIT_CARD_OPTIONS_POPUP" desc="The label of the text displayed in the Autofill Credit Card popup to direct the user to the Autofill settings UI.">
Chrome Autofill settings...
</message>
</if>
<if expr="not _google_chrome">
<message name="IDS_AUTOFILL_CREDIT_CARD_OPTIONS_POPUP" desc="The label of the text displayed in the Autofill Credit Card popup to direct the user to the Autofill settings UI.">
Chromium Autofill settings...
</message>
</if>
<message name="IDS_AUTOFILL_OPTIONS_CONTENT_DESCRIPTION" desc="The text verbalised by a screen reader for the button that directs the user to the Autofill settings UI. This string is not displayed."> <message name="IDS_AUTOFILL_OPTIONS_CONTENT_DESCRIPTION" desc="The text verbalised by a screen reader for the button that directs the user to the Autofill settings UI. This string is not displayed.">
settings settings
</message> </message>
...@@ -229,6 +240,10 @@ ...@@ -229,6 +240,10 @@
Exp: <ph name="EXPIRATION_MONTH">$1<ex>06</ex></ph>/<ph name="EXPIRATION_YEAR">$2<ex>17</ex></ph> Exp: <ph name="EXPIRATION_MONTH">$1<ex>06</ex></ph>/<ph name="EXPIRATION_YEAR">$2<ex>17</ex></ph>
</message> </message>
<message name="IDS_AUTOFILL_CREDIT_CARD_EXPIRATION_DATE_LABEL_AND_ABBR" desc="text displayed in the Autofill Credit Card popup before the credit card expiration date and the abbreviated expiration date.">
, exp <ph name="EXPIRATION_DATE_ABBR">$1<ex>06/17</ex></ph>
</message>
<!-- Autofill credit card unmask prompt --> <!-- Autofill credit card unmask prompt -->
<message name="IDS_AUTOFILL_CARD_UNMASK_PROMPT_ERROR_TRY_AGAIN_CVC" desc="Error message that encourages the user to try to re-enter their credit card CVC after a previous failed attempt." formatter_data="android_java"> <message name="IDS_AUTOFILL_CARD_UNMASK_PROMPT_ERROR_TRY_AGAIN_CVC" desc="Error message that encourages the user to try to re-enter their credit card CVC after a previous failed attempt." formatter_data="android_java">
Check your CVC and try again Check your CVC and try again
......
...@@ -310,6 +310,10 @@ void PasswordAutofillManager::ClearPreviewedForm() { ...@@ -310,6 +310,10 @@ void PasswordAutofillManager::ClearPreviewedForm() {
password_manager_driver_->ClearPreviewedForm(); password_manager_driver_->ClearPreviewedForm();
} }
bool PasswordAutofillManager::IsCreditCardPopup() {
return false;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// PasswordAutofillManager, private: // PasswordAutofillManager, private:
......
...@@ -42,6 +42,7 @@ class PasswordAutofillManager : public autofill::AutofillPopupDelegate { ...@@ -42,6 +42,7 @@ class PasswordAutofillManager : public autofill::AutofillPopupDelegate {
base::string16* body) override; base::string16* body) override;
bool RemoveSuggestion(const base::string16& value, int identifier) override; bool RemoveSuggestion(const base::string16& value, int identifier) override;
void ClearPreviewedForm() override; void ClearPreviewedForm() override;
bool IsCreditCardPopup() override;
// Invoked when a password mapping is added. // Invoked when a password mapping is added.
void OnAddPasswordFormMapping( void OnAddPasswordFormMapping(
......
...@@ -44,7 +44,9 @@ public class SelectPopupDropdown implements SelectPopup { ...@@ -44,7 +44,9 @@ public class SelectPopupDropdown implements SelectPopup {
initialSelection = selected[0]; initialSelection = selected[0];
} }
mDropdownPopupWindow.setInitialSelection(initialSelection); mDropdownPopupWindow.setInitialSelection(initialSelection);
mDropdownPopupWindow.setAdapter(new DropdownAdapter(mContext, items, null)); mDropdownPopupWindow.setAdapter(new DropdownAdapter(
mContext, items, null /* separators */, null /* backgroundColor */,
null /* dividerColor */, null /* dropdownItemHeight */));
mDropdownPopupWindow.setRtl(rightAligned); mDropdownPopupWindow.setRtl(rightAligned);
mDropdownPopupWindow.setOnDismissListener( mDropdownPopupWindow.setOnDismissListener(
new PopupWindow.OnDismissListener() { new PopupWindow.OnDismissListener() {
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
android:orientation="horizontal" > android:orientation="horizontal" >
<!-- These layout params are overwritten in DropdownAdapter.java --> <!-- These layout params are overwritten in DropdownAdapter.java -->
<ImageView <ImageView
android:id="@+id/start_dropdown_icon" android:id="@+id/start_dropdown_icon"
android:layout_width="wrap_content" android:layout_width="wrap_content"
......
...@@ -30,14 +30,34 @@ public class DropdownAdapter extends ArrayAdapter<DropdownItem> { ...@@ -30,14 +30,34 @@ public class DropdownAdapter extends ArrayAdapter<DropdownItem> {
private final Context mContext; private final Context mContext;
private final Set<Integer> mSeparators; private final Set<Integer> mSeparators;
private final boolean mAreAllItemsEnabled; private final boolean mAreAllItemsEnabled;
private final Integer mBackgroundColor;
public DropdownAdapter( private final Integer mDividerColor;
Context context, List<? extends DropdownItem> items, Set<Integer> separators) { private final Integer mDropdownItemHeight;
/**
* Creates an {@code ArrayAdapter} with specified parameters.
* @param context Application context.
* @param items List of labels and icons to display.
* @param separators Set of positions that separate {@code items}.
* @param backgroundColor Popup background color, or {@code null} to use default background
* color. The default color is {@code Color.TRANSPARENT}.
* @param dividerColor If {@code null}, use the values in colors.xml for the divider
* between items. Otherwise, uses {@param dividerColor} for the divider between items. Always
* uses the values in colors.xml for the dark divider for the separators.
* @param dropdownItemHeight If {@code null}, uses the {@code dropdown_item_height} in
* dimens.xml. Otherwise, uses {@param dropdownItemHeight}.
*/
public DropdownAdapter(Context context, List<? extends DropdownItem> items,
Set<Integer> separators, Integer backgroundColor, Integer dividerColor,
Integer dropdownItemHeight) {
super(context, R.layout.dropdown_item); super(context, R.layout.dropdown_item);
mContext = context;
addAll(items); addAll(items);
mSeparators = separators; mSeparators = separators;
mContext = context;
mAreAllItemsEnabled = checkAreAllItemsEnabled(); mAreAllItemsEnabled = checkAreAllItemsEnabled();
mBackgroundColor = backgroundColor;
mDividerColor = dividerColor;
mDropdownItemHeight = dropdownItemHeight;
} }
private boolean checkAreAllItemsEnabled() { private boolean checkAreAllItemsEnabled() {
...@@ -57,25 +77,35 @@ public class DropdownAdapter extends ArrayAdapter<DropdownItem> { ...@@ -57,25 +77,35 @@ public class DropdownAdapter extends ArrayAdapter<DropdownItem> {
LayoutInflater inflater = LayoutInflater inflater =
(LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
layout = inflater.inflate(R.layout.dropdown_item, null); layout = inflater.inflate(R.layout.dropdown_item, null);
layout.setBackground(new DropdownDividerDrawable()); layout.setBackground(new DropdownDividerDrawable(mBackgroundColor));
} }
DropdownDividerDrawable divider = (DropdownDividerDrawable) layout.getBackground(); DropdownDividerDrawable divider = (DropdownDividerDrawable) layout.getBackground();
int height = mContext.getResources().getDimensionPixelSize(R.dimen.dropdown_item_height); int height;
if (mDropdownItemHeight == null) {
height = mContext.getResources().getDimensionPixelSize(R.dimen.dropdown_item_height);
} else {
height = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
mDropdownItemHeight, mContext.getResources().getDisplayMetrics());
}
if (position == 0) { if (position == 0) {
divider.setColor(Color.TRANSPARENT); divider.setDividerColor(Color.TRANSPARENT);
} else { } else {
int dividerHeight = mContext.getResources().getDimensionPixelSize( int dividerHeight = mContext.getResources().getDimensionPixelSize(
R.dimen.dropdown_item_divider_height); R.dimen.dropdown_item_divider_height);
height += dividerHeight; height += dividerHeight;
divider.setHeight(dividerHeight); divider.setHeight(dividerHeight);
int dividerColor;
if (mSeparators != null && mSeparators.contains(position)) { if (mSeparators != null && mSeparators.contains(position)) {
divider.setColor(ApiCompatibilityUtils.getColor(mContext.getResources(), dividerColor = ApiCompatibilityUtils.getColor(mContext.getResources(),
R.color.dropdown_dark_divider_color)); R.color.dropdown_dark_divider_color);
} else if (mDividerColor == null) {
dividerColor = ApiCompatibilityUtils.getColor(mContext.getResources(),
R.color.dropdown_divider_color);
} else { } else {
divider.setColor(ApiCompatibilityUtils.getColor(mContext.getResources(), dividerColor = mDividerColor;
R.color.dropdown_divider_color));
} }
divider.setDividerColor(dividerColor);
} }
DropdownItem item = getItem(position); DropdownItem item = getItem(position);
...@@ -113,7 +143,7 @@ public class DropdownAdapter extends ArrayAdapter<DropdownItem> { ...@@ -113,7 +143,7 @@ public class DropdownAdapter extends ArrayAdapter<DropdownItem> {
} }
labelView.setEnabled(item.isEnabled()); labelView.setEnabled(item.isEnabled());
if (item.isGroupHeader()) { if (item.isGroupHeader() || item.isBoldLabel()) {
labelView.setTypeface(null, Typeface.BOLD); labelView.setTypeface(null, Typeface.BOLD);
} else { } else {
labelView.setTypeface(null, Typeface.NORMAL); labelView.setTypeface(null, Typeface.NORMAL);
......
...@@ -13,16 +13,24 @@ import android.graphics.drawable.Drawable; ...@@ -13,16 +13,24 @@ import android.graphics.drawable.Drawable;
class DropdownDividerDrawable extends Drawable { class DropdownDividerDrawable extends Drawable {
private Paint mPaint; private final Paint mPaint;
private Rect mDividerRect; private final Rect mDividerRect;
private final Integer mBackgroundColor;
public DropdownDividerDrawable() {
/**
* Creates a drawable to draw a divider line that separates the list of {@link DropdownItem}
* and, optionally, paints the rectangular canvas.
* @param backgroundColor Popup background color. If {@code null}, does not paint the canvas.
*/
public DropdownDividerDrawable(Integer backgroundColor) {
mPaint = new Paint(); mPaint = new Paint();
mDividerRect = new Rect(); mDividerRect = new Rect();
mBackgroundColor = backgroundColor;
} }
@Override @Override
public void draw(Canvas canvas) { public void draw(Canvas canvas) {
if (mBackgroundColor != null) canvas.drawColor(mBackgroundColor);
canvas.drawRect(mDividerRect, mPaint); canvas.drawRect(mDividerRect, mPaint);
} }
...@@ -35,7 +43,7 @@ class DropdownDividerDrawable extends Drawable { ...@@ -35,7 +43,7 @@ class DropdownDividerDrawable extends Drawable {
mDividerRect.set(0, 0, mDividerRect.right, height); mDividerRect.set(0, 0, mDividerRect.right, height);
} }
public void setColor(int color) { public void setDividerColor(int color) {
mPaint.setColor(color); mPaint.setColor(color);
} }
......
...@@ -35,6 +35,10 @@ public interface DropdownItem { ...@@ -35,6 +35,10 @@ public interface DropdownItem {
* Returns whether the label should be displayed over multiple lines. * Returns whether the label should be displayed over multiple lines.
*/ */
boolean isMultilineLabel(); boolean isMultilineLabel();
/**
* Returns whether the label should be displayed in bold.
*/
boolean isBoldLabel();
/** /**
* Returns resource ID of label's font color. * Returns resource ID of label's font color.
*/ */
......
...@@ -39,6 +39,11 @@ public class DropdownItemBase implements DropdownItem { ...@@ -39,6 +39,11 @@ public class DropdownItemBase implements DropdownItem {
return false; return false;
} }
@Override
public boolean isBoldLabel() {
return false;
}
@Override @Override
public int getLabelFontColorResId() { public int getLabelFontColorResId() {
return R.drawable.dropdown_label_color; return R.drawable.dropdown_label_color;
......
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