[Web Payments] Add inline items to the Order Summary section.

BUG=698322

Review-Url: https://codereview.chromium.org/2730123002
Cr-Commit-Position: refs/heads/master@{#454943}
diff --git a/chrome/browser/ui/views/payments/order_summary_view_controller.cc b/chrome/browser/ui/views/payments/order_summary_view_controller.cc
index c2dc0896..15503c24 100644
--- a/chrome/browser/ui/views/payments/order_summary_view_controller.cc
+++ b/chrome/browser/ui/views/payments/order_summary_view_controller.cc
@@ -6,6 +6,7 @@
 
 #include <memory>
 #include <utility>
+#include <vector>
 
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
@@ -102,11 +103,6 @@
       views::BoxLayout::CROSS_AXIS_ALIGNMENT_STRETCH);
   content_view->SetLayoutManager(layout);
 
-  CurrencyFormatter* formatter = request()->GetOrCreateCurrencyFormatter(
-      request()->details()->total->amount->currency,
-      request()->details()->total->amount->currency_system,
-      g_browser_process->GetApplicationLocale());
-
   // Set the ID for the first few line items labels, for testing.
   const std::vector<DialogViewID> line_items{
       DialogViewID::ORDER_SUMMARY_LINE_ITEM_1,
@@ -118,7 +114,7 @@
     content_view->AddChildView(
         CreateLineItemView(
             base::UTF8ToUTF16(request()->details()->display_items[i]->label),
-            formatter->Format(
+            request()->GetFormattedCurrencyAmount(
                 request()->details()->display_items[i]->amount->value),
             false, view_id)
             .release());
@@ -127,7 +123,8 @@
   base::string16 total_label_value = l10n_util::GetStringFUTF16(
       IDS_PAYMENT_REQUEST_ORDER_SUMMARY_SHEET_TOTAL_FORMAT,
       base::UTF8ToUTF16(request()->details()->total->amount->currency),
-      formatter->Format(request()->details()->total->amount->value));
+      request()->GetFormattedCurrencyAmount(
+          request()->details()->total->amount->value));
 
   content_view->AddChildView(
       CreateLineItemView(base::UTF8ToUTF16(request()->details()->total->label),
diff --git a/chrome/browser/ui/views/payments/payment_request_views_util.cc b/chrome/browser/ui/views/payments/payment_request_views_util.cc
index 9df256a1..6e110bb 100644
--- a/chrome/browser/ui/views/payments/payment_request_views_util.cc
+++ b/chrome/browser/ui/views/payments/payment_request_views_util.cc
@@ -237,4 +237,13 @@
       gfx::Insets());
 }
 
+std::unique_ptr<views::Label> CreateBoldLabel(const base::string16& text) {
+  std::unique_ptr<views::Label> label = base::MakeUnique<views::Label>(text);
+
+  label->SetFontList(
+      label->font_list().DeriveWithWeight(gfx::Font::Weight::BOLD));
+
+  return label;
+}
+
 }  // namespace payments
diff --git a/chrome/browser/ui/views/payments/payment_request_views_util.h b/chrome/browser/ui/views/payments/payment_request_views_util.h
index e388009..a15adda 100644
--- a/chrome/browser/ui/views/payments/payment_request_views_util.h
+++ b/chrome/browser/ui/views/payments/payment_request_views_util.h
@@ -17,6 +17,7 @@
 namespace views {
 class Border;
 class ImageView;
+class Label;
 class VectorIconButtonDelegate;
 class View;
 }
@@ -84,6 +85,9 @@
 // as a separator between items in the Payment Request dialog.
 std::unique_ptr<views::Border> CreatePaymentRequestRowBorder();
 
+// Creates a label with a bold font.
+std::unique_ptr<views::Label> CreateBoldLabel(const base::string16& text);
+
 }  // namespace payments
 
 #endif  // CHROME_BROWSER_UI_VIEWS_PAYMENTS_PAYMENT_REQUEST_VIEWS_UTIL_H_
diff --git a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
index 8fbc5f0..80043e1 100644
--- a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
+++ b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
@@ -12,6 +12,7 @@
 
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/browser_process.h"
@@ -164,6 +165,25 @@
   return std::move(row);
 }
 
+// Creates a GridLayout object to be used in the Order Summary section's list of
+// items and the list of prices. |host| is the view that will be assigned the
+// returned Layout Manager and |trailing| indicates whether the elements added
+// to the manager should have trailing horizontal alignment. If trailing is
+// |false|, their horizontal alignment is leading.
+std::unique_ptr<views::GridLayout> CreateOrderSummarySectionContainerLayout(
+    views::View* host,
+    bool trailing) {
+  std::unique_ptr<views::GridLayout> layout =
+      base::MakeUnique<views::GridLayout>(host);
+
+  views::ColumnSet* columns = layout->AddColumnSet(0);
+  columns->AddColumn(
+      trailing ? views::GridLayout::TRAILING : views::GridLayout::LEADING,
+      views::GridLayout::LEADING, 1, views::GridLayout::USE_PREF, 0, 0);
+
+  return layout;
+}
+
 }  // namespace
 
 PaymentSheetViewController::PaymentSheetViewController(
@@ -288,33 +308,80 @@
   pay_button_->SetEnabled(enabled);
 }
 
-std::unique_ptr<views::View>
-PaymentSheetViewController::CreateOrderSummarySectionContent() {
-  CurrencyFormatter* formatter = request()->GetOrCreateCurrencyFormatter(
-      request()->details()->total->amount->currency,
-      request()->details()->total->amount->currency_system,
-      g_browser_process->GetApplicationLocale());
-  base::string16 label_value = l10n_util::GetStringFUTF16(
-      IDS_PAYMENT_REQUEST_ORDER_SUMMARY_SECTION_TOTAL_FORMAT,
-      base::UTF8ToUTF16(request()->details()->total->label),
-      base::UTF8ToUTF16(formatter->formatted_currency_code()),
-      formatter->Format(request()->details()->total->amount->value));
-
-  return base::MakeUnique<views::Label>(label_value);
-}
-
 // Creates the Order Summary row, which contains an "Order Summary" label,
-// a Total Amount label, and a Chevron.
+// an inline list of display items, a Total Amount label, and a Chevron.
 // +----------------------------------------------+
-// | Order Summary           Total USD $12.34   > |
+// | Order Summary   Item 1            $ 1.34     |
+// |                 Item 2            $ 2.00   > |
+// |                 2 more items...              |
+// |                 Total         USD $12.34     |
 // +----------------------------------------------+
 std::unique_ptr<views::Button>
 PaymentSheetViewController::CreatePaymentSheetSummaryRow() {
+  std::unique_ptr<views::View> item_summaries = base::MakeUnique<views::View>();
+  std::unique_ptr<views::GridLayout> item_summaries_layout =
+      CreateOrderSummarySectionContainerLayout(item_summaries.get(),
+                                               /* trailing =*/false);
+
+  std::unique_ptr<views::View> item_amounts = base::MakeUnique<views::View>();
+  std::unique_ptr<views::GridLayout> item_amounts_layout =
+      CreateOrderSummarySectionContainerLayout(item_amounts.get(),
+                                               /* trailing =*/true);
+
+  const std::vector<mojom::PaymentItemPtr>& items =
+      request()->details()->display_items;
+  // The inline items section contains the first 2 display items of the
+  // request's details, followed by a label indicating "N more items..." if
+  // there are more than 2 items in the details. The total label and amount
+  // always follow.
+  constexpr int kMaxNumberOfItemsShown = 2;
+  for (size_t i = 0; i < items.size() && i < kMaxNumberOfItemsShown; ++i) {
+    item_summaries_layout->StartRow(0, 0);
+    item_summaries_layout->AddView(
+        new views::Label(base::ASCIIToUTF16(items[i]->label)));
+
+    item_amounts_layout->StartRow(0, 0);
+    item_amounts_layout->AddView(new views::Label(
+        request()->GetFormattedCurrencyAmount(items[i]->amount->value)));
+  }
+
+  int hidden_item_count = items.size() - kMaxNumberOfItemsShown;
+  if (hidden_item_count > 0) {
+    item_summaries_layout->StartRow(0, 0);
+    std::unique_ptr<views::Label> label = base::MakeUnique<views::Label>(
+        l10n_util::GetStringFUTF16(IDS_PAYMENT_REQUEST_ORDER_SUMMARY_MORE_ITEMS,
+                                   base::IntToString16(hidden_item_count)));
+    label->SetDisabledColor(label->GetNativeTheme()->GetSystemColor(
+        ui::NativeTheme::kColorId_LabelDisabledColor));
+    label->SetEnabled(false);
+    item_summaries_layout->AddView(label.release());
+
+    item_amounts_layout->StartRow(0, 0);
+    item_amounts_layout->AddView(new views::Label(base::ASCIIToUTF16("")));
+  }
+
+  item_summaries_layout->StartRow(0, 0);
+  item_summaries_layout->AddView(
+      CreateBoldLabel(base::ASCIIToUTF16(request()->details()->total->label))
+          .release());
+
+  item_amounts_layout->StartRow(0, 0);
+  item_amounts_layout->AddView(
+      CreateBoldLabel(
+          l10n_util::GetStringFUTF16(
+              IDS_PAYMENT_REQUEST_ORDER_SUMMARY_SHEET_TOTAL_FORMAT,
+              base::UTF8ToUTF16(request()->GetFormattedCurrencyCode()),
+              request()->GetFormattedCurrencyAmount(
+                  request()->details()->total->amount->value)))
+          .release());
+
+  item_summaries->SetLayoutManager(item_summaries_layout.release());
+  item_amounts->SetLayoutManager(item_amounts_layout.release());
+
   std::unique_ptr<views::Button> section = CreatePaymentSheetRow(
       this,
       l10n_util::GetStringUTF16(IDS_PAYMENT_REQUEST_ORDER_SUMMARY_SECTION_NAME),
-      std::unique_ptr<views::View>(nullptr),
-      CreateOrderSummarySectionContent(),
+      std::move(item_summaries), std::move(item_amounts),
       widest_name_column_view_width_);
   section->set_tag(static_cast<int>(
       PaymentSheetViewControllerTags::SHOW_ORDER_SUMMARY_BUTTON));
diff --git a/chrome/browser/ui/views/payments/payment_sheet_view_controller.h b/chrome/browser/ui/views/payments/payment_sheet_view_controller.h
index 1e65dd1..6413afd 100644
--- a/chrome/browser/ui/views/payments/payment_sheet_view_controller.h
+++ b/chrome/browser/ui/views/payments/payment_sheet_view_controller.h
@@ -40,7 +40,6 @@
 
   void UpdatePayButtonState(bool enabled);
 
-  std::unique_ptr<views::View> CreateOrderSummarySectionContent();
   std::unique_ptr<views::View> CreateShippingSectionContent();
   std::unique_ptr<views::Button> CreateShippingRow();
   std::unique_ptr<views::Button> CreatePaymentSheetSummaryRow();
diff --git a/components/payments/content/payment_request.cc b/components/payments/content/payment_request.cc
index e55e68b..613bff17 100644
--- a/components/payments/content/payment_request.cc
+++ b/components/payments/content/payment_request.cc
@@ -135,6 +135,24 @@
   return currency_formatter_.get();
 }
 
+base::string16 PaymentRequest::GetFormattedCurrencyAmount(
+    const std::string& amount) {
+  CurrencyFormatter* formatter =
+      GetOrCreateCurrencyFormatter(details()->total->amount->currency,
+                                   details()->total->amount->currency_system,
+                                   delegate_->GetApplicationLocale());
+  return formatter->Format(amount);
+}
+
+std::string PaymentRequest::GetFormattedCurrencyCode() {
+  CurrencyFormatter* formatter =
+      GetOrCreateCurrencyFormatter(details()->total->amount->currency,
+                                   details()->total->amount->currency_system,
+                                   delegate_->GetApplicationLocale());
+
+  return formatter->formatted_currency_code();
+}
+
 void PaymentRequest::SetSelectedShippingProfile(
     autofill::AutofillProfile* profile) {
   selected_shipping_profile_ = profile;
diff --git a/components/payments/content/payment_request.h b/components/payments/content/payment_request.h
index 18d3f94..f947000 100644
--- a/components/payments/content/payment_request.h
+++ b/components/payments/content/payment_request.h
@@ -86,6 +86,14 @@
       const std::string& currency_system,
       const std::string& locale_name);
 
+  // Uses CurrencyFormatter to format |amount| with the currency symbol for this
+  // request's currency.
+  base::string16 GetFormattedCurrencyAmount(const std::string& amount);
+
+  // Uses CurrencyFormatter to get the formatted currency code for this
+  // request's currency.
+  std::string GetFormattedCurrencyCode();
+
   // Returns the appropriate Autofill Profiles for this user. On the first
   // invocation of either getter, the profiles are fetched from the
   // PersonalDataManager; on subsequent invocations, a cached version is
diff --git a/components/payments_strings.grdp b/components/payments_strings.grdp
index 5046856..e661419 100644
--- a/components/payments_strings.grdp
+++ b/components/payments_strings.grdp
@@ -176,6 +176,9 @@
   <message name="IDS_PAYMENT_REQUEST_ORDER_SUMMARY_SHEET_TOTAL_FORMAT" desc="The format specifier of the Total label in the Order Summary Sheet of the Payment Request dialog.">
     <ph name="CURRENCY_CODE">$1<ex>USD</ex></ph> <ph name="FORMATTED_TOTAL_AMOUNT">$2<ex>$ 12.34</ex></ph>
   </message>
+  <message name="IDS_PAYMENT_REQUEST_ORDER_SUMMARY_MORE_ITEMS" desc="The label in the Order Summary section of the Payment Sheet that indicates how many display items are hidden.">
+    <ph name="ITEM_COUNT">$1<ex>2</ex></ph> more items...
+  </message>
   <message name="IDS_PAYMENT_REQUEST_SHIPPING_SECTION_NAME" desc="The name of the Shipping Address section in the Payment Sheet of the Payment Request dialog.">
     Shipping address
   </message>