[Autofill] Update suggestion UI to include offer message.

Includes a third line in the autofill popup suggestion UI, which will
include credit card offer data.

(cherry picked from commit edf32f6bbc794ea0da259eca8c6c9983406a3aba)

Bug: 1138956
Change-Id: I26b2c647a6dbe81ec367ff75dbdcc2074375b7fe
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2436849
Reviewed-by: Vasilii Sukhanov <[email protected]>
Reviewed-by: Siyu An <[email protected]>
Reviewed-by: Evan Stade <[email protected]>
Reviewed-by: Dominic Battré <[email protected]>
Commit-Queue: Manas Verma <[email protected]>
Cr-Original-Commit-Position: refs/heads/master@{#817528}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2485135
Reviewed-by: Manas Verma <[email protected]>
Cr-Commit-Position: refs/branch-heads/4280@{#502}
Cr-Branched-From: ea420fb963f9658c9969b6513c56b8f47efa1a2a-refs/heads/master@{#812852}
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc
index fae120b..80212002 100644
--- a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc
+++ b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc
@@ -70,6 +70,9 @@
 // The additional height of the row in case it has two lines of text.
 constexpr int kAutofillPopupAdditionalDoubleRowHeight = 22;
 
+// The additional padding of the row in case it has three lines of text.
+constexpr int kAutofillPopupAdditionalPadding = 16;
+
 // Vertical spacing between labels in one row.
 constexpr int kAdjacentLabelsVerticalSpacing = 2;
 
@@ -201,6 +204,17 @@
   return GetIconImageViewByName(suggestion.store_indicator_icon);
 }
 
+// Creates a label with a specific context and style.
+std::unique_ptr<views::Label> CreateLabelWithStyleAndContext(
+    const base::string16& text,
+    int text_context,
+    int text_style) {
+  auto label = std::make_unique<views::Label>(text, text_context, text_style);
+  label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+
+  return label;
+}
+
 }  // namespace
 
 namespace autofill {
@@ -273,20 +287,9 @@
   // Returns a value view. The label part is optional but allow caller to keep
   // track of all the labels for background color update.
   virtual ViewWithLabel CreateValueLabel();
-  // Creates an optional label below the value.
-  virtual ViewWithLabel CreateSubtextLabel();
   // The description view can be nullptr.
   virtual ViewWithLabel CreateDescriptionLabel();
 
-  // Creates a label matching the style of the description label.
-  std::unique_ptr<views::Label> CreateSecondaryLabel(
-      const base::string16& text) const;
-  // Creates a label with a specific context and style.
-  std::unique_ptr<views::Label> CreateLabelWithStyleAndContext(
-      const base::string16& text,
-      int text_context,
-      int text_style) const;
-
   // Returns the font weight to be applied to primary info.
   virtual gfx::Font::Weight GetPrimaryTextWeight() const = 0;
 
@@ -300,6 +303,13 @@
   }
 
  private:
+  // Returns a vector of optional labels to be displayed beneath value.
+  virtual std::vector<ViewWithLabel> CreateSubtextLabels();
+
+  // Returns the minimum cross axis size depending on the length of
+  // GetSubtexts();
+  void UpdateLayoutSize(views::BoxLayout* layout_manager, int64_t num_subtexts);
+
   const int frontend_id_;
 
   // All the labels inside this view.
@@ -321,7 +331,7 @@
   // AutofillPopupItemView:
   int GetPrimaryTextStyle() override;
   gfx::Font::Weight GetPrimaryTextWeight() const override;
-  ViewWithLabel CreateSubtextLabel() override;
+  std::vector<ViewWithLabel> CreateSubtextLabels() override;
   AutofillPopupSuggestionView(AutofillPopupViewNativeViews* popup_view,
                               int line_number,
                               int frontend_id);
@@ -342,7 +352,7 @@
  protected:
   // AutofillPopupItemView:
   ViewWithLabel CreateValueLabel() override;
-  ViewWithLabel CreateSubtextLabel() override;
+  std::vector<ViewWithLabel> CreateSubtextLabels() override;
   ViewWithLabel CreateDescriptionLabel() override;
   gfx::Font::Weight GetPrimaryTextWeight() const override;
 
@@ -451,6 +461,11 @@
     text.push_back(suggestion.label);
   }
 
+  if (!suggestion.offer_label.empty()) {
+    // |offer_label| is only populated for credit card suggestions.
+    text.push_back(suggestion.offer_label);
+  }
+
   if (!suggestion.additional_label.empty()) {
     // |additional_label| is only populated in a passwords context.
     text.push_back(suggestion.additional_label);
@@ -542,8 +557,8 @@
                       /*resize=*/false, layout_manager);
   }
 
-  ViewWithLabel lower_value_label = CreateSubtextLabel();
   ViewWithLabel value_label = CreateValueLabel();
+  std::vector<ViewWithLabel> subtext_labels = CreateSubtextLabels();
   ViewWithLabel description_label = CreateDescriptionLabel();
 
   std::unique_ptr<views::View> all_labels = std::make_unique<views::View>();
@@ -560,17 +575,12 @@
     grid_layout->SkipColumns(1);
   }
 
-  const int kStandardRowHeight =
-      views::MenuConfig::instance().touchable_menu_height;
-  if (lower_value_label.first) {
-    layout_manager->set_minimum_cross_axis_size(
-        kStandardRowHeight + kAutofillPopupAdditionalDoubleRowHeight);
+  UpdateLayoutSize(layout_manager, subtext_labels.size());
+  for (ViewWithLabel& subtext_label : subtext_labels) {
     grid_layout->StartRowWithPadding(0, 0, 0, kAdjacentLabelsVerticalSpacing);
-    grid_layout->AddView(std::move(lower_value_label.first));
-    KeepLabel(lower_value_label.second);
+    grid_layout->AddView(std::move(subtext_label.first));
+    KeepLabel(subtext_label.second);
     grid_layout->SkipColumns(1);
-  } else {
-    layout_manager->set_minimum_cross_axis_size(kStandardRowHeight);
   }
 
   AddChildView(std::move(all_labels));
@@ -618,7 +628,9 @@
           ->controller()
           ->GetSuggestionAt(line_number())
           .is_value_secondary) {
-    std::unique_ptr<views::Label> label = CreateSecondaryLabel(text);
+    std::unique_ptr<views::Label> label = CreateLabelWithStyleAndContext(
+        text, views::style::CONTEXT_DIALOG_BODY_TEXT,
+        views::style::STYLE_SECONDARY);
     view_and_label.second = label.get();
     view_and_label.first = std::move(label);
     return view_and_label;
@@ -640,31 +652,33 @@
 }
 
 AutofillPopupItemView::ViewWithLabel
-AutofillPopupItemView::CreateSubtextLabel() {
-  return ViewWithLabel();
-}
-
-AutofillPopupItemView::ViewWithLabel
 AutofillPopupItemView::CreateDescriptionLabel() {
   return ViewWithLabel();
 }
 
-std::unique_ptr<views::Label> AutofillPopupItemView::CreateSecondaryLabel(
-    const base::string16& text) const {
-  return CreateLabelWithStyleAndContext(text,
-                                        views::style::CONTEXT_DIALOG_BODY_TEXT,
-                                        views::style::STYLE_SECONDARY);
+std::vector<AutofillPopupItemView::ViewWithLabel>
+AutofillPopupItemView::CreateSubtextLabels() {
+  return {};
 }
 
-std::unique_ptr<views::Label>
-AutofillPopupItemView::CreateLabelWithStyleAndContext(
-    const base::string16& text,
-    int text_context,
-    int text_style) const {
-  auto label = std::make_unique<views::Label>(text, text_context, text_style);
-  label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+void AutofillPopupItemView::UpdateLayoutSize(views::BoxLayout* layout_manager,
+                                             int64_t num_subtexts) {
+  const int kStandardRowHeight =
+      views::MenuConfig::instance().touchable_menu_height;
+  if (num_subtexts == 0) {
+    layout_manager->set_minimum_cross_axis_size(kStandardRowHeight);
+  } else {
+    layout_manager->set_minimum_cross_axis_size(
+        kStandardRowHeight + kAutofillPopupAdditionalDoubleRowHeight);
+  }
 
-  return label;
+  // In the case that there are three rows in total, adding extra padding to
+  // avoid cramming.
+  if (num_subtexts == 2) {
+    layout_manager->set_inside_border_insets(
+        gfx::Insets(kAutofillPopupAdditionalPadding, GetHorizontalMargin(),
+                    kAutofillPopupAdditionalPadding, GetHorizontalMargin()));
+  }
 }
 
 void AutofillPopupItemView::AddSpacerWithSize(int spacer_width,
@@ -706,20 +720,29 @@
   SetFocusBehavior(FocusBehavior::ALWAYS);
 }
 
-AutofillPopupItemView::ViewWithLabel
-AutofillPopupSuggestionView::CreateSubtextLabel() {
-  base::string16 label_text =
+std::vector<AutofillPopupItemView::ViewWithLabel>
+AutofillPopupSuggestionView::CreateSubtextLabels() {
+  const base::string16& second_row_label =
       popup_view()->controller()->GetSuggestionAt(line_number()).label;
-  if (label_text.empty())
-    return ViewWithLabel();
+  const base::string16& third_row_label =
+      popup_view()->controller()->GetSuggestionAt(line_number()).offer_label;
 
-  auto label = CreateLabelWithStyleAndContext(
-      label_text, ChromeTextContext::CONTEXT_DIALOG_BODY_TEXT_SMALL,
-      views::style::STYLE_SECONDARY);
-  ViewWithLabel result;
-  result.second = label.get();
-  result.first = std::move(label);
-  return result;
+  std::vector<AutofillPopupItemView::ViewWithLabel> labels;
+  for (const base::string16& text : {second_row_label, third_row_label}) {
+    // If a row is missing, do not include any further rows.
+    if (text.empty())
+      return labels;
+
+    auto label = CreateLabelWithStyleAndContext(
+        text, ChromeTextContext::CONTEXT_DIALOG_BODY_TEXT_SMALL,
+        views::style::STYLE_SECONDARY);
+    ViewWithLabel result;
+    result.second = label.get();
+    result.first = std::move(label);
+    labels.emplace_back(std::move(result));
+  }
+
+  return labels;
 }
 
 /************** PasswordPopupSuggestionView **************/
@@ -742,15 +765,19 @@
   return label;
 }
 
-AutofillPopupItemView::ViewWithLabel
-PasswordPopupSuggestionView::CreateSubtextLabel() {
-  auto label = CreateSecondaryLabel(masked_password_);
+std::vector<AutofillPopupItemView::ViewWithLabel>
+PasswordPopupSuggestionView::CreateSubtextLabels() {
+  auto label = CreateLabelWithStyleAndContext(
+      masked_password_, views::style::CONTEXT_DIALOG_BODY_TEXT,
+      views::style::STYLE_SECONDARY);
   label->SetElideBehavior(gfx::TRUNCATE);
   ViewWithLabel result;
   result.second = label.get();
   result.first = std::make_unique<ConstrainedWidthView>(
       std::move(label), kAutofillPopupPasswordMaxWidth);
-  return result;
+  std::vector<AutofillPopupItemView::ViewWithLabel> labels;
+  labels.emplace_back(std::move(result));
+  return labels;
 }
 
 AutofillPopupItemView::ViewWithLabel
@@ -758,7 +785,9 @@
   if (origin_.empty())
     return ViewWithLabel();
 
-  auto label = CreateSecondaryLabel(origin_);
+  auto label = CreateLabelWithStyleAndContext(
+      origin_, views::style::CONTEXT_DIALOG_BODY_TEXT,
+      views::style::STYLE_SECONDARY);
   label->SetElideBehavior(gfx::ELIDE_HEAD);
   ViewWithLabel result;
   result.second = label.get();