Pop up requestAutocomplete UI when autofill server hints chrome client that it is in a multipage autofill flow.

* Added AutofillFlowInfobarDelegate for the Infobar. (Note that this might evolve soon when we have much concrete UX)
* Strings used are also temporary.
* browser/autofill/autofill_flow_util.* : helper functions to build FormStructure representing all the information needed for autofill_flow.
* browser/autofill/autofill_manager.* : Added new methods to pop the UI and callback method to handle data from UI.
* browser/autofill/autofill_xml_parser/form_structure: To get information about step in the autofill flow from autofill servers.
* renderer/autofill/autofill_agent.* : To send SSL Status of the page back to the browser process. 


BUG=159830

Review URL: https://chromiumcodereview.appspot.com/11539003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@177746 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 3a2ea76..cd5923b 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -10605,6 +10605,15 @@
       <message name="IDS_AUTOFILL_CC_INFOBAR_DENY" desc="Text to show for the Autofill credit card request infobar deny button.">
         Don't save
       </message>
+      <message name="IDS_AUTOFILL_FLOW_INFOBAR_TEXT" desc="Text to show in the Autofill flow request infobar.">
+        Do you want to use Accelarated Autofill?
+      </message>
+      <message name="IDS_AUTOFILL_FLOW_INFOBAR_ACCEPT" desc="Text to show for the Autofill flow request infobar accept button.">
+        Accelarate
+      </message>
+      <message name="IDS_AUTOFILL_FLOW_INFOBAR_DENY" desc="Text to show for the Autofill flow request infobar deny button.">
+        No thanks
+      </message>
       <message name="IDS_AUTOFILL_CLEAR_FORM_MENU_ITEM" desc="The entry in the suggestions dropdown that clears an auto-filled form.">
         Clear form
       </message>
diff --git a/chrome/browser/autofill/autocheckout_infobar_delegate.cc b/chrome/browser/autofill/autocheckout_infobar_delegate.cc
new file mode 100644
index 0000000..b23b2e0
--- /dev/null
+++ b/chrome/browser/autofill/autocheckout_infobar_delegate.cc
@@ -0,0 +1,118 @@
+// Copyright (c) 2013 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/autofill/autocheckout_infobar_delegate.h"
+
+#include "base/logging.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/browser/api/infobars/infobar_service.h"
+#include "chrome/browser/autofill/autocheckout_manager.h"
+#include "chrome/common/url_constants.h"
+#include "content/public/browser/page_navigator.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/browser/web_contents_delegate.h"
+#include "grit/generated_resources.h"
+#include "grit/theme_resources.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/resource/resource_bundle.h"
+
+// static
+void AutocheckoutInfoBarDelegate::Create(
+    const AutofillMetrics& metric_logger,
+    const GURL& source_url,
+    const content::SSLStatus& ssl_status,
+    AutocheckoutManager* autocheckout_manager,
+    InfoBarService* infobar_service) {
+  infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
+      new AutocheckoutInfoBarDelegate(metric_logger, source_url, ssl_status,
+          autocheckout_manager, infobar_service)));
+}
+
+AutocheckoutInfoBarDelegate::AutocheckoutInfoBarDelegate(
+    const AutofillMetrics& metric_logger,
+    const GURL& source_url,
+    const content::SSLStatus& ssl_status,
+    AutocheckoutManager* autocheckout_manager,
+    InfoBarService* infobar_service)
+    : ConfirmInfoBarDelegate(infobar_service),
+      metric_logger_(metric_logger),
+      autocheckout_manager_(autocheckout_manager),
+      source_url_(source_url),
+      ssl_status_(ssl_status),
+      had_user_interaction_(false) {
+  metric_logger_.LogAutocheckoutInfoBarMetric(AutofillMetrics::INFOBAR_SHOWN);
+}
+
+AutocheckoutInfoBarDelegate::~AutocheckoutInfoBarDelegate() {
+  if (!had_user_interaction_)
+    LogUserAction(AutofillMetrics::INFOBAR_IGNORED);
+}
+
+void AutocheckoutInfoBarDelegate::LogUserAction(
+    AutofillMetrics::InfoBarMetric user_action) {
+  DCHECK(!had_user_interaction_);
+  metric_logger_.LogAutocheckoutInfoBarMetric(user_action);
+  had_user_interaction_ = true;
+}
+
+void AutocheckoutInfoBarDelegate::InfoBarDismissed() {
+  LogUserAction(AutofillMetrics::INFOBAR_DENIED);
+}
+
+gfx::Image* AutocheckoutInfoBarDelegate::GetIcon() const {
+  return &ResourceBundle::GetSharedInstance().GetNativeImageNamed(
+      IDR_INFOBAR_AUTOFILL);
+}
+
+InfoBarDelegate::Type AutocheckoutInfoBarDelegate::GetInfoBarType() const {
+  return PAGE_ACTION_TYPE;
+}
+
+bool AutocheckoutInfoBarDelegate::ShouldExpireInternal(
+    const content::LoadCommittedDetails& details) const {
+  // The user has submitted a form, causing the page to navigate elsewhere. We
+  // want the infobar to be expired at this point, because the user has
+  // potentially started the checkout flow manually.
+  return true;
+}
+
+
+string16 AutocheckoutInfoBarDelegate::GetMessageText() const {
+  return l10n_util::GetStringUTF16(IDS_AUTOFILL_FLOW_INFOBAR_TEXT);
+}
+
+string16 AutocheckoutInfoBarDelegate::GetButtonLabel(
+    InfoBarButton button) const {
+  return l10n_util::GetStringUTF16((button == BUTTON_OK) ?
+      IDS_AUTOFILL_FLOW_INFOBAR_ACCEPT : IDS_AUTOFILL_FLOW_INFOBAR_DENY);
+}
+
+bool AutocheckoutInfoBarDelegate::Accept() {
+  LogUserAction(AutofillMetrics::INFOBAR_ACCEPTED);
+  autocheckout_manager_->ShowAutocheckoutDialog(source_url_, ssl_status_);
+  return true;
+}
+
+bool AutocheckoutInfoBarDelegate::Cancel() {
+  LogUserAction(AutofillMetrics::INFOBAR_DENIED);
+  return true;
+}
+
+string16 AutocheckoutInfoBarDelegate::GetLinkText() const {
+  return l10n_util::GetStringUTF16(IDS_LEARN_MORE);
+}
+
+bool AutocheckoutInfoBarDelegate::LinkClicked(
+    WindowOpenDisposition disposition) {
+  // TODO(ramankk): Fix the help URL when we have one.
+  owner()->GetWebContents()->GetDelegate()->OpenURLFromTab(
+      owner()->GetWebContents(),
+      content::OpenURLParams(GURL(chrome::kAutofillHelpURL),
+                             content::Referrer(),
+                             NEW_FOREGROUND_TAB,
+                             content::PAGE_TRANSITION_LINK,
+                             false));
+  return false;
+}
+
diff --git a/chrome/browser/autofill/autocheckout_infobar_delegate.h b/chrome/browser/autofill/autocheckout_infobar_delegate.h
new file mode 100644
index 0000000..60c82f4
--- /dev/null
+++ b/chrome/browser/autofill/autocheckout_infobar_delegate.h
@@ -0,0 +1,91 @@
+// Copyright (c) 2013 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_AUTOFILL_AUTOCHECKOUT_INFOBAR_DELEGATE_H_
+#define CHROME_BROWSER_AUTOFILL_AUTOCHECKOUT_INFOBAR_DELEGATE_H_
+
+#include "base/basictypes.h"
+#include "base/gtest_prod_util.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/string16.h"
+#include "chrome/browser/api/infobars/confirm_infobar_delegate.h"
+#include "chrome/browser/autofill/autofill_metrics.h"
+#include "content/public/common/ssl_status.h"
+#include "googleurl/src/gurl.h"
+
+class AutocheckoutManager;
+
+namespace content {
+struct LoadCommittedDetails;
+}
+
+// An InfoBar delegate that enables the user to allow or deny storing credit
+// card information gathered from a form submission.
+class AutocheckoutInfoBarDelegate : public ConfirmInfoBarDelegate {
+ public:
+  // Creates an autofillflow infobar delegate and adds it to |infobar_service|.
+  static void Create(const AutofillMetrics& metric_logger,
+                     const GURL& source_url,
+                     const content::SSLStatus& ssl_status,
+                     AutocheckoutManager* autocheckout_manager,
+                     InfoBarService* infobar_service);
+
+#if defined(UNIT_TEST)
+  static scoped_ptr<ConfirmInfoBarDelegate> Create(
+      const AutofillMetrics& metric_logger,
+      const GURL& source_url,
+      const content::SSLStatus& ssl_status,
+      AutocheckoutManager* autocheckout_manager) {
+    return scoped_ptr<ConfirmInfoBarDelegate>(new AutocheckoutInfoBarDelegate(
+        metric_logger, source_url, ssl_status, autocheckout_manager, NULL));
+  }
+#endif
+
+ private:
+  AutocheckoutInfoBarDelegate(const AutofillMetrics& metric_logger,
+                              const GURL& source_url,
+                              const content::SSLStatus& ssl_status,
+                              AutocheckoutManager* autocheckout_manager,
+                              InfoBarService* infobar_service);
+
+  virtual ~AutocheckoutInfoBarDelegate();
+
+  // Logs UMA metric for user action type.
+  void LogUserAction(AutofillMetrics::InfoBarMetric user_action);
+
+  // ConfirmInfoBarDelegate:
+  virtual void InfoBarDismissed() OVERRIDE;
+  virtual gfx::Image* GetIcon() const OVERRIDE;
+  virtual Type GetInfoBarType() const OVERRIDE;
+  virtual bool ShouldExpireInternal(
+      const content::LoadCommittedDetails& details) const OVERRIDE;
+  virtual string16 GetMessageText() const OVERRIDE;
+  virtual string16 GetButtonLabel(InfoBarButton button) const OVERRIDE;
+  virtual bool Accept() OVERRIDE;
+  virtual bool Cancel() OVERRIDE;
+  virtual string16 GetLinkText() const OVERRIDE;
+  virtual bool LinkClicked(WindowOpenDisposition disposition) OVERRIDE;
+
+  // For logging UMA metrics.
+  // Weak reference. Owned by the AutofillManager that initiated this infobar.
+  const AutofillMetrics& metric_logger_;
+
+  // To callback AutocheckoutManager's ShowAutocheckoutDialog.
+  AutocheckoutManager* autocheckout_manager_;
+
+  // URL of the page which triggered infobar.
+  GURL source_url_;
+
+  // SSL status of the page which triggered infobar.
+  content::SSLStatus ssl_status_;
+
+  // Did the user ever explicitly accept or dismiss this infobar?
+  bool had_user_interaction_;
+
+  FRIEND_TEST_ALL_PREFIXES(AutofillMetricsTest, AutocheckoutInfoBar);
+
+  DISALLOW_COPY_AND_ASSIGN(AutocheckoutInfoBarDelegate);
+};
+
+#endif  // CHROME_BROWSER_AUTOFILL_AUTOCHECKOUT_INFOBAR_DELEGATE_H_
diff --git a/chrome/browser/autofill/autocheckout_manager.cc b/chrome/browser/autofill/autocheckout_manager.cc
new file mode 100644
index 0000000..3c623affe
--- /dev/null
+++ b/chrome/browser/autofill/autocheckout_manager.cc
@@ -0,0 +1,84 @@
+// Copyright (c) 2013 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/autofill/autocheckout_manager.h"
+
+#include "base/basictypes.h"
+#include "base/bind.h"
+#include "chrome/browser/autofill/autofill_manager.h"
+#include "chrome/browser/ui/autofill/autofill_dialog_controller_impl.h"
+#include "chrome/common/form_data.h"
+#include "chrome/common/form_field_data.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/common/ssl_status.h"
+#include "googleurl/src/gurl.h"
+
+using content::SSLStatus;
+using content::WebContents;
+
+namespace {
+
+// Build FormFieldData based on the supplied |autocomplete_attribute|. Will
+// fill rest of properties with default values.
+FormFieldData BuildField(const std::string& autocomplete_attribute) {
+  FormFieldData field;
+  field.name = string16();
+  field.value = string16();
+  field.autocomplete_attribute = autocomplete_attribute;
+  field.form_control_type = "text";
+  return field;
+}
+
+// Build Autocheckout specific form data to be consumed by
+// AutofillDialogController to show the Autocheckout specific UI.
+FormData BuildAutocheckoutFormData() {
+  FormData formdata;
+  formdata.fields.push_back(BuildField("name"));
+  formdata.fields.push_back(BuildField("email"));
+  formdata.fields.push_back(BuildField("cc-name"));
+  formdata.fields.push_back(BuildField("cc-number"));
+  formdata.fields.push_back(BuildField("cc-exp"));
+  formdata.fields.push_back(BuildField("cc-csc"));
+  formdata.fields.push_back(BuildField("billing street-address"));
+  formdata.fields.push_back(BuildField("billing locality"));
+  formdata.fields.push_back(BuildField("billing region"));
+  formdata.fields.push_back(BuildField("billing country"));
+  formdata.fields.push_back(BuildField("billing postal-code"));
+  formdata.fields.push_back(BuildField("shipping street-address"));
+  formdata.fields.push_back(BuildField("shipping locality"));
+  formdata.fields.push_back(BuildField("shipping region"));
+  formdata.fields.push_back(BuildField("shipping country"));
+  formdata.fields.push_back(BuildField("shipping postal-code"));
+  return formdata;
+}
+
+}  // namespace
+
+AutocheckoutManager::AutocheckoutManager(AutofillManager* autofill_manager)
+  : autofill_manager_(autofill_manager),
+    ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
+}
+
+AutocheckoutManager::~AutocheckoutManager() {
+}
+
+void AutocheckoutManager::ShowAutocheckoutDialog(
+    const GURL& frame_url,
+    const SSLStatus& ssl_status) {
+  base::Callback<void(const FormStructure*)> callback =
+      base::Bind(&AutocheckoutManager::ReturnAutocheckoutData,
+                 weak_ptr_factory_.GetWeakPtr());
+  autofill::AutofillDialogControllerImpl* controller =
+      new autofill::AutofillDialogControllerImpl(
+          autofill_manager_->GetWebContents(),
+          BuildAutocheckoutFormData(),
+          frame_url,
+          ssl_status,
+          callback);
+  controller->Show();
+}
+
+void AutocheckoutManager::ReturnAutocheckoutData(const FormStructure* result) {
+  // TODO(ramankk): Parse the response FormStructure.
+}
diff --git a/chrome/browser/autofill/autocheckout_manager.h b/chrome/browser/autofill/autocheckout_manager.h
new file mode 100644
index 0000000..548042b
--- /dev/null
+++ b/chrome/browser/autofill/autocheckout_manager.h
@@ -0,0 +1,42 @@
+// Copyright (c) 2013 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_AUTOFILL_AUTOCHECKOUT_MANAGER_H_
+#define CHROME_BROWSER_AUTOFILL_AUTOCHECKOUT_MANAGER_H_
+
+#include <string>
+
+#include "base/memory/weak_ptr.h"
+
+class AutofillManager;
+class FormStructure;
+class GURL;
+
+struct FormData;
+
+namespace content {
+struct SSLStatus;
+}
+
+class AutocheckoutManager {
+ public:
+  explicit AutocheckoutManager(AutofillManager* autofill_manager);
+
+  virtual void ShowAutocheckoutDialog(const GURL& frame_url,
+                                      const content::SSLStatus& ssl_status);
+
+  virtual ~AutocheckoutManager();
+
+ private:
+
+  // Callback called from AutofillDialogController on filling up the UI form.
+  void ReturnAutocheckoutData(const FormStructure* result);
+
+  AutofillManager* autofill_manager_;  // WEAK; owns us
+  base::WeakPtrFactory<AutocheckoutManager> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(AutocheckoutManager);
+};
+
+#endif  // CHROME_BROWSER_AUTOFILL_AUTOCHECKOUT_MANAGER_H_
diff --git a/chrome/browser/autofill/autofill_manager.cc b/chrome/browser/autofill/autofill_manager.cc
index 7da1731..90f6874 100644
--- a/chrome/browser/autofill/autofill_manager.cc
+++ b/chrome/browser/autofill/autofill_manager.cc
@@ -23,6 +23,8 @@
 #include "base/utf_string_conversions.h"
 #include "chrome/browser/api/infobars/infobar_service.h"
 #include "chrome/browser/api/sync/profile_sync_service_base.h"
+#include "chrome/browser/autofill/autocheckout_manager.h"
+#include "chrome/browser/autofill/autocheckout_infobar_delegate.h"
 #include "chrome/browser/autofill/autocomplete_history_manager.h"
 #include "chrome/browser/autofill/autofill_cc_infobar_delegate.h"
 #include "chrome/browser/autofill/autofill_country.h"
@@ -200,6 +202,7 @@
       download_manager_(delegate->GetBrowserContext(), this),
       disable_download_manager_requests_(false),
       autocomplete_history_manager_(web_contents),
+      autocheckout_manager_(this),
       metric_logger_(new AutofillMetrics),
       has_logged_autofill_enabled_(false),
       has_logged_address_suggestions_count_(false),
@@ -575,6 +578,18 @@
         }
       }
     }
+
+    // If form is known to be at the start of the autofillable flow (i.e, when
+    // Autofill server said so), then trigger payments UI while also returning
+    // standard autofill suggestions to renderer process.
+    if (form_structure->IsStartOfAutofillableFlow()) {
+      AutocheckoutInfoBarDelegate::Create(
+          *metric_logger_,
+          form.origin,
+          form.ssl_status,
+          &autocheckout_manager_,
+          manager_delegate_->GetInfoBarService());
+    }
   }
 
   // Add the results from AutoComplete.  They come back asynchronously, so we
@@ -749,6 +764,10 @@
   autocomplete_history_manager_.OnRemoveAutocompleteEntry(name, value);
 }
 
+content::WebContents* AutofillManager::GetWebContents() {
+  return web_contents();
+}
+
 void AutofillManager::OnAddPasswordFormMapping(
       const FormFieldData& form,
       const PasswordFormFillData& fill_data) {
@@ -947,6 +966,7 @@
       download_manager_(delegate->GetBrowserContext(), this),
       disable_download_manager_requests_(true),
       autocomplete_history_manager_(web_contents),
+      autocheckout_manager_(this),
       metric_logger_(new AutofillMetrics),
       has_logged_autofill_enabled_(false),
       has_logged_address_suggestions_count_(false),
diff --git a/chrome/browser/autofill/autofill_manager.h b/chrome/browser/autofill/autofill_manager.h
index e2edbd5b..0c2c8fb1 100644
--- a/chrome/browser/autofill/autofill_manager.h
+++ b/chrome/browser/autofill/autofill_manager.h
@@ -21,12 +21,14 @@
 #include "base/string16.h"
 #include "base/time.h"
 #include "chrome/browser/api/sync/profile_sync_service_observer.h"
+#include "chrome/browser/autofill/autocheckout_manager.h"
 #include "chrome/browser/autofill/autocomplete_history_manager.h"
 #include "chrome/browser/autofill/autofill_download.h"
 #include "chrome/browser/autofill/field_types.h"
 #include "chrome/browser/autofill/form_structure.h"
 #include "chrome/browser/autofill/personal_data_manager.h"
 #include "chrome/common/autofill/autocheckout_status.h"
+#include "chrome/common/form_data.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/common/ssl_status.h"
 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFormElement.h"
@@ -107,6 +109,9 @@
   // Remove the specified Autocomplete entry.
   void RemoveAutocompleteEntry(const string16& name, const string16& value);
 
+  // Returns the present web_contents state.
+  content::WebContents* GetWebContents();
+
  protected:
   // Only test code should subclass AutofillManager.
   friend class base::RefCounted<AutofillManager>;
@@ -336,6 +341,9 @@
   // Handles single-field autocomplete form data.
   AutocompleteHistoryManager autocomplete_history_manager_;
 
+  // Handles autocheckout flows.
+  AutocheckoutManager autocheckout_manager_;
+
   // For logging UMA metrics. Overridden by metrics tests.
   scoped_ptr<const AutofillMetrics> metric_logger_;
   // Have we logged whether Autofill is enabled for this page load?
diff --git a/chrome/browser/autofill/autofill_metrics.cc b/chrome/browser/autofill/autofill_metrics.cc
index c806a9849..24c9e706 100644
--- a/chrome/browser/autofill/autofill_metrics.cc
+++ b/chrome/browser/autofill/autofill_metrics.cc
@@ -261,6 +261,13 @@
                             NUM_INFO_BAR_METRICS);
 }
 
+void AutofillMetrics::LogAutocheckoutInfoBarMetric(InfoBarMetric metric) const {
+  DCHECK(metric < NUM_INFO_BAR_METRICS);
+
+  UMA_HISTOGRAM_ENUMERATION("Autofill.AutocheckoutInfoBar", metric,
+                            NUM_INFO_BAR_METRICS);
+}
+
 void AutofillMetrics::LogDeveloperEngagementMetric(
     DeveloperEngagementMetric metric) const {
   DCHECK(metric < NUM_DEVELOPER_ENGAGEMENT_METRICS);
diff --git a/chrome/browser/autofill/autofill_metrics.h b/chrome/browser/autofill/autofill_metrics.h
index f270c7a0..b7143ba 100644
--- a/chrome/browser/autofill/autofill_metrics.h
+++ b/chrome/browser/autofill/autofill_metrics.h
@@ -156,6 +156,8 @@
 
   virtual void LogUserHappinessMetric(UserHappinessMetric metric) const;
 
+  virtual void LogAutocheckoutInfoBarMetric(InfoBarMetric metric) const;
+
   // This should be called when a form that has been Autofilled is submitted.
   // |duration| should be the time elapsed between form load and submission.
   virtual void LogFormFillDurationFromLoadWithAutofill(
diff --git a/chrome/browser/autofill/autofill_metrics_unittest.cc b/chrome/browser/autofill/autofill_metrics_unittest.cc
index 40fb33fe..9946a5d 100644
--- a/chrome/browser/autofill/autofill_metrics_unittest.cc
+++ b/chrome/browser/autofill/autofill_metrics_unittest.cc
@@ -8,6 +8,7 @@
 #include "base/string16.h"
 #include "base/time.h"
 #include "base/utf_string_conversions.h"
+#include "chrome/browser/autofill/autocheckout_infobar_delegate.h"
 #include "chrome/browser/autofill/autofill_cc_infobar_delegate.h"
 #include "chrome/browser/autofill/autofill_common_test.h"
 #include "chrome/browser/autofill/autofill_manager.h"
@@ -22,6 +23,7 @@
 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/test/test_browser_thread.h"
+#include "googleurl/src/gurl.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/rect.h"
@@ -39,6 +41,7 @@
  public:
   MockAutofillMetrics() {}
   MOCK_CONST_METHOD1(LogCreditCardInfoBarMetric, void(InfoBarMetric metric));
+  MOCK_CONST_METHOD1(LogAutocheckoutInfoBarMetric, void(InfoBarMetric metric));
   MOCK_CONST_METHOD1(LogDeveloperEngagementMetric,
                      void(DeveloperEngagementMetric metric));
   MOCK_CONST_METHOD3(LogHeuristicTypePrediction,
@@ -257,6 +260,25 @@
   DISALLOW_COPY_AND_ASSIGN(TestAutofillManager);
 };
 
+class TestAutocheckoutManager : public AutocheckoutManager {
+ public:
+  explicit TestAutocheckoutManager(AutofillManager* autofill_manager)
+      : AutocheckoutManager(autofill_manager) {
+  }
+
+  virtual void ShowAutocheckoutDialog(
+      const GURL& frame_url,
+      const content::SSLStatus& ssl_status) OVERRIDE {
+    // no-op. Just used as callback from autocheckout_infobar_delegate.
+  }
+
+  virtual ~TestAutocheckoutManager() {
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TestAutocheckoutManager);
+};
+
 }  // namespace
 
 class AutofillMetricsTest : public ChromeRenderViewHostTestHarness {
@@ -272,6 +294,9 @@
       MockAutofillMetrics* metric_logger,
       CreditCard** created_card);
 
+  scoped_ptr<ConfirmInfoBarDelegate> CreateAutocheckoutDelegate(
+      MockAutofillMetrics* metric_logger);
+
   content::TestBrowserThread ui_thread_;
   content::TestBrowserThread file_thread_;
 
@@ -347,6 +372,20 @@
                                            metric_logger);
 }
 
+scoped_ptr<ConfirmInfoBarDelegate>
+AutofillMetricsTest::CreateAutocheckoutDelegate(
+    MockAutofillMetrics* metric_logger) {
+  EXPECT_CALL(*metric_logger,
+              LogAutocheckoutInfoBarMetric(AutofillMetrics::INFOBAR_SHOWN));
+  GURL url("www.google.com");
+  content::SSLStatus ssl_status;
+  return AutocheckoutInfoBarDelegate::Create(
+      *metric_logger,
+      url,
+      ssl_status,
+      new TestAutocheckoutManager(NULL));
+}
+
 // Test that we log quality metrics appropriately.
 TEST_F(AutofillMetricsTest, QualityMetrics) {
   // Set up our form data.
@@ -1186,6 +1225,65 @@
   }
 }
 
+// Test that autofill flow infobar metrics are logged correctly.
+TEST_F(AutofillMetricsTest, AutocheckoutInfoBar) {
+  MockAutofillMetrics metric_logger;
+  ::testing::InSequence dummy;
+
+  // Accept the infobar.
+  {
+    scoped_ptr<ConfirmInfoBarDelegate> infobar(
+        CreateAutocheckoutDelegate(&metric_logger));
+    ASSERT_TRUE(infobar);
+    EXPECT_CALL(metric_logger,
+        LogAutocheckoutInfoBarMetric(
+            AutofillMetrics::INFOBAR_ACCEPTED)).Times(1);
+    EXPECT_CALL(metric_logger,
+        LogAutocheckoutInfoBarMetric(
+            AutofillMetrics::INFOBAR_IGNORED)).Times(0);
+    EXPECT_TRUE(infobar->Accept());
+  }
+
+  // Cancel the infobar.
+  {
+    scoped_ptr<ConfirmInfoBarDelegate> infobar(
+        CreateAutocheckoutDelegate(&metric_logger));
+    ASSERT_TRUE(infobar);
+    EXPECT_CALL(metric_logger,
+        LogAutocheckoutInfoBarMetric(
+            AutofillMetrics::INFOBAR_DENIED)).Times(1);
+    EXPECT_CALL(metric_logger,
+        LogAutocheckoutInfoBarMetric(
+            AutofillMetrics::INFOBAR_IGNORED)).Times(0);
+    EXPECT_TRUE(infobar->Cancel());
+  }
+
+  // Dismiss the infobar.
+  {
+    scoped_ptr<ConfirmInfoBarDelegate> infobar(
+        CreateAutocheckoutDelegate(&metric_logger));
+    ASSERT_TRUE(infobar);
+    EXPECT_CALL(metric_logger,
+        LogAutocheckoutInfoBarMetric(
+            AutofillMetrics::INFOBAR_DENIED)).Times(1);
+    EXPECT_CALL(metric_logger,
+        LogAutocheckoutInfoBarMetric(
+            AutofillMetrics::INFOBAR_IGNORED)).Times(0);
+    infobar->InfoBarDismissed();
+  }
+
+  // Ignore the infobar.
+  {
+    scoped_ptr<ConfirmInfoBarDelegate> infobar(
+        CreateAutocheckoutDelegate(&metric_logger));
+    ASSERT_TRUE(infobar);
+    EXPECT_CALL(metric_logger,
+        LogAutocheckoutInfoBarMetric(
+            AutofillMetrics::INFOBAR_IGNORED)).Times(1);
+  }
+}
+
+
 // Test that server query response experiment id metrics are logged correctly.
 TEST_F(AutofillMetricsTest, ServerQueryExperimentIdForQuery) {
   MockAutofillMetrics metric_logger;
diff --git a/chrome/browser/autofill/autofill_xml_parser.cc b/chrome/browser/autofill/autofill_xml_parser.cc
index 92a1ede9..425185b7 100644
--- a/chrome/browser/autofill/autofill_xml_parser.cc
+++ b/chrome/browser/autofill/autofill_xml_parser.cc
@@ -33,6 +33,8 @@
     std::string* experiment_id)
     : field_types_(field_types),
       upload_required_(upload_required),
+      current_page_number_(-1),
+      total_pages_(-1),
       experiment_id_(experiment_id) {
   DCHECK(upload_required_);
   DCHECK(experiment_id_);
@@ -89,6 +91,18 @@
 
     // Record this field type.
     field_types_->push_back(field_type);
+  } else if (element.compare("autofill_flow") == 0) {
+    // |attrs| is a NULL-terminated list of (attribute, value) pairs.
+    while (*attrs) {
+      buzz::QName attribute_qname = context->ResolveQName(*attrs, true);
+      ++attrs;
+      const std::string& attribute_name = attribute_qname.LocalPart();
+      if (attribute_name.compare("page_no") == 0)
+        current_page_number_ = GetIntValue(context, *attrs);
+      else if (attribute_name.compare("total_pages") == 0)
+        total_pages_ = GetIntValue(context, *attrs);
+      ++attrs;
+    }
   }
 }
 
diff --git a/chrome/browser/autofill/autofill_xml_parser.h b/chrome/browser/autofill/autofill_xml_parser.h
index da3d5bf6..42df566 100644
--- a/chrome/browser/autofill/autofill_xml_parser.h
+++ b/chrome/browser/autofill/autofill_xml_parser.h
@@ -70,6 +70,10 @@
                          UploadRequired* upload_required,
                          std::string* experiment_id);
 
+  int current_page_number() const { return current_page_number_; }
+
+  int total_pages() const { return total_pages_; }
+
  private:
   // A callback for the beginning of a new <element>, called by Expat.
   // |context| is a parsing context used to resolve element/attribute names.
@@ -92,6 +96,12 @@
   // form is submitted.
   UploadRequired* upload_required_;
 
+  // Page number of present page in multipage autofill flow.
+  int current_page_number_;
+
+  // Total number of pages in multipage autofill flow.
+  int total_pages_;
+
   // The server experiment to which this query response belongs.
   // For the default server implementation, this is empty.
   std::string* experiment_id_;
diff --git a/chrome/browser/autofill/autofill_xml_parser_unittest.cc b/chrome/browser/autofill/autofill_xml_parser_unittest.cc
index a0a1024..44ea704 100644
--- a/chrome/browser/autofill/autofill_xml_parser_unittest.cc
+++ b/chrome/browser/autofill/autofill_xml_parser_unittest.cc
@@ -154,6 +154,28 @@
   EXPECT_EQ(std::string("ServerSmartyPants"), experiment_id);
 }
 
+// Test XML response with autofill_flow information.
+TEST(AutofillQueryXmlParserTest, ParseAutofillFlow) {
+  std::vector<AutofillFieldType> field_types;
+  UploadRequired upload_required = USE_UPLOAD_RATES;
+  std::string experiment_id;
+
+  std::string xml = "<autofillqueryresponse>"
+                    "<field autofilltype=\"55\"/>"
+                    "<autofill_flow page_no=\"1\" total_pages=\"10\"/>"
+                    "</autofillqueryresponse>";
+
+  scoped_ptr<AutofillQueryXmlParser> parse_handler(
+      new AutofillQueryXmlParser(&field_types, &upload_required,
+                                 &experiment_id));
+  scoped_ptr<buzz::XmlParser> parser(new buzz::XmlParser(parse_handler.get()));
+  parser->Parse(xml.c_str(), xml.length(), true);
+  EXPECT_TRUE(parse_handler->succeeded());
+  EXPECT_EQ(1U, field_types.size());
+  EXPECT_EQ(1, parse_handler->current_page_number());
+  EXPECT_EQ(10, parse_handler->total_pages());
+}
+
 // Test badly formed XML queries.
 TEST(AutofillQueryXmlParserTest, ParseErrors) {
   std::vector<AutofillFieldType> field_types;
diff --git a/chrome/browser/autofill/form_structure.cc b/chrome/browser/autofill/form_structure.cc
index d1ca6d1..8852240 100644
--- a/chrome/browser/autofill/form_structure.cc
+++ b/chrome/browser/autofill/form_structure.cc
@@ -229,6 +229,8 @@
       autofill_count_(0),
       upload_required_(USE_UPLOAD_RATES),
       server_experiment_id_("no server response"),
+      current_page_number_(-1),
+      total_pages_(-1),
       has_author_specified_types_(false) {
   // Copy the form fields.
   std::map<string16, size_t> unique_names;
@@ -429,6 +431,8 @@
     FormStructure* form = *iter;
     form->upload_required_ = upload_required;
     form->server_experiment_id_ = experiment_id;
+    form->current_page_number_ = parse_handler.current_page_number();
+    form->total_pages_ = parse_handler.total_pages();
 
     for (std::vector<AutofillField*>::iterator field = form->fields_.begin();
          field != form->fields_.end(); ++field, ++current_type) {
@@ -1016,6 +1020,14 @@
   }
 }
 
+bool FormStructure::IsStartOfAutofillableFlow() const {
+  return current_page_number_ == 0 && total_pages_ > 0;
+}
+
+bool FormStructure::IsInAutofillableFlow() const {
+  return current_page_number_ >= 0 && current_page_number_ < total_pages_;
+}
+
 void FormStructure::IdentifySections(bool has_author_specified_sections) {
   if (fields_.empty())
     return;
diff --git a/chrome/browser/autofill/form_structure.h b/chrome/browser/autofill/form_structure.h
index 45cf2bb..2b47756 100644
--- a/chrome/browser/autofill/form_structure.h
+++ b/chrome/browser/autofill/form_structure.h
@@ -124,6 +124,14 @@
   void ParseFieldTypesFromAutocompleteAttributes(bool* found_types,
                                                  bool* found_sections);
 
+  // Returns true if the autofill server says that the current page is start of
+  // the autofillable flow.
+  bool IsStartOfAutofillableFlow() const;
+
+  // Returns true if the autofill server says that the current page is in the
+  // autofillable flow.
+  bool IsInAutofillableFlow() const;
+
   const AutofillField* field(size_t index) const;
   AutofillField* field(size_t index);
   size_t field_count() const;
@@ -208,6 +216,14 @@
   // GET or POST.
   RequestMethod method_;
 
+  // Page number of the autofill flow this form belongs to (zero-indexed).
+  // If this form doesn't belong to any autofill flow, it is set to -1.
+  int current_page_number_;
+
+  // Total number of pages in the autofill flow. If this form doesn't belong
+  // to any autofill flow, it is set to -1.
+  int total_pages_;
+
   // Whether the form includes any field types explicitly specified by the site
   // author, via the |autocompletetype| attribute.
   bool has_author_specified_types_;
diff --git a/chrome/browser/autofill/form_structure_unittest.cc b/chrome/browser/autofill/form_structure_unittest.cc
index bd2bded..7ea1012 100644
--- a/chrome/browser/autofill/form_structure_unittest.cc
+++ b/chrome/browser/autofill/form_structure_unittest.cc
@@ -59,6 +59,13 @@
   static std::string Hash64Bit(const std::string& str) {
     return FormStructure::Hash64Bit(str);
   }
+
+  static void SetPageDetails(FormStructure* form,
+                             int page_number,
+                             int total_pages) {
+    form->current_page_number_ = page_number;
+    form->total_pages_ = total_pages;
+  }
 };
 
 TEST(FormStructureTest, FieldCount) {
@@ -87,6 +94,41 @@
   EXPECT_EQ(3U, form_structure.field_count());
 }
 
+TEST(FormStructureTest, AutofillFlowInfo) {
+  FormData form;
+  form.method = ASCIIToUTF16("post");
+
+  FormFieldData field;
+  field.label = ASCIIToUTF16("username");
+  field.name = ASCIIToUTF16("username");
+  field.form_control_type = "text";
+  form.fields.push_back(field);
+
+  FormStructure form_structure(form);
+  EXPECT_FALSE(form_structure.IsStartOfAutofillableFlow());
+  EXPECT_FALSE(form_structure.IsInAutofillableFlow());
+
+  FormStructureTest::SetPageDetails(&form_structure, -1, 0);
+  EXPECT_FALSE(form_structure.IsStartOfAutofillableFlow());
+  EXPECT_FALSE(form_structure.IsInAutofillableFlow());
+
+  FormStructureTest::SetPageDetails(&form_structure, 0, 0);
+  EXPECT_FALSE(form_structure.IsStartOfAutofillableFlow());
+  EXPECT_FALSE(form_structure.IsInAutofillableFlow());
+
+  FormStructureTest::SetPageDetails(&form_structure, 0, 1);
+  EXPECT_TRUE(form_structure.IsStartOfAutofillableFlow());
+  EXPECT_TRUE(form_structure.IsInAutofillableFlow());
+
+  FormStructureTest::SetPageDetails(&form_structure, 1, 2);
+  EXPECT_FALSE(form_structure.IsStartOfAutofillableFlow());
+  EXPECT_TRUE(form_structure.IsInAutofillableFlow());
+
+  FormStructureTest::SetPageDetails(&form_structure, 2, 2);
+  EXPECT_FALSE(form_structure.IsStartOfAutofillableFlow());
+  EXPECT_FALSE(form_structure.IsInAutofillableFlow());
+}
+
 TEST(FormStructureTest, AutofillCount) {
   FormData form;
   form.method = ASCIIToUTF16("post");
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index d6f7261..7a7c0ca 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -176,6 +176,10 @@
         'browser/autofill/address.h',
         'browser/autofill/address_field.cc',
         'browser/autofill/address_field.h',
+        'browser/autofill/autocheckout_infobar_delegate.cc',
+        'browser/autofill/autocheckout_infobar_delegate.h',
+        'browser/autofill/autocheckout_manager.cc',
+        'browser/autofill/autocheckout_manager.h',
         'browser/autofill/autocomplete_history_manager.cc',
         'browser/autofill/autocomplete_history_manager.h',
         'browser/autofill/autofill-inl.h',
diff --git a/chrome/common/form_data.cc b/chrome/common/form_data.cc
index a78d4514..d857a14b 100644
--- a/chrome/common/form_data.cc
+++ b/chrome/common/form_data.cc
@@ -16,7 +16,8 @@
       origin(data.origin),
       action(data.action),
       user_submitted(data.user_submitted),
-      fields(data.fields) {
+      fields(data.fields),
+      ssl_status(data.ssl_status) {
 }
 
 FormData::~FormData() {
@@ -28,7 +29,8 @@
           origin == form.origin &&
           action == form.action &&
           user_submitted == form.user_submitted &&
-          fields == form.fields);
+          fields == form.fields &&
+          ssl_status.Equals(form.ssl_status));
 }
 
 bool FormData::operator!=(const FormData& form) const {
diff --git a/chrome/common/form_data.h b/chrome/common/form_data.h
index 018c9f9..40d9434 100644
--- a/chrome/common/form_data.h
+++ b/chrome/common/form_data.h
@@ -9,10 +9,19 @@
 
 #include "base/string16.h"
 #include "chrome/common/form_field_data.h"
+#include "content/public/common/ssl_status.h"
 #include "googleurl/src/gurl.h"
 
 // Holds information about a form to be filled and/or submitted.
 struct FormData {
+  FormData();
+  FormData(const FormData& data);
+  ~FormData();
+
+  // Used by FormStructureTest.
+  bool operator==(const FormData& form) const;
+  bool operator!=(const FormData& form) const;
+
   // The name of the form.
   string16 name;
   // GET or POST.
@@ -25,14 +34,8 @@
   bool user_submitted;
   // A vector of all the input fields in the form.
   std::vector<FormFieldData> fields;
-
-  FormData();
-  FormData(const FormData& data);
-  ~FormData();
-
-  // Used by FormStructureTest.
-  bool operator==(const FormData& form) const;
-  bool operator!=(const FormData& form) const;
+  // SSL status of the frame contatining the form.
+  content::SSLStatus ssl_status;
 };
 
 #endif  // CHROME_COMMON_FORM_DATA_H__
diff --git a/chrome/renderer/autofill/autofill_agent.cc b/chrome/renderer/autofill/autofill_agent.cc
index b20be00..820523c 100644
--- a/chrome/renderer/autofill/autofill_agent.cc
+++ b/chrome/renderer/autofill/autofill_agent.cc
@@ -236,6 +236,7 @@
   HidePopups();
 
   in_flight_request_form_ = form;
+  // TODO(ramankk): Include SSLStatus within form_data and update the IPC.
   Send(new AutofillHostMsg_RequestAutocomplete(
       routing_id(),
       form_data,
@@ -713,6 +714,10 @@
                                        data_list_icons,
                                        data_list_unique_ids));
 
+  // Add SSL Status in the formdata to let browser process alert user
+  // appropriately using browser UI.
+  form.ssl_status = render_view()->GetSSLStatusOfFrame(
+      element.document().frame());
   Send(new AutofillHostMsg_QueryFormFieldAutofill(routing_id(),
                                                   autofill_query_id_,
                                                   form,