summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorapiccion@chromium.org <apiccion@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-27 07:05:00 +0000
committerapiccion@chromium.org <apiccion@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-27 07:05:00 +0000
commit1c2f1007002184c0ea9668352d4ac4748dde4586 (patch)
treee0d585298c6103b6f0ee875483cdd789fd8d207e
parent8a5b386945d0ed8a702c3b882e23224dca919ebe (diff)
downloadchromium_src-1c2f1007002184c0ea9668352d4ac4748dde4586.zip
chromium_src-1c2f1007002184c0ea9668352d4ac4748dde4586.tar.gz
chromium_src-1c2f1007002184c0ea9668352d4ac4748dde4586.tar.bz2
Added personal_data_manager android implementation for auto-populating auto-fill on android builds
Enabled auxiliary autofill profile for Android builds. Fixed unit tests for android version for autofill. Disabled autofill address population until we can parse the info from the contacts. Added permissions READ_CONTACTS and READ_PROFILE to testshell. These permissions are required to read the user's contact information using the ContactsContract and ContactsContract.Profile API. TBR=thakis@chromium.org,joi@chromium.org BUG=173268 Review URL: https://chromiumcodereview.appspot.com/12282004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@190842 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/android/chrome_jni_registrar.cc3
-rw-r--r--chrome/chrome.gyp1
-rw-r--r--chrome/chrome_tests_unit.gypi3
-rw-r--r--components/autofill.gypi48
-rw-r--r--components/autofill/DEPS1
-rw-r--r--components/autofill/browser/android/auxiliary_profile_loader_android.cc121
-rw-r--r--components/autofill/browser/android/auxiliary_profile_loader_android.h73
-rw-r--r--components/autofill/browser/android/auxiliary_profile_unittest_android.cc159
-rw-r--r--components/autofill/browser/android/auxiliary_profiles_android.cc115
-rw-r--r--components/autofill/browser/android/auxiliary_profiles_android.h52
-rw-r--r--components/autofill/browser/android/component_jni_registrar.cc23
-rw-r--r--components/autofill/browser/android/component_jni_registrar.h18
-rw-r--r--components/autofill/browser/android/java/src/org/chromium/components/browser/autofill/PersonalAutofillPopulator.java317
-rw-r--r--components/autofill/browser/android/personal_data_manager_android.cc21
-rw-r--r--components/autofill/browser/android/test_auxiliary_profile_loader_android.cc125
-rw-r--r--components/autofill/browser/android/test_auxiliary_profile_loader_android.h70
-rw-r--r--components/autofill/browser/autofill_manager.cc2
-rw-r--r--components/autofill/browser/autofill_manager_unittest.cc7
-rw-r--r--components/autofill/browser/personal_data_manager.cc6
-rw-r--r--components/autofill/browser/personal_data_manager.h2
-rw-r--r--components/autofill/common/password_form_fill_data.h2
21 files changed, 1157 insertions, 12 deletions
diff --git a/chrome/browser/android/chrome_jni_registrar.cc b/chrome/browser/android/chrome_jni_registrar.cc
index 35b864f..bdb38ee 100644
--- a/chrome/browser/android/chrome_jni_registrar.cc
+++ b/chrome/browser/android/chrome_jni_registrar.cc
@@ -25,6 +25,7 @@
#include "chrome/browser/ui/android/navigation_popup.h"
#include "chrome/browser/ui/android/ssl_client_certificate_request.h"
#include "chrome/browser/ui/android/website_settings_popup_android.h"
+#include "components/autofill/browser/android/component_jni_registrar.h"
#include "components/navigation_interception/component_jni_registrar.h"
#include "components/web_contents_delegate_android/component_jni_registrar.h"
@@ -38,6 +39,8 @@ static base::android::RegistrationMethod kChromeRegisteredMethods[] = {
{ "NavigationInterception", components::RegisterNavigationInterceptionJni },
{ "WebContentsDelegateAndroid",
components::RegisterWebContentsDelegateAndroidJni },
+ { "RegisterAuxiliaryProfileLoader",
+ components::RegisterAutofillAndroidJni },
// Register JNI for chrome classes.
{ "ApplicationLifetime", RegisterApplicationLifetimeAndroid},
{ "AutofillDialog",
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 94407c6..f181d4d 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -1090,6 +1090,7 @@
'toolbar_model_security_levels_java',
'../base/base.gyp:base',
'../components/components.gyp:navigation_interception_java',
+ '../components/components.gyp:autofill_java',
'../components/components.gyp:web_contents_delegate_android_java',
'../content/content.gyp:content_java',
'../sync/sync.gyp:sync_java',
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index 904e432..f302839 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -271,6 +271,8 @@
# TODO(joi): Move to //components/components.gypi once
# remaining dependencies back to //chrome are eliminated.
+ '../components/autofill/browser/android/test_auxiliary_profile_loader_android.cc',
+ '../components/autofill/browser/android/test_auxiliary_profile_loader_android.h',
'../components/autofill/browser/autofill_common_test.cc',
'../components/autofill/browser/autofill_common_test.h',
'../components/autofill/browser/data_driven_test.cc',
@@ -1639,6 +1641,7 @@
# remaining dependencies back to //chrome are eliminated.
'../components/autofill/browser/address_field_unittest.cc',
'../components/autofill/browser/address_unittest.cc',
+ '../components/autofill/browser/android/auxiliary_profile_unittest_android.cc',
'../components/autofill/browser/autocheckout/whitelist_manager_unittest.cc',
'../components/autofill/browser/autocheckout_manager_unittest.cc',
'../components/autofill/browser/autocheckout_page_meta_data_unittest.cc',
diff --git a/components/autofill.gypi b/components/autofill.gypi
index 815c51d..7c7be31 100644
--- a/components/autofill.gypi
+++ b/components/autofill.gypi
@@ -41,9 +41,6 @@
{
'target_name': 'autofill_common',
'type': 'static_library',
- 'include_dirs': [
- '..',
- ],
'dependencies': [
'../base/base.gyp:base',
'../build/temp_gyp/googleurl.gyp:googleurl',
@@ -52,7 +49,25 @@
'../third_party/WebKit/Source/WebKit/chromium/WebKit.gyp:webkit',
'../ui/ui.gyp:ui',
],
+ 'conditions': [
+ ['OS == "android"', {
+ 'dependencies': [
+ 'autofill_jni_headers',
+ ],
+ }],
+ ],
+ 'include_dirs': [
+ '..',
+ '<(SHARED_INTERMEDIATE_DIR)/autofill'
+ ],
'sources': [
+ 'autofill/browser/android/auxiliary_profile_loader_android.cc',
+ 'autofill/browser/android/auxiliary_profile_loader_android.h',
+ 'autofill/browser/android/auxiliary_profiles_android.cc',
+ 'autofill/browser/android/auxiliary_profiles_android.h',
+ 'autofill/browser/android/component_jni_registrar.cc',
+ 'autofill/browser/android/component_jni_registrar.h',
+ 'autofill/browser/android/personal_data_manager_android.cc',
'autofill/common/autocheckout_status.h',
'autofill/common/autofill_constants.cc',
'autofill/common/autofill_constants.h',
@@ -79,5 +94,32 @@
},
],
}],
+ ['OS == "android"', {
+ 'targets': [
+ {
+ 'target_name': 'autofill_java',
+ 'type': 'none',
+ 'dependencies': [
+ '../base/base.gyp:base',
+ '../content/content.gyp:content_java',
+ ],
+ 'variables': {
+ 'java_in_dir': 'autofill/browser/android/java',
+ },
+ 'includes': [ '../build/java.gypi' ],
+ },
+ {
+ 'target_name': 'autofill_jni_headers',
+ 'type': 'none',
+ 'sources': [
+ 'autofill/browser/android/java/src/org/chromium/components/browser/autofill/PersonalAutofillPopulator.java',
+ ],
+ 'variables': {
+ 'jni_gen_package': 'autofill',
+ },
+ 'includes': [ '../build/jni_generator.gypi' ],
+ },
+ ],
+ }],
],
}
diff --git a/components/autofill/DEPS b/components/autofill/DEPS
index cd724eb..fb54544 100644
--- a/components/autofill/DEPS
+++ b/components/autofill/DEPS
@@ -1,6 +1,7 @@
include_rules = [
"+google_apis/gaia/gaia_urls.h",
"+grit", # For generated headers
+ "+jni",
"+net",
# Allow inclusion of WebKit API files.
"+third_party/WebKit/Source/Platform/chromium",
diff --git a/components/autofill/browser/android/auxiliary_profile_loader_android.cc b/components/autofill/browser/android/auxiliary_profile_loader_android.cc
new file mode 100644
index 0000000..0fa1234
--- /dev/null
+++ b/components/autofill/browser/android/auxiliary_profile_loader_android.cc
@@ -0,0 +1,121 @@
+// 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 "components/autofill/browser/android/auxiliary_profile_loader_android.h"
+
+#include <vector>
+
+#include "base/android/jni_android.h"
+#include "base/android/jni_array.h"
+#include "base/android/jni_string.h"
+#include "jni/PersonalAutofillPopulator_jni.h"
+
+#define JAVA_METHOD(__jmethod__) Java_PersonalAutofillPopulator_##__jmethod__( \
+ env_, \
+ populator_.obj())
+
+namespace {
+
+string16 SafeJavaStringToUTF16(const ScopedJavaLocalRef<jstring>& jstring) {
+ if (jstring.is_null())
+ return string16();
+
+ return ConvertJavaStringToUTF16(jstring);
+}
+
+void SafeJavaStringArrayToStringVector(
+ const ScopedJavaLocalRef<jobjectArray>& jarray,
+ JNIEnv* env,
+ std::vector<string16>* string_vector) {
+ if (!jarray.is_null()) {
+ base::android::AppendJavaStringArrayToStringVector(env,
+ jarray.obj(),
+ string_vector);
+ }
+}
+
+} // namespace
+
+namespace autofill {
+
+bool RegisterAuxiliaryProfileLoader(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
+AuxiliaryProfileLoaderAndroid::AuxiliaryProfileLoaderAndroid() {}
+
+AuxiliaryProfileLoaderAndroid::~AuxiliaryProfileLoaderAndroid() {}
+
+void AuxiliaryProfileLoaderAndroid::Init(JNIEnv* env, const jobject& context) {
+ env_ = env;
+ populator_ = Java_PersonalAutofillPopulator_create(env_, context);
+}
+
+bool AuxiliaryProfileLoaderAndroid::GetHasPermissions() const {
+ return (bool)JAVA_METHOD(getHasPermissions);
+}
+
+// Address info
+string16 AuxiliaryProfileLoaderAndroid::GetStreet() const {
+ return SafeJavaStringToUTF16(JAVA_METHOD(getStreet));
+}
+
+string16 AuxiliaryProfileLoaderAndroid::GetPostOfficeBox() const {
+ return SafeJavaStringToUTF16(JAVA_METHOD(getPobox));
+}
+
+string16 AuxiliaryProfileLoaderAndroid::GetNeighborhood() const {
+ return SafeJavaStringToUTF16(JAVA_METHOD(getNeighborhood));
+}
+
+string16 AuxiliaryProfileLoaderAndroid::GetRegion() const {
+ return SafeJavaStringToUTF16(JAVA_METHOD(getRegion));
+}
+
+string16 AuxiliaryProfileLoaderAndroid::GetCity() const {
+ return SafeJavaStringToUTF16(JAVA_METHOD(getCity));
+}
+
+string16 AuxiliaryProfileLoaderAndroid::GetPostalCode() const {
+ return SafeJavaStringToUTF16(JAVA_METHOD(getPostalCode));
+}
+
+string16 AuxiliaryProfileLoaderAndroid::GetCountry() const {
+ return SafeJavaStringToUTF16(JAVA_METHOD(getCountry));
+}
+
+// Name info
+string16 AuxiliaryProfileLoaderAndroid::GetFirstName() const {
+ return SafeJavaStringToUTF16(JAVA_METHOD(getFirstName));
+}
+
+string16 AuxiliaryProfileLoaderAndroid::GetMiddleName() const {
+ return SafeJavaStringToUTF16(JAVA_METHOD(getMiddleName));
+}
+
+string16 AuxiliaryProfileLoaderAndroid::GetLastName() const {
+ return SafeJavaStringToUTF16(JAVA_METHOD(getLastName));
+}
+
+string16 AuxiliaryProfileLoaderAndroid::GetSuffix() const {
+ return SafeJavaStringToUTF16(JAVA_METHOD(getSuffix));
+}
+
+// Email info
+void AuxiliaryProfileLoaderAndroid::GetEmailAddresses(
+ std::vector<string16>* email_addresses) const {
+ SafeJavaStringArrayToStringVector(JAVA_METHOD(getEmailAddresses),
+ env_,
+ email_addresses);
+}
+
+// Phone info
+void AuxiliaryProfileLoaderAndroid::GetPhoneNumbers(
+ std::vector<string16>* phone_numbers) const {
+ SafeJavaStringArrayToStringVector(JAVA_METHOD(getPhoneNumbers),
+ env_,
+ phone_numbers);
+}
+
+} // namespace
diff --git a/components/autofill/browser/android/auxiliary_profile_loader_android.h b/components/autofill/browser/android/auxiliary_profile_loader_android.h
new file mode 100644
index 0000000..0e9b110
--- /dev/null
+++ b/components/autofill/browser/android/auxiliary_profile_loader_android.h
@@ -0,0 +1,73 @@
+// 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 COMPONENTS_AUTOFILL_BROWSER_ANDROID_AUXILIARY_PROFILE_LOADER_ANDROID_H_
+#define COMPONENTS_AUTOFILL_BROWSER_ANDROID_AUXILIARY_PROFILE_LOADER_ANDROID_H_
+
+#include <vector>
+
+#include "base/android/jni_android.h"
+#include "base/string16.h"
+
+namespace autofill {
+
+bool RegisterAuxiliaryProfileLoader(JNIEnv* env);
+
+// This class loads user's contact information from their device.
+// The populated data corresponds to the user's 'Me' profile in their
+// contact list.
+class AuxiliaryProfileLoaderAndroid {
+ public:
+ AuxiliaryProfileLoaderAndroid();
+ virtual ~AuxiliaryProfileLoaderAndroid();
+
+ // Init method should be called after object initialization.
+ // context parameter is an Android context.
+ void Init(JNIEnv* env, const jobject& context);
+
+ // Returns true IFF the application has priviledges to access the user's
+ // contact information.
+ virtual bool GetHasPermissions() const;
+ // Returns address street.
+ virtual string16 GetStreet() const;
+ // Returns address post office box.
+ virtual string16 GetPostOfficeBox() const;
+ // Returns address neighborhood (e.g. Noe Valley, Nob Hill, Twin Peaks, ...).
+ virtual string16 GetNeighborhood() const;
+ // Returns address region such as state or province information
+ // (e.g. Ontario, California, Hubei).
+ virtual string16 GetRegion() const;
+ // Returns address city.
+ virtual string16 GetCity() const;
+ // Returns address postal code or zip code.
+ virtual string16 GetPostalCode() const;
+ // Returns address country.
+ virtual string16 GetCountry() const;
+
+ // Returns contact's first name.
+ virtual string16 GetFirstName() const;
+ // Returns contact's middle name.
+ virtual string16 GetMiddleName() const;
+ // Returns contact's last name.
+ virtual string16 GetLastName() const;
+ // Returns contact's suffix (e.g. Ph.D, M.D., ...).
+ virtual string16 GetSuffix() const;
+
+ // Populates string vector parameter with contact's email addresses.
+ virtual void GetEmailAddresses(std::vector<string16>* email_addresses) const;
+
+ // Populates string vector parameter with contact's phones numbers.
+ virtual void GetPhoneNumbers(std::vector<string16>* phone_numbers) const;
+
+ private:
+ JNIEnv* env_;
+ // The reference to java |PersonalAutofillPopulator| which
+ // actually extracts users contact information from the physical device
+ base::android::ScopedJavaLocalRef<jobject> populator_;
+ DISALLOW_COPY_AND_ASSIGN(AuxiliaryProfileLoaderAndroid);
+};
+
+} // namespace
+
+#endif // COMPONENTS_AUTOFILL_BROWSER_ANDROID_AUXILIARY_PROFILE_LOADER_ANDROID_H_
diff --git a/components/autofill/browser/android/auxiliary_profile_unittest_android.cc b/components/autofill/browser/android/auxiliary_profile_unittest_android.cc
new file mode 100644
index 0000000..2bf26b9
--- /dev/null
+++ b/components/autofill/browser/android/auxiliary_profile_unittest_android.cc
@@ -0,0 +1,159 @@
+// 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 "base/memory/scoped_vector.h"
+#include "base/string16.h"
+#include "base/utf_string_conversions.h"
+#include "components/autofill/browser/android/auxiliary_profile_loader_android.h"
+#include "components/autofill/browser/android/auxiliary_profiles_android.h"
+#include "components/autofill/browser/android/test_auxiliary_profile_loader_android.h"
+#include "components/autofill/browser/autofill_profile.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+class AuxiliaryProfileAndroidTest : public testing::Test {
+ public:
+ AuxiliaryProfileAndroidTest() {}
+
+ AutofillProfile* GetAndLoadProfile() {
+ autofill::AuxiliaryProfilesAndroid impl(profile_loader_);
+ profile_ = impl.LoadContactsProfile();
+ return profile_.get();
+ }
+
+ TestAuxiliaryProfileLoader& profile_loader() {
+ return profile_loader_;
+ }
+
+ private:
+ TestAuxiliaryProfileLoader profile_loader_;
+ scoped_ptr<AutofillProfile> profile_;
+};
+
+TEST_F(AuxiliaryProfileAndroidTest, SetNameInfo) {
+ string16 first_name = ASCIIToUTF16("John");
+ string16 middle_name = ASCIIToUTF16("H.");
+ string16 last_name = ASCIIToUTF16("Waston");
+
+ profile_loader().SetFirstName(first_name);
+ profile_loader().SetMiddleName(middle_name);
+ profile_loader().SetLastName(last_name);
+
+ AutofillProfile* profile = GetAndLoadProfile();
+
+ EXPECT_EQ(profile->GetRawInfo(NAME_FIRST), first_name);
+ EXPECT_EQ(profile->GetRawInfo(NAME_MIDDLE), middle_name);
+ EXPECT_EQ(profile->GetRawInfo(NAME_LAST), last_name);
+}
+
+TEST_F(AuxiliaryProfileAndroidTest, SetNameInfoEmpty) {
+ AutofillProfile* profile = GetAndLoadProfile();
+
+ EXPECT_EQ(profile->GetRawInfo(NAME_FIRST), string16());
+ EXPECT_EQ(profile->GetRawInfo(NAME_MIDDLE), string16());
+ EXPECT_EQ(profile->GetRawInfo(NAME_LAST), string16());
+}
+
+TEST_F(AuxiliaryProfileAndroidTest, SetEmailInfo) {
+ std::vector<string16> email_addresses;
+ email_addresses.push_back(ASCIIToUTF16("sherlock@holmes.com"));
+ email_addresses.push_back(ASCIIToUTF16("watson@holmes.com"));
+ profile_loader().SetEmailAddresses(email_addresses);
+
+ AutofillProfile* profile = GetAndLoadProfile();
+ std::vector<string16> loaded_email_addresses;
+ profile->GetRawMultiInfo(EMAIL_ADDRESS, &loaded_email_addresses);
+ EXPECT_EQ(loaded_email_addresses, email_addresses);
+}
+
+TEST_F(AuxiliaryProfileAndroidTest, SetEmailInfoEmpty) {
+ std::vector<string16> expected_email_addresses;
+ expected_email_addresses.push_back(string16());
+ std::vector<string16> loaded_email_addresses;
+ AutofillProfile* profile = GetAndLoadProfile();
+ profile->GetRawMultiInfo(EMAIL_ADDRESS, &loaded_email_addresses);
+ EXPECT_EQ(loaded_email_addresses, expected_email_addresses);
+}
+
+TEST_F(AuxiliaryProfileAndroidTest, SetPhoneInfo) {
+ std::vector<string16> phone_numbers;
+ phone_numbers.push_back(ASCIIToUTF16("6502530000"));
+ profile_loader().SetPhoneNumbers(phone_numbers);
+
+ std::vector<string16> loaded_phone_numbers;
+ AutofillProfile* profile = GetAndLoadProfile();
+ profile->GetRawMultiInfo(PHONE_HOME_WHOLE_NUMBER, &loaded_phone_numbers);
+ EXPECT_EQ(loaded_phone_numbers, phone_numbers);
+}
+
+TEST_F(AuxiliaryProfileAndroidTest, SetPhoneInfoEmpty) {
+ std::vector<string16> expected_phone_numbers;
+ expected_phone_numbers.push_back(string16());
+
+ std::vector<string16> loaded_phone_numbers;
+ AutofillProfile* profile = GetAndLoadProfile();
+ profile->GetRawMultiInfo(PHONE_HOME_WHOLE_NUMBER, &loaded_phone_numbers);
+ EXPECT_EQ(loaded_phone_numbers, expected_phone_numbers);
+}
+
+//
+// Android user's profile contact does not parse its address
+// into constituent parts. Instead we just Get a long string blob.
+// Disable address population tests until we implement a way to parse the
+// data.
+//
+
+#if 0
+TEST_F(AuxiliaryProfileAndroidTest, SetAddressInfo) {
+ string16 street = ASCIIToUTF16("221 B Baker Street");
+ string16 city = ASCIIToUTF16("London");
+ string16 postal_code = ASCIIToUTF16("123456");
+ string16 region = ASCIIToUTF16("Georgian Terrace");
+ string16 country = ASCIIToUTF16("England");
+
+ profile_loader().SetStreet(street);
+ profile_loader().SetCity(city);
+ profile_loader().SetPostalCode(postal_code);
+ profile_loader().SetRegion(region);
+ profile_loader().SetCountry(country);
+
+ AutofillProfile* profile = GetAndLoadProfile();
+ EXPECT_EQ(profile->GetRawInfo(ADDRESS_HOME_LINE1), street);
+ EXPECT_EQ(profile->GetRawInfo(ADDRESS_HOME_CITY), city);
+ EXPECT_EQ(profile->GetRawInfo(ADDRESS_HOME_ZIP), postal_code);
+ EXPECT_EQ(profile->GetRawInfo(ADDRESS_HOME_STATE), region);
+ EXPECT_EQ(profile->GetRawInfo(ADDRESS_HOME_COUNTRY), country);
+}
+
+string16 post_office_box= ASCIIToUTF16("222");
+string16 neighborhood = ASCIIToUTF16("Doyle");
+TEST_F(AuxiliaryProfileAndroidTest, SetAddressInfoCompoundFields1) {
+ profile_loader().SetPostOfficeBox(post_office_box);
+ profile_loader().SetNeighborhood(neighborhood);
+ string16 expectedLine2= ASCIIToUTF16("222, Doyle");
+ AutofillProfile* profile = GetAndLoadProfile();
+ EXPECT_EQ(profile->GetRawInfo(ADDRESS_HOME_LINE2), expectedLine2);
+}
+
+TEST_F(AuxiliaryProfileAndroidTest, SetAddressInfoCompoundFields2) {
+ profile_loader().SetPostOfficeBox(post_office_box);
+ AutofillProfile* profile = GetAndLoadProfile();
+ EXPECT_EQ(profile->GetRawInfo(ADDRESS_HOME_LINE2), post_office_box);
+}
+
+TEST_F(AuxiliaryProfileAndroidTest, SetAddressInfoCompoundFields3) {
+ profile_loader().SetNeighborhood(neighborhood);
+ AutofillProfile* profile = GetAndLoadProfile();
+ EXPECT_EQ(profile->GetRawInfo(ADDRESS_HOME_LINE2), neighborhood);
+}
+
+TEST_F(AuxiliaryProfileAndroidTest, SetAddressInfoEmpty) {
+ AutofillProfile* profile = GetAndLoadProfile();
+ EXPECT_EQ(profile->GetRawInfo(ADDRESS_HOME_LINE1), string16());
+ EXPECT_EQ(profile->GetRawInfo(ADDRESS_HOME_LINE2), string16());
+ EXPECT_EQ(profile->GetRawInfo(ADDRESS_HOME_CITY), string16());
+ EXPECT_EQ(profile->GetRawInfo(ADDRESS_HOME_ZIP), string16());
+ EXPECT_EQ(profile->GetRawInfo(ADDRESS_HOME_STATE), string16());
+ EXPECT_EQ(profile->GetRawInfo(ADDRESS_HOME_COUNTRY), string16());
+}
+#endif
diff --git a/components/autofill/browser/android/auxiliary_profiles_android.cc b/components/autofill/browser/android/auxiliary_profiles_android.cc
new file mode 100644
index 0000000..52c5fe3
--- /dev/null
+++ b/components/autofill/browser/android/auxiliary_profiles_android.cc
@@ -0,0 +1,115 @@
+// 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.
+
+// Populates default autofill profile from user's own Android contact.
+#include "components/autofill/browser/android/auxiliary_profiles_android.h"
+
+#include <vector>
+
+#include "base/guid.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/scoped_vector.h"
+#include "base/string16.h"
+#include "base/string_util.h"
+#include "base/utf_string_conversions.h"
+#include "components/autofill/browser/android/auxiliary_profile_loader_android.h"
+#include "components/autofill/browser/autofill_profile.h"
+#include "components/autofill/browser/phone_number.h"
+
+// Generates the autofill profile by accessing the Android
+// ContactsContract.Profile API through PersonalAutofillPopulator via JNI.
+// The generated profile corresponds to the user's "ME" contact in the
+// "People" app. The caller passes a vector of profiles into the constructor
+// then initiates a fetch using |GetContactsProfile()| method. This clears
+// any existing addresses.
+
+// Randomly generated guid. The Autofillprofile class requires a consistent
+// unique guid or else things break.
+const char kAndroidMeContactA[] = "9A9E1C06-7A3B-48FA-AA4F-135CA6FC25D9";
+
+namespace {
+
+// Takes misc. address information strings from Android API and collapses
+// into single string for "address line 2"
+string16 CollapseAddress(const string16& post_office_box,
+ const string16& neighborhood) {
+ std::vector<string16> accumulator;
+ if (!post_office_box.empty())
+ accumulator.push_back(post_office_box);
+ if (!neighborhood.empty())
+ accumulator.push_back(neighborhood);
+
+ return JoinString(accumulator, ASCIIToUTF16(", "));
+}
+
+} // namespace
+
+namespace autofill {
+
+AuxiliaryProfilesAndroid::AuxiliaryProfilesAndroid(
+ const AuxiliaryProfileLoaderAndroid& profileLoader)
+ : profile_loader_(profileLoader) {}
+
+AuxiliaryProfilesAndroid::~AuxiliaryProfilesAndroid() {
+}
+
+scoped_ptr<AutofillProfile> AuxiliaryProfilesAndroid::LoadContactsProfile() {
+ scoped_ptr<AutofillProfile> profile(new AutofillProfile(kAndroidMeContactA));
+ LoadName(profile.get());
+ LoadEmailAddress(profile.get());
+ LoadPhoneNumbers(profile.get());
+
+ // Android user's profile contact does not parse its address
+ // into constituent parts. Instead we just get a long string blob.
+ // Disable address population until we implement a way to parse the
+ // data.
+ // http://crbug.com/178838
+ // LoadAddress(profile.get());
+
+ return profile.Pass();
+}
+
+void AuxiliaryProfilesAndroid::LoadAddress(AutofillProfile* profile) {
+ string16 street = profile_loader_.GetStreet();
+ string16 post_office_box = profile_loader_.GetPostOfficeBox();
+ string16 neighborhood = profile_loader_.GetNeighborhood();
+ string16 city = profile_loader_.GetCity();
+ string16 postal_code = profile_loader_.GetPostalCode();
+ string16 region = profile_loader_.GetRegion();
+ string16 country = profile_loader_.GetCountry();
+
+ string16 street2 = CollapseAddress(post_office_box, neighborhood);
+
+ profile->SetRawInfo(ADDRESS_HOME_LINE1, street);
+ profile->SetRawInfo(ADDRESS_HOME_LINE2, street2);
+ profile->SetRawInfo(ADDRESS_HOME_CITY, city);
+ profile->SetRawInfo(ADDRESS_HOME_STATE, region);
+ profile->SetRawInfo(ADDRESS_HOME_ZIP, postal_code);
+ profile->SetRawInfo(ADDRESS_HOME_COUNTRY, country);
+}
+
+void AuxiliaryProfilesAndroid::LoadName(AutofillProfile* profile) {
+ string16 first_name = profile_loader_.GetFirstName();
+ string16 middle_name = profile_loader_.GetMiddleName();
+ string16 last_name = profile_loader_.GetLastName();
+
+ profile->SetRawInfo(NAME_FIRST, first_name);
+ profile->SetRawInfo(NAME_MIDDLE, middle_name);
+ profile->SetRawInfo(NAME_LAST, last_name);
+}
+
+void AuxiliaryProfilesAndroid::LoadEmailAddress(AutofillProfile* profile) {
+ std::vector<string16> emails;
+ profile_loader_.GetEmailAddresses(&emails);
+ profile->SetRawMultiInfo(EMAIL_ADDRESS, emails);
+}
+
+void AuxiliaryProfilesAndroid::LoadPhoneNumbers(AutofillProfile* profile) {
+ std::vector<string16> phone_numbers;
+ profile_loader_.GetPhoneNumbers(&phone_numbers);
+ profile->SetRawMultiInfo(PHONE_HOME_WHOLE_NUMBER, phone_numbers);
+}
+
+} // namespace autofill
diff --git a/components/autofill/browser/android/auxiliary_profiles_android.h b/components/autofill/browser/android/auxiliary_profiles_android.h
new file mode 100644
index 0000000..ec0ee9c
--- /dev/null
+++ b/components/autofill/browser/android/auxiliary_profiles_android.h
@@ -0,0 +1,52 @@
+// 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 COMPONENTS_AUTOFILL_BROWSER_ANDROID_AUXILIARY_PROFILES_ANDROID_H_
+#define COMPONENTS_AUTOFILL_BROWSER_ANDROID_AUXILIARY_PROFILES_ANDROID_H_
+
+#include <jni.h>
+#include <vector>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/string16.h"
+#include "components/autofill/browser/android/auxiliary_profile_loader_android.h"
+
+class AutofillProfile;
+
+namespace autofill {
+class AuxiliaryProfileLoaderAndroid;
+
+ // This class is used to populate an AutofillProfile vector with
+ // a 'default' auxiliary profile. It depends on an
+ // AuxiliaryProfileLoaderAndroid object to provide contact information
+ // that is re-organized into an Autofill profile.
+class AuxiliaryProfilesAndroid {
+ public:
+ // Takes in an AuxiliaryProfileLoader object which provides contact
+ // information methods.
+ explicit AuxiliaryProfilesAndroid(
+ const autofill::AuxiliaryProfileLoaderAndroid& profile_loader);
+ ~AuxiliaryProfilesAndroid();
+
+ // Returns autofill profile constructed from profile_loader_.
+ scoped_ptr<AutofillProfile> LoadContactsProfile();
+
+ private:
+ // Inserts contact's address data into profile.
+ void LoadAddress(AutofillProfile* profile);
+ // Inserts contact's name data into profile.
+ void LoadName(AutofillProfile* profile);
+ // Inserts contact's email address data into profile.
+ void LoadEmailAddress(AutofillProfile* profile);
+ // Inserts contact's phone number data into profile.
+ void LoadPhoneNumbers(AutofillProfile* profile);
+
+ const AuxiliaryProfileLoaderAndroid& profile_loader_;
+
+ DISALLOW_COPY_AND_ASSIGN(AuxiliaryProfilesAndroid);
+};
+
+} // namespace
+
+#endif // COMPONENTS_AUTOFILL_BROWSER_ANDROID_AUXILIARY_PROFILES_ANDROID_H_
diff --git a/components/autofill/browser/android/component_jni_registrar.cc b/components/autofill/browser/android/component_jni_registrar.cc
new file mode 100644
index 0000000..7bb1a66
--- /dev/null
+++ b/components/autofill/browser/android/component_jni_registrar.cc
@@ -0,0 +1,23 @@
+// 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 "components/autofill/browser/android/component_jni_registrar.h"
+
+#include "base/android/jni_android.h"
+#include "base/android/jni_registrar.h"
+#include "components/autofill/browser/android/auxiliary_profile_loader_android.h"
+
+namespace components {
+
+static base::android::RegistrationMethod kComponentRegisteredMethods[] = {
+ { "RegisterAuxiliaryProfileLoader",
+ autofill::RegisterAuxiliaryProfileLoader },
+};
+
+bool RegisterAutofillAndroidJni(JNIEnv* env) {
+ return RegisterNativeMethods(env,
+ kComponentRegisteredMethods, arraysize(kComponentRegisteredMethods));
+}
+
+} // namespace components
diff --git a/components/autofill/browser/android/component_jni_registrar.h b/components/autofill/browser/android/component_jni_registrar.h
new file mode 100644
index 0000000..86c1327
--- /dev/null
+++ b/components/autofill/browser/android/component_jni_registrar.h
@@ -0,0 +1,18 @@
+// Copyright (c) 2012 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 COMPONENT_AUTOFILL_BROWSER_ANDROID_COMPONENT_JNI_REGISTRAR_H_
+#define COMPONENT_AUTOFILL_BROWSER_ANDROID_COMPONENT_JNI_REGISTRAR_H_
+
+#include <jni.h>
+
+namespace components {
+
+// Register all JNI bindings necessary for the autofill
+// component.
+bool RegisterAutofillAndroidJni(JNIEnv* env);
+
+} // namespace components
+
+#endif // COMPONENT_AUTOFILL_BROWSER_ANDROID_COMPONENT_JNI_REGISTRAR_H_
diff --git a/components/autofill/browser/android/java/src/org/chromium/components/browser/autofill/PersonalAutofillPopulator.java b/components/autofill/browser/android/java/src/org/chromium/components/browser/autofill/PersonalAutofillPopulator.java
new file mode 100644
index 0000000..b99d6dd
--- /dev/null
+++ b/components/autofill/browser/android/java/src/org/chromium/components/browser/autofill/PersonalAutofillPopulator.java
@@ -0,0 +1,317 @@
+// 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.
+
+// Populates data fields from Android contacts profile API (i.e. "me" contact).
+
+package org.chromium.components.browser.autofill;
+
+import android.app.Activity;
+import android.content.ContentProviderOperation;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.OperationApplicationException;
+import android.content.pm.PackageManager;
+import android.database.Cursor;
+import android.database.DatabaseUtils;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract.Profile;
+import android.provider.ContactsContract;
+import android.util.Log;
+import android.view.View.OnClickListener;
+import android.view.View;
+import android.widget.Button;
+import android.widget.Toast;
+
+import org.chromium.base.CalledByNative;
+
+import java.util.ArrayList;
+
+/**
+ * Loads user profile information stored under the "Me" contact.
+ * Requires permissions: READ_CONTACTS and READ_PROFILE.
+ */
+public class PersonalAutofillPopulator {
+ /**
+ * SQL query definitions for obtaining specific profile information.
+ */
+ private abstract static class ProfileQuery {
+ Uri profileDataUri = Uri.withAppendedPath(
+ ContactsContract.Profile.CONTENT_URI,
+ ContactsContract.Contacts.Data.CONTENT_DIRECTORY
+ );
+ public abstract String[] projection();
+ public abstract String mimeType();
+ }
+
+ private static class EmailProfileQuery extends ProfileQuery {
+ private static final int EMAIL_ADDRESS = 0;
+
+ @Override
+ public String[] projection() {
+ return new String[] {
+ ContactsContract.CommonDataKinds.Email.ADDRESS,
+ };
+ }
+
+ @Override
+ public String mimeType() {
+ return ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE;
+ }
+ }
+
+ private static class PhoneProfileQuery extends ProfileQuery {
+ private static final int NUMBER = 0;
+
+ @Override
+ public String[] projection() {
+ return new String[] {
+ ContactsContract.CommonDataKinds.Phone.NUMBER,
+ };
+ }
+
+ @Override
+ public String mimeType() {
+ return ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE;
+ }
+ }
+
+ private static class AddressProfileQuery extends ProfileQuery {
+ private static final int STREET = 0;
+ private static final int POBOX = 1;
+ private static final int NEIGHBORHOOD = 2;
+ private static final int CITY = 3;
+ private static final int REGION = 4;
+ private static final int POSTALCODE = 5;
+ private static final int COUNTRY = 6;
+
+ @Override
+ public String[] projection() {
+ return new String[] {
+ ContactsContract.CommonDataKinds.StructuredPostal.STREET,
+ ContactsContract.CommonDataKinds.StructuredPostal.POBOX,
+ ContactsContract.CommonDataKinds.StructuredPostal.NEIGHBORHOOD,
+ ContactsContract.CommonDataKinds.StructuredPostal.CITY,
+ ContactsContract.CommonDataKinds.StructuredPostal.REGION,
+ ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE,
+ ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY,
+ };
+ }
+
+ @Override
+ public String mimeType() {
+ return ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_ITEM_TYPE;
+ }
+ }
+
+ private static class NameProfileQuery extends ProfileQuery {
+ private static final int GIVEN_NAME = 0;
+ private static final int MIDDLE_NAME = 1;
+ private static final int FAMILY_NAME = 2;
+ private static final int SUFFIX = 3;
+
+ @Override
+ public String[] projection() {
+ return new String[] {
+ ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME,
+ ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME,
+ ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME,
+ ContactsContract.CommonDataKinds.StructuredName.SUFFIX
+ };
+ }
+
+ @Override
+ public String mimeType() {
+ return ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE;
+ }
+ }
+
+ /**
+ * Takes a query object, transforms into actual query and returns cursor.
+ * Primary contact values will be first.
+ */
+ private Cursor cursorFromProfileQuery(ProfileQuery query, ContentResolver contentResolver) {
+ String sortDescriptor = ContactsContract.Contacts.Data.IS_PRIMARY + " DESC";
+ return contentResolver.query(
+ query.profileDataUri,
+ query.projection(),
+ ContactsContract.Contacts.Data.MIMETYPE + " = ?",
+ new String[]{query.mimeType()},
+ sortDescriptor
+ );
+ }
+ // Extracted data variables.
+ private String[] mEmailAddresses;
+ private String mGivenName;
+ private String mMiddleName;
+ private String mFamilyName;
+ private String mSuffix;
+ private String mPobox;
+ private String mStreet;
+ private String mNeighborhood;
+ private String mCity;
+ private String mRegion;
+ private String mCountry;
+ private String mPostalCode;
+ private String[] mPhoneNumbers;
+ private boolean mHasPermissions;
+
+ /**
+ * Constructor
+ * @param context a valid android context reference
+ */
+ PersonalAutofillPopulator(Context context) {
+ mHasPermissions = hasPermissions(context);
+ if (mHasPermissions) {
+ ContentResolver contentResolver = context.getContentResolver();
+ populateName(contentResolver);
+ populateEmail(contentResolver);
+ populateAddress(contentResolver);
+ populatePhone(contentResolver);
+ }
+ }
+
+ // Check if the user has granted permissions.
+ private boolean hasPermissions(Context context) {
+ String [] permissions = {
+ "android.permission.READ_CONTACTS",
+ "android.permission.READ_PROFILE"
+ };
+ for (String permission : permissions) {
+ int res = context.checkCallingOrSelfPermission(permission);
+ if (res != PackageManager.PERMISSION_GRANTED) return false;
+ }
+ return true;
+ }
+
+ // Populating data fields.
+ private void populateName(ContentResolver contentResolver) {
+ NameProfileQuery nameProfileQuery = new NameProfileQuery();
+ Cursor nameCursor = cursorFromProfileQuery(nameProfileQuery, contentResolver);
+ if (nameCursor.moveToNext()) {
+ mGivenName = nameCursor.getString(nameProfileQuery.GIVEN_NAME);
+ mMiddleName = nameCursor.getString(nameProfileQuery.MIDDLE_NAME);
+ mFamilyName = nameCursor.getString(nameProfileQuery.FAMILY_NAME);
+ mSuffix = nameCursor.getString(nameProfileQuery.SUFFIX);
+ }
+ nameCursor.close();
+ }
+
+ private void populateEmail(ContentResolver contentResolver) {
+ EmailProfileQuery emailProfileQuery = new EmailProfileQuery();
+ Cursor emailCursor = cursorFromProfileQuery(emailProfileQuery, contentResolver);
+ mEmailAddresses = new String[emailCursor.getCount()];
+ for (int i = 0; emailCursor.moveToNext(); i++) {
+ mEmailAddresses[i] = emailCursor.getString(emailProfileQuery.EMAIL_ADDRESS);
+ }
+ emailCursor.close();
+ }
+
+ private void populateAddress(ContentResolver contentResolver) {
+ AddressProfileQuery addressProfileQuery = new AddressProfileQuery();
+ Cursor addressCursor = cursorFromProfileQuery(addressProfileQuery, contentResolver);
+ if(addressCursor.moveToNext()) {
+ mPobox = addressCursor.getString(addressProfileQuery.POBOX);
+ mStreet = addressCursor.getString(addressProfileQuery.STREET);
+ mNeighborhood = addressCursor.getString(addressProfileQuery.NEIGHBORHOOD);
+ mCity = addressCursor.getString(addressProfileQuery.CITY);
+ mRegion = addressCursor.getString(addressProfileQuery.REGION);
+ mPostalCode = addressCursor.getString(addressProfileQuery.POSTALCODE);
+ mCountry = addressCursor.getString(addressProfileQuery.COUNTRY);
+ }
+ addressCursor.close();
+ }
+
+ private void populatePhone(ContentResolver contentResolver) {
+ PhoneProfileQuery phoneProfileQuery = new PhoneProfileQuery();
+ Cursor phoneCursor = cursorFromProfileQuery(phoneProfileQuery, contentResolver);
+ mPhoneNumbers = new String[phoneCursor.getCount()];
+ for (int i = 0; phoneCursor.moveToNext(); i++) {
+ mPhoneNumbers[i] = phoneCursor.getString(phoneProfileQuery.NUMBER);
+ }
+ phoneCursor.close();
+ }
+
+ /**
+ * Static factory method for instance creation.
+ * @param context valid Android context.
+ * @return PersonalAutofillPopulator new instance of PersonalAutofillPopulator.
+ */
+ @CalledByNative
+ static PersonalAutofillPopulator create(Context context) {
+ return new PersonalAutofillPopulator(context);
+ }
+
+ @CalledByNative
+ private String getFirstName() {
+ return mGivenName;
+ }
+
+ @CalledByNative
+ private String getLastName() {
+ return mFamilyName;
+ }
+
+ @CalledByNative
+ private String getMiddleName() {
+ return mMiddleName;
+ }
+
+ @CalledByNative
+ private String getSuffix() {
+ return mSuffix;
+ }
+
+ @CalledByNative
+ private String[] getEmailAddresses() {
+ return mEmailAddresses;
+ }
+
+ @CalledByNative
+ private String getStreet() {
+ return mStreet;
+ }
+
+ @CalledByNative
+ private String getPobox() {
+ return mPobox;
+ }
+
+ @CalledByNative
+ private String getNeighborhood() {
+ return mNeighborhood;
+ }
+
+ @CalledByNative
+ private String getCity() {
+ return mCity;
+ }
+
+ @CalledByNative
+ private String getRegion() {
+ return mRegion;
+ }
+
+ @CalledByNative
+ private String getPostalCode() {
+ return mPostalCode;
+ }
+
+ @CalledByNative
+ private String getCountry() {
+ return mCountry;
+ }
+
+ @CalledByNative
+ private String[] getPhoneNumbers() {
+ return mPhoneNumbers;
+ }
+
+ @CalledByNative
+ private boolean getHasPermissions() {
+ return mHasPermissions;
+ }
+}
diff --git a/components/autofill/browser/android/personal_data_manager_android.cc b/components/autofill/browser/android/personal_data_manager_android.cc
new file mode 100644
index 0000000..0d47e5d
--- /dev/null
+++ b/components/autofill/browser/android/personal_data_manager_android.cc
@@ -0,0 +1,21 @@
+// 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.
+
+// Populates default autofill profile from user's own Android contact.
+
+#include "components/autofill/browser/android/auxiliary_profile_loader_android.h"
+#include "components/autofill/browser/android/auxiliary_profiles_android.h"
+#include "components/autofill/browser/personal_data_manager.h"
+
+void PersonalDataManager::LoadAuxiliaryProfiles() {
+ auxiliary_profiles_.clear();
+ autofill::AuxiliaryProfileLoaderAndroid profile_loader;
+ profile_loader.Init(
+ base::android::AttachCurrentThread(),
+ base::android::GetApplicationContext());
+ if (profile_loader.GetHasPermissions()) {
+ autofill::AuxiliaryProfilesAndroid impl(profile_loader);
+ auxiliary_profiles_.push_back(impl.LoadContactsProfile().release());
+ }
+}
diff --git a/components/autofill/browser/android/test_auxiliary_profile_loader_android.cc b/components/autofill/browser/android/test_auxiliary_profile_loader_android.cc
new file mode 100644
index 0000000..bf67d91
--- /dev/null
+++ b/components/autofill/browser/android/test_auxiliary_profile_loader_android.cc
@@ -0,0 +1,125 @@
+// 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 "components/autofill/browser/android/test_auxiliary_profile_loader_android.h"
+
+TestAuxiliaryProfileLoader::TestAuxiliaryProfileLoader() {
+}
+
+TestAuxiliaryProfileLoader::~TestAuxiliaryProfileLoader() {
+}
+
+bool TestAuxiliaryProfileLoader::GetHasPermissions() const {
+ return true;
+}
+
+string16 TestAuxiliaryProfileLoader::GetFirstName() const {
+ return first_name_;
+}
+
+string16 TestAuxiliaryProfileLoader::GetMiddleName() const {
+ return middle_name_;
+}
+
+string16 TestAuxiliaryProfileLoader::GetLastName() const {
+ return last_name_;
+}
+
+string16 TestAuxiliaryProfileLoader::GetSuffix() const {
+ return suffix_;
+}
+
+string16 TestAuxiliaryProfileLoader::GetStreet() const {
+ return street_;
+}
+
+string16 TestAuxiliaryProfileLoader::GetPostOfficeBox() const {
+ return post_office_box_;
+}
+
+string16 TestAuxiliaryProfileLoader::GetCity() const {
+ return city_;
+}
+
+string16 TestAuxiliaryProfileLoader::GetNeighborhood() const {
+ return neighborhood_;
+}
+
+string16 TestAuxiliaryProfileLoader::GetRegion() const {
+ return region_;
+}
+
+string16 TestAuxiliaryProfileLoader::GetPostalCode() const {
+ return postal_code_;
+}
+
+string16 TestAuxiliaryProfileLoader::GetCountry() const {
+ return country_;
+}
+
+void TestAuxiliaryProfileLoader::GetEmailAddresses(
+ std::vector<string16>* email_addresses) const {
+ *email_addresses = email_addresses_;
+}
+
+void TestAuxiliaryProfileLoader::GetPhoneNumbers(
+ std::vector<string16>* phone_numbers) const {
+ *phone_numbers = phone_numbers_;
+}
+
+void TestAuxiliaryProfileLoader::SetFirstName(const string16& first_name) {
+ first_name_ = first_name;
+}
+
+void TestAuxiliaryProfileLoader::SetMiddleName(const string16& middle_name) {
+ middle_name_ = middle_name;
+}
+
+void TestAuxiliaryProfileLoader::SetLastName(const string16& last_name) {
+ last_name_ = last_name;
+}
+
+void TestAuxiliaryProfileLoader::SetSuffix(const string16& suffix) {
+ suffix_ = suffix;
+}
+
+void TestAuxiliaryProfileLoader::SetStreet(const string16& street) {
+ street_ = street;
+}
+
+void TestAuxiliaryProfileLoader::SetPostOfficeBox(
+ const string16& post_office_box) {
+ post_office_box_ = post_office_box;
+}
+
+void TestAuxiliaryProfileLoader::SetNeighborhood(
+ const string16& neighborhood) {
+ neighborhood_ = neighborhood;
+}
+
+void TestAuxiliaryProfileLoader::SetRegion(const string16& region) {
+ region_ = region;
+}
+
+void TestAuxiliaryProfileLoader::SetCity(const string16& city) {
+ city_ = city;
+}
+
+void TestAuxiliaryProfileLoader::SetPostalCode(const string16& postal_code) {
+ postal_code_ = postal_code;
+}
+
+void TestAuxiliaryProfileLoader::SetCountry(const string16& country) {
+ country_ = country;
+}
+
+void TestAuxiliaryProfileLoader::SetEmailAddresses(
+ const std::vector<string16>& addresses) {
+ email_addresses_ = addresses;
+}
+
+void TestAuxiliaryProfileLoader::SetPhoneNumbers(
+ const std::vector<string16>& phone_numbers) {
+ phone_numbers_ = phone_numbers;
+}
diff --git a/components/autofill/browser/android/test_auxiliary_profile_loader_android.h b/components/autofill/browser/android/test_auxiliary_profile_loader_android.h
new file mode 100644
index 0000000..795af4f
--- /dev/null
+++ b/components/autofill/browser/android/test_auxiliary_profile_loader_android.h
@@ -0,0 +1,70 @@
+// 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 COMPONENTS_AUTOFILL_BROWSER_ANDROID_TEST_AUXILIARY_PROFILE_LOADER_ANDROID_H_
+#define COMPONENTS_AUTOFILL_BROWSER_ANDROID_TEST_AUXILIARY_PROFILE_LOADER_ANDROID_H_
+
+#include "base/compiler_specific.h"
+#include "components/autofill/browser/android/auxiliary_profile_loader_android.h"
+
+class TestAuxiliaryProfileLoader
+ : public autofill::AuxiliaryProfileLoaderAndroid {
+ // Mock object for unit testing |AuxiliaryProfilesAndroid|
+ public:
+ TestAuxiliaryProfileLoader();
+ virtual ~TestAuxiliaryProfileLoader();
+
+ virtual bool GetHasPermissions() const OVERRIDE;
+
+ virtual string16 GetFirstName() const OVERRIDE;
+ virtual string16 GetMiddleName() const OVERRIDE;
+ virtual string16 GetLastName() const OVERRIDE;
+ virtual string16 GetSuffix() const OVERRIDE;
+
+ virtual string16 GetStreet() const OVERRIDE;
+ virtual string16 GetCity() const OVERRIDE;
+ virtual string16 GetNeighborhood() const OVERRIDE;
+ virtual string16 GetPostalCode() const OVERRIDE;
+ virtual string16 GetRegion() const OVERRIDE;
+ virtual string16 GetPostOfficeBox() const OVERRIDE;
+ virtual string16 GetCountry() const OVERRIDE;
+
+ virtual void GetEmailAddresses(
+ std::vector<string16>* email_addresses) const OVERRIDE;
+ virtual void GetPhoneNumbers(
+ std::vector<string16>* phone_numbers) const OVERRIDE;
+
+ void SetFirstName(const string16& first_name);
+ void SetMiddleName(const string16& middle_name);
+ void SetLastName(const string16& last_name);
+ void SetSuffix(const string16& suffix);
+
+ void SetStreet(const string16& street);
+ void SetPostOfficeBox(const string16& post_office_box);
+ void SetNeighborhood(const string16& neighborhood);
+ void SetRegion(const string16& region);
+ void SetCity(const string16& city);
+ void SetPostalCode(const string16& postal_code);
+ void SetCountry(const string16& country);
+
+ void SetEmailAddresses(const std::vector<string16>& email_addresses);
+ void SetPhoneNumbers(const std::vector<string16>& phone_numbers);
+
+ private:
+ string16 street_;
+ string16 post_office_box_;
+ string16 neighborhood_;
+ string16 region_;
+ string16 city_;
+ string16 postal_code_;
+ string16 country_;
+ string16 first_name_;
+ string16 middle_name_;
+ string16 last_name_;
+ string16 suffix_;
+ std::vector<string16> email_addresses_;
+ std::vector<string16> phone_numbers_;
+};
+
+#endif // COMPONENTS_AUTOFILL_BROWSER_ANDROID_TEST_AUXILIARY_PROFILE_LOADER_ANDROID_H_
diff --git a/components/autofill/browser/autofill_manager.cc b/components/autofill/browser/autofill_manager.cc
index e7de168..d2632fc 100644
--- a/components/autofill/browser/autofill_manager.cc
+++ b/components/autofill/browser/autofill_manager.cc
@@ -231,7 +231,7 @@ void AutofillManager::RegisterUserPrefs(PrefRegistrySyncable* registry) {
registry->RegisterBooleanPref(prefs::kPasswordGenerationEnabled,
true,
PrefRegistrySyncable::SYNCABLE_PREF);
-#if defined(OS_MACOSX)
+#if defined(OS_MACOSX) || defined(OS_ANDROID)
registry->RegisterBooleanPref(prefs::kAutofillAuxiliaryProfilesEnabled,
true,
PrefRegistrySyncable::SYNCABLE_PREF);
diff --git a/components/autofill/browser/autofill_manager_unittest.cc b/components/autofill/browser/autofill_manager_unittest.cc
index 1b4a700..2f9e5f5 100644
--- a/components/autofill/browser/autofill_manager_unittest.cc
+++ b/components/autofill/browser/autofill_manager_unittest.cc
@@ -2820,9 +2820,10 @@ TEST_F(AutofillManagerTest, FormSubmittedWithDefaultValues) {
// thing on all platforms.
TEST_F(AutofillManagerTest, AuxiliaryProfilesReset) {
PrefService* prefs = components::UserPrefs::Get(profile());
-#if defined(OS_MACOSX)
- // Auxiliary profiles is implemented on Mac only. It enables Mac Address
- // Book integration.
+#if defined(OS_MACOSX) || defined(OS_ANDROID)
+ // Auxiliary profiles is implemented on Mac and Android only.
+ // OSX: enables Mac Address Book integration.
+ // Android: enables integration with user's contact profile.
ASSERT_TRUE(prefs->GetBoolean(prefs::kAutofillAuxiliaryProfilesEnabled));
prefs->SetBoolean(prefs::kAutofillAuxiliaryProfilesEnabled, false);
prefs->ClearPref(prefs::kAutofillAuxiliaryProfilesEnabled);
diff --git a/components/autofill/browser/personal_data_manager.cc b/components/autofill/browser/personal_data_manager.cc
index 5743f03..0e69187 100644
--- a/components/autofill/browser/personal_data_manager.cc
+++ b/components/autofill/browser/personal_data_manager.cc
@@ -824,9 +824,9 @@ void PersonalDataManager::LoadProfiles() {
pending_profiles_query_ = autofill_data->GetAutofillProfiles(this);
}
-// Win and Linux implementations do nothing. Mac implementation fills in the
-// contents of |auxiliary_profiles_|.
-#if !defined(OS_MACOSX)
+// Win and Linux implementations do nothing. Mac and Android implementations
+// fill in the contents of |auxiliary_profiles_|.
+#if !defined(OS_MACOSX) && !defined(OS_ANDROID)
void PersonalDataManager::LoadAuxiliaryProfiles() {
}
#endif
diff --git a/components/autofill/browser/personal_data_manager.h b/components/autofill/browser/personal_data_manager.h
index 4a1292a..12f991e 100644
--- a/components/autofill/browser/personal_data_manager.h
+++ b/components/autofill/browser/personal_data_manager.h
@@ -204,7 +204,7 @@ class PersonalDataManager : public WebDataServiceConsumer,
// Loads the saved profiles from the web database.
virtual void LoadProfiles();
- // Loads the auxiliary profiles. Currently Mac only.
+ // Loads the auxiliary profiles. Currently Mac and Android only.
virtual void LoadAuxiliaryProfiles();
// Loads the saved credit cards from the web database.
diff --git a/components/autofill/common/password_form_fill_data.h b/components/autofill/common/password_form_fill_data.h
index 288f9f8..01985df 100644
--- a/components/autofill/common/password_form_fill_data.h
+++ b/components/autofill/common/password_form_fill_data.h
@@ -1,4 +1,4 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
+// 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.