summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraruslan@chromium.org <aruslan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-10 18:27:05 +0000
committeraruslan@chromium.org <aruslan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-10 18:27:05 +0000
commit8f5999edb03c488b5ce26d1de034c9ebcd4c48c5 (patch)
tree83effeef3ecf4a177d1a03a1965666e21dc632ea
parentdc6cb14e949d890eb6b87bc498bb7a266c665335 (diff)
downloadchromium_src-8f5999edb03c488b5ce26d1de034c9ebcd4c48c5.zip
chromium_src-8f5999edb03c488b5ce26d1de034c9ebcd4c48c5.tar.gz
chromium_src-8f5999edb03c488b5ce26d1de034c9ebcd4c48c5.tar.bz2
[rAc Android dialog] Stubs for Autofill dialog integration.
This includes JNI bindings, Java interfaces and necessary glue for the requestAutocomplete dialog. BUG=157277 Review URL: https://chromiumcodereview.appspot.com/22566004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@216883 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--build/common.gypi4
-rw-r--r--chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillDialogControllerAndroid.java190
-rw-r--r--chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillDialogResult.java246
-rw-r--r--chrome/browser/android/chrome_jni_registrar.cc7
-rw-r--r--chrome/browser/ui/android/autofill/autofill_dialog_controller_android.cc488
-rw-r--r--chrome/browser/ui/android/autofill/autofill_dialog_controller_android.h144
-rw-r--r--chrome/browser/ui/android/autofill/autofill_dialog_result.cc138
-rw-r--r--chrome/browser/ui/android/autofill/autofill_dialog_result.h49
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--chrome/chrome_browser_ui.gypi4
-rw-r--r--chrome/common/pref_names.cc4
-rw-r--r--chrome/common/pref_names.h1
12 files changed, 1275 insertions, 2 deletions
diff --git a/build/common.gypi b/build/common.gypi
index 3517971..1589955 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -530,8 +530,8 @@
'native_memory_pressure_signals%': 1,
}],
- # Enable autofill dialog for Mac and Views-enabled platforms for now.
- ['toolkit_views==1 or OS=="mac"', {
+ # Enable autofill dialog for Android, Mac and Views-enabled platforms.
+ ['toolkit_views==1 or (OS=="android" and android_webview_build==0) or OS=="mac"', {
'enable_autofill_dialog%': 1
}],
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillDialogControllerAndroid.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillDialogControllerAndroid.java
new file mode 100644
index 0000000..e7696d5
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillDialogControllerAndroid.java
@@ -0,0 +1,190 @@
+// Copyright 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.
+
+package org.chromium.chrome.browser.autofill;
+
+import org.chromium.base.CalledByNative;
+import org.chromium.base.JNINamespace;
+import org.chromium.ui.WindowAndroid;
+
+/**
+ * Java-side AutofillDialog and AutofillDialogFactory interfaces, and
+ * JNI glue for C++ AutofillDialogControllerAndroid.
+ */
+@JNINamespace("autofill")
+public class AutofillDialogControllerAndroid {
+ private static AutofillDialogFactory mDialogFactory;
+
+ private int mNativeDelegate; // could be 0 after onDestroy().
+ private AutofillDialog mDialog;
+
+ /**
+ * An interface to the two possible continuations for the dialog.
+ * The dialog is expected to be dismissed when either of the calls is made.
+ */
+ public interface AutofillDialogDelegate {
+ /**
+ * Cancels the requestAutocomplete.
+ */
+ void dialogCancel();
+
+ /**
+ * Submits the data to the web-page and persists the last account/card/address choices.
+ * @param fullWallet Resulting billing/shipping information obtained from the user
+ * @param lastUsedChoiceIsAutofill Whether the last selected data source is Autofill
+ * @param lastUsedAccountName The last selected account name, or null
+ * @param guidLastUsedBilling GUID of the last selected Autofill billing address, or null
+ * @param guidLastUsedShipping GUID of the last selected Autofill shipping address, or null
+ * @param guidLastUsedCard GUID of the last selected Autofill credit card, or null
+ */
+ void dialogContinue(
+ AutofillDialogResult.ResultWallet fullWallet,
+ boolean lastUsedChoiceIsAutofill, String lastUsedAccountName,
+ String guidLastUsedBilling, String guidLastUsedShipping, String guidLastUsedCard);
+ }
+
+ /**
+ * An interface that exposes the necessary functionality for an Autofill dialog.
+ * Note that all information necessary to construct the dialog is passed to the factory.
+ */
+ public interface AutofillDialog {
+ /**
+ * Notifies the dialog that the C++ side is gone.
+ * The dialog needs to clear its reference to the no longer valid AutofillDialogDelegate.
+ */
+ void onDestroy();
+ }
+
+ /**
+ * An interface to the factory that creates Autofill dialogs.
+ */
+ public interface AutofillDialogFactory {
+ /**
+ * Creates the dialog.
+ * Reasonable attempts should be made to respect "initial choices",
+ * Initial choices don't have to be self-consistent or valid.
+ *
+ * @param delegate Continuations for the dialog
+ * @param windowAndroid Context in which the dialog should be shown
+ * @param requestFullBillingAddress Whether the full billing address is required
+ * @param requestShippingAddress Whether the shipping address is required
+ * @param requestPhoneNumbers Whether the phone numbers are required in addresses
+ * @param incognitoMode True if the dialog started from an incognito tab
+ * @param initialChoiceIsAutofill Whether the selected data source should be Autofill
+ * @param initialAccountName Account to be selected, or null
+ * @param initialBillingGuid GUID of the initial billing address selection in Autofill
+ * @param initialShippingGuid GUID of the initial shipping address selection in Autofill
+ * @param initialCardGuid GUID of the initial credit card selection in Autofill
+ * @param merchantDomain Scheme+origin for the originating web page, or null
+ * @return The Autofill dialog that would later call into the delegate, or null
+ */
+ AutofillDialog createDialog(
+ final AutofillDialogDelegate delegate,
+ final WindowAndroid windowAndroid,
+ final boolean requestFullBillingAddress, final boolean requestShippingAddress,
+ final boolean requestPhoneNumbers,
+ final boolean incognitoMode,
+ final boolean initialChoiceIsAutofill, final String initialAccountName,
+ final String initialBillingGuid, final String initialShippingGuid,
+ final String initialCardGuid,
+ final String merchantDomain);
+ }
+
+ /**
+ * Sets the factory to be used.
+ * @param factory An instance of the AutofillDialogFactory that will handle requests.
+ */
+ public static void setDialogFactory(AutofillDialogFactory factory) {
+ mDialogFactory = factory;
+ }
+
+ private AutofillDialogControllerAndroid(
+ final int nativeAutofillDialogControllerAndroid,
+ final WindowAndroid windowAndroid,
+ final boolean requestFullBillingAddress, final boolean requestShippingAddress,
+ final boolean requestPhoneNumbers,
+ final boolean incognitoMode,
+ final boolean initialChoiceIsAutofill, final String initialWalletAccountName,
+ final String initialBillingGuid, final String initialShippingGuid,
+ final String initialCardGuid,
+ final String merchantDomain) {
+ mNativeDelegate = nativeAutofillDialogControllerAndroid;
+
+ if (mDialogFactory == null) {
+ nativeDialogCancel(mNativeDelegate);
+ return;
+ }
+
+ AutofillDialogDelegate delegate = new AutofillDialogDelegate() {
+ @Override
+ public void dialogCancel() {
+ nativeDialogCancel(mNativeDelegate);
+ }
+
+ @Override
+ public void dialogContinue(
+ AutofillDialogResult.ResultWallet fullWallet,
+ boolean lastUsedChoiceIsAutofill, String lastUsedAccountName,
+ String guidLastUsedBilling, String guidLastUsedShipping,
+ String guidLastUsedCard) {
+ nativeDialogContinue(mNativeDelegate, fullWallet,
+ lastUsedChoiceIsAutofill, lastUsedAccountName,
+ guidLastUsedBilling, guidLastUsedShipping, guidLastUsedCard);
+ }
+ };
+
+ mDialog = mDialogFactory.createDialog(
+ delegate,
+ windowAndroid,
+ requestFullBillingAddress, requestShippingAddress,
+ requestPhoneNumbers,
+ incognitoMode,
+ initialChoiceIsAutofill, initialWalletAccountName,
+ initialBillingGuid, initialShippingGuid, initialCardGuid,
+ merchantDomain);
+ if (mDialog == null) {
+ nativeDialogCancel(mNativeDelegate);
+ return;
+ }
+ }
+
+ @CalledByNative
+ private static AutofillDialogControllerAndroid create(
+ final int nativeAutofillDialogControllerAndroid,
+ final WindowAndroid windowAndroid,
+ final boolean requestFullBillingAddress, final boolean requestShippingAddress,
+ final boolean requestPhoneNumbers,
+ final boolean incognitoMode,
+ final boolean initialChoiceIsAutofill, final String initialWalletAccountName,
+ final String initialBillingGuid, final String initialShippingGuid,
+ final String initialCreditCardGuid,
+ final String merchantDomain) {
+ return new AutofillDialogControllerAndroid(
+ nativeAutofillDialogControllerAndroid, windowAndroid,
+ requestFullBillingAddress, requestShippingAddress, requestPhoneNumbers,
+ incognitoMode,
+ initialChoiceIsAutofill, initialWalletAccountName,
+ initialBillingGuid, initialShippingGuid,
+ initialCreditCardGuid,
+ merchantDomain);
+ }
+
+ @CalledByNative
+ private void onDestroy() {
+ if (mNativeDelegate == 0) return;
+
+ if (mDialog != null) mDialog.onDestroy();
+
+ mDialog = null;
+ mNativeDelegate = 0;
+ }
+
+ // Calls from Java to C++ AutofillDialogControllerAndroid:
+
+ private native void nativeDialogCancel(int nativeAutofillDialogControllerAndroid);
+ private native void nativeDialogContinue(int nativeAutofillDialogControllerAndroid,
+ Object fullWallet,
+ boolean lastUsedChoiceIsAutofill, String lastUsedAccountName,
+ String guidLastUsedBilling, String guidLastUsedShipping, String guidLastUsedCard);
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillDialogResult.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillDialogResult.java
new file mode 100644
index 0000000..92f0cd8
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillDialogResult.java
@@ -0,0 +1,246 @@
+// Copyright 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.
+
+package org.chromium.chrome.browser.autofill;
+
+import org.chromium.base.CalledByNative;
+import org.chromium.base.JNINamespace;
+
+/**
+ * Java-side result of a non-cancelled AutofillDialog invocation, and
+ * JNI glue for C++ AutofillDialogResult used by AutofillDialogControllerAndroid.
+ */
+@JNINamespace("autofill")
+public class AutofillDialogResult {
+ /**
+ * Information about the credit card in the dialog result.
+ */
+ public static class ResultCard {
+ private final int mExpirationMonth;
+ private final int mExpirationYear;
+ private final String mPan;
+ private final String mCvn;
+
+ /**
+ * Creates a ResultCard.
+ * @param expirationMonth Expiration month
+ * @param expirationYear Expiration year
+ * @param pan Credit card number
+ * @param cvn Credit card verification number
+ */
+ public ResultCard(int expirationMonth, int expirationYear, String pan, String cvn) {
+ mExpirationMonth = expirationMonth;
+ mExpirationYear = expirationYear;
+ mPan = pan;
+ mCvn = cvn;
+ }
+
+ /**
+ * @return Expiration month
+ */
+ @CalledByNative("ResultCard")
+ public int getExpirationMonth() {
+ return mExpirationMonth;
+ }
+
+ /**
+ * @return Expiration year
+ */
+ @CalledByNative("ResultCard")
+ public int getExpirationYear() {
+ return mExpirationYear;
+ }
+
+ /**
+ * @return Credit card number
+ */
+ @CalledByNative("ResultCard")
+ public String getPan() {
+ return mPan;
+ }
+
+ /**
+ * @return Credit card verification number
+ */
+ @CalledByNative("ResultCard")
+ public String getCvn() {
+ return mCvn;
+ }
+ }
+
+ /**
+ * Information about an address in the dialog result.
+ */
+ public static class ResultAddress {
+ private final String mName;
+ private final String mPhoneNumber;
+ private final String mAddress1;
+ private final String mAddress2;
+ private final String mCity;
+ private final String mState;
+ private final String mPostalCode;
+ private final String mCountryCode;
+
+ /**
+ * Creates a ResultAddress.
+ * Any parameter can be empty or null.
+ * @param name Full name
+ * @param phoneNumber Phone number
+ * @param address1 Address line 1
+ * @param address2 Address line 2
+ * @param city City
+ * @param state State
+ * @param postalCode Postal code
+ * @param countryCode Country code
+ */
+ public ResultAddress(
+ String name, String phoneNumber,
+ String address1, String address2,
+ String city, String state, String postalCode,
+ String countryCode) {
+ mName = name;
+ mPhoneNumber = phoneNumber;
+ mAddress1 = address1;
+ mAddress2 = address2;
+ mCity = city;
+ mState = state;
+ mPostalCode = postalCode;
+ mCountryCode = countryCode;
+ }
+
+ /**
+ * @return Full name
+ */
+ @CalledByNative("ResultAddress")
+ public String getName() {
+ return mName;
+ }
+
+ /**
+ * @return Phone number
+ */
+ @CalledByNative("ResultAddress")
+ public String getPhoneNumber() {
+ return mPhoneNumber;
+ }
+
+ /**
+ * @return Address line 1
+ */
+ @CalledByNative("ResultAddress")
+ public String getAddress1() {
+ return mAddress1;
+ }
+
+ /**
+ * @return Address line 2
+ */
+ @CalledByNative("ResultAddress")
+ public String getAddress2() {
+ return mAddress2;
+ }
+
+ /**
+ * @return City
+ */
+ @CalledByNative("ResultAddress")
+ public String getCity() {
+ return mCity;
+ }
+
+ /**
+ * @return State
+ */
+ @CalledByNative("ResultAddress")
+ public String getState() {
+ return mState;
+ }
+
+ /**
+ * @return Postal code
+ */
+ @CalledByNative("ResultAddress")
+ public String getPostalCode() {
+ return mPostalCode;
+ }
+
+ /**
+ * @return Country code
+ */
+ @CalledByNative("ResultAddress")
+ public String getCountryCode() {
+ return mCountryCode;
+ }
+ }
+
+ /**
+ * A response from the dialog.
+ */
+ public static class ResultWallet {
+ private final String mEmail;
+ private final String mGoogleTransactionId;
+ private final ResultCard mCard;
+ private final ResultAddress mBillingAddress;
+ private final ResultAddress mShippingAddress;
+
+ /**
+ * Creates a ResultWallet.
+ * Any fields could be empty or null.
+ * @param email Email address
+ * @param googleTransactionId Google transaction ID if any
+ * @param card Information about the credit card
+ * @param billingAddress Information about the billing address
+ * @param shippingAddress Information about the shipping address
+ */
+ public ResultWallet(
+ String email, String googleTransactionId,
+ ResultCard card, ResultAddress billingAddress, ResultAddress shippingAddress) {
+ mEmail = email;
+ mGoogleTransactionId = googleTransactionId;
+ mCard = card;
+ mBillingAddress = billingAddress;
+ mShippingAddress = shippingAddress;
+ }
+
+ /**
+ * @return Email address
+ */
+ @CalledByNative("ResultWallet")
+ public String getEmail() {
+ return mEmail;
+ }
+
+ /**
+ * @return Google transaction ID if any
+ */
+ @CalledByNative("ResultWallet")
+ public String getGoogleTransactionId() {
+ return mGoogleTransactionId;
+ }
+
+ /**
+ * @return Credit card information, or null
+ */
+ @CalledByNative("ResultWallet")
+ public ResultCard getCard() {
+ return mCard;
+ }
+
+ /**
+ * @return Billing address information, or null
+ */
+ @CalledByNative("ResultWallet")
+ public ResultAddress getBillingAddress() {
+ return mBillingAddress;
+ }
+
+ /**
+ * @return Shipping address information, or null
+ */
+ @CalledByNative("ResultWallet")
+ public ResultAddress getShippingAddress() {
+ return mShippingAddress;
+ }
+ }
+}
diff --git a/chrome/browser/android/chrome_jni_registrar.cc b/chrome/browser/android/chrome_jni_registrar.cc
index 5b6c457e..1675c62 100644
--- a/chrome/browser/android/chrome_jni_registrar.cc
+++ b/chrome/browser/android/chrome_jni_registrar.cc
@@ -27,6 +27,8 @@
#include "chrome/browser/signin/android_profile_oauth2_token_service.h"
#include "chrome/browser/speech/tts_android.h"
#include "chrome/browser/sync/profile_sync_service_android.h"
+#include "chrome/browser/ui/android/autofill/autofill_dialog_controller_android.h"
+#include "chrome/browser/ui/android/autofill/autofill_dialog_result.h"
#include "chrome/browser/ui/android/autofill/autofill_popup_view_android.h"
#include "chrome/browser/ui/android/chrome_http_auth_handler.h"
#include "chrome/browser/ui/android/javascript_app_modal_dialog_android.h"
@@ -54,6 +56,11 @@ static base::android::RegistrationMethod kChromeRegisteredMethods[] = {
{ "AndroidProfileOAuth2TokenService",
AndroidProfileOAuth2TokenService::Register },
{ "ApplicationLifetime", RegisterApplicationLifetimeAndroid },
+ { "AutofillDialogControllerAndroid",
+ autofill::AutofillDialogControllerAndroid::
+ RegisterAutofillDialogControllerAndroid },
+ { "AutofillDialogResult",
+ autofill::AutofillDialogResult::RegisterAutofillDialogResult },
{ "AutofillPopup",
autofill::AutofillPopupViewAndroid::RegisterAutofillPopupViewAndroid },
{ "CertificateViewer", RegisterCertificateViewer },
diff --git a/chrome/browser/ui/android/autofill/autofill_dialog_controller_android.cc b/chrome/browser/ui/android/autofill/autofill_dialog_controller_android.cc
new file mode 100644
index 0000000..00f5da8
--- /dev/null
+++ b/chrome/browser/ui/android/autofill/autofill_dialog_controller_android.cc
@@ -0,0 +1,488 @@
+// Copyright 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/ui/android/autofill/autofill_dialog_controller_android.h"
+
+#include "base/android/jni_android.h"
+#include "base/android/jni_array.h"
+#include "base/android/jni_string.h"
+#include "base/android/scoped_java_ref.h"
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/prefs/pref_service.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/autofill/personal_data_manager_factory.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/prefs/scoped_user_pref_update.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/ui/android/autofill/autofill_dialog_result.h"
+#include "chrome/browser/ui/android/window_android_helper.h"
+#include "chrome/browser/ui/autofill/autofill_dialog_common.h"
+#include "chrome/browser/ui/autofill/data_model_wrapper.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/common/url_constants.h"
+#include "components/autofill/content/browser/wallet/full_wallet.h"
+#include "components/autofill/core/browser/autofill_metrics.h"
+#include "components/autofill/core/browser/autofill_profile.h"
+#include "components/autofill/core/browser/autofill_type.h"
+#include "components/autofill/core/browser/credit_card.h"
+#include "components/autofill/core/browser/personal_data_manager.h"
+#include "components/autofill/core/common/form_data.h"
+#include "components/user_prefs/pref_registry_syncable.h"
+#include "content/public/browser/navigation_controller.h"
+#include "content/public/browser/navigation_details.h"
+#include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/web_contents.h"
+#include "grit/generated_resources.h"
+#include "jni/AutofillDialogControllerAndroid_jni.h"
+#include "ui/android/window_android.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/models/combobox_model.h"
+#include "ui/base/models/menu_model.h"
+#include "ui/gfx/android/java_bitmap.h"
+#include "ui/gfx/rect.h"
+#include "url/gurl.h"
+
+namespace autofill {
+
+namespace {
+
+// Keys in kAutofillDialogDefaults pref dictionary (do not change these values).
+const char kLastUsedAccountName[] = "last_used_account_name";
+const char kLastUsedChoiceIsAutofill[] = "last_used_choice_is_autofill";
+const char kLastUsedBillingAddressGuid[] = "last_used_billing";
+const char kLastUsedShippingAddressGuid[] = "last_used_shipping";
+const char kLastUsedCreditCardGuid[] = "last_used_card";
+
+scoped_ptr<DataModelWrapper> CreateWrapper(
+ DialogSection section, wallet::FullWallet* full_wallet) {
+ if (section == SECTION_CC_BILLING) {
+ if (!full_wallet->billing_address())
+ return scoped_ptr<DataModelWrapper>();
+
+ return scoped_ptr<DataModelWrapper>(
+ new FullWalletBillingWrapper(full_wallet));
+ }
+ if (section == SECTION_SHIPPING) {
+ if (!full_wallet->shipping_address())
+ return scoped_ptr<DataModelWrapper>();
+
+ return scoped_ptr<DataModelWrapper>(
+ new FullWalletShippingWrapper(full_wallet));
+ }
+ NOTREACHED();
+ return scoped_ptr<DataModelWrapper>();
+}
+
+void FillOutputForSectionWithComparator(
+ DialogSection section, const DetailInputs& inputs,
+ const InputFieldComparator& compare,
+ FormStructure& form_structure, wallet::FullWallet* full_wallet,
+ const base::string16& email_address) {
+
+ // Email is hidden while using Wallet, special case it.
+ if (section == SECTION_EMAIL) {
+ AutofillProfile profile;
+ profile.SetRawInfo(EMAIL_ADDRESS, email_address);
+ AutofillProfileWrapper profile_wrapper(&profile, 0);
+ profile_wrapper.FillFormStructure(inputs, compare, &form_structure);
+ return;
+ }
+
+ scoped_ptr<DataModelWrapper> wrapper = CreateWrapper(section, full_wallet);
+ if (wrapper)
+ wrapper->FillFormStructure(inputs, compare, &form_structure);
+}
+
+void FillOutputForSection(
+ DialogSection section,
+ FormStructure& form_structure,
+ wallet::FullWallet* full_wallet,
+ const base::string16& email_address) {
+ DetailInputs inputs;
+ common::BuildInputsForSection(section, &inputs);
+
+ FillOutputForSectionWithComparator(
+ section, inputs,
+ base::Bind(common::DetailInputMatchesField, section),
+ form_structure, full_wallet, email_address);
+}
+
+} // namespace
+
+
+// static
+base::WeakPtr<AutofillDialogController> AutofillDialogControllerAndroid::Create(
+ content::WebContents* contents,
+ const FormData& form_structure,
+ const GURL& source_url,
+ const DialogType dialog_type,
+ const base::Callback<void(const FormStructure*,
+ const std::string&)>& callback) {
+ // AutofillDialogControllerAndroid owns itself.
+ AutofillDialogControllerAndroid* autofill_dialog_controller =
+ new AutofillDialogControllerAndroid(contents,
+ form_structure,
+ source_url,
+ dialog_type,
+ callback);
+ return autofill_dialog_controller->weak_ptr_factory_.GetWeakPtr();
+}
+
+// static
+void AutofillDialogControllerAndroid::RegisterProfilePrefs(
+ user_prefs::PrefRegistrySyncable* registry) {
+ registry->RegisterDictionaryPref(
+ ::prefs::kAutofillDialogDefaults,
+ user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
+}
+
+// static
+base::WeakPtr<AutofillDialogController>
+AutofillDialogController::Create(
+ content::WebContents* contents,
+ const FormData& form_structure,
+ const GURL& source_url,
+ const DialogType dialog_type,
+ const base::Callback<void(const FormStructure*,
+ const std::string&)>& callback) {
+ return AutofillDialogControllerAndroid::Create(contents,
+ form_structure,
+ source_url,
+ dialog_type,
+ callback);
+}
+
+// static
+void AutofillDialogController::RegisterProfilePrefs(
+ user_prefs::PrefRegistrySyncable* registry) {
+ AutofillDialogControllerAndroid::RegisterProfilePrefs(registry);
+}
+
+AutofillDialogControllerAndroid::~AutofillDialogControllerAndroid() {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ Java_AutofillDialogControllerAndroid_onDestroy(env, java_object_.obj());
+}
+
+void AutofillDialogControllerAndroid::Show() {
+ dialog_shown_timestamp_ = base::Time::Now();
+
+ content::NavigationEntry* entry = contents_->GetController().GetActiveEntry();
+ const GURL& active_url = entry ? entry->GetURL() : contents_->GetURL();
+ invoked_from_same_origin_ = active_url.GetOrigin() == source_url_.GetOrigin();
+
+ // Log any relevant UI metrics and security exceptions.
+ GetMetricLogger().LogDialogUiEvent(
+ GetDialogType(), AutofillMetrics::DIALOG_UI_SHOWN);
+
+ GetMetricLogger().LogDialogSecurityMetric(
+ GetDialogType(), AutofillMetrics::SECURITY_METRIC_DIALOG_SHOWN);
+
+ if (RequestingCreditCardInfo() && !TransmissionWillBeSecure()) {
+ GetMetricLogger().LogDialogSecurityMetric(
+ GetDialogType(),
+ AutofillMetrics::SECURITY_METRIC_CREDIT_CARD_OVER_HTTP);
+ }
+
+ if (!invoked_from_same_origin_) {
+ GetMetricLogger().LogDialogSecurityMetric(
+ GetDialogType(),
+ AutofillMetrics::SECURITY_METRIC_CROSS_ORIGIN_FRAME);
+ }
+
+ // Determine what field types should be included in the dialog.
+ bool has_types = false;
+ bool has_sections = false;
+ form_structure_.ParseFieldTypesFromAutocompleteAttributes(
+ &has_types, &has_sections);
+
+ // Fail if the author didn't specify autocomplete types.
+ if (!has_types) {
+ callback_.Run(NULL, std::string());
+ delete this;
+ return;
+ }
+
+ bool request_full_billing_address = true;
+ bool request_shipping_address = false;
+ bool request_phone_numbers = false;
+
+ for (size_t i = 0; i < form_structure_.field_count(); ++i) {
+ const ServerFieldType type =
+ form_structure_.field(i)->Type().GetStorableType();
+ if (type == PHONE_HOME_WHOLE_NUMBER || type == PHONE_BILLING_WHOLE_NUMBER) {
+ request_phone_numbers = true;
+ }
+ if (type == NAME_FULL ||
+ type == ADDRESS_HOME_LINE1 || type == ADDRESS_HOME_LINE2 ||
+ type == ADDRESS_HOME_CITY || type == ADDRESS_HOME_STATE ||
+ type == ADDRESS_HOME_ZIP || type == ADDRESS_HOME_COUNTRY ||
+ type == PHONE_HOME_WHOLE_NUMBER) {
+ request_shipping_address = true;
+ }
+ if (type == ADDRESS_BILLING_LINE1 || type == ADDRESS_BILLING_LINE2 ||
+ type == ADDRESS_BILLING_CITY || type == ADDRESS_BILLING_STATE ||
+ type == PHONE_BILLING_WHOLE_NUMBER) {
+ request_full_billing_address = true;
+ }
+ }
+
+ if (request_shipping_address)
+ request_full_billing_address = true;
+
+ const bool incognito_mode = profile_->IsOffTheRecord();
+
+ bool last_used_choice_is_autofill = false;
+ base::string16 last_used_account_name;
+ std::string last_used_billing;
+ std::string last_used_shipping;
+ std::string last_used_credit_card;
+ {
+ const base::DictionaryValue* defaults =
+ profile_->GetPrefs()->GetDictionary(::prefs::kAutofillDialogDefaults);
+ if (defaults) {
+ defaults->GetString(kLastUsedAccountName, &last_used_account_name);
+ defaults->GetBoolean(kLastUsedChoiceIsAutofill,
+ &last_used_choice_is_autofill);
+ defaults->GetString(kLastUsedBillingAddressGuid, &last_used_billing);
+ defaults->GetString(kLastUsedShippingAddressGuid, &last_used_shipping);
+ defaults->GetString(kLastUsedCreditCardGuid, &last_used_credit_card);
+ } else {
+ DLOG(ERROR) << "Failed to read AutofillDialog preferences";
+ }
+ }
+
+ if (contents_->GetBrowserContext()->IsOffTheRecord())
+ last_used_choice_is_autofill = true;
+
+ JNIEnv* env = base::android::AttachCurrentThread();
+ ScopedJavaLocalRef<jstring> jlast_used_account_name =
+ base::android::ConvertUTF16ToJavaString(
+ env, last_used_account_name);
+ ScopedJavaLocalRef<jstring> jlast_used_billing =
+ base::android::ConvertUTF8ToJavaString(
+ env, last_used_billing);
+ ScopedJavaLocalRef<jstring> jlast_used_shipping =
+ base::android::ConvertUTF8ToJavaString(
+ env, last_used_shipping);
+ ScopedJavaLocalRef<jstring> jlast_used_card =
+ base::android::ConvertUTF8ToJavaString(
+ env, last_used_credit_card);
+ ScopedJavaLocalRef<jstring> jmerchant_domain =
+ base::android::ConvertUTF8ToJavaString(
+ env, source_url_.GetOrigin().spec());
+ java_object_.Reset(Java_AutofillDialogControllerAndroid_create(
+ env,
+ reinterpret_cast<jint>(this),
+ WindowAndroidHelper::FromWebContents(contents_)->
+ GetWindowAndroid()->GetJavaObject().obj(),
+ request_full_billing_address, request_shipping_address,
+ request_phone_numbers, incognito_mode,
+ last_used_choice_is_autofill, jlast_used_account_name.obj(),
+ jlast_used_billing.obj(), jlast_used_shipping.obj(),
+ jlast_used_card.obj(),
+ jmerchant_domain.obj()));
+}
+
+void AutofillDialogControllerAndroid::Hide() {
+ // TODO(aruslan): http://crbug.com/177373 Autocheckout.
+ NOTIMPLEMENTED();
+}
+
+void AutofillDialogControllerAndroid::TabActivated() {}
+
+void AutofillDialogControllerAndroid::AddAutocheckoutStep(
+ AutocheckoutStepType step_type) {
+ // TODO(aruslan): http://crbug.com/177373 Autocheckout.
+ NOTIMPLEMENTED() << " step_type = " << step_type;
+}
+
+void AutofillDialogControllerAndroid::UpdateAutocheckoutStep(
+ AutocheckoutStepType step_type,
+ AutocheckoutStepStatus step_status) {
+ // TODO(aruslan): http://crbug.com/177373 Autocheckout.
+ NOTIMPLEMENTED() << " step_type=" << step_type
+ << " step_status=" << step_status;
+}
+
+void AutofillDialogControllerAndroid::OnAutocheckoutError() {
+ // TODO(aruslan): http://crbug.com/177373 Autocheckout.
+ NOTIMPLEMENTED();
+ DCHECK_EQ(AUTOCHECKOUT_IN_PROGRESS, autocheckout_state_);
+ GetMetricLogger().LogAutocheckoutDuration(
+ base::Time::Now() - autocheckout_started_timestamp_,
+ AutofillMetrics::AUTOCHECKOUT_FAILED);
+ SetAutocheckoutState(AUTOCHECKOUT_ERROR);
+ autocheckout_started_timestamp_ = base::Time();
+}
+
+void AutofillDialogControllerAndroid::OnAutocheckoutSuccess() {
+ // TODO(aruslan): http://crbug.com/177373 Autocheckout.
+ NOTIMPLEMENTED();
+ DCHECK_EQ(AUTOCHECKOUT_IN_PROGRESS, autocheckout_state_);
+ GetMetricLogger().LogAutocheckoutDuration(
+ base::Time::Now() - autocheckout_started_timestamp_,
+ AutofillMetrics::AUTOCHECKOUT_SUCCEEDED);
+ SetAutocheckoutState(AUTOCHECKOUT_SUCCESS);
+ autocheckout_started_timestamp_ = base::Time();
+}
+
+DialogType AutofillDialogControllerAndroid::GetDialogType() const {
+ return dialog_type_;
+}
+
+// static
+bool AutofillDialogControllerAndroid::
+ RegisterAutofillDialogControllerAndroid(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
+void AutofillDialogControllerAndroid::DialogCancel(JNIEnv* env,
+ jobject obj) {
+ if (autocheckout_state_ == AUTOCHECKOUT_NOT_STARTED)
+ LogOnCancelMetrics();
+
+ if (autocheckout_state_ == AUTOCHECKOUT_IN_PROGRESS) {
+ GetMetricLogger().LogAutocheckoutDuration(
+ base::Time::Now() - autocheckout_started_timestamp_,
+ AutofillMetrics::AUTOCHECKOUT_CANCELLED);
+ }
+
+ callback_.Run(NULL, std::string());
+}
+
+void AutofillDialogControllerAndroid::DialogContinue(
+ JNIEnv* env,
+ jobject obj,
+ jobject wallet,
+ jboolean jlast_used_choice_is_autofill,
+ jstring jlast_used_account_name,
+ jstring jlast_used_billing,
+ jstring jlast_used_shipping,
+ jstring jlast_used_card) {
+ const string16 email = AutofillDialogResult::GetWalletEmail(env, wallet);
+ const std::string google_transaction_id =
+ AutofillDialogResult::GetWalletGoogleTransactionId(env, wallet);
+
+ const string16 last_used_account_name =
+ base::android::ConvertJavaStringToUTF16(env, jlast_used_account_name);
+ const std::string last_used_billing =
+ base::android::ConvertJavaStringToUTF8(env, jlast_used_billing);
+ const std::string last_used_shipping =
+ base::android::ConvertJavaStringToUTF8(env, jlast_used_shipping);
+ const std::string last_used_card =
+ base::android::ConvertJavaStringToUTF8(env, jlast_used_card);
+
+ scoped_ptr<wallet::FullWallet> full_wallet =
+ AutofillDialogResult::ConvertFromJava(env, wallet);
+ FillOutputForSection(
+ SECTION_EMAIL, form_structure_, full_wallet.get(), email);
+ FillOutputForSection(
+ SECTION_CC_BILLING, form_structure_, full_wallet.get(), email);
+ FillOutputForSection(
+ SECTION_SHIPPING, form_structure_, full_wallet.get(), email);
+
+ {
+ DictionaryPrefUpdate updater(profile_->GetPrefs(),
+ ::prefs::kAutofillDialogDefaults);
+ base::DictionaryValue* defaults = updater.Get();
+ if (defaults) {
+ const bool last_used_choice_is_autofill = !!jlast_used_choice_is_autofill;
+ defaults->SetString(kLastUsedAccountName, last_used_account_name);
+ defaults->SetBoolean(kLastUsedChoiceIsAutofill,
+ last_used_choice_is_autofill);
+ if (!last_used_billing.empty())
+ defaults->SetString(kLastUsedBillingAddressGuid, last_used_billing);
+ if (!last_used_shipping.empty())
+ defaults->SetString(kLastUsedShippingAddressGuid, last_used_shipping);
+ if (!last_used_card.empty())
+ defaults->SetString(kLastUsedCreditCardGuid, last_used_card);
+ } else {
+ LOG(ERROR) << "Failed to save AutofillDialog preferences";
+ }
+ }
+
+ if (GetDialogType() == DIALOG_TYPE_AUTOCHECKOUT) {
+ autocheckout_started_timestamp_ = base::Time::Now();
+ SetAutocheckoutState(AUTOCHECKOUT_IN_PROGRESS);
+ }
+
+ LogOnFinishSubmitMetrics();
+
+ // Callback should be called as late as possible.
+ callback_.Run(&form_structure_, google_transaction_id);
+
+ // This might delete us.
+ if (GetDialogType() == DIALOG_TYPE_REQUEST_AUTOCOMPLETE)
+ Hide();
+}
+
+AutofillDialogControllerAndroid::AutofillDialogControllerAndroid(
+ content::WebContents* contents,
+ const FormData& form_structure,
+ const GURL& source_url,
+ const DialogType dialog_type,
+ const base::Callback<void(const FormStructure*,
+ const std::string&)>& callback)
+ : profile_(Profile::FromBrowserContext(contents->GetBrowserContext())),
+ contents_(contents),
+ initial_user_state_(AutofillMetrics::DIALOG_USER_STATE_UNKNOWN),
+ dialog_type_(dialog_type),
+ form_structure_(form_structure, std::string()),
+ invoked_from_same_origin_(true),
+ source_url_(source_url),
+ callback_(callback),
+ cares_about_shipping_(true),
+ weak_ptr_factory_(this),
+ autocheckout_state_(AUTOCHECKOUT_NOT_STARTED),
+ was_ui_latency_logged_(false) {
+ DCHECK(!callback_.is_null());
+}
+
+bool AutofillDialogControllerAndroid::RequestingCreditCardInfo() const {
+ DCHECK_GT(form_structure_.field_count(), 0U);
+
+ for (size_t i = 0; i < form_structure_.field_count(); ++i) {
+ AutofillType type = form_structure_.field(i)->Type();
+ if (common::IsCreditCardType(type.GetStorableType()))
+ return true;
+ }
+
+ return false;
+}
+
+bool AutofillDialogControllerAndroid::TransmissionWillBeSecure() const {
+ return source_url_.SchemeIs(chrome::kHttpsScheme);
+}
+
+void AutofillDialogControllerAndroid::SetAutocheckoutState(
+ AutocheckoutState autocheckout_state) {
+ if (autocheckout_state_ == autocheckout_state)
+ return;
+
+ autocheckout_state_ = autocheckout_state;
+}
+
+void AutofillDialogControllerAndroid::LogOnFinishSubmitMetrics() {
+ GetMetricLogger().LogDialogUiDuration(
+ base::Time::Now() - dialog_shown_timestamp_,
+ GetDialogType(),
+ AutofillMetrics::DIALOG_ACCEPTED);
+
+ GetMetricLogger().LogDialogUiEvent(
+ GetDialogType(), AutofillMetrics::DIALOG_UI_ACCEPTED);
+}
+
+void AutofillDialogControllerAndroid::LogOnCancelMetrics() {
+ GetMetricLogger().LogDialogUiDuration(
+ base::Time::Now() - dialog_shown_timestamp_,
+ GetDialogType(),
+ AutofillMetrics::DIALOG_CANCELED);
+
+ GetMetricLogger().LogDialogUiEvent(
+ GetDialogType(), AutofillMetrics::DIALOG_UI_CANCELED);
+}
+
+} // namespace autofill
diff --git a/chrome/browser/ui/android/autofill/autofill_dialog_controller_android.h b/chrome/browser/ui/android/autofill/autofill_dialog_controller_android.h
new file mode 100644
index 0000000..01a08d6
--- /dev/null
+++ b/chrome/browser/ui/android/autofill/autofill_dialog_controller_android.h
@@ -0,0 +1,144 @@
+// Copyright 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_UI_ANDROID_AUTOFILL_AUTOFILL_DIALOG_CONTROLLER_ANDROID_H_
+#define CHROME_BROWSER_UI_ANDROID_AUTOFILL_AUTOFILL_DIALOG_CONTROLLER_ANDROID_H_
+
+#include <jni.h>
+
+#include "base/android/jni_string.h"
+#include "base/android/scoped_java_ref.h"
+#include "base/time/time.h"
+#include "chrome/browser/ui/autofill/autofill_dialog_controller.h"
+#include "chrome/browser/ui/autofill/autofill_dialog_types.h"
+
+class Profile;
+
+namespace user_prefs {
+class PrefRegistrySyncable;
+}
+
+namespace autofill {
+
+// This class defines the form-filling host and JNI glue for the Java-side
+// implementation of the requestAutocomplete dialog.
+class AutofillDialogControllerAndroid : public AutofillDialogController {
+ public:
+ // Creates an instance of the AutofillDialogControllerAndroid.
+ static base::WeakPtr<AutofillDialogController> Create(
+ content::WebContents* contents,
+ const FormData& form_structure,
+ const GURL& source_url,
+ const DialogType dialog_type,
+ const base::Callback<void(const FormStructure*,
+ const std::string&)>& callback);
+
+ // Registers profile preferences for the AutofillDialogControllerAndroid.
+ static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
+
+ virtual ~AutofillDialogControllerAndroid();
+
+ // AutofillDialogController implementation:
+ virtual void Show() OVERRIDE;
+ virtual void Hide() OVERRIDE;
+ virtual void TabActivated() OVERRIDE;
+ virtual void AddAutocheckoutStep(AutocheckoutStepType step_type) OVERRIDE;
+ virtual void UpdateAutocheckoutStep(
+ AutocheckoutStepType step_type,
+ AutocheckoutStepStatus step_status) OVERRIDE;
+ virtual void OnAutocheckoutError() OVERRIDE;
+ virtual void OnAutocheckoutSuccess() OVERRIDE;
+ virtual DialogType GetDialogType() const OVERRIDE;
+
+ // JNI bindings for Java-side AutofillDialogDelegate:
+ void DialogCancel(JNIEnv* env, jobject obj);
+ void DialogContinue(JNIEnv* env,
+ jobject obj,
+ jobject full_wallet,
+ jboolean last_used_choice_is_autofill,
+ jstring last_used_account_name,
+ jstring last_used_billing,
+ jstring last_used_shipping,
+ jstring last_used_credit_card);
+
+ // Establishes JNI bindings.
+ static bool RegisterAutofillDialogControllerAndroid(JNIEnv* env);
+
+ private:
+ AutofillDialogControllerAndroid(
+ content::WebContents* contents,
+ const FormData& form_structure,
+ const GURL& source_url,
+ const DialogType dialog_type,
+ const base::Callback<void(const FormStructure*,
+ const std::string&)>& callback);
+
+ const AutofillMetrics& GetMetricLogger() const {
+ return metric_logger_;
+ }
+
+ // Logs metrics when the dialog is submitted.
+ void LogOnFinishSubmitMetrics();
+
+ // Logs metrics when the dialog is canceled.
+ void LogOnCancelMetrics();
+
+ bool RequestingCreditCardInfo() const;
+ bool TransmissionWillBeSecure() const;
+
+ void SetAutocheckoutState(AutocheckoutState autocheckout_state);
+
+ // The |profile| for |contents_|.
+ Profile* const profile_;
+
+ // The WebContents where the Autocomplete/Checkout action originated.
+ content::WebContents* const contents_;
+
+ // For logging UMA metrics.
+ const AutofillMetrics metric_logger_;
+ base::Time dialog_shown_timestamp_;
+ AutofillMetrics::DialogInitialUserStateMetric initial_user_state_;
+
+ // The time that Autocheckout started running. Reset on error. While this is
+ // a valid time, |AutocheckoutIsRunning()| will return true.
+ base::Time autocheckout_started_timestamp_;
+
+ // Whether this is an Autocheckout or a requestAutocomplete dialog.
+ const DialogType dialog_type_;
+
+ FormStructure form_structure_;
+
+ // Whether the URL visible to the user when this dialog was requested to be
+ // invoked is the same as |source_url_|.
+ bool invoked_from_same_origin_;
+
+ // The URL of the invoking site.
+ GURL source_url_;
+
+ // The callback via which we return the collected data and, if Online Wallet
+ // was used, the Google transaction id.
+ base::Callback<void(const FormStructure*, const std::string&)> callback_;
+
+ // Whether |form_structure_| has asked for any details that would indicate
+ // we should show a shipping section.
+ bool cares_about_shipping_;
+
+ base::WeakPtrFactory<AutofillDialogControllerAndroid>
+ weak_ptr_factory_;
+
+ // The current state of the Autocheckout flow.
+ AutocheckoutState autocheckout_state_;
+
+ // Whether the latency to display to the UI was logged to UMA yet.
+ bool was_ui_latency_logged_;
+
+ // The corresponding java object.
+ base::android::ScopedJavaGlobalRef<jobject> java_object_;
+
+ DISALLOW_COPY_AND_ASSIGN(AutofillDialogControllerAndroid);
+};
+
+} // namespace autofill
+
+#endif // CHROME_BROWSER_UI_ANDROID_AUTOFILL_AUTOFILL_DIALOG_CONTROLLER_ANDROID_H_
diff --git a/chrome/browser/ui/android/autofill/autofill_dialog_result.cc b/chrome/browser/ui/android/autofill/autofill_dialog_result.cc
new file mode 100644
index 0000000..7c223a1
--- /dev/null
+++ b/chrome/browser/ui/android/autofill/autofill_dialog_result.cc
@@ -0,0 +1,138 @@
+// Copyright 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/ui/android/autofill/autofill_dialog_result.h"
+
+#include "base/android/jni_android.h"
+#include "base/android/jni_array.h"
+#include "base/android/jni_string.h"
+#include "base/android/scoped_java_ref.h"
+#include "base/bind.h"
+#include "base/logging.h"
+#include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/ui/autofill/data_model_wrapper.h"
+#include "components/autofill/content/browser/wallet/full_wallet.h"
+#include "components/autofill/core/browser/credit_card.h"
+#include "components/autofill/core/common/form_data.h"
+#include "jni/AutofillDialogResult_jni.h"
+#include "ui/base/l10n/l10n_util.h"
+
+namespace autofill {
+
+namespace {
+
+std::string ConvertNullOrJavaStringToUTF8(JNIEnv* env, jstring str) {
+ return str ? base::android::ConvertJavaStringToUTF8(env, str) : std::string();
+}
+
+base::string16 ConvertNullOrJavaStringToUTF16(JNIEnv* env, jstring str) {
+ return str ? base::android::ConvertJavaStringToUTF16(env, str)
+ : base::string16();
+}
+
+#define FETCH_JFIELD(env, jobj, cls, getter) \
+ (Java_##cls##_get##getter((env), (jobj)))
+
+#define FETCH_JSTRING(utf, env, jobj, cls, getter) \
+ (ConvertNullOrJavaStringTo##utf( \
+ (env), FETCH_JFIELD((env), (jobj), cls, getter).obj()))
+
+scoped_ptr<wallet::Address> ParseJavaWalletAddress(
+ JNIEnv* env, jobject address) {
+ if (!address)
+ return scoped_ptr<wallet::Address>();
+
+ const base::string16 recipient_name =
+ FETCH_JSTRING(UTF16, env, address, ResultAddress, Name);
+ const base::string16 address_line_1 =
+ FETCH_JSTRING(UTF16, env, address, ResultAddress, Address1);
+ const base::string16 address_line_2 =
+ FETCH_JSTRING(UTF16, env, address, ResultAddress, Address2);
+ const base::string16 locality_name =
+ FETCH_JSTRING(UTF16, env, address, ResultAddress, City);
+ const base::string16 administrative_area_name =
+ FETCH_JSTRING(UTF16, env, address, ResultAddress, State);
+ const base::string16 postal_code_number =
+ FETCH_JSTRING(UTF16, env, address, ResultAddress, PostalCode);
+ const base::string16 phone_number =
+ FETCH_JSTRING(UTF16, env, address, ResultAddress, PhoneNumber);
+ const std::string country_name_code =
+ FETCH_JSTRING(UTF8, env, address, ResultAddress, CountryCode);
+ DCHECK(!country_name_code.empty());
+
+ return scoped_ptr<wallet::Address>(new wallet::Address(
+ country_name_code,
+ recipient_name,
+ address_line_1,
+ address_line_2,
+ locality_name,
+ administrative_area_name,
+ postal_code_number,
+ phone_number,
+ std::string()));
+}
+
+scoped_ptr<wallet::FullWallet> ParseJavaWallet(JNIEnv* env, jobject wallet) {
+ const ScopedJavaLocalRef<jobject> billing_address(
+ FETCH_JFIELD(env, wallet, ResultWallet, BillingAddress));
+ const ScopedJavaLocalRef<jobject> shipping_address(
+ FETCH_JFIELD(env, wallet, ResultWallet, ShippingAddress));
+ const ScopedJavaLocalRef<jobject> card(
+ FETCH_JFIELD(env, wallet, ResultWallet, Card));
+
+ const int expiration_month =
+ FETCH_JFIELD(env, card.obj(), ResultCard, ExpirationMonth);
+ const int expiration_year =
+ FETCH_JFIELD(env, card.obj(), ResultCard, ExpirationYear);
+ const std::string pan =
+ FETCH_JSTRING(UTF8, env, card.obj(), ResultCard, Pan);
+ const std::string cvn =
+ FETCH_JSTRING(UTF8, env, card.obj(), ResultCard, Cvn);
+
+ return wallet::FullWallet::CreateFullWalletFromClearText(
+ expiration_month,
+ expiration_year,
+ pan,
+ cvn,
+ ParseJavaWalletAddress(env, billing_address.obj()),
+ ParseJavaWalletAddress(env, shipping_address.obj()));
+}
+
+base::string16 ParseWalletEmail(JNIEnv* env, jobject wallet) {
+ return FETCH_JSTRING(UTF16, env, wallet, ResultWallet, Email);
+}
+
+std::string ParseGoogleTransactionId(JNIEnv* env, jobject wallet) {
+ return FETCH_JSTRING(UTF8, env, wallet, ResultWallet, GoogleTransactionId);
+}
+
+#undef FETCH_JSTRING
+#undef FETCH_FIELD
+
+} // namespace
+
+// static
+scoped_ptr<wallet::FullWallet> AutofillDialogResult::ConvertFromJava(
+ JNIEnv* env, jobject wallet) {
+ return ParseJavaWallet(env, wallet);
+}
+
+// static
+base::string16 AutofillDialogResult::GetWalletEmail(
+ JNIEnv* env, jobject wallet) {
+ return ParseWalletEmail(env, wallet);
+}
+
+// static
+std::string AutofillDialogResult::GetWalletGoogleTransactionId(
+ JNIEnv* env, jobject wallet) {
+ return ParseGoogleTransactionId(env, wallet);
+}
+
+// static
+bool AutofillDialogResult::RegisterAutofillDialogResult(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
+} // namespace autofill
diff --git a/chrome/browser/ui/android/autofill/autofill_dialog_result.h b/chrome/browser/ui/android/autofill/autofill_dialog_result.h
new file mode 100644
index 0000000..2fe26a9
--- /dev/null
+++ b/chrome/browser/ui/android/autofill/autofill_dialog_result.h
@@ -0,0 +1,49 @@
+// Copyright 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_UI_ANDROID_AUTOFILL_AUTOFILL_DIALOG_RESULT_H_
+#define CHROME_BROWSER_UI_ANDROID_AUTOFILL_AUTOFILL_DIALOG_RESULT_H_
+
+#include <jni.h>
+#include <string>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/strings/string16.h"
+
+namespace autofill {
+namespace wallet {
+class FullWallet;
+}
+}
+
+namespace autofill {
+
+// A result of the non-cancelled Java-side AutofillDialog invocation.
+// Passed to the AutofillDialogControllerAndroid in dialogContinue.
+class AutofillDialogResult {
+ public:
+ // Converts the requested information to wallet::FullWallet.
+ // The dialog stores the requested information in the same format
+ // regardless if the information was obtained from Autofill or Google Wallet.
+ static scoped_ptr<wallet::FullWallet> ConvertFromJava(
+ JNIEnv* env, jobject wallet);
+
+ // Returns the email address to be associated with this request,
+ // or an empty string.
+ static base::string16 GetWalletEmail(JNIEnv* env, jobject wallet);
+
+ // Returns the Google Transaction ID to be associated with this request,
+ // or an empty string.
+ static std::string GetWalletGoogleTransactionId(JNIEnv* env, jobject wallet);
+
+ // Establishes JNI bindings.
+ static bool RegisterAutofillDialogResult(JNIEnv* env);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(AutofillDialogResult);
+};
+
+} // namespace autofill
+
+#endif // CHROME_BROWSER_UI_ANDROID_AUTOFILL_AUTOFILL_DIALOG_RESULT_H_
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 9f9a5b6..97546aa 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -3389,6 +3389,8 @@
'type': 'none',
'sources': [
'android/java/src/org/chromium/chrome/browser/ApplicationLifetime.java',
+ 'android/java/src/org/chromium/chrome/browser/autofill/AutofillDialogControllerAndroid.java',
+ 'android/java/src/org/chromium/chrome/browser/autofill/AutofillDialogResult.java',
'android/java/src/org/chromium/chrome/browser/autofill/AutofillPopupGlue.java',
'android/java/src/org/chromium/chrome/browser/autofill/PersonalDataManager.java',
'android/java/src/org/chromium/chrome/browser/CertificateViewer.java',
diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi
index d8e687f..eeafcbd 100644
--- a/chrome/chrome_browser_ui.gypi
+++ b/chrome/chrome_browser_ui.gypi
@@ -71,6 +71,10 @@
'browser/ui/alternate_error_tab_observer.h',
'browser/ui/android/android_about_app_info.cc',
'browser/ui/android/android_about_app_info.h',
+ 'browser/ui/android/autofill/autofill_dialog_controller_android.cc',
+ 'browser/ui/android/autofill/autofill_dialog_controller_android.h',
+ 'browser/ui/android/autofill/autofill_dialog_result.cc',
+ 'browser/ui/android/autofill/autofill_dialog_result.h',
'browser/ui/android/autofill/autofill_popup_view_android.cc',
'browser/ui/android/autofill/autofill_popup_view_android.h',
'browser/ui/android/certificate_viewer_android.cc',
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index a2af745..65b4c93 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -1157,6 +1157,10 @@ const char kAutofillDialogShowCount[] = "autofill.show_count";
const char kAutofillGeneratedCardBubbleTimesShown[] =
"autofill.generated_card_bubble_times_shown";
+// A dictionary that tracks the defaults to be set on the next invocation
+// of the requestAutocomplete/Autocheckout dialog.
+const char kAutofillDialogDefaults[] = "autofill.rac_dialog_defaults";
+
// Modifying bookmarks is completely disabled when this is set to false.
const char kEditBookmarksEnabled[] = "bookmarks.editing_enabled";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 3a75f8e..d1bfbe7 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -401,6 +401,7 @@ extern const char kAutofillDialogHasPaidWithWallet[];
extern const char kAutofillDialogPayWithoutWallet[];
extern const char kAutofillDialogShowCount[];
extern const char kAutofillGeneratedCardBubbleTimesShown[];
+extern const char kAutofillDialogDefaults[];
extern const char kEditBookmarksEnabled[];
extern const char kEnableTranslate[];