Initial implementation of the credit card assisted filling infobar.

On page load, this will prompt the user for automatic credit card filling. When user accepts the prompt, the credit card form is filled with their credit card data.

Several big TODOs:
* Opening a dialog to get the CVC (hoping to reuse PaymentRequest code)
* Only proposing the assist when the form is in the viewport.
* Offering more than 1 card in the infobar.

Mocks (internal): https://folio.googleplex.com/chrome-ux/mocks/304-payments-zero-integration/ZI_V2_Exploration/autofill-ahead-infobar#%2F06.png%3Fc=show

Video (public): https://drive.google.com/file/d/0B3xzZ-vFr2LRMW1yUkZDYWR4Um8/view?usp=sharing

BUG=630656
TEST=AssistManagerTest,AutofillCreditCardFillingInfoBarDelegateMobileTest

Review-Url: https://codereview.chromium.org/2026353002
Cr-Commit-Position: refs/heads/master@{#409841}
diff --git a/android_webview/native/aw_autofill_client.cc b/android_webview/native/aw_autofill_client.cc
index f149041..be7a4ae 100644
--- a/android_webview/native/aw_autofill_client.cc
+++ b/android_webview/native/aw_autofill_client.cc
@@ -242,6 +242,12 @@
   NOTIMPLEMENTED();
 }
 
+void AwAutofillClient::ConfirmCreditCardFillAssist(
+    const autofill::CreditCard& card,
+    const base::Closure& callback) {
+  NOTIMPLEMENTED();
+}
+
 void AwAutofillClient::LoadRiskData(
     const base::Callback<void(const std::string&)>& callback) {
   NOTIMPLEMENTED();
diff --git a/android_webview/native/aw_autofill_client.h b/android_webview/native/aw_autofill_client.h
index ca4119d..ec350f5 100644
--- a/android_webview/native/aw_autofill_client.h
+++ b/android_webview/native/aw_autofill_client.h
@@ -78,6 +78,8 @@
       const autofill::CreditCard& card,
       std::unique_ptr<base::DictionaryValue> legal_message,
       const base::Closure& callback) override;
+  void ConfirmCreditCardFillAssist(const autofill::CreditCard& card,
+                                   const base::Closure& callback) override;
   void LoadRiskData(
       const base::Callback<void(const std::string&)>& callback) override;
   bool HasCreditCardScanFeature() override;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AutofillCreditCardFillingInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AutofillCreditCardFillingInfoBar.java
new file mode 100644
index 0000000..b34ca865
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AutofillCreditCardFillingInfoBar.java
@@ -0,0 +1,84 @@
+// Copyright 2016 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.infobar;
+
+import android.graphics.Bitmap;
+
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.chrome.browser.ResourceId;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * An infobar for assisted credit card filling.
+ */
+public class AutofillCreditCardFillingInfoBar extends ConfirmInfoBar {
+    private final List<CardDetail> mCardDetails = new ArrayList<>();
+
+    /**
+     * Creates a new instance of the infobar.
+     *
+     * @param nativeAutofillCreditCardFillingInfoBar The pointer to the native object for callbacks.
+     * @param enumeratedIconId ID corresponding to the icon that will be shown for the InfoBar.
+     *                         The ID must have been mapped using the ResourceMapper class before
+     *                         passing it to this function.
+     * @param iconBitmap Bitmap to use if there is no equivalent Java resource for enumeratedIconId.
+     * @param message Message to display to the user indicating what the InfoBar is for.
+     * @param buttonOk String to display on the OK button.
+     * @param buttonCancel String to display on the Cancel button.
+     */
+    private AutofillCreditCardFillingInfoBar(long nativeAutofillCreditCardFillingInfoBar,
+            int enumeratedIconId, Bitmap iconBitmap, String message, String buttonOk,
+            String buttonCancel) {
+        super(ResourceId.mapToDrawableId(enumeratedIconId), iconBitmap, message, null, buttonOk,
+                buttonCancel);
+    }
+
+    /**
+     * Creates an infobar for assisted credit card filling.
+     *
+     * @param nativeAutofillCreditCardFillingInfoBar The pointer to the native object for callbacks.
+     * @param enumeratedIconId ID corresponding to the icon that will be shown for the InfoBar.
+     *                         The ID must have been mapped using the ResourceMapper class before
+     *                         passing it to this function.
+     * @param iconBitmap Bitmap to use if there is no equivalent Java resource for enumeratedIconId.
+     * @param message Message to display to the user indicating what the InfoBar is for.
+     * @param buttonOk String to display on the OK button.
+     * @param buttonCancel String to display on the Cancel button.
+     * @return A new instance of the infobar.
+     */
+    @CalledByNative
+    private static AutofillCreditCardFillingInfoBar create(
+            long nativeAutofillCreditCardFillingInfoBar, int enumeratedIconId, Bitmap iconBitmap,
+            String message, String buttonOk, String buttonCancel) {
+        return new AutofillCreditCardFillingInfoBar(nativeAutofillCreditCardFillingInfoBar,
+                enumeratedIconId, iconBitmap, message, buttonOk, buttonCancel);
+    }
+
+    /**
+     * Adds information to the infobar about the credit card that will be proposed for the assist.
+     *
+     * @param enumeratedIconId ID corresponding to the icon that will be shown for this credit card.
+     *                         The ID must have been mapped using the ResourceMapper class before
+     *                         passing it to this function.
+     * @param label The credit card label, for example "***1234".
+     * @param subLabel The credit card sub-label, for example "Exp: 06/17".
+     */
+    @CalledByNative
+    private void addDetail(int enumeratedIconId, String label, String subLabel) {
+        mCardDetails.add(new CardDetail(enumeratedIconId, label, subLabel));
+    }
+
+    @Override
+    public void createContent(InfoBarLayout layout) {
+        super.createContent(layout);
+        InfoBarControlLayout control = layout.addControlLayout();
+        for (int i = 0; i < mCardDetails.size(); i++) {
+            CardDetail detail = mCardDetails.get(i);
+            control.addIcon(detail.issuerIconDrawableId, 0, detail.label, detail.subLabel);
+        }
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AutofillSaveCardInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AutofillSaveCardInfoBar.java
index d4d09b5..151a58d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/AutofillSaveCardInfoBar.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/AutofillSaveCardInfoBar.java
@@ -13,6 +13,7 @@
 import org.chromium.base.annotations.CalledByNative;
 import org.chromium.chrome.browser.ResourceId;
 
+import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
 
@@ -21,41 +22,6 @@
  */
 public class AutofillSaveCardInfoBar extends ConfirmInfoBar {
     /**
-     * Detailed card information to show in the infobar.
-     */
-    public static class CardDetail {
-        /**
-         * The identifier of the drawable of the card issuer icon.
-         */
-        public int issuerIconDrawableId;
-
-        /**
-         * The label for the card.
-         */
-        public String label;
-
-        /**
-         * The sub-label for the card.
-         */
-        public String subLabel;
-
-        /**
-         * Creates a new instance of the detailed card information.
-         *
-         * @param enumeratedIconId ID corresponding to the icon that will be shown for this credit
-         *                         card. The ID must have been mapped using the ResourceMapper class
-         *                         before passing it to this function.
-         * @param label The credit card label, for example "***1234".
-         * @param subLabel The credit card sub-label, for example "Exp: 06/17".
-         */
-        public CardDetail(int enumeratedIconId, String label, String subLabel) {
-            this.issuerIconDrawableId = ResourceId.mapToDrawableId(enumeratedIconId);
-            this.label = label;
-            this.subLabel = subLabel;
-        }
-    }
-
-    /**
      * Legal message line with links to show in the infobar.
      */
     public static class LegalMessageLine {
@@ -113,7 +79,7 @@
     }
 
     private final long mNativeAutofillSaveCardInfoBar;
-    private final List<CardDetail> mCardDetails = new LinkedList<CardDetail>();
+    private final List<CardDetail> mCardDetails = new ArrayList<>();
     private final LinkedList<LegalMessageLine> mLegalMessageLines =
             new LinkedList<LegalMessageLine>();
 
@@ -200,7 +166,8 @@
     public void createContent(InfoBarLayout layout) {
         super.createContent(layout);
         InfoBarControlLayout control = layout.addControlLayout();
-        for (CardDetail detail : mCardDetails) {
+        for (int i = 0; i < mCardDetails.size(); i++) {
+            CardDetail detail = mCardDetails.get(i);
             control.addIcon(detail.issuerIconDrawableId, 0, detail.label, detail.subLabel);
         }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/CardDetail.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/CardDetail.java
new file mode 100644
index 0000000..4a20552c
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/CardDetail.java
@@ -0,0 +1,42 @@
+// Copyright 2016 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.infobar;
+
+import org.chromium.chrome.browser.ResourceId;
+
+/**
+ * Detailed card information to show in the various Autofill infobars.
+ */
+public class CardDetail {
+    /**
+     * The identifier of the drawable of the card issuer icon.
+     */
+    public int issuerIconDrawableId;
+
+    /**
+     * The label for the card.
+     */
+    public String label;
+
+    /**
+     * The sub-label for the card.
+     */
+    public String subLabel;
+
+    /**
+     * Creates a new instance of the detailed card information.
+     *
+     * @param enumeratedIconId ID corresponding to the icon that will be shown for this credit
+     *                         card. The ID must have been mapped using the ResourceMapper class
+     *                         before passing it to this function.
+     * @param label The credit card label, for example "***1234".
+     * @param subLabel The credit card sub-label, for example "Exp: 06/17".
+     */
+    public CardDetail(int enumeratedIconId, String label, String subLabel) {
+        this.issuerIconDrawableId = ResourceId.mapToDrawableId(enumeratedIconId);
+        this.label = label;
+        this.subLabel = subLabel;
+    }
+}
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index 6f8c6db..f945f167 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -383,7 +383,9 @@
   "java/src/org/chromium/chrome/browser/incognito/IncognitoNotificationService.java",
   "java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarAndroid.java",
   "java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarDelegateAndroid.java",
+  "java/src/org/chromium/chrome/browser/infobar/AutofillCreditCardFillingInfoBar.java",
   "java/src/org/chromium/chrome/browser/infobar/AutofillSaveCardInfoBar.java",
+  "java/src/org/chromium/chrome/browser/infobar/CardDetail.java",
   "java/src/org/chromium/chrome/browser/infobar/ConfirmInfoBar.java",
   "java/src/org/chromium/chrome/browser/infobar/DataReductionPromoInfoBar.java",
   "java/src/org/chromium/chrome/browser/infobar/DataReductionPromoInfoBarDelegate.java",
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 54438e4..1fad3466 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -13522,6 +13522,14 @@
         </message>
       </if>
 
+      <!-- Strings for controlling credit card assist feature in about:flags. -->
+      <message name="IDS_FLAGS_CREDIT_CARD_ASSIST_NAME" desc="The name of about:flags option to enable the credit card assisted filling.">
+        Credit Card Assisted Filling
+      </message>
+      <message name="IDS_FLAGS_CREDIT_CARD_ASSIST_DESCRIPTION" desc="The description of about:flags option to enable the credit card assisted filling..">
+        Enable assisted credit card filling on certain sites.
+      </message>
+
       <!-- Strings for controlling credit card scanning feature in about:flags. -->
       <message name="IDS_FLAGS_CREDIT_CARD_SCAN_NAME" desc="The name of about:flags option to enable scanning of credit cards using device camera.">
         Credit card scanning
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index f7887bb..8bd203f 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -1499,6 +1499,13 @@
     {"disable-new-zip-unpacker", IDS_FLAGS_NEW_ZIP_UNPACKER_NAME,
      IDS_FLAGS_NEW_ZIP_UNPACKER_DESCRIPTION, kOsCrOS,
      SINGLE_DISABLE_VALUE_TYPE(chromeos::switches::kDisableNewZIPUnpacker)},
+#endif  // defined(OS_CHROMEOS)
+#if defined(OS_ANDROID)
+    {"enable-credit-card-assist", IDS_FLAGS_CREDIT_CARD_ASSIST_NAME,
+     IDS_FLAGS_CREDIT_CARD_ASSIST_DESCRIPTION, kOsAndroid,
+     FEATURE_VALUE_TYPE(autofill::kAutofillCreditCardAssist)},
+#endif  // defined(OS_ANDROID)
+#if defined(OS_CHROMEOS)
     {"disable-captive-portal-bypass-proxy",
      IDS_FLAGS_CAPTIVE_PORTAL_BYPASS_PROXY_NAME,
      IDS_FLAGS_CAPTIVE_PORTAL_BYPASS_PROXY_DESCRIPTION, kOsCrOS,
diff --git a/chrome/browser/android/chrome_jni_registrar.cc b/chrome/browser/android/chrome_jni_registrar.cc
index b0d717c..c93b323 100644
--- a/chrome/browser/android/chrome_jni_registrar.cc
+++ b/chrome/browser/android/chrome_jni_registrar.cc
@@ -134,6 +134,7 @@
 #include "chrome/browser/ui/android/chrome_http_auth_handler.h"
 #include "chrome/browser/ui/android/connection_info_popup_android.h"
 #include "chrome/browser/ui/android/context_menu_helper.h"
+#include "chrome/browser/ui/android/infobars/app_banner_infobar_android.h"
 #include "chrome/browser/ui/android/infobars/autofill_save_card_infobar.h"
 #include "chrome/browser/ui/android/infobars/grouped_permission_infobar.h"
 #include "chrome/browser/ui/android/infobars/infobar_android.h"
diff --git a/chrome/browser/autofill/autofill_credit_card_filling_infobar_delegate_mobile_unittest.cc b/chrome/browser/autofill/autofill_credit_card_filling_infobar_delegate_mobile_unittest.cc
new file mode 100644
index 0000000..a3eabe1
--- /dev/null
+++ b/chrome/browser/autofill/autofill_credit_card_filling_infobar_delegate_mobile_unittest.cc
@@ -0,0 +1,113 @@
+// Copyright 2016 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.
+
+#include "components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.h"
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/test/histogram_tester.h"
+#include "chrome/test/base/chrome_render_view_host_test_harness.h"
+#include "components/autofill/core/browser/autofill_test_utils.h"
+#include "components/infobars/core/confirm_infobar_delegate.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace autofill {
+
+class AutofillCreditCardFillingInfoBarDelegateMobileTest
+    : public ChromeRenderViewHostTestHarness {
+ public:
+  AutofillCreditCardFillingInfoBarDelegateMobileTest()
+      : infobar_callback_has_run_(false) {}
+  ~AutofillCreditCardFillingInfoBarDelegateMobileTest() override {}
+
+ protected:
+  std::unique_ptr<AutofillCreditCardFillingInfoBarDelegateMobile>
+  CreateDelegate();
+
+  void AcceptInfoBarCallback() { infobar_callback_has_run_ = true; }
+
+  bool infobar_callback_has_run_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(AutofillCreditCardFillingInfoBarDelegateMobileTest);
+};
+
+std::unique_ptr<AutofillCreditCardFillingInfoBarDelegateMobile>
+AutofillCreditCardFillingInfoBarDelegateMobileTest::CreateDelegate() {
+  infobar_callback_has_run_ = false;
+  CreditCard credit_card;
+  std::unique_ptr<AutofillCreditCardFillingInfoBarDelegateMobile> delegate(
+      new AutofillCreditCardFillingInfoBarDelegateMobile(
+          credit_card,
+          base::Bind(&AutofillCreditCardFillingInfoBarDelegateMobileTest::
+                         AcceptInfoBarCallback,
+                     base::Unretained(this))));
+  delegate->set_was_shown();
+  return delegate;
+}
+
+// Test that credit card infobar metrics are logged correctly.
+TEST_F(AutofillCreditCardFillingInfoBarDelegateMobileTest, Metrics) {
+  // Accept the infobar.
+  {
+    std::unique_ptr<AutofillCreditCardFillingInfoBarDelegateMobile> infobar(
+        CreateDelegate());
+
+    base::HistogramTester histogram_tester;
+    EXPECT_TRUE(infobar->Accept());
+    EXPECT_TRUE(infobar_callback_has_run_);
+    histogram_tester.ExpectBucketCount("Autofill.CreditCardFillingInfoBar",
+                                       AutofillMetrics::INFOBAR_ACCEPTED, 1);
+    infobar.reset();
+    histogram_tester.ExpectBucketCount("Autofill.CreditCardFillingInfoBar",
+                                       AutofillMetrics::INFOBAR_SHOWN, 1);
+  }
+
+  // Cancel the infobar.
+  {
+    std::unique_ptr<AutofillCreditCardFillingInfoBarDelegateMobile> infobar(
+        CreateDelegate());
+
+    base::HistogramTester histogram_tester;
+    EXPECT_TRUE(infobar->Cancel());
+    EXPECT_FALSE(infobar_callback_has_run_);
+    histogram_tester.ExpectBucketCount("Autofill.CreditCardFillingInfoBar",
+                                       AutofillMetrics::INFOBAR_DENIED, 1);
+    infobar.reset();
+    histogram_tester.ExpectBucketCount("Autofill.CreditCardFillingInfoBar",
+                                       AutofillMetrics::INFOBAR_SHOWN, 1);
+  }
+
+  // Dismiss the infobar.
+  {
+    std::unique_ptr<AutofillCreditCardFillingInfoBarDelegateMobile> infobar(
+        CreateDelegate());
+
+    base::HistogramTester histogram_tester;
+    infobar->InfoBarDismissed();
+    EXPECT_FALSE(infobar_callback_has_run_);
+    histogram_tester.ExpectBucketCount("Autofill.CreditCardFillingInfoBar",
+                                       AutofillMetrics::INFOBAR_DENIED, 1);
+    infobar.reset();
+    histogram_tester.ExpectBucketCount("Autofill.CreditCardFillingInfoBar",
+                                       AutofillMetrics::INFOBAR_SHOWN, 1);
+  }
+
+  // Ignore the infobar.
+  {
+    std::unique_ptr<AutofillCreditCardFillingInfoBarDelegateMobile> infobar(
+        CreateDelegate());
+
+    base::HistogramTester histogram_tester;
+    infobar.reset();
+    EXPECT_FALSE(infobar_callback_has_run_);
+    histogram_tester.ExpectBucketCount("Autofill.CreditCardFillingInfoBar",
+                                       AutofillMetrics::INFOBAR_SHOWN, 1);
+    histogram_tester.ExpectBucketCount("Autofill.CreditCardFillingInfoBar",
+                                       AutofillMetrics::INFOBAR_IGNORED, 1);
+  }
+}
+
+}  // namespace autofill
diff --git a/chrome/browser/ui/android/infobars/autofill_credit_card_filling_infobar.cc b/chrome/browser/ui/android/infobars/autofill_credit_card_filling_infobar.cc
new file mode 100644
index 0000000..47c5b27
--- /dev/null
+++ b/chrome/browser/ui/android/infobars/autofill_credit_card_filling_infobar.cc
@@ -0,0 +1,61 @@
+// Copyright 2016 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.
+
+#include "chrome/browser/ui/android/infobars/autofill_credit_card_filling_infobar.h"
+
+#include <utility>
+
+#include "base/android/jni_android.h"
+#include "base/android/jni_string.h"
+#include "base/memory/ptr_util.h"
+#include "chrome/browser/android/resource_mapper.h"
+#include "chrome/browser/infobars/infobar_service.h"
+#include "components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.h"
+#include "jni/AutofillCreditCardFillingInfoBar_jni.h"
+#include "ui/gfx/android/java_bitmap.h"
+#include "ui/gfx/image/image.h"
+#include "url/gurl.h"
+
+AutofillCreditCardFillingInfoBar::AutofillCreditCardFillingInfoBar(
+    std::unique_ptr<autofill::AutofillCreditCardFillingInfoBarDelegateMobile>
+        delegate)
+    : ConfirmInfoBar(std::move(delegate)) {}
+
+AutofillCreditCardFillingInfoBar::~AutofillCreditCardFillingInfoBar() {}
+
+base::android::ScopedJavaLocalRef<jobject>
+AutofillCreditCardFillingInfoBar::CreateRenderInfoBar(JNIEnv* env) {
+  autofill::AutofillCreditCardFillingInfoBarDelegateMobile* delegate =
+      static_cast<autofill::AutofillCreditCardFillingInfoBarDelegateMobile*>(
+          GetDelegate());
+  ScopedJavaLocalRef<jobject> java_bitmap;
+  if (delegate->GetIconId() == infobars::InfoBarDelegate::kNoIconID &&
+      !delegate->GetIcon().IsEmpty()) {
+    java_bitmap = gfx::ConvertToJavaBitmap(delegate->GetIcon().ToSkBitmap());
+  }
+
+  base::android::ScopedJavaLocalRef<jobject> java_delegate =
+      Java_AutofillCreditCardFillingInfoBar_create(
+          env, reinterpret_cast<intptr_t>(this), GetEnumeratedIconId(),
+          java_bitmap.obj(),
+          base::android::ConvertUTF16ToJavaString(
+              env, delegate->GetMessageText())
+              .obj(),
+          base::android::ConvertUTF16ToJavaString(
+              env, GetTextFor(ConfirmInfoBarDelegate::BUTTON_OK))
+              .obj(),
+          base::android::ConvertUTF16ToJavaString(
+              env, GetTextFor(ConfirmInfoBarDelegate::BUTTON_CANCEL))
+              .obj());
+
+  Java_AutofillCreditCardFillingInfoBar_addDetail(
+      env, java_delegate.obj(),
+      ResourceMapper::MapFromChromiumId(delegate->issuer_icon_id()),
+      base::android::ConvertUTF16ToJavaString(env, delegate->card_label())
+          .obj(),
+      base::android::ConvertUTF16ToJavaString(env, delegate->card_sub_label())
+          .obj());
+
+  return java_delegate;
+}
diff --git a/chrome/browser/ui/android/infobars/autofill_credit_card_filling_infobar.h b/chrome/browser/ui/android/infobars/autofill_credit_card_filling_infobar.h
new file mode 100644
index 0000000..8a2a8d3
--- /dev/null
+++ b/chrome/browser/ui/android/infobars/autofill_credit_card_filling_infobar.h
@@ -0,0 +1,38 @@
+// Copyright 2016 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.
+
+#ifndef CHROME_BROWSER_UI_ANDROID_INFOBARS_AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_H_
+#define CHROME_BROWSER_UI_ANDROID_INFOBARS_AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_H_
+
+#include <jni.h>
+
+#include <memory>
+
+#include "base/macros.h"
+#include "chrome/browser/ui/android/infobars/confirm_infobar.h"
+
+namespace autofill {
+class AutofillCreditCardFillingInfoBarDelegateMobile;
+}
+
+// Android implementation of the infobar for credit card assisted filling, which
+// proposes to autofill user data into the detected credit card form in the
+// page. Upon accepting the infobar, the form is filled automatically. If
+// the infobar is dismissed, nothing happens.
+class AutofillCreditCardFillingInfoBar : public ConfirmInfoBar {
+ public:
+  explicit AutofillCreditCardFillingInfoBar(
+      std::unique_ptr<autofill::AutofillCreditCardFillingInfoBarDelegateMobile>
+          delegate);
+  ~AutofillCreditCardFillingInfoBar() override;
+
+ private:
+  // ConfirmInfoBar:
+  base::android::ScopedJavaLocalRef<jobject> CreateRenderInfoBar(
+      JNIEnv* env) override;
+
+  DISALLOW_COPY_AND_ASSIGN(AutofillCreditCardFillingInfoBar);
+};
+
+#endif  // CHROME_BROWSER_UI_ANDROID_INFOBARS_AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_H_
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.cc b/chrome/browser/ui/autofill/chrome_autofill_client.cc
index e9d8756..b071971 100644
--- a/chrome/browser/ui/autofill/chrome_autofill_client.cc
+++ b/chrome/browser/ui/autofill/chrome_autofill_client.cc
@@ -14,7 +14,6 @@
 #include "chrome/browser/autofill/personal_data_manager_factory.h"
 #include "chrome/browser/autofill/risk_util.h"
 #include "chrome/browser/browser_process.h"
-#include "chrome/browser/infobars/infobar_service.h"
 #include "chrome/browser/password_manager/chrome_password_manager_client.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
@@ -62,6 +61,9 @@
 #if defined(OS_ANDROID)
 #include "base/android/context_utils.h"
 #include "chrome/browser/android/signin/signin_promo_util_android.h"
+#include "chrome/browser/infobars/infobar_service.h"
+#include "chrome/browser/ui/android/infobars/autofill_credit_card_filling_infobar.h"
+#include "components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.h"
 #include "components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.h"
 #include "components/autofill/core/browser/autofill_save_card_infobar_mobile.h"
 #include "components/infobars/core/infobar.h"
@@ -211,6 +213,22 @@
 #endif
 }
 
+void ChromeAutofillClient::ConfirmCreditCardFillAssist(
+    const CreditCard& card,
+    const base::Closure& callback) {
+#if defined(OS_ANDROID)
+  auto infobar_delegate =
+      base::MakeUnique<AutofillCreditCardFillingInfoBarDelegateMobile>(
+          card, callback);
+  auto* raw_delegate = infobar_delegate.get();
+  if (InfoBarService::FromWebContents(web_contents())->AddInfoBar(
+          base::MakeUnique<AutofillCreditCardFillingInfoBar>(
+              std::move(infobar_delegate)))) {
+    raw_delegate->set_was_shown();
+  }
+#endif
+}
+
 void ChromeAutofillClient::LoadRiskData(
     const base::Callback<void(const std::string&)>& callback) {
   ::autofill::LoadRiskData(0, web_contents(), callback);
diff --git a/chrome/browser/ui/autofill/chrome_autofill_client.h b/chrome/browser/ui/autofill/chrome_autofill_client.h
index 81791fc..70fda229 100644
--- a/chrome/browser/ui/autofill/chrome_autofill_client.h
+++ b/chrome/browser/ui/autofill/chrome_autofill_client.h
@@ -58,6 +58,8 @@
       const CreditCard& card,
       std::unique_ptr<base::DictionaryValue> legal_message,
       const base::Closure& callback) override;
+  void ConfirmCreditCardFillAssist(const CreditCard& card,
+                                   const base::Closure& callback) override;
   void LoadRiskData(
       const base::Callback<void(const std::string&)>& callback) override;
   bool HasCreditCardScanFeature() override;
diff --git a/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.mm b/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.mm
index 46bf2f6e..051bd0b 100644
--- a/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.mm
+++ b/chrome/browser/ui/cocoa/autofill/save_card_bubble_view_bridge.mm
@@ -284,7 +284,7 @@
 
   // Cancel button.
   base::scoped_nsobject<NSButton> cancelButton([SaveCardBubbleViewCocoa
-      makeButton:l10n_util::GetNSString(IDS_AUTOFILL_SAVE_CARD_PROMPT_DENY)]);
+      makeButton:l10n_util::GetNSString(IDS_NO_THANKS)]);
   [cancelButton setTarget:self];
   [cancelButton setAction:@selector(onCancelButton:)];
   [cancelButton setKeyEquivalent:@"\e"];
diff --git a/chrome/browser/ui/views/autofill/save_card_bubble_views.cc b/chrome/browser/ui/views/autofill/save_card_bubble_views.cc
index 09c8f60..40e964d 100644
--- a/chrome/browser/ui/views/autofill/save_card_bubble_views.cc
+++ b/chrome/browser/ui/views/autofill/save_card_bubble_views.cc
@@ -119,7 +119,7 @@
     ui::DialogButton button) const {
   return l10n_util::GetStringUTF16(button == ui::DIALOG_BUTTON_OK
                                        ? IDS_AUTOFILL_SAVE_CARD_PROMPT_ACCEPT
-                                       : IDS_AUTOFILL_SAVE_CARD_PROMPT_DENY);
+                                       : IDS_NO_THANKS);
 }
 
 bool SaveCardBubbleViews::ShouldDefaultButtonBeBlue() const {
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 450c826..0de83b5 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -2120,6 +2120,7 @@
       'android/java/src/org/chromium/chrome/browser/WebContentsFactory.java',
       'android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarAndroid.java',
       'android/java/src/org/chromium/chrome/browser/infobar/AppBannerInfoBarDelegateAndroid.java',
+      'android/java/src/org/chromium/chrome/browser/infobar/AutofillCreditCardFillingInfoBar.java',
       'android/java/src/org/chromium/chrome/browser/infobar/AutofillSaveCardInfoBar.java',
       'android/java/src/org/chromium/chrome/browser/infobar/ConfirmInfoBar.java',
       'android/java/src/org/chromium/chrome/browser/infobar/DataReductionPromoInfoBarDelegate.java',
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi
index 6908eef..f7e01f03 100644
--- a/chrome/chrome_browser_ui.gypi
+++ b/chrome/chrome_browser_ui.gypi
@@ -429,6 +429,8 @@
       'browser/ui/android/context_menu_helper.h',
       'browser/ui/android/infobars/app_banner_infobar_android.cc',
       'browser/ui/android/infobars/app_banner_infobar_android.h',
+      'browser/ui/android/infobars/autofill_credit_card_filling_infobar.cc',
+      'browser/ui/android/infobars/autofill_credit_card_filling_infobar.h',
       'browser/ui/android/infobars/autofill_save_card_infobar.cc',
       'browser/ui/android/infobars/autofill_save_card_infobar.h',
       'browser/ui/android/infobars/confirm_infobar.cc',
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index e6d7f1d..0190250a 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -359,6 +359,7 @@
       '../tools/json_schema_compiler/test/simple_api_unittest.cc',
     ],
     'chrome_unit_tests_android_sources': [
+      'browser/autofill/autofill_credit_card_filling_infobar_delegate_mobile_unittest.cc',
       'browser/autofill/autofill_save_card_infobar_delegate_mobile_unittest.cc',
       'browser/password_manager/account_chooser_dialog_android_unittest.cc',
       'browser/password_manager/auto_signin_first_run_dialog_android_unittest.cc',
diff --git a/components/autofill.gypi b/components/autofill.gypi
index faa823a..860ae23 100644
--- a/components/autofill.gypi
+++ b/components/autofill.gypi
@@ -252,6 +252,14 @@
           'sources': [
             'autofill/core/browser/keyboard_accessory_metrics_logger.h',
             'autofill/core/browser/keyboard_accessory_metrics_logger.mm',
+        ],
+        }],
+        ['OS=="android"', {
+          'sources': [
+            'autofill/core/browser/autofill_assistant.cc',
+            'autofill/core/browser/autofill_assistant.h',
+            'autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.cc',
+            'autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.h',
           ],
         }],
         ['OS=="ios" or OS=="android"', {
@@ -296,6 +304,7 @@
         '../testing/gtest.gyp:gtest',
         'autofill_core_common',
         'autofill_core_browser',
+        'infobars',
         'os_crypt',
         'pref_registry',
         'prefs/prefs.gyp:prefs',
diff --git a/components/autofill/content/renderer/autofill_agent.cc b/components/autofill/content/renderer/autofill_agent.cc
index 9f32ae8..0a17887 100644
--- a/components/autofill/content/renderer/autofill_agent.cc
+++ b/components/autofill/content/renderer/autofill_agent.cc
@@ -468,7 +468,7 @@
 }
 
 void AutofillAgent::FillForm(int32_t id, const FormData& form) {
-  if (id != autofill_query_id_)
+  if (id != autofill_query_id_ && id != kNoQueryId)
     return;
 
   was_query_node_autofilled_ = element_.isAutofilled();
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn
index e9d6016..6643319 100644
--- a/components/autofill/core/browser/BUILD.gn
+++ b/components/autofill/core/browser/BUILD.gn
@@ -152,6 +152,15 @@
     ]
   }
 
+  if (is_android) {
+    sources += [
+      "autofill_assistant.cc",
+      "autofill_assistant.h",
+      "autofill_credit_card_filling_infobar_delegate_mobile.cc",
+      "autofill_credit_card_filling_infobar_delegate_mobile.h",
+    ]
+  }
+
   if (is_ios || is_android) {
     sources += [
       "autofill_save_card_infobar_delegate_mobile.cc",
@@ -321,6 +330,10 @@
     "webdata/web_data_service_unittest.cc",
   ]
 
+  if (is_android) {
+    sources += [ "autofill_assistant_unittest.cc" ]
+  }
+
   deps = [
     ":browser",
     ":test_support",
diff --git a/components/autofill/core/browser/autofill_assistant.cc b/components/autofill/core/browser/autofill_assistant.cc
new file mode 100644
index 0000000..c74776f9
--- /dev/null
+++ b/components/autofill/core/browser/autofill_assistant.cc
@@ -0,0 +1,60 @@
+// Copyright 2016 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.
+
+#include "components/autofill/core/browser/autofill_assistant.h"
+
+#include "base/containers/adapters.h"
+#include "base/strings/string16.h"
+#include "components/autofill/core/browser/autofill_experiments.h"
+#include "components/autofill/core/browser/autofill_manager.h"
+#include "components/autofill/core/browser/credit_card.h"
+#include "components/autofill/core/browser/form_structure.h"
+#include "components/autofill/core/common/autofill_constants.h"
+
+namespace autofill {
+
+AutofillAssistant::AutofillAssistant(AutofillManager* autofill_manager)
+    : credit_card_form_data_(nullptr),
+      autofill_manager_(autofill_manager),
+      weak_ptr_factory_(this) {}
+
+AutofillAssistant::~AutofillAssistant() {}
+
+void AutofillAssistant::Reset() {
+  credit_card_form_data_.reset();
+}
+
+bool AutofillAssistant::CanShowCreditCardAssist(
+    const std::vector<FormStructure*>& form_structures) {
+#if !defined(OS_ANDROID)
+  return false;
+#else
+  if (!IsAutofillCreditCardAssistEnabled() || credit_card_form_data_)
+    return false;
+
+  for (FormStructure* cur_form : base::Reversed(form_structures)) {
+    if (cur_form->IsCompleteCreditCardForm()) {
+      credit_card_form_data_.reset(new FormData(cur_form->ToFormData()));
+      break;
+    }
+  }
+  return !!credit_card_form_data_;
+#endif
+}
+
+void AutofillAssistant::ShowAssistForCreditCard(const CreditCard& card) {
+  DCHECK(credit_card_form_data_);
+  autofill_manager_->client()->ConfirmCreditCardFillAssist(
+      card, base::Bind(&AutofillAssistant::OnUserDidAcceptCreditCardFill,
+                       weak_ptr_factory_.GetWeakPtr(), card));
+}
+
+void AutofillAssistant::OnUserDidAcceptCreditCardFill(const CreditCard& card) {
+  // TODO(crbug.com/630656): Trigger CVC dialog flow for card filling.
+  autofill_manager_->FillCreditCardForm(kNoQueryId, *credit_card_form_data_,
+                                        credit_card_form_data_->fields[0], card,
+                                        base::string16());
+}
+
+}  // namespace autofill
diff --git a/components/autofill/core/browser/autofill_assistant.h b/components/autofill/core/browser/autofill_assistant.h
new file mode 100644
index 0000000..1a15b4c7
--- /dev/null
+++ b/components/autofill/core/browser/autofill_assistant.h
@@ -0,0 +1,59 @@
+// Copyright 2016 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.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_ASSISTANT_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_ASSISTANT_H_
+
+#include <memory>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "components/autofill/core/common/form_data.h"
+
+namespace autofill {
+
+class AutofillManager;
+class CreditCard;
+class FormStructure;
+
+// This class encompasses the triggering rules and the logic for the autofill
+// assisted filling mechanisms.
+class AutofillAssistant {
+ public:
+  explicit AutofillAssistant(AutofillManager* autofill_manager);
+  ~AutofillAssistant();
+
+  // Should be called at every page navigation to clear state.
+  void Reset();
+
+  // Returns whether a credit card assist can be shown. Will go through the
+  // forms in |form_structures| and extract the credit card form.
+  bool CanShowCreditCardAssist(
+      const std::vector<FormStructure*>& form_structures);
+
+  // Will show an assist infobar for the previously extracted form proposing to
+  // autofill it. Should only be called if CanShowCreditCardAssist() returned
+  // true.
+  void ShowAssistForCreditCard(const CreditCard& card);
+
+ private:
+  // Called by the infobar delegate when the user accepts the infobar.
+  void OnUserDidAcceptCreditCardFill(const CreditCard& card);
+
+  // Holds the FormData to be filled with a credit card.
+  std::unique_ptr<FormData> credit_card_form_data_;
+
+  // Weak reference to the AutofillManager that created and maintains this
+  // AutofillAssistant.
+  AutofillManager* autofill_manager_;
+
+  base::WeakPtrFactory<AutofillAssistant> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(AutofillAssistant);
+};
+
+}  // namespace autofill
+
+#endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_ASSISTANT_H_
diff --git a/components/autofill/core/browser/autofill_assistant_unittest.cc b/components/autofill/core/browser/autofill_assistant_unittest.cc
new file mode 100644
index 0000000..b1a61d8
--- /dev/null
+++ b/components/autofill/core/browser/autofill_assistant_unittest.cc
@@ -0,0 +1,159 @@
+// Copyright 2016 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.
+
+#include "components/autofill/core/browser/autofill_assistant.h"
+
+#include <memory>
+
+#include "base/callback.h"
+#include "base/feature_list.h"
+#include "base/message_loop/message_loop.h"
+#include "base/strings/utf_string_conversions.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_test_utils.h"
+#include "components/autofill/core/browser/credit_card.h"
+#include "components/autofill/core/browser/form_structure.h"
+#include "components/autofill/core/browser/test_autofill_client.h"
+#include "components/autofill/core/browser/test_autofill_driver.h"
+#include "components/autofill/core/common/autofill_constants.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::_;
+
+namespace autofill {
+namespace {
+
+class MockAutofillManager : public AutofillManager {
+ public:
+  MockAutofillManager(TestAutofillDriver* driver, TestAutofillClient* client)
+      // Force to use the constructor designated for unit test, but we don't
+      // really need personal_data in this test so we pass a NULL pointer.
+      : AutofillManager(driver, client, NULL) {}
+  virtual ~MockAutofillManager() {}
+
+  MOCK_METHOD5(FillCreditCardForm,
+               void(int query_id,
+                    const FormData& form,
+                    const FormFieldData& field,
+                    const CreditCard& credit_card,
+                    const base::string16& cvc));
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MockAutofillManager);
+};
+
+}  // namespace
+
+class AutofillAssistantTest : public testing::Test {
+ protected:
+  AutofillAssistantTest()
+      : message_loop_(),
+        autofill_client_(),
+        autofill_driver_(),
+        autofill_manager_(&autofill_driver_, &autofill_client_),
+        autofill_assistant_(&autofill_manager_) {}
+
+  void EnableAutofillCreditCardAssist() {
+    base::FeatureList::ClearInstanceForTesting();
+    std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
+    feature_list->InitializeFromCommandLine(kAutofillCreditCardAssist.name,
+                                            std::string());
+    base::FeatureList::SetInstance(std::move(feature_list));
+  }
+
+  // Returns an initialized FormStructure with credit card form data. To be
+  // owned by the caller.
+  std::unique_ptr<FormStructure> CreateValidCreditCardForm() {
+    std::unique_ptr<FormStructure> form_structure;
+    FormData form;
+
+    FormFieldData field;
+    field.form_control_type = "text";
+
+    field.label = base::ASCIIToUTF16("Name on Card");
+    field.name = base::ASCIIToUTF16("name_on_card");
+    form.fields.push_back(field);
+
+    field.label = base::ASCIIToUTF16("Card Number");
+    field.name = base::ASCIIToUTF16("card_number");
+    form.fields.push_back(field);
+
+    field.label = base::ASCIIToUTF16("Exp Month");
+    field.name = base::ASCIIToUTF16("ccmonth");
+    form.fields.push_back(field);
+
+    field.label = base::ASCIIToUTF16("Exp Year");
+    field.name = base::ASCIIToUTF16("ccyear");
+    form.fields.push_back(field);
+
+    field.label = base::ASCIIToUTF16("Verification");
+    field.name = base::ASCIIToUTF16("verification");
+    form.fields.push_back(field);
+
+    form_structure.reset(new FormStructure(form));
+    form_structure->DetermineHeuristicTypes();
+
+    return form_structure;
+  }
+
+  base::MessageLoop message_loop_;
+  TestAutofillClient autofill_client_;
+  testing::NiceMock<TestAutofillDriver> autofill_driver_;
+  MockAutofillManager autofill_manager_;
+  AutofillAssistant autofill_assistant_;
+};
+
+MATCHER_P(CreditCardMatches, guid, "") {
+  return arg.guid() == guid;
+}
+
+// If the feature is turned off, CanShowCreditCardAssist() always returns
+// false.
+TEST_F(AutofillAssistantTest, CanShowCreditCardAssist_FeatureOff) {
+  std::unique_ptr<FormStructure> form_structure = CreateValidCreditCardForm();
+
+  std::vector<FormStructure*> form_structures{form_structure.get()};
+  EXPECT_FALSE(autofill_assistant_.CanShowCreditCardAssist(form_structures));
+}
+
+// Tests that with the feature enabled and proper input,
+// CanShowCreditCardAssist() behaves as expected.
+TEST_F(AutofillAssistantTest, CanShowCreditCardAssist_FeatureOn) {
+  EnableAutofillCreditCardAssist();
+  std::unique_ptr<FormStructure> form_structure = CreateValidCreditCardForm();
+
+  std::vector<FormStructure*> form_structures;
+  EXPECT_FALSE(autofill_assistant_.CanShowCreditCardAssist(form_structures));
+
+  // With valid input, the function extracts the credit card form properly.
+  form_structures.push_back(form_structure.get());
+  EXPECT_TRUE(autofill_assistant_.CanShowCreditCardAssist(form_structures));
+}
+
+TEST_F(AutofillAssistantTest, ShowAssistForCreditCard_ValidCard) {
+  EnableAutofillCreditCardAssist();
+  std::unique_ptr<FormStructure> form_structure = CreateValidCreditCardForm();
+
+  // Will extract the credit card form data.
+  std::vector<FormStructure*> form_structures{form_structure.get()};
+  EXPECT_TRUE(autofill_assistant_.CanShowCreditCardAssist(form_structures));
+
+  // Create a valid card for the assist.
+  CreditCard card;
+  test::SetCreditCardInfo(&card, "John Doe", "4111111111111111", "05", "2999");
+
+  // FillCreditCardForm ends up being called after user has accepted the
+  // prompt.
+  EXPECT_CALL(
+      autofill_manager_,
+      FillCreditCardForm(kNoQueryId, _, _, CreditCardMatches(card.guid()),
+                         /* empty cvc */ base::string16()));
+
+  autofill_assistant_.ShowAssistForCreditCard(card);
+}
+
+}  // namespace autofill
diff --git a/components/autofill/core/browser/autofill_client.h b/components/autofill/core/browser/autofill_client.h
index 354610b..d475691 100644
--- a/components/autofill/core/browser/autofill_client.h
+++ b/components/autofill/core/browser/autofill_client.h
@@ -132,6 +132,11 @@
       std::unique_ptr<base::DictionaryValue> legal_message,
       const base::Closure& callback) = 0;
 
+  // Will show an infobar to get user consent for Credit Card assistive filling.
+  // Will run |callback| on success.
+  virtual void ConfirmCreditCardFillAssist(const CreditCard& card,
+                                           const base::Closure& callback) = 0;
+
   // Gathers risk data and provides it to |callback|.
   virtual void LoadRiskData(
       const base::Callback<void(const std::string&)>& callback) = 0;
diff --git a/components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.cc b/components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.cc
new file mode 100644
index 0000000..432bb26
--- /dev/null
+++ b/components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.cc
@@ -0,0 +1,89 @@
+// Copyright 2016 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.
+
+#include "components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.h"
+
+#include "base/memory/ptr_util.h"
+#include "components/autofill/core/browser/credit_card.h"
+#include "components/autofill/core/common/autofill_constants.h"
+#include "components/infobars/core/infobar_delegate.h"
+#include "grit/components_scaled_resources.h"
+#include "grit/components_strings.h"
+#include "ui/base/l10n/l10n_util.h"
+
+namespace autofill {
+
+AutofillCreditCardFillingInfoBarDelegateMobile::
+    AutofillCreditCardFillingInfoBarDelegateMobile(
+        const CreditCard& card,
+        const base::Closure& card_filling_callback)
+    : ConfirmInfoBarDelegate(),
+      card_filling_callback_(card_filling_callback),
+      had_user_interaction_(false),
+      was_shown_(false),
+      issuer_icon_id_(CreditCard::IconResourceId(card.type())),
+      card_label_(base::string16(kMidlineEllipsis) + card.LastFourDigits()),
+      card_sub_label_(card.AbbreviatedExpirationDateForDisplay()) {}
+
+AutofillCreditCardFillingInfoBarDelegateMobile::
+    ~AutofillCreditCardFillingInfoBarDelegateMobile() {
+  if (was_shown_) {
+    AutofillMetrics::LogCreditCardFillingInfoBarMetric(
+        AutofillMetrics::INFOBAR_SHOWN);
+    if (!had_user_interaction_)
+      LogUserAction(AutofillMetrics::INFOBAR_IGNORED);
+  }
+}
+
+int AutofillCreditCardFillingInfoBarDelegateMobile::GetIconId() const {
+  return IDR_INFOBAR_AUTOFILL_CC;
+}
+
+base::string16 AutofillCreditCardFillingInfoBarDelegateMobile::GetMessageText()
+    const {
+  return l10n_util::GetStringUTF16(
+      IDS_AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_TITLE);
+}
+
+void AutofillCreditCardFillingInfoBarDelegateMobile::InfoBarDismissed() {
+  LogUserAction(AutofillMetrics::INFOBAR_DENIED);
+}
+
+bool AutofillCreditCardFillingInfoBarDelegateMobile::Accept() {
+  card_filling_callback_.Run();
+  LogUserAction(AutofillMetrics::INFOBAR_ACCEPTED);
+  return true;
+}
+
+bool AutofillCreditCardFillingInfoBarDelegateMobile::Cancel() {
+  LogUserAction(AutofillMetrics::INFOBAR_DENIED);
+  return true;
+}
+
+infobars::InfoBarDelegate::Type
+AutofillCreditCardFillingInfoBarDelegateMobile::GetInfoBarType() const {
+  return PAGE_ACTION_TYPE;
+}
+
+infobars::InfoBarDelegate::InfoBarIdentifier
+AutofillCreditCardFillingInfoBarDelegateMobile::GetIdentifier() const {
+  return AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_DELEGATE_ANDROID;
+}
+
+base::string16 AutofillCreditCardFillingInfoBarDelegateMobile::GetButtonLabel(
+    InfoBarButton button) const {
+  return l10n_util::GetStringUTF16(
+      button == BUTTON_OK ? IDS_AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_ACCEPT
+                          : IDS_NO_THANKS);
+}
+
+void AutofillCreditCardFillingInfoBarDelegateMobile::LogUserAction(
+    AutofillMetrics::InfoBarMetric user_action) {
+  DCHECK(!had_user_interaction_);
+
+  AutofillMetrics::LogCreditCardFillingInfoBarMetric(user_action);
+  had_user_interaction_ = true;
+}
+
+}  // namespace autofill
diff --git a/components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.h b/components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.h
new file mode 100644
index 0000000..fe1cc19
--- /dev/null
+++ b/components/autofill/core/browser/autofill_credit_card_filling_infobar_delegate_mobile.h
@@ -0,0 +1,75 @@
+// Copyright 2016 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.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_DELEGATE_MOBILE_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_DELEGATE_MOBILE_H_
+
+#include <memory>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/strings/string16.h"
+#include "components/autofill/core/browser/autofill_metrics.h"
+#include "components/infobars/core/confirm_infobar_delegate.h"
+
+namespace infobars {
+class InfoBarManager;
+}
+
+namespace autofill {
+
+class CreditCard;
+
+// An InfoBarDelegate that enables the user to allow or deny filling credit
+// card information on a website form. Only used on mobile.
+class AutofillCreditCardFillingInfoBarDelegateMobile
+    : public ConfirmInfoBarDelegate {
+ public:
+  AutofillCreditCardFillingInfoBarDelegateMobile(
+      const CreditCard& card,
+      const base::Closure& card_filling_callback);
+  ~AutofillCreditCardFillingInfoBarDelegateMobile() override;
+
+  int issuer_icon_id() const { return issuer_icon_id_; }
+  const base::string16& card_label() const { return card_label_; }
+  const base::string16& card_sub_label() const { return card_sub_label_; }
+  void set_was_shown() { was_shown_ = true; }
+
+  // ConfirmInfoBarDelegate (publicly exposed):
+  int GetIconId() const override;
+  base::string16 GetMessageText() const override;
+  void InfoBarDismissed() override;
+  bool Accept() override;
+  bool Cancel() override;
+
+ private:
+  // ConfirmInfoBarDelegate (continued):
+  Type GetInfoBarType() const override;
+  infobars::InfoBarDelegate::InfoBarIdentifier GetIdentifier() const override;
+  base::string16 GetButtonLabel(InfoBarButton button) const override;
+
+  void LogUserAction(AutofillMetrics::InfoBarMetric user_action);
+
+  // The callback after having accepted the infobar; will initiate filling the
+  // credit card information.
+  base::Closure card_filling_callback_;
+
+  // Did the user ever explicitly accept or dismiss this infobar?
+  bool had_user_interaction_;
+
+  // Tracks whether the infobar was shown.
+  bool was_shown_;
+
+  // The resource ID for the icon that identifies the issuer of the card.
+  int issuer_icon_id_;
+
+  base::string16 card_label_;
+  base::string16 card_sub_label_;
+
+  DISALLOW_COPY_AND_ASSIGN(AutofillCreditCardFillingInfoBarDelegateMobile);
+};
+
+}  // namespace autofill
+
+#endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_DELEGATE_MOBILE_H_
diff --git a/components/autofill/core/browser/autofill_experiments.cc b/components/autofill/core/browser/autofill_experiments.cc
index 6136569..03731e9 100644
--- a/components/autofill/core/browser/autofill_experiments.cc
+++ b/components/autofill/core/browser/autofill_experiments.cc
@@ -19,6 +19,8 @@
 
 namespace autofill {
 
+const base::Feature kAutofillCreditCardAssist{
+    "AutofillCreditCardAssist", base::FEATURE_DISABLED_BY_DEFAULT};
 const base::Feature kAutofillProfileCleanup{"AutofillProfileCleanup",
                                             base::FEATURE_DISABLED_BY_DEFAULT};
 const base::Feature kAutofillCreditCardSigninPromo{
@@ -43,6 +45,10 @@
   return base::FeatureList::IsEnabled(kAutofillCreditCardSigninPromo);
 }
 
+bool IsAutofillCreditCardAssistEnabled() {
+  return base::FeatureList::IsEnabled(kAutofillCreditCardAssist);
+}
+
 int GetCreditCardSigninPromoImpressionLimit() {
   int impression_limit;
   std::string param_value = variations::GetVariationParamValueByFeature(
diff --git a/components/autofill/core/browser/autofill_experiments.h b/components/autofill/core/browser/autofill_experiments.h
index 70fc201f..700e41ee 100644
--- a/components/autofill/core/browser/autofill_experiments.h
+++ b/components/autofill/core/browser/autofill_experiments.h
@@ -19,6 +19,7 @@
 
 namespace autofill {
 
+extern const base::Feature kAutofillCreditCardAssist;
 extern const base::Feature kAutofillProfileCleanup;
 extern const base::Feature kAutofillCreditCardSigninPromo;
 extern const char kCreditCardSigninPromoImpressionLimitParamKey[];
@@ -39,6 +40,9 @@
 // Returns whether the Autofill credit card signin promo should be shown.
 bool IsAutofillCreditCardSigninPromoEnabled();
 
+// Returns whether the Autofill credit card assist infobar should be shown.
+bool IsAutofillCreditCardAssistEnabled();
+
 // Returns the maximum number of impressions of the credit card signin promo, or
 // 0 if there are no limits.
 int GetCreditCardSigninPromoImpressionLimit();
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc
index 3e353ee5..c5df1860 100644
--- a/components/autofill/core/browser/autofill_manager.cc
+++ b/components/autofill/core/browser/autofill_manager.cc
@@ -208,6 +208,9 @@
       user_did_accept_upload_prompt_(false),
       external_delegate_(NULL),
       test_delegate_(NULL),
+#if defined(OS_ANDROID)
+      autofill_assistant_(this),
+#endif
       weak_ptr_factory_(this) {
   if (enable_download_manager == ENABLE_AUTOFILL_DOWNLOAD_MANAGER) {
     download_manager_.reset(new AutofillDownloadManager(driver, this));
@@ -1285,6 +1288,9 @@
       new AutofillMetrics::FormEventLogger(false /* is_for_credit_card */));
   credit_card_form_event_logger_.reset(
       new AutofillMetrics::FormEventLogger(true /* is_for_credit_card */));
+#if defined(OS_ANDROID)
+  autofill_assistant_.Reset();
+#endif
   has_logged_autofill_enabled_ = false;
   has_logged_address_suggestions_count_ = false;
   did_show_suggestions_ = false;
@@ -1324,6 +1330,9 @@
       unmasking_query_id_(-1),
       external_delegate_(NULL),
       test_delegate_(NULL),
+#if defined(OS_ANDROID)
+      autofill_assistant_(this),
+#endif
       weak_ptr_factory_(this) {
   DCHECK(driver_);
   DCHECK(client_);
@@ -1772,6 +1781,21 @@
 #endif
   }
 
+#if defined(OS_ANDROID)
+  // When a credit card form is parsed and conditions are met, show an infobar
+  // prompt for credit card assisted filling. Upon accepting the infobar, the
+  // form will automatically be filled with the user's information through this
+  // class' FillCreditCardForm().
+  if (autofill_assistant_.CanShowCreditCardAssist(form_structures_.get())) {
+    const std::vector<CreditCard*> cards =
+        personal_data_->GetCreditCardsToSuggest();
+    // Expired cards are last in the sorted order, so if the first one is
+    // expired, they all are.
+    if (!cards.empty() && !cards.front()->IsExpired(base::Time::Now()))
+      autofill_assistant_.ShowAssistForCreditCard(*cards.front());
+  }
+#endif
+
   // For the |non_queryable_forms|, we have all the field type info we're ever
   // going to get about them.  For the other forms, we'll wait until we get a
   // response from the server.
diff --git a/components/autofill/core/browser/autofill_manager.h b/components/autofill/core/browser/autofill_manager.h
index 4b906a5..9e8663d2 100644
--- a/components/autofill/core/browser/autofill_manager.h
+++ b/components/autofill/core/browser/autofill_manager.h
@@ -32,6 +32,10 @@
 #include "components/autofill/core/browser/personal_data_manager.h"
 #include "components/autofill/core/common/form_data.h"
 
+#if defined(OS_ANDROID)
+#include "components/autofill/core/browser/autofill_assistant.h"
+#endif
+
 // This define protects some debugging code (see DumpAutofillData). This
 // is here to make it easier to delete this code when the test is complete,
 // and to prevent adding the code on mobile where there is no desktop (the
@@ -251,7 +255,6 @@
 
   ScopedVector<FormStructure>* form_structures() { return &form_structures_; }
 
- protected:
   // Exposed for testing.
   AutofillExternalDelegate* external_delegate() {
     return external_delegate_;
@@ -535,6 +538,10 @@
   // Delegate used in test to get notifications on certain events.
   AutofillManagerTestDelegate* test_delegate_;
 
+#if defined(OS_ANDROID)
+  AutofillAssistant autofill_assistant_;
+#endif
+
   base::WeakPtrFactory<AutofillManager> weak_ptr_factory_;
 
   friend class AutofillManagerTest;
diff --git a/components/autofill/core/browser/autofill_metrics.cc b/components/autofill/core/browser/autofill_metrics.cc
index aed621c..7bcb4517 100644
--- a/components/autofill/core/browser/autofill_metrics.cc
+++ b/components/autofill/core/browser/autofill_metrics.cc
@@ -265,6 +265,13 @@
 }
 
 // static
+void AutofillMetrics::LogCreditCardFillingInfoBarMetric(InfoBarMetric metric) {
+  DCHECK_LT(metric, NUM_INFO_BAR_METRICS);
+  UMA_HISTOGRAM_ENUMERATION("Autofill.CreditCardFillingInfoBar", metric,
+                            NUM_INFO_BAR_METRICS);
+}
+
+// static
 void AutofillMetrics::LogSaveCardPromptMetric(SaveCardPromptMetric metric,
                                               bool is_uploading,
                                               bool is_reshow) {
diff --git a/components/autofill/core/browser/autofill_metrics.h b/components/autofill/core/browser/autofill_metrics.h
index d0fcb7c..8f8b4239 100644
--- a/components/autofill/core/browser/autofill_metrics.h
+++ b/components/autofill/core/browser/autofill_metrics.h
@@ -513,6 +513,7 @@
 
   static void LogCardUploadDecisionMetric(CardUploadDecisionMetric metric);
   static void LogCreditCardInfoBarMetric(InfoBarMetric metric);
+  static void LogCreditCardFillingInfoBarMetric(InfoBarMetric metric);
   static void LogSaveCardPromptMetric(SaveCardPromptMetric metric,
                                       bool is_uploading,
                                       bool is_reshow);
diff --git a/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc b/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc
index 471e0d2f..4343a1f 100644
--- a/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc
+++ b/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc
@@ -97,7 +97,7 @@
     InfoBarButton button) const {
   return l10n_util::GetStringUTF16(button == BUTTON_OK
                                        ? IDS_AUTOFILL_SAVE_CARD_PROMPT_ACCEPT
-                                       : IDS_AUTOFILL_SAVE_CARD_PROMPT_DENY);
+                                       : IDS_NO_THANKS);
 }
 
 bool AutofillSaveCardInfoBarDelegateMobile::Accept() {
diff --git a/components/autofill/core/browser/form_structure.cc b/components/autofill/core/browser/form_structure.cc
index 164bd717..5d6815f 100644
--- a/components/autofill/core/browser/form_structure.cc
+++ b/components/autofill/core/browser/form_structure.cc
@@ -290,6 +290,14 @@
   return out;
 }
 
+bool IsCreditCardExpirationType(ServerFieldType type) {
+  return type == CREDIT_CARD_EXP_MONTH ||
+         type == CREDIT_CARD_EXP_2_DIGIT_YEAR ||
+         type == CREDIT_CARD_EXP_4_DIGIT_YEAR ||
+         type == CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR ||
+         type == CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR;
+}
+
 }  // namespace
 
 FormStructure::FormStructure(const FormData& form)
@@ -577,6 +585,22 @@
   return ShouldBeParsed();
 }
 
+bool FormStructure::IsCompleteCreditCardForm() const {
+  bool found_cc_number = false;
+  bool found_cc_expiration = false;
+  for (const AutofillField* field : fields_) {
+    ServerFieldType type = field->Type().GetStorableType();
+    if (!found_cc_expiration && IsCreditCardExpirationType(type)) {
+      found_cc_expiration = true;
+    } else if (!found_cc_number && type == CREDIT_CARD_NUMBER) {
+      found_cc_number = true;
+    }
+    if (found_cc_expiration && found_cc_number)
+      return true;
+  }
+  return false;
+}
+
 void FormStructure::UpdateAutofillCount() {
   autofill_count_ = 0;
   for (const AutofillField* field : *this) {
diff --git a/components/autofill/core/browser/form_structure.h b/components/autofill/core/browser/form_structure.h
index aab2a66..074c229 100644
--- a/components/autofill/core/browser/form_structure.h
+++ b/components/autofill/core/browser/form_structure.h
@@ -99,6 +99,11 @@
   // auto-fillable, like google/yahoo/msn search, etc.
   bool IsAutofillable() const;
 
+  // Returns whether |this| form represents a complete Credit Card form, which
+  // consists in having at least a credit card number field and an expiration
+  // field.
+  bool IsCompleteCreditCardForm() const;
+
   // Resets |autofill_count_| and counts the number of auto-fillable fields.
   // This is used when we receive server data for form fields.  At that time,
   // we may have more known fields than just the number of fields we matched
diff --git a/components/autofill/core/browser/form_structure_unittest.cc b/components/autofill/core/browser/form_structure_unittest.cc
index 0463c67..8d7f6473 100644
--- a/components/autofill/core/browser/form_structure_unittest.cc
+++ b/components/autofill/core/browser/form_structure_unittest.cc
@@ -605,6 +605,129 @@
   EXPECT_EQ(ADDRESS_HOME_LINE3, form_structure->field(2)->heuristic_type());
 }
 
+TEST_F(FormStructureTest, IsCompleteCreditCardForm_Minimal) {
+  std::unique_ptr<FormStructure> form_structure;
+  FormData form;
+
+  FormFieldData field;
+  field.form_control_type = "text";
+
+  field.label = ASCIIToUTF16("Card Number");
+  field.name = ASCIIToUTF16("card_number");
+  form.fields.push_back(field);
+
+  field.label = ASCIIToUTF16("Expiration");
+  field.name = ASCIIToUTF16("cc_exp");
+  form.fields.push_back(field);
+
+  // Another field to reach the minimum 3.
+  field.label = ASCIIToUTF16("Zip");
+  field.name = ASCIIToUTF16("zip");
+  form.fields.push_back(field);
+
+  form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
+
+  EXPECT_TRUE(form_structure->IsCompleteCreditCardForm());
+}
+
+TEST_F(FormStructureTest, IsCompleteCreditCardForm_Full) {
+  std::unique_ptr<FormStructure> form_structure;
+  FormData form;
+
+  FormFieldData field;
+  field.form_control_type = "text";
+
+  field.label = ASCIIToUTF16("Name on Card");
+  field.name = ASCIIToUTF16("name_on_card");
+  form.fields.push_back(field);
+
+  field.label = ASCIIToUTF16("Card Number");
+  field.name = ASCIIToUTF16("card_number");
+  form.fields.push_back(field);
+
+  field.label = ASCIIToUTF16("Exp Month");
+  field.name = ASCIIToUTF16("ccmonth");
+  form.fields.push_back(field);
+
+  field.label = ASCIIToUTF16("Exp Year");
+  field.name = ASCIIToUTF16("ccyear");
+  form.fields.push_back(field);
+
+  field.label = ASCIIToUTF16("Verification");
+  field.name = ASCIIToUTF16("verification");
+  form.fields.push_back(field);
+
+  field.label = base::string16();
+  field.name = ASCIIToUTF16("Submit");
+  field.form_control_type = "submit";
+  form.fields.push_back(field);
+
+  form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
+
+  EXPECT_TRUE(form_structure->IsCompleteCreditCardForm());
+}
+
+// A form with only the credit card number is not considered sufficient.
+TEST_F(FormStructureTest, IsCompleteCreditCardForm_OnlyCCNumber) {
+  std::unique_ptr<FormStructure> form_structure;
+  FormData form;
+
+  FormFieldData field;
+  field.form_control_type = "text";
+
+  field.label = ASCIIToUTF16("Card Number");
+  field.name = ASCIIToUTF16("card_number");
+  form.fields.push_back(field);
+
+  form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
+
+  EXPECT_FALSE(form_structure->IsCompleteCreditCardForm());
+}
+
+// A form with only the credit card number is not considered sufficient.
+TEST_F(FormStructureTest, IsCompleteCreditCardForm_AddressForm) {
+  std::unique_ptr<FormStructure> form_structure;
+  FormData form;
+
+  FormFieldData field;
+  field.form_control_type = "text";
+
+  field.label = ASCIIToUTF16("First Name");
+  field.name = base::string16();
+  form.fields.push_back(field);
+
+  field.label = ASCIIToUTF16("Last Name");
+  field.name = base::string16();
+  form.fields.push_back(field);
+
+  field.label = ASCIIToUTF16("Email");
+  field.name = base::string16();
+  form.fields.push_back(field);
+
+  field.label = ASCIIToUTF16("Phone");
+  field.name = base::string16();
+  form.fields.push_back(field);
+
+  field.label = ASCIIToUTF16("Address");
+  field.name = base::string16();
+  form.fields.push_back(field);
+
+  field.label = ASCIIToUTF16("Address");
+  field.name = base::string16();
+  form.fields.push_back(field);
+
+  field.label = ASCIIToUTF16("Zip code");
+  field.name = base::string16();
+  form.fields.push_back(field);
+  form_structure.reset(new FormStructure(form));
+  form_structure->DetermineHeuristicTypes();
+
+  EXPECT_FALSE(form_structure->IsCompleteCreditCardForm());
+}
+
 // Verify that we can correctly process the 'autocomplete' attribute for phone
 // number types (especially phone prefixes and suffixes).
 TEST_F(FormStructureTest, HeuristicsAutocompleteAttributePhoneTypes) {
diff --git a/components/autofill/core/browser/test_autofill_client.cc b/components/autofill/core/browser/test_autofill_client.cc
index 647696c..37ea5b5 100644
--- a/components/autofill/core/browser/test_autofill_client.cc
+++ b/components/autofill/core/browser/test_autofill_client.cc
@@ -66,6 +66,12 @@
   callback.Run();
 }
 
+void TestAutofillClient::ConfirmCreditCardFillAssist(
+    const CreditCard& card,
+    const base::Closure& callback) {
+  callback.Run();
+}
+
 void TestAutofillClient::LoadRiskData(
     const base::Callback<void(const std::string&)>& callback) {
   callback.Run("some risk data");
diff --git a/components/autofill/core/browser/test_autofill_client.h b/components/autofill/core/browser/test_autofill_client.h
index ea36a9c..e936e42e 100644
--- a/components/autofill/core/browser/test_autofill_client.h
+++ b/components/autofill/core/browser/test_autofill_client.h
@@ -43,6 +43,8 @@
       const CreditCard& card,
       std::unique_ptr<base::DictionaryValue> legal_message,
       const base::Closure& callback) override;
+  void ConfirmCreditCardFillAssist(const CreditCard& card,
+                                   const base::Closure& callback) override;
   void LoadRiskData(
       const base::Callback<void(const std::string&)>& callback) override;
   bool HasCreditCardScanFeature() override;
diff --git a/components/autofill/core/common/autofill_constants.h b/components/autofill/core/common/autofill_constants.h
index ab09290..872f6974 100644
--- a/components/autofill/core/common/autofill_constants.h
+++ b/components/autofill/core/common/autofill_constants.h
@@ -32,6 +32,10 @@
 // upload the form to and request predictions from the Autofill servers.
 const size_t kRequiredFieldsForFormsWithOnlyPasswordFields = 2;
 
+// Special query id used between the browser and the renderer when the action
+// is initiated from the browser.
+const int kNoQueryId = -1;
+
 // Options bitmask values for AutofillHostMsg_ShowPasswordSuggestions IPC
 enum ShowPasswordSuggestionsOptions {
   SHOW_ALL = 1 << 0 /* show all credentials, not just ones matching username */,
diff --git a/components/autofill_strings.grdp b/components/autofill_strings.grdp
index 4b7b57e..1c8fef8a 100644
--- a/components/autofill_strings.grdp
+++ b/components/autofill_strings.grdp
@@ -174,13 +174,18 @@
     Use password for:
   </message>
 
+  <!-- Autofill Credit Card Assisted Filling Infobar -->
+  <message name="IDS_AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_TITLE" desc="Title text for the Autofill Credit Card Assisted Filling Infobar">
+    Do you want to fill in your card info?
+  </message>
+  <message name="IDS_AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_ACCEPT" desc="Text to show for the Autofill credit card Assisted Filling infobar accept button.">
+    Fill in
+  </message>
+
   <!-- Autofill save credit card bubble or infobar prompt -->
   <message name="IDS_AUTOFILL_SAVE_CARD_PROMPT_ACCEPT" desc="Text to show for the Autofill save credit card prompt accept button. The prompt can be either a bubble or an infobar.">
     Save
   </message>
-  <message name="IDS_AUTOFILL_SAVE_CARD_PROMPT_DENY" desc="Text to show for the Autofill save credit card prompt deny button. The prompt can be either a bubble or an infobar.">
-    No thanks
-  </message>
   <if expr="_google_chrome">
     <message name="IDS_AUTOFILL_SAVE_CARD_PROMPT_TITLE_LOCAL" desc="Title text for the Autofill save card prompt when the card is to be saved locally. The prompt can be either a bubble or an infobar.">
       Do you want Chrome to save this card?
diff --git a/components/components_strings.grd b/components/components_strings.grd
index bd5901b..8e1adc5 100644
--- a/components/components_strings.grd
+++ b/components/components_strings.grd
@@ -227,6 +227,9 @@
       <message name="IDS_OK" desc="Used for OK on buttons">
         OK
       </message>
+      <message name="IDS_NO_THANKS" desc="Used to dismiss various prompts.">
+        No thanks
+      </message>
       <if expr="not use_titlecase">
         <message name="IDS_NOT_NOW" desc="Used on a button that avoids taking a suggested action.  The action will likely be suggested again or automatically taken later.">
           Not now
diff --git a/components/components_tests.gyp b/components/components_tests.gyp
index 333b164..04f368e 100644
--- a/components/components_tests.gyp
+++ b/components/components_tests.gyp
@@ -1500,6 +1500,7 @@
         }],
         ['OS == "android"', {
           'sources': [
+            'autofill/core/browser/autofill_assistant_unittest.cc',
             'data_usage/android/traffic_stats_amortizer_unittest.cc',
             'invalidation/impl/invalidation_logger_unittest.cc',
             'invalidation/impl/invalidation_service_android_unittest.cc',
diff --git a/components/infobars/core/infobar_delegate.h b/components/infobars/core/infobar_delegate.h
index 07d7ce7..7ab41b6 100644
--- a/components/infobars/core/infobar_delegate.h
+++ b/components/infobars/core/infobar_delegate.h
@@ -132,6 +132,7 @@
     // Removed: DESKTOP_SEARCH_REDIRECTION_INFOBAR_DELEGATE = 62,
     UPDATE_PASSWORD_INFOBAR_DELEGATE = 63,
     DATA_REDUCTION_PROMO_INFOBAR_DELEGATE_ANDROID = 64,
+    AUTOFILL_CREDIT_CARD_FILLING_INFOBAR_DELEGATE_ANDROID = 65,
   };
 
   // Describes navigation events, used to decide whether infobars should be
diff --git a/ios/chrome/browser/ui/autofill/autofill_client_ios.h b/ios/chrome/browser/ui/autofill/autofill_client_ios.h
index 6c5575f..8ce38ae 100644
--- a/ios/chrome/browser/ui/autofill/autofill_client_ios.h
+++ b/ios/chrome/browser/ui/autofill/autofill_client_ios.h
@@ -66,6 +66,8 @@
       const CreditCard& card,
       std::unique_ptr<base::DictionaryValue> legal_message,
       const base::Closure& callback) override;
+  void ConfirmCreditCardFillAssist(const CreditCard& card,
+                                   const base::Closure& callback) override;
   void LoadRiskData(
       const base::Callback<void(const std::string&)>& callback) override;
   bool HasCreditCardScanFeature() override;
diff --git a/ios/chrome/browser/ui/autofill/autofill_client_ios.mm b/ios/chrome/browser/ui/autofill/autofill_client_ios.mm
index c7b6f59..b8a2e7f 100644
--- a/ios/chrome/browser/ui/autofill/autofill_client_ios.mm
+++ b/ios/chrome/browser/ui/autofill/autofill_client_ios.mm
@@ -109,6 +109,12 @@
           true, card, std::move(legal_message), callback))));
 }
 
+void AutofillClientIOS::ConfirmCreditCardFillAssist(
+    const CreditCard& card,
+    const base::Closure& callback) {
+  NOTREACHED();
+}
+
 void AutofillClientIOS::LoadRiskData(
     const base::Callback<void(const std::string&)>& callback) {
   callback.Run(ios::GetChromeBrowserProvider()->GetRiskData());
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 585db5b..f4a6676 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -2755,6 +2755,15 @@
   <summary>The Autofill credit card info bar was denied.</summary>
 </histogram>
 
+<histogram name="Autofill.CreditCardFillingInfoBar"
+    enum="AutofillCreditCardInfoBar">
+  <owner>[email protected]</owner>
+  <summary>
+    The relative frequency with which users accept, deny, or ignore the Autofill
+    credit card assisted filling infobar prompt.
+  </summary>
+</histogram>
+
 <histogram name="Autofill.CreditCardInfoBar" enum="AutofillCreditCardInfoBar">
   <owner>[email protected]</owner>
   <summary>
@@ -80742,6 +80751,7 @@
   <int value="62" label="WINDOWS_DESKTOP_SEARCH_INFOBAR_DELEGATE"/>
   <int value="63" label="UPDATE_PASSWORD_INFOBAR_DELEGATE"/>
   <int value="64" label="DATA_REDUCTION_PROMO_INFOBAR_DELEGATE_ANDROID"/>
+  <int value="65" label="AUTOFILL_CC_ASSIST_INFOBAR_DELEGATE"/>
 </enum>
 
 <enum name="InfoBarResponse" type="int">