diff options
author | Iain Merrick <husky@google.com> | 2010-11-01 12:19:54 +0000 |
---|---|---|
committer | Iain Merrick <husky@google.com> | 2010-11-03 10:21:10 +0000 |
commit | 731df977c0511bca2206b5f333555b1205ff1f43 (patch) | |
tree | 0e750b949b3f00a1ac11fda25d3c2de512f2b465 /chrome/browser/autofill | |
parent | 5add15e10e7bb80512f2c597ca57221314abe577 (diff) | |
download | external_chromium-731df977c0511bca2206b5f333555b1205ff1f43.zip external_chromium-731df977c0511bca2206b5f333555b1205ff1f43.tar.gz external_chromium-731df977c0511bca2206b5f333555b1205ff1f43.tar.bz2 |
Merge Chromium at r63472 : Initial merge by git.
Change-Id: Ifb9ee821af006a5f2211e81471be93ae440a1f5a
Diffstat (limited to 'chrome/browser/autofill')
41 files changed, 1257 insertions, 376 deletions
diff --git a/chrome/browser/autofill/address.cc b/chrome/browser/autofill/address.cc index cd5358e..8e75eec 100644 --- a/chrome/browser/autofill/address.cc +++ b/chrome/browser/autofill/address.cc @@ -27,6 +27,10 @@ const int kAutoFillAddressLength = arraysize(kAutoFillAddressTypes); } // namespace +Address::Address() {} + +Address::~Address() {} + void Address::GetPossibleFieldTypes(const string16& text, FieldTypeSet* possible_types) const { DCHECK(possible_types); diff --git a/chrome/browser/autofill/address.h b/chrome/browser/autofill/address.h index 1f826ee..a2b4dd3 100644 --- a/chrome/browser/autofill/address.h +++ b/chrome/browser/autofill/address.h @@ -14,8 +14,8 @@ // A form group that stores address information. class Address : public FormGroup { public: - Address() {} - virtual ~Address() {} + Address(); + virtual ~Address(); // FormGroup implementation: virtual FormGroup* Clone() const = 0; diff --git a/chrome/browser/autofill/autofill_address_model_mac_unittest.mm b/chrome/browser/autofill/autofill_address_model_mac_unittest.mm index adab6aa..3cf29c8 100644 --- a/chrome/browser/autofill/autofill_address_model_mac_unittest.mm +++ b/chrome/browser/autofill/autofill_address_model_mac_unittest.mm @@ -5,7 +5,7 @@ #include "base/scoped_nsobject.h" #include "base/utf_string_conversions.h" #import "chrome/browser/autofill/autofill_address_model_mac.h" -#include "chrome/browser/autofill/autofill_common_unittest.h" +#include "chrome/browser/autofill/autofill_common_test.h" #include "chrome/browser/autofill/autofill_profile.h" #include "chrome/browser/cocoa/browser_test_helper.h" #import "chrome/browser/cocoa/cocoa_test_helper.h" @@ -26,7 +26,7 @@ TEST(AutoFillAddressModelTest, Basic) { TEST(AutoFillAddressModelTest, InitializationFromProfile) { AutoFillProfile profile(ASCIIToUTF16("Home"), 0); - autofill_unittest::SetProfileInfo( + autofill_test::SetProfileInfo( &profile, "Billing", "Marion", @@ -60,7 +60,7 @@ TEST(AutoFillAddressModelTest, InitializationFromProfile) { TEST(AutoFillAddressModelTest, CopyModelToProfile) { AutoFillProfile profile(ASCIIToUTF16("Home"), 0); - autofill_unittest::SetProfileInfo( + autofill_test::SetProfileInfo( &profile, "Billing", "Marion", diff --git a/chrome/browser/autofill/autofill_browsertest.cc b/chrome/browser/autofill/autofill_browsertest.cc new file mode 100644 index 0000000..527cccd --- /dev/null +++ b/chrome/browser/autofill/autofill_browsertest.cc @@ -0,0 +1,156 @@ +// Copyright (c) 2010 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 <string> + +#include "app/keyboard_code_conversion.h" +#include "base/basictypes.h" +#include "base/ref_counted.h" +#include "base/scoped_ptr.h" +#include "base/string16.h" +#include "chrome/browser/autofill/autofill_common_test.h" +#include "chrome/browser/autofill/autofill_profile.h" +#include "chrome/browser/autofill/personal_data_manager.h" +#include "chrome/browser/browser.h" +#include "chrome/browser/browser_window.h" +#include "chrome/browser/net/predictor_api.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/common/pref_names.h" +#include "chrome/test/in_process_browser_test.h" +#include "chrome/test/ui_test_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +class AutoFillTest : public InProcessBrowserTest { + protected: + AutoFillTest() { + set_show_window(true); + EnableDOMAutomation(); + } + + void SetUpProfile() { + autofill_test::DisableSystemServices(browser()->profile()); + + AutoFillProfile profile(string16(), 0); + autofill_test::SetProfileInfo( + &profile, "Office Space", "Milton", "C.", "Waddams", + "red.swingline@initech.com", "Initech", "4120 Freidrich Lane", + "Basement", "Austin", "Texas", "78744", "United States", "5125551234", + "5125550000"); + + PersonalDataManager* personal_data_manager = + browser()->profile()->GetPersonalDataManager(); + ASSERT_TRUE(personal_data_manager); + + std::vector<AutoFillProfile> profiles(1, profile); + personal_data_manager->SetProfiles(&profiles); + } + + void ExpectFieldValue(const std::wstring& field_name, + const std::string& expected_value) { + std::string value; + ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString( + browser()->GetSelectedTabContents()->render_view_host(), L"", + L"window.domAutomationController.send(" + L"document.getElementById('" + field_name + L"').value);", &value)); + EXPECT_EQ(expected_value, value); + } +}; + +// Test that basic form fill is working. +// FAILS on windows: http://crbug.com/57962 +#if defined(OS_WIN) +#define MAYBE_BasicFormFill DISABLED_BasicFormFill +#else +#define MAYBE_BasicFormFill BasicFormFill +#endif +IN_PROC_BROWSER_TEST_F(AutoFillTest, MAYBE_BasicFormFill) { + SetUpProfile(); + + ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); + ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL( + browser(), GURL("data:text/html;charset=utf-8," + "<form action=\"http://www.google.com/\" method=\"POST\">" + "<label for=\"firstname\">First name:</label>" + " <input type=\"text\" id=\"firstname\" /><br />" + "<label for=\"lastname\">Last name:</label>" + " <input type=\"text\" id=\"lastname\" /><br />" + "<label for=\"address1\">Address line 1:</label>" + " <input type=\"text\" id=\"address1\" /><br />" + "<label for=\"address2\">Address line 2:</label>" + " <input type=\"text\" id=\"address2\" /><br />" + "<label for=\"city\">City:</label>" + " <input type=\"text\" id=\"city\" /><br />" + "<label for=\"state\">State:</label>" + " <select id=\"state\">" + " <option value=\"\" selected=\"yes\">--</option>" + " <option value=\"CA\">California</option>" + " <option value=\"TX\">Texas</option>" + " </select><br />" + "<label for=\"zip\">ZIP code:</label>" + " <input type=\"text\" id=\"zip\" /><br />" + "<label for=\"country\">Country:</label>" + " <select id=\"country\">" + " <option value=\"\" selected=\"yes\">--</option>" + " <option value=\"CA\">Canada</option>" + " <option value=\"US\">United States</option>" + " </select><br />" + "<label for=\"phone\">Phone number:</label>" + " <input type=\"text\" id=\"phone\" /><br />" + "</form>"))); + + ASSERT_NO_FATAL_FAILURE(ui_test_utils::ClickOnView(browser(), + VIEW_ID_TAB_CONTAINER)); + ASSERT_TRUE(ui_test_utils::IsViewFocused(browser(), + VIEW_ID_TAB_CONTAINER_FOCUS_VIEW)); + + RenderViewHost* render_view_host = + browser()->GetSelectedTabContents()->render_view_host(); + ASSERT_TRUE(ui_test_utils::ExecuteJavaScript( + render_view_host, L"", L"document.getElementById('firstname').focus();")); + + // Start filling the first name field with "M" and wait for the popup to be + // shown. + ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( + browser(), app::VKEY_M, false, true, false, false, + NotificationType::AUTOFILL_DID_SHOW_SUGGESTIONS, + Source<RenderViewHost>(render_view_host))); + + // Press the down arrow to select the suggestion and preview the autofilled + // form. + ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( + browser(), app::VKEY_DOWN, false, false, false, false, + NotificationType::AUTOFILL_DID_FILL_FORM_DATA, + Source<RenderViewHost>(render_view_host))); + + // The previewed values should not be accessible to JavaScript. + ExpectFieldValue(L"firstname", "M"); + ExpectFieldValue(L"lastname", ""); + ExpectFieldValue(L"address1", ""); + ExpectFieldValue(L"address2", ""); + ExpectFieldValue(L"city", ""); + ExpectFieldValue(L"state", ""); + ExpectFieldValue(L"zip", ""); + ExpectFieldValue(L"country", ""); + ExpectFieldValue(L"phone", ""); + // TODO(isherman): It would be nice to test that the previewed values are + // displayed: http://crbug.com/57220 + + // Press Enter to accept the autofill suggestions. + ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( + browser(), app::VKEY_RETURN, false, false, false, false, + NotificationType::AUTOFILL_DID_FILL_FORM_DATA, + Source<RenderViewHost>(render_view_host))); + + // The form should be filled. + ExpectFieldValue(L"firstname", "Milton"); + ExpectFieldValue(L"lastname", "Waddams"); + ExpectFieldValue(L"address1", "4120 Freidrich Lane"); + ExpectFieldValue(L"address2", "Basement"); + ExpectFieldValue(L"city", "Austin"); + ExpectFieldValue(L"state", "TX"); + ExpectFieldValue(L"zip", "78744"); + ExpectFieldValue(L"country", "US"); + ExpectFieldValue(L"phone", "5125551234"); +} diff --git a/chrome/browser/autofill/autofill_cc_infobar_delegate.cc b/chrome/browser/autofill/autofill_cc_infobar_delegate.cc index 2dadc7d..01b49eb 100644 --- a/chrome/browser/autofill/autofill_cc_infobar_delegate.cc +++ b/chrome/browser/autofill/autofill_cc_infobar_delegate.cc @@ -6,9 +6,10 @@ #include "app/l10n_util.h" #include "app/resource_bundle.h" -#include "base/histogram.h" +#include "base/metrics/histogram.h" #include "chrome/browser/autofill/autofill_cc_infobar.h" #include "chrome/browser/autofill/autofill_manager.h" +#include "chrome/browser/browser_list.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profile.h" #include "chrome/browser/tab_contents/tab_contents.h" @@ -92,8 +93,9 @@ string16 AutoFillCCInfoBarDelegate::GetLinkText() { } bool AutoFillCCInfoBarDelegate::LinkClicked(WindowOpenDisposition disposition) { - host_->tab_contents()->OpenURL(GURL(kAutoFillLearnMoreUrl), GURL(), - NEW_FOREGROUND_TAB, PageTransition::TYPED); + Browser* browser = BrowserList::GetLastActive(); + DCHECK(browser); + browser->OpenAutoFillHelpTabAndActivate(); return false; } diff --git a/chrome/browser/autofill/autofill_common_unittest.cc b/chrome/browser/autofill/autofill_common_test.cc index bad2784..3c7c319 100644 --- a/chrome/browser/autofill/autofill_common_unittest.cc +++ b/chrome/browser/autofill/autofill_common_test.cc @@ -2,14 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/autofill/autofill_common_unittest.h" +#include "chrome/browser/autofill/autofill_common_test.h" #include "base/utf_string_conversions.h" #include "chrome/browser/autofill/autofill_profile.h" #include "chrome/browser/autofill/credit_card.h" +#include "chrome/browser/password_manager/encryptor.h" +#include "chrome/browser/prefs/pref_service.h" +#include "chrome/browser/profile.h" +#include "chrome/common/pref_names.h" #include "webkit/glue/form_field.h" -namespace autofill_unittest { +namespace autofill_test { void CreateTestFormField(const char* label, const char* name, @@ -63,4 +67,16 @@ void SetCreditCardInfo(CreditCard* credit_card, credit_card->set_billing_address_id(billing_address_id); } -} // namespace autofill_unittest +void DisableSystemServices(Profile* profile) { + // Use a mock Keychain rather than the OS one to store credit card data. +#if defined(OS_MACOSX) + Encryptor::UseMockKeychain(true); +#endif + + // Disable auxiliary profiles for unit testing. These reach out to system + // services on the Mac. + profile->GetPrefs()->SetBoolean(prefs::kAutoFillAuxiliaryProfilesEnabled, + false); +} + +} // namespace autofill_test diff --git a/chrome/browser/autofill/autofill_common_unittest.h b/chrome/browser/autofill/autofill_common_test.h index a53bf84..3b7b83e 100644 --- a/chrome/browser/autofill/autofill_common_unittest.h +++ b/chrome/browser/autofill/autofill_common_test.h @@ -2,19 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_AUTOFILL_AUTOFILL_COMMON_UNITTEST_H_ -#define CHROME_BROWSER_AUTOFILL_AUTOFILL_COMMON_UNITTEST_H_ +#ifndef CHROME_BROWSER_AUTOFILL_AUTOFILL_COMMON_TEST_H_ +#define CHROME_BROWSER_AUTOFILL_AUTOFILL_COMMON_TEST_H_ #pragma once class AutoFillProfile; class CreditCard; +class Profile; namespace webkit_glue { class FormField; } // namespace webkit_glue -// Common utilities shared amongst AutoFill unit tests. -namespace autofill_unittest { +// Common utilities shared amongst AutoFill tests. +namespace autofill_test { // Provides a quick way to populate a FormField with c-strings. void CreateTestFormField(const char* label, @@ -41,6 +42,11 @@ void SetCreditCardInfo(CreditCard* credit_card, const char* card_number, const char* expiration_month, const char* expiration_year, int billing_address_id); -} // namespace autofill_unittest +// TODO(isherman): We should do this automatically for all tests, not manually +// on a per-test basis: http://crbug.com/57221 +// Disables or mocks out code that would otherwise reach out to system services. +void DisableSystemServices(Profile* profile); -#endif // CHROME_BROWSER_AUTOFILL_AUTOFILL_COMMON_UNITTEST_H_ +} // namespace autofill_test + +#endif // CHROME_BROWSER_AUTOFILL_AUTOFILL_COMMON_TEST_H_ diff --git a/chrome/browser/autofill/autofill_credit_card_model_mac_unittest.mm b/chrome/browser/autofill/autofill_credit_card_model_mac_unittest.mm index 6caab87..f90f7d1 100644 --- a/chrome/browser/autofill/autofill_credit_card_model_mac_unittest.mm +++ b/chrome/browser/autofill/autofill_credit_card_model_mac_unittest.mm @@ -4,7 +4,7 @@ #include "base/scoped_nsobject.h" #include "base/utf_string_conversions.h" -#include "chrome/browser/autofill/autofill_common_unittest.h" +#include "chrome/browser/autofill/autofill_common_test.h" #import "chrome/browser/autofill/autofill_credit_card_model_mac.h" #include "chrome/browser/autofill/credit_card.h" #include "chrome/browser/cocoa/browser_test_helper.h" @@ -26,7 +26,7 @@ TEST(AutoFillCreditCardModelTest, Basic) { TEST(AutoFillCreditCardModelTest, InitializationFromCreditCard) { CreditCard credit_card(string16(), 0); - autofill_unittest::SetCreditCardInfo(&credit_card, "Corporate", + autofill_test::SetCreditCardInfo(&credit_card, "Corporate", "John Dillinger", "Visa", "123456789012", "01", "2010", 1); scoped_nsobject<AutoFillCreditCardModel> model( [[AutoFillCreditCardModel alloc] initWithCreditCard:credit_card]); @@ -41,7 +41,7 @@ TEST(AutoFillCreditCardModelTest, InitializationFromCreditCard) { TEST(AutoFillCreditCardModelTest, CopyModelToCreditCard) { CreditCard credit_card(string16(), 0); - autofill_unittest::SetCreditCardInfo(&credit_card, "Corporate", + autofill_test::SetCreditCardInfo(&credit_card, "Corporate", "John Dillinger", "Visa", "123456789012", "01", "2010", 1); scoped_nsobject<AutoFillCreditCardModel> model( [[AutoFillCreditCardModel alloc] initWithCreditCard:credit_card]); diff --git a/chrome/browser/autofill/autofill_dialog_controller_mac.mm b/chrome/browser/autofill/autofill_dialog_controller_mac.mm index 26bd111..f48f952 100644 --- a/chrome/browser/autofill/autofill_dialog_controller_mac.mm +++ b/chrome/browser/autofill/autofill_dialog_controller_mac.mm @@ -8,13 +8,13 @@ #include "base/mac_util.h" #include "base/singleton.h" #include "base/sys_string_conversions.h" -#include "chrome/browser/browser.h" -#include "chrome/browser/browser_list.h" #import "chrome/browser/autofill/autofill_address_model_mac.h" #import "chrome/browser/autofill/autofill_address_sheet_controller_mac.h" #import "chrome/browser/autofill/autofill_credit_card_model_mac.h" #import "chrome/browser/autofill/autofill_credit_card_sheet_controller_mac.h" #import "chrome/browser/autofill/personal_data_manager.h" +#include "chrome/browser/browser.h" +#include "chrome/browser/browser_list.h" #include "chrome/browser/browser_process.h" #import "chrome/browser/cocoa/window_size_autosaver.h" #include "chrome/browser/prefs/pref_service.h" @@ -938,7 +938,7 @@ class PreferenceObserver : public NotificationObserver { profile.SetInfo(AutoFillType(PHONE_HOME_WHOLE_NUMBER), base::SysNSStringToUTF16(string)); if (profile.GetFieldText(AutoFillType(PHONE_HOME_WHOLE_NUMBER)).empty()) { - image = rb.GetNSImageNamed(IDR_INPUT_ALERT); + image = rb.GetNativeImageNamed(IDR_INPUT_ALERT); DCHECK(image); return image; } @@ -946,7 +946,7 @@ class PreferenceObserver : public NotificationObserver { // No alert icon, so must be valid input. if (!image) { - image = rb.GetNSImageNamed(IDR_INPUT_GOOD); + image = rb.GetNativeImageNamed(IDR_INPUT_GOOD); DCHECK(image); return image; } diff --git a/chrome/browser/autofill/autofill_dialog_gtk.cc b/chrome/browser/autofill/autofill_dialog_gtk.cc index 1e6a12b..bc305ff 100644 --- a/chrome/browser/autofill/autofill_dialog_gtk.cc +++ b/chrome/browser/autofill/autofill_dialog_gtk.cc @@ -366,8 +366,9 @@ gboolean AutoFillDialog::OnSelectionFilter(GtkTreeSelection* selection, void AutoFillDialog::OnLinkActivated() { Browser* browser = BrowserList::GetLastActive(); - browser->OpenURL(GURL(kAutoFillLearnMoreUrl), GURL(), NEW_FOREGROUND_TAB, - PageTransition::TYPED); + if (!browser || !browser->GetSelectedTabContents()) + browser = Browser::Create(profile_); + browser->OpenAutoFillHelpTabAndActivate(); } void AutoFillDialog::LoadAutoFillData() { diff --git a/chrome/browser/autofill/autofill_download.cc b/chrome/browser/autofill/autofill_download.cc index d36a6ac..a08794b 100644 --- a/chrome/browser/autofill/autofill_download.cc +++ b/chrome/browser/autofill/autofill_download.cc @@ -25,6 +25,11 @@ #define AUTO_FILL_QUERY_SERVER_NAME_START_IN_HEADER "SOMESERVER/" #endif +struct AutoFillDownloadManager::FormRequestData { + std::vector<std::string> form_signatures; + AutoFillRequestType request_type; +}; + AutoFillDownloadManager::AutoFillDownloadManager(Profile* profile) : profile_(profile), observer_(NULL), @@ -92,7 +97,7 @@ bool AutoFillDownloadManager::StartUploadRequest( double upload_rate = form_was_matched ? GetPositiveUploadRate() : GetNegativeUploadRate(); if (base::RandDouble() > upload_rate) { - LOG(INFO) << "AutoFillDownloadManager: Upload request is ignored"; + VLOG(1) << "AutoFillDownloadManager: Upload request is ignored"; // If we ever need notification that upload was skipped, add it here. return false; } @@ -233,16 +238,16 @@ void AutoFillDownloadManager::OnURLFetchComplete(const URLFetcher* source, } } - LOG(INFO) << "AutoFillDownloadManager: " << type_of_request << - " request has failed with response" << response_code; + VLOG(1) << "AutoFillDownloadManager: " << type_of_request + << " request has failed with response" << response_code; if (observer_) { observer_->OnHeuristicsRequestError(it->second.form_signatures[0], it->second.request_type, response_code); } } else { - LOG(INFO) << "AutoFillDownloadManager: " << type_of_request << - " request has succeeded"; + VLOG(1) << "AutoFillDownloadManager: " << type_of_request + << " request has succeeded"; if (it->second.request_type == AutoFillDownloadManager::REQUEST_QUERY) { if (observer_) observer_->OnLoadedAutoFillHeuristics(data); diff --git a/chrome/browser/autofill/autofill_download.h b/chrome/browser/autofill/autofill_download.h index fdcbba0..fc24c92 100644 --- a/chrome/browser/autofill/autofill_download.h +++ b/chrome/browser/autofill/autofill_download.h @@ -7,7 +7,6 @@ #pragma once #include <map> -#include <vector> #include <string> #include "base/scoped_vector.h" @@ -96,10 +95,8 @@ class AutoFillDownloadManager : public URLFetcher::Delegate { private: friend class AutoFillDownloadTestHelper; // unit-test. - struct FormRequestData { - std::vector<std::string> form_signatures; - AutoFillRequestType request_type; - }; + + struct FormRequestData; // Initiates request to AutoFill servers to download/upload heuristics. // |form_xml| - form structure XML to upload/download. diff --git a/chrome/browser/autofill/autofill_download_unittest.cc b/chrome/browser/autofill/autofill_download_unittest.cc index baecd97..deb9b49 100644 --- a/chrome/browser/autofill/autofill_download_unittest.cc +++ b/chrome/browser/autofill/autofill_download_unittest.cc @@ -5,6 +5,7 @@ #include <list> #include "base/string_util.h" +#include "base/test/test_timeouts.h" #include "base/utf_string_conversions.h" #include "chrome/browser/autofill/autofill_download.h" #include "chrome/common/net/test_url_fetcher_factory.h" @@ -245,15 +246,12 @@ TEST(AutoFillDownloadTest, QueryAndUploadTest) { fetcher = factory.GetFetcherByID(3); EXPECT_EQ(NULL, fetcher); - // Verify DOS attack back-offs. - const int kBackOffTimeout = 10000; - // Request with id 3. EXPECT_TRUE(helper.download_manager.StartQueryRequest(form_structures)); fetcher = factory.GetFetcherByID(3); ASSERT_TRUE(fetcher); fetcher->set_backoff_delay( - base::TimeDelta::FromMilliseconds(kBackOffTimeout)); + base::TimeDelta::FromMilliseconds(TestTimeouts::action_max_timeout_ms())); fetcher->delegate()->OnURLFetchComplete(fetcher, GURL(), URLRequestStatus(), 500, ResponseCookies(), std::string(responses[0])); @@ -277,7 +275,7 @@ TEST(AutoFillDownloadTest, QueryAndUploadTest) { fetcher = factory.GetFetcherByID(4); ASSERT_TRUE(fetcher); fetcher->set_backoff_delay( - base::TimeDelta::FromMilliseconds(kBackOffTimeout)); + base::TimeDelta::FromMilliseconds(TestTimeouts::action_max_timeout_ms())); fetcher->delegate()->OnURLFetchComplete(fetcher, GURL(), URLRequestStatus(), 503, ResponseCookies(), std::string(responses[2])); @@ -297,4 +295,3 @@ TEST(AutoFillDownloadTest, QueryAndUploadTest) { } } // namespace - diff --git a/chrome/browser/autofill/autofill_field.cc b/chrome/browser/autofill/autofill_field.cc index 9503f7c..cd41b65 100644 --- a/chrome/browser/autofill/autofill_field.cc +++ b/chrome/browser/autofill/autofill_field.cc @@ -38,6 +38,8 @@ AutoFillField::AutoFillField(const webkit_glue::FormField& field, heuristic_type_(UNKNOWN_TYPE) { } +AutoFillField::~AutoFillField() {} + void AutoFillField::set_heuristic_type(const AutoFillFieldType& type) { DCHECK(type >= 0 && type < MAX_VALID_FIELD_TYPE); if (type >= 0 && type < MAX_VALID_FIELD_TYPE) diff --git a/chrome/browser/autofill/autofill_field.h b/chrome/browser/autofill/autofill_field.h index e0fe324..a5a3290 100644 --- a/chrome/browser/autofill/autofill_field.h +++ b/chrome/browser/autofill/autofill_field.h @@ -21,6 +21,7 @@ class AutoFillField : public webkit_glue::FormField { AutoFillField(); AutoFillField(const webkit_glue::FormField& field, const string16& unique_name); + virtual ~AutoFillField(); const string16& unique_name() const { return unique_name_; } diff --git a/chrome/browser/autofill/autofill_ie_toolbar_import_win.cc b/chrome/browser/autofill/autofill_ie_toolbar_import_win.cc new file mode 100644 index 0000000..dcfe0a5 --- /dev/null +++ b/chrome/browser/autofill/autofill_ie_toolbar_import_win.cc @@ -0,0 +1,244 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/autofill/autofill_ie_toolbar_import_win.h" + +#include "base/basictypes.h" +#include "base/string16.h" +#include "base/win/registry.h" +#include "chrome/browser/autofill/autofill_profile.h" +#include "chrome/browser/autofill/credit_card.h" +#include "chrome/browser/autofill/field_types.h" +#include "chrome/browser/autofill/personal_data_manager.h" +#include "chrome/browser/sync/util/data_encryption.h" + +using base::win::RegKey; + +// Forward declaration. This function is not in unnamed namespace as it +// is referenced in the unittest. +bool ImportCurrentUserProfiles(std::vector<AutoFillProfile>* profiles, + std::vector<CreditCard>* credit_cards); +namespace { + +#if defined(GOOGLE_CHROME_BUILD) +#include "chrome/browser/autofill/internal/autofill_ie_toolbar_decryption.h" +#else // defined(GOOGLE_CHROME_BUILD) +inline std::wstring DecryptCCNumber(const std::wstring& data) { + return std::wstring(); +} +inline bool IsEmptySalt(const std::wstring& salt) { + return false; +} +#endif // defined(GOOGLE_CHROME_BUILD) + +const wchar_t* const kProfileKey = + L"Software\\Google\\Google Toolbar\\4.0\\Autofill\\Profiles"; +const wchar_t* const kCreditCardKey = + L"Software\\Google\\Google Toolbar\\4.0\\Autofill\\Credit Cards"; +const wchar_t* const kPasswordHashValue = L"password_hash"; +const wchar_t* const kSaltValue = L"salt"; + +string16 ReadAndDecryptValue(RegKey* key, const wchar_t* value_name) { + DWORD data_type = REG_BINARY; + DWORD data_size = 0; + if (!key->ReadValue(value_name, NULL, &data_size, &data_type) || + !data_size || data_type != REG_BINARY) + return string16(); + std::vector<uint8> data; + data.resize(data_size); + if (key->ReadValue(value_name, &(data[0]), &data_size, &data_type)) { + std::string out_data; + if (DecryptData(data, &out_data)) { + // The actual data is in UTF16 already. + if (!(out_data.size() & 1) && (out_data.size() > 2) && + !out_data[out_data.size() - 1] && !out_data[out_data.size() - 2]) { + return string16( + reinterpret_cast<const wchar_t *>(out_data.c_str())); + } + } + } + return string16(); +} + +struct { + AutoFillFieldType field_type; + const wchar_t *reg_value_name; +} profile_reg_values[] = { + { NAME_FIRST, L"name_first" }, + { NAME_MIDDLE, L"name_middle" }, + { NAME_LAST, L"name_last" }, + { NAME_SUFFIX, L"name_suffix" }, + { EMAIL_ADDRESS, L"email" }, + { COMPANY_NAME, L"company_name" }, + { PHONE_HOME_NUMBER, L"phone_home_number" }, + { PHONE_HOME_CITY_CODE, L"phone_home_city_code" }, + { PHONE_HOME_COUNTRY_CODE, L"phone_home_country_code" }, + { PHONE_FAX_NUMBER, L"phone_fax_number" }, + { PHONE_FAX_CITY_CODE, L"phone_fax_city_code" }, + { PHONE_FAX_COUNTRY_CODE, L"phone_fax_country_code" }, + { ADDRESS_HOME_LINE1, L"address_home_line1" }, + { ADDRESS_HOME_LINE2, L"address_home_line2" }, + { ADDRESS_HOME_CITY, L"address_home_city" }, + { ADDRESS_HOME_STATE, L"address_home_state" }, + { ADDRESS_HOME_ZIP, L"address_home_zip" }, + { ADDRESS_HOME_COUNTRY, L"address_home_country" }, + { ADDRESS_BILLING_LINE1, L"address_billing_line1" }, + { ADDRESS_BILLING_LINE2, L"address_billing_line2" }, + { ADDRESS_BILLING_CITY, L"address_billing_city" }, + { ADDRESS_BILLING_STATE, L"address_billing_state" }, + { ADDRESS_BILLING_ZIP, L"address_billing_zip" }, + { ADDRESS_BILLING_COUNTRY, L"address_billing_country" }, + { CREDIT_CARD_NAME, L"credit_card_name" }, + { CREDIT_CARD_NUMBER, L"credit_card_number" }, + { CREDIT_CARD_EXP_MONTH, L"credit_card_exp_month" }, + { CREDIT_CARD_EXP_4_DIGIT_YEAR, L"credit_card_exp_4_digit_year" }, + { CREDIT_CARD_TYPE, L"credit_card_type" }, + // We do not import verification code. +}; + +typedef std::map<std::wstring, AutoFillFieldType> RegToFieldMap; + +bool ImportSingleProfile(FormGroup* profile, + RegKey* key, + const RegToFieldMap& reg_to_field ) { + DCHECK(profile != NULL); + if (!key->Valid()) + return false; + + bool has_non_empty_fields = false; + + for (uint32 value_index = 0; value_index < key->ValueCount(); ++value_index) { + std::wstring value_name; + if (!key->ReadName(value_index, &value_name)) + continue; + RegToFieldMap::const_iterator it = reg_to_field.find(value_name); + if (it == reg_to_field.end()) + continue; // This field is not imported. + string16 field_value = ReadAndDecryptValue(key, value_name.c_str()); + if (!field_value.empty()) { + has_non_empty_fields = true; + profile->SetInfo(AutoFillType(it->second), field_value); + } + } + return has_non_empty_fields; +} + +// Imports profiles from the IE toolbar and stores them. Asynchronous +// if PersonalDataManager has not been loaded yet. Deletes itself on completion. +class AutoFillImporter : public PersonalDataManager::Observer { + public: + explicit AutoFillImporter(PersonalDataManager* personal_data_manager) + : personal_data_manager_(personal_data_manager) { + personal_data_manager_->SetObserver(this); + } + + bool ImportProfiles() { + if (!ImportCurrentUserProfiles(&profiles_, &credit_cards_)) { + delete this; + return false; + } + if (personal_data_manager_->IsDataLoaded()) + OnPersonalDataLoaded(); + return true; + } + + // PersonalDataManager::Observer methods: + virtual void OnPersonalDataLoaded() { + if (!profiles_.empty()) + personal_data_manager_->SetProfiles(&profiles_); + if (!credit_cards_.empty()) + personal_data_manager_->SetCreditCards(&credit_cards_); + delete this; + } + + private: + ~AutoFillImporter() { + personal_data_manager_->RemoveObserver(this); + } + + PersonalDataManager* personal_data_manager_; + std::vector<AutoFillProfile> profiles_; + std::vector<CreditCard> credit_cards_; +}; + +} // namespace + +// Imports AutoFill profiles and credit cards from IE Toolbar if present and not +// password protected. Returns true if data is successfully retrieved. False if +// there is no data, data is password protected or error occurred. +bool ImportCurrentUserProfiles(std::vector<AutoFillProfile>* profiles, + std::vector<CreditCard>* credit_cards) { + DCHECK(profiles); + DCHECK(credit_cards); + + // Create a map of possible fields for a quick access. + RegToFieldMap reg_to_field; + for (size_t i = 0; i < arraysize(profile_reg_values); ++i) { + reg_to_field[std::wstring(profile_reg_values[i].reg_value_name)] = + profile_reg_values[i].field_type; + } + + base::win::RegistryKeyIterator iterator_profiles(HKEY_CURRENT_USER, + kProfileKey); + for (; iterator_profiles.Valid(); ++iterator_profiles) { + std::wstring key_name(kProfileKey); + key_name.append(L"\\"); + key_name.append(iterator_profiles.Name()); + RegKey key(HKEY_CURRENT_USER, key_name.c_str(), KEY_READ); + AutoFillProfile profile; + if (ImportSingleProfile(&profile, &key, reg_to_field)) { + // Combine phones into whole phone #. + string16 phone; + phone = profile.GetFieldText(AutoFillType(PHONE_HOME_COUNTRY_CODE)); + phone.append(profile.GetFieldText(AutoFillType(PHONE_HOME_CITY_CODE))); + phone.append(profile.GetFieldText(AutoFillType(PHONE_HOME_NUMBER))); + profile.SetInfo(AutoFillType(PHONE_HOME_WHOLE_NUMBER), phone); + phone = profile.GetFieldText(AutoFillType(PHONE_FAX_COUNTRY_CODE)); + phone.append(profile.GetFieldText(AutoFillType(PHONE_FAX_CITY_CODE))); + phone.append(profile.GetFieldText(AutoFillType(PHONE_FAX_NUMBER))); + profile.SetInfo(AutoFillType(PHONE_FAX_WHOLE_NUMBER), phone); + profiles->push_back(profile); + } + } + string16 password_hash; + string16 salt; + RegKey cc_key(HKEY_CURRENT_USER, kCreditCardKey, KEY_READ); + if (cc_key.Valid()) { + password_hash = ReadAndDecryptValue(&cc_key, kPasswordHashValue); + salt = ReadAndDecryptValue(&cc_key, kSaltValue); + } + + // We import CC profiles only if they are not password protected. + if (password_hash.empty() && IsEmptySalt(salt)) { + base::win::RegistryKeyIterator iterator_cc(HKEY_CURRENT_USER, + kCreditCardKey); + for (; iterator_cc.Valid(); ++iterator_cc) { + std::wstring key_name(kCreditCardKey); + key_name.append(L"\\"); + key_name.append(iterator_cc.Name()); + RegKey key(HKEY_CURRENT_USER, key_name.c_str(), KEY_READ); + CreditCard credit_card; + if (ImportSingleProfile(&credit_card, &key, reg_to_field)) { + string16 cc_number = credit_card.GetFieldText( + AutoFillType(CREDIT_CARD_NUMBER)); + + if (!cc_number.empty()) { + // No additional password, and CC# is not empty, decrypt CC#. + cc_number = DecryptCCNumber(cc_number); + } + credit_card.SetInfo(AutoFillType(CREDIT_CARD_NUMBER), cc_number); + if (!cc_number.empty()) + credit_cards->push_back(credit_card); + } + } + } + return (profiles->size() + credit_cards->size()) > 0; +} + +bool ImportAutofillDataWin(PersonalDataManager* pdm) { + AutoFillImporter *importer = new AutoFillImporter(pdm); + // importer will self delete. + return importer->ImportProfiles(); +} + diff --git a/chrome/browser/autofill/autofill_ie_toolbar_import_win.h b/chrome/browser/autofill/autofill_ie_toolbar_import_win.h new file mode 100644 index 0000000..b38da9c --- /dev/null +++ b/chrome/browser/autofill/autofill_ie_toolbar_import_win.h @@ -0,0 +1,23 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_AUTOFILL_AUTOFILL_IE_TOOLBAR_IMPORT_WIN_H_ +#define CHROME_BROWSER_AUTOFILL_AUTOFILL_IE_TOOLBAR_IMPORT_WIN_H_ + +#include <vector> + +// This importer is here and not in chrome/browser/importer/toolbar_importer.cc +// because of the following: +// 1. The data is not saved in profile, but rather in registry, thus it is +// accessed without going through toolbar front end. +// 2. This applies to IE (thus Windows) toolbar only. +// 3. The functionality relevant only to and completely encapsulated in the +// autofill. +// 4. This is completely automated as opposed to Importers, which are explicit. +class PersonalDataManager; + +bool ImportAutofillDataWin(PersonalDataManager* pdm); + +#endif // CHROME_BROWSER_AUTOFILL_AUTOFILL_IE_TOOLBAR_IMPORT_WIN_H_ + diff --git a/chrome/browser/autofill/autofill_ie_toolbar_import_win_unittest.cc b/chrome/browser/autofill/autofill_ie_toolbar_import_win_unittest.cc new file mode 100644 index 0000000..0512139 --- /dev/null +++ b/chrome/browser/autofill/autofill_ie_toolbar_import_win_unittest.cc @@ -0,0 +1,233 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/autofill/autofill_ie_toolbar_import_win.h" + +#include "base/basictypes.h" +#include "base/string16.h" +#include "base/win/registry.h" +#include "chrome/browser/autofill/autofill_profile.h" +#include "chrome/browser/autofill/credit_card.h" +#include "chrome/browser/autofill/field_types.h" +#include "chrome/browser/sync/util/data_encryption.h" +#include "testing/gtest/include/gtest/gtest.h" + +using base::win::RegKey; + +// Defined in autofill_ie_toolbar_import_win.cc. Not exposed in the header file. +bool ImportCurrentUserProfiles(std::vector<AutoFillProfile>* profiles, + std::vector<CreditCard>* credit_cards); + +namespace { + +const wchar_t kUnitTestRegistrySubKey[] = L"SOFTWARE\\Chromium Unit Tests"; +const wchar_t kUnitTestUserOverrideSubKey[] = + L"SOFTWARE\\Chromium Unit Tests\\HKCU Override"; + +const wchar_t* const kProfileKey = + L"Software\\Google\\Google Toolbar\\4.0\\Autofill\\Profiles"; +const wchar_t* const kCreditCardKey = + L"Software\\Google\\Google Toolbar\\4.0\\Autofill\\Credit Cards"; +const wchar_t* const kPasswordHashValue = L"password_hash"; +const wchar_t* const kSaltValue = L"salt"; + +struct ValueDescription { + wchar_t const* const value_name; + wchar_t const* const value; +}; + +ValueDescription profile1[] = { + { L"name_first", L"John" }, + { L"name_middle", L"Herman" }, + { L"name_last", L"Doe" }, + { L"email", L"jdoe@test.com" }, + { L"company_name", L"Testcompany" }, + { L"phone_home_number", L"555-5555" }, + { L"phone_home_city_code", L"444" }, + { L"phone_home_country_code", L"1" }, +}; + +ValueDescription profile2[] = { + { L"name_first", L"Jane" }, + { L"name_last", L"Doe" }, + { L"email", L"janedoe@test.com" }, + { L"company_name", L"Testcompany" }, + { L"phone_fax_number", L"555-6666" }, + { L"phone_fax_city_code", L"777" }, + { L"phone_fax_country_code", L"2" }, +}; + +ValueDescription credit_card[] = { + { L"credit_card_name", L"Tommy Gun" }, + // "12345790087665675" encrypted: + { L"credit_card_number", L"\x18B7\xE586\x459B\x7457\xA066\x3842\x71DA" + L"\x4854\xB906\x9C7C\x50A6\x4376\xFD9D\x1E02" + L"\x790A\x7330\xB77B\xAF32\x93EB\xB84F\xEC8F" + L"\x265B\xD0E1\x4E27\xB758\x7985\xB92F" }, + { L"credit_card_exp_month", L"11" }, + { L"credit_card_exp_4_digit_year", L"2011" }, +}; + +ValueDescription empty_salt = { + L"salt", L"\x1\x2\x3\x4\x5\x6\x7\x8\x9\xA\xB\xC\xD\xE\xF\x10\x11\x12\x13\x14" +}; + +ValueDescription empty_password = { + L"password_hash", L"" +}; + +ValueDescription protected_salt = { + L"salt", L"\x4854\xB906\x9C7C\x50A6\x4376\xFD9D\x1E02" +}; + +ValueDescription protected_password = { + L"password_hash", L"\x18B7\xE586\x459B\x7457\xA066\x3842\x71DA" +}; + +void EncryptAndWrite(RegKey* key, const ValueDescription* value) { + string data; + size_t data_size = (lstrlen(value->value) + 1) * sizeof(wchar_t); + data.resize(data_size); + memcpy(&data[0], value->value, data_size); + + std::vector<uint8> encrypted_data = EncryptData(data); + EXPECT_TRUE(key->WriteValue(value->value_name, &encrypted_data[0], + encrypted_data.size(), REG_BINARY)); +} + +void CreateSubkey(RegKey* key, wchar_t const* subkey_name, + const ValueDescription* values, size_t values_size) { + RegKey subkey; + subkey.Create(key->Handle(), subkey_name, KEY_ALL_ACCESS); + EXPECT_TRUE(subkey.Valid()); + for (size_t i = 0; i < values_size; ++i) + EncryptAndWrite(&subkey, values + i); +} + +} // namespace + +class AutofillIeToolbarImportTest : public testing::Test { + public: + AutofillIeToolbarImportTest(); + + // testing::Test method overrides: + virtual void SetUp(); + virtual void TearDown(); + + private: + RegKey temp_hkcu_hive_key_; + + DISALLOW_COPY_AND_ASSIGN(AutofillIeToolbarImportTest); +}; + +AutofillIeToolbarImportTest::AutofillIeToolbarImportTest() { +} + +void AutofillIeToolbarImportTest::SetUp() { + temp_hkcu_hive_key_.Create(HKEY_CURRENT_USER, + kUnitTestUserOverrideSubKey, + KEY_ALL_ACCESS); + EXPECT_TRUE(temp_hkcu_hive_key_.Valid()); + EXPECT_EQ(ERROR_SUCCESS, RegOverridePredefKey(HKEY_CURRENT_USER, + temp_hkcu_hive_key_.Handle())); +} + +void AutofillIeToolbarImportTest::TearDown() { + EXPECT_EQ(ERROR_SUCCESS, RegOverridePredefKey(HKEY_CURRENT_USER, NULL)); + temp_hkcu_hive_key_.Close(); + RegKey key(HKEY_CURRENT_USER, kUnitTestRegistrySubKey, KEY_ALL_ACCESS); + key.DeleteKey(L""); +} + +TEST_F(AutofillIeToolbarImportTest, TestAutoFillImport) { + RegKey profile_key; + profile_key.Create(HKEY_CURRENT_USER, kProfileKey, KEY_ALL_ACCESS); + EXPECT_TRUE(profile_key.Valid()); + + CreateSubkey(&profile_key, L"0", profile1, arraysize(profile1)); + CreateSubkey(&profile_key, L"1", profile2, arraysize(profile2)); + + RegKey cc_key; + cc_key.Create(HKEY_CURRENT_USER, kCreditCardKey, KEY_ALL_ACCESS); + EXPECT_TRUE(cc_key.Valid()); + CreateSubkey(&cc_key, L"0", credit_card, arraysize(credit_card)); + EncryptAndWrite(&cc_key, &empty_password); + EncryptAndWrite(&cc_key, &empty_salt); + + profile_key.Close(); + cc_key.Close(); + + std::vector<AutoFillProfile> profiles; + std::vector<CreditCard> credit_cards; + EXPECT_TRUE(ImportCurrentUserProfiles(&profiles, &credit_cards)); + ASSERT_EQ(profiles.size(), 2); + // The profiles are read in reverse order. + EXPECT_EQ(profiles[1].GetFieldText(AutoFillType(NAME_FIRST)), + profile1[0].value); + EXPECT_EQ(profiles[1].GetFieldText(AutoFillType(NAME_MIDDLE)), + profile1[1].value); + EXPECT_EQ(profiles[1].GetFieldText(AutoFillType(NAME_LAST)), + profile1[2].value); + EXPECT_EQ(profiles[1].GetFieldText(AutoFillType(EMAIL_ADDRESS)), + profile1[3].value); + EXPECT_EQ(profiles[1].GetFieldText(AutoFillType(COMPANY_NAME)), + profile1[4].value); + EXPECT_EQ(profiles[1].GetFieldText(AutoFillType(PHONE_HOME_COUNTRY_CODE)), + profile1[7].value); + EXPECT_EQ(profiles[1].GetFieldText(AutoFillType(PHONE_HOME_CITY_CODE)), + profile1[6].value); + EXPECT_EQ(profiles[1].GetFieldText(AutoFillType(PHONE_HOME_NUMBER)), + L"5555555"); + EXPECT_EQ(profiles[1].GetFieldText(AutoFillType(PHONE_HOME_WHOLE_NUMBER)), + L"14445555555"); + + EXPECT_EQ(profiles[0].GetFieldText(AutoFillType(NAME_FIRST)), + profile2[0].value); + EXPECT_EQ(profiles[0].GetFieldText(AutoFillType(NAME_LAST)), + profile2[1].value); + EXPECT_EQ(profiles[0].GetFieldText(AutoFillType(EMAIL_ADDRESS)), + profile2[2].value); + EXPECT_EQ(profiles[0].GetFieldText(AutoFillType(COMPANY_NAME)), + profile2[3].value); + EXPECT_EQ(profiles[0].GetFieldText(AutoFillType(PHONE_FAX_COUNTRY_CODE)), + profile2[6].value); + EXPECT_EQ(profiles[0].GetFieldText(AutoFillType(PHONE_FAX_CITY_CODE)), + profile2[5].value); + EXPECT_EQ(profiles[0].GetFieldText(AutoFillType(PHONE_FAX_NUMBER)), + L"5556666"); + EXPECT_EQ(profiles[0].GetFieldText(AutoFillType(PHONE_FAX_WHOLE_NUMBER)), + L"27775556666"); +#if defined(GOOGLE_CHROME_BUILD) + // We have the ability to export credit cards only in chrome build. + ASSERT_EQ(credit_cards.size(), 1); + EXPECT_EQ(credit_cards[0].GetFieldText(AutoFillType(CREDIT_CARD_NAME)), + credit_card[0].value); + EXPECT_EQ(credit_cards[0].GetFieldText(AutoFillType(CREDIT_CARD_NUMBER)), + L"12345790087665675"); + EXPECT_EQ(credit_cards[0].GetFieldText(AutoFillType(CREDIT_CARD_EXP_MONTH)), + credit_card[2].value); + EXPECT_EQ(credit_cards[0].GetFieldText( + AutoFillType(CREDIT_CARD_EXP_4_DIGIT_YEAR)), + credit_card[3].value); + + // Mock password encrypted cc. + cc_key.Open(HKEY_CURRENT_USER, kCreditCardKey, KEY_ALL_ACCESS); + EXPECT_TRUE(cc_key.Valid()); + EncryptAndWrite(&cc_key, &protected_password); + EncryptAndWrite(&cc_key, &protected_salt); + cc_key.Close(); + + profiles.clear(); + credit_cards.clear(); + EXPECT_TRUE(ImportCurrentUserProfiles(&profiles, &credit_cards)); + // Profiles are not protected. + EXPECT_EQ(profiles.size(), 2); + // Credit cards are. + EXPECT_EQ(credit_cards.size(), 0); +#else // defined(GOOGLE_CHROME_BUILD) + // Cannot decrypt CC in non-chrome build. + EXPECT_EQ(credit_cards.size(), 0); +#endif // defined(GOOGLE_CHROME_BUILD) +} + diff --git a/chrome/browser/autofill/autofill_manager.cc b/chrome/browser/autofill/autofill_manager.cc index cf2ce54..8e80752 100644 --- a/chrome/browser/autofill/autofill_manager.cc +++ b/chrome/browser/autofill/autofill_manager.cc @@ -100,10 +100,6 @@ bool FormIsHTTPS(FormStructure* form) { } // namespace -// TODO(jhawkins): Maybe this should be in a grd file? -const char* kAutoFillLearnMoreUrl = - "http://www.google.com/support/chrome/bin/answer.py?answer=142893"; - AutoFillManager::AutoFillManager(TabContents* tab_contents) : tab_contents_(tab_contents), personal_data_(NULL), @@ -757,31 +753,6 @@ void AutoFillManager::FillFormField(const AutoFillProfile* profile, } } -void AutoFillManager::FillSelectOneField(const AutoFillProfile* profile, - AutoFillType type, - webkit_glue::FormField* field) { - DCHECK(profile); - DCHECK(field); - DCHECK(field->form_control_type() == ASCIIToUTF16("select-one")); - string16 selected_string = profile->GetFieldText(type); - std::string ascii_value = UTF16ToASCII(selected_string); - for (size_t i = 0; i < field->option_strings().size(); ++i) { - if (profile->GetFieldText(type) == field->option_strings()[i]) { - // An exact match - use it. - selected_string = profile->GetFieldText(type); - break; - } - if (!base::strcasecmp(UTF16ToASCII(field->option_strings()[i]).c_str(), - ascii_value.c_str())) { - // A match, but not in the same case - save it for the case we won't - // find an exact match. - selected_string = field->option_strings()[i]; - } - } - field->set_value(selected_string); -} - - void AutoFillManager::FillPhoneNumberField(const AutoFillProfile* profile, webkit_glue::FormField* field) { // If we are filling a phone number, check to see if the size field diff --git a/chrome/browser/autofill/autofill_manager.h b/chrome/browser/autofill/autofill_manager.h index 59d41ba..51c322f 100644 --- a/chrome/browser/autofill/autofill_manager.h +++ b/chrome/browser/autofill/autofill_manager.h @@ -34,9 +34,6 @@ struct FormData; class FormField; } // namespace webkit_glue -// TODO(jhawkins): Maybe this should be in a grd file? -extern const char* kAutoFillLearnMoreUrl; - // Manages saving and restoring the user's personal information entered into web // forms. class AutoFillManager : @@ -162,13 +159,6 @@ class AutoFillManager : AutoFillType type, webkit_glue::FormField* field); - // Select matching data in the |field|. For now only fixes the cases of the - // wrong case, in the future should do extended matching (for example, - // Hawaii -> HI). - void FillSelectOneField(const AutoFillProfile* profile, - AutoFillType type, - webkit_glue::FormField* field); - // Set |field| argument's value for phone number based on contents of the // |profile|. void FillPhoneNumberField(const AutoFillProfile* profile, diff --git a/chrome/browser/autofill/autofill_manager_unittest.cc b/chrome/browser/autofill/autofill_manager_unittest.cc index c84d482..7cc9769 100644 --- a/chrome/browser/autofill/autofill_manager_unittest.cc +++ b/chrome/browser/autofill/autofill_manager_unittest.cc @@ -10,7 +10,7 @@ #include "base/string16.h" #include "base/tuple.h" #include "base/utf_string_conversions.h" -#include "chrome/browser/autofill/autofill_common_unittest.h" +#include "chrome/browser/autofill/autofill_common_test.h" #include "chrome/browser/autofill/autofill_manager.h" #include "chrome/browser/autofill/autofill_profile.h" #include "chrome/browser/autofill/credit_card.h" @@ -62,44 +62,44 @@ class TestPersonalDataManager : public PersonalDataManager { private: void CreateTestAutoFillProfiles(ScopedVector<AutoFillProfile>* profiles) { AutoFillProfile* profile = new AutoFillProfile; - autofill_unittest::SetProfileInfo(profile, "Home", "Elvis", "Aaron", - "Presley", "theking@gmail.com", "RCA", - "3734 Elvis Presley Blvd.", "Apt. 10", - "Memphis", "Tennessee", "38116", "USA", - "12345678901", ""); + autofill_test::SetProfileInfo(profile, "Home", "Elvis", "Aaron", + "Presley", "theking@gmail.com", "RCA", + "3734 Elvis Presley Blvd.", "Apt. 10", + "Memphis", "Tennessee", "38116", "USA", + "12345678901", ""); profile->set_unique_id(1); profiles->push_back(profile); profile = new AutoFillProfile; - autofill_unittest::SetProfileInfo(profile, "Work", "Charles", "Hardin", - "Holley", "buddy@gmail.com", "Decca", - "123 Apple St.", "unit 6", "Lubbock", - "Texas", "79401", "USA", "23456789012", - ""); + autofill_test::SetProfileInfo(profile, "Work", "Charles", "Hardin", + "Holley", "buddy@gmail.com", "Decca", + "123 Apple St.", "unit 6", "Lubbock", + "Texas", "79401", "USA", "23456789012", + ""); profile->set_unique_id(2); profiles->push_back(profile); profile = new AutoFillProfile; - autofill_unittest::SetProfileInfo(profile, "Empty", "", "", "", "", "", "", - "", "", "", "", "", "", ""); + autofill_test::SetProfileInfo(profile, "Empty", "", "", "", "", "", "", "", + "", "", "", "", "", ""); profile->set_unique_id(3); profiles->push_back(profile); } void CreateTestCreditCards(ScopedVector<CreditCard>* credit_cards) { CreditCard* credit_card = new CreditCard; - autofill_unittest::SetCreditCardInfo(credit_card, "First", "Elvis Presley", - "Visa", "1234567890123456", "04", - "2012", 1); + autofill_test::SetCreditCardInfo(credit_card, "First", "Elvis Presley", + "Visa", "1234567890123456", + "04", "2012", 1); credit_card->set_unique_id(4); credit_cards->push_back(credit_card); credit_card = new CreditCard; - autofill_unittest::SetCreditCardInfo(credit_card, "Second", "Buddy Holly", - "Mastercard", "0987654321098765", "10", - "2014", 2); + autofill_test::SetCreditCardInfo(credit_card, "Second", "Buddy Holly", + "Mastercard", "0987654321098765", + "10", "2014", 2); credit_card->set_unique_id(5); credit_cards->push_back(credit_card); credit_card = new CreditCard; - autofill_unittest::SetCreditCardInfo(credit_card, "Empty", "", "", "", "", - "", 3); + autofill_test::SetCreditCardInfo(credit_card, "Empty", "", "", "", "", "", + 3); credit_card->set_unique_id(6); credit_cards->push_back(credit_card); } @@ -143,37 +143,37 @@ void CreateTestFormData(FormData* form) { form->user_submitted = true; webkit_glue::FormField field; - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "First Name", "firstname", "", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Middle Name", "middlename", "", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Last Name", "lastname", "", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Address Line 1", "addr1", "", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Address Line 2", "addr2", "", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "City", "city", "", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "State", "state", "", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Postal Code", "zipcode", "", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Country", "country", "", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Phone Number", "phonenumber", "", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Email", "email", "", "text", &field); form->fields.push_back(field); } @@ -186,49 +186,49 @@ void CreateTestFormDataBilling(FormData* form) { form->user_submitted = true; webkit_glue::FormField field; - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "First Name", "firstname", "", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Middle Name", "middlename", "", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Last Name", "lastname", "", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Address Line 1", "billingAddr1", "", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Address Line 2", "billingAddr2", "", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "City", "billingCity", "", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "State", "billingState", "", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Postal Code", "billingZipcode", "", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Country", "billingCountry", "", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Phone Number", "phonenumber", "", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Email", "email", "", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Name on Card", "nameoncard", "", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Card Number", "cardnumber", "", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Expiration Date", "ccmonth", "", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "", "ccyear", "", "text", &field); form->fields.push_back(field); } @@ -309,7 +309,7 @@ TEST_F(AutoFillManagerTest, GetProfileSuggestionsEmptyValue) { const int kPageID = 1; webkit_glue::FormField field; - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "First Name", "firstname", "", "text", &field); EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); @@ -347,7 +347,7 @@ TEST_F(AutoFillManagerTest, GetProfileSuggestionsMatchCharacter) { const int kPageID = 1; webkit_glue::FormField field; - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "First Name", "firstname", "E", "text", &field); EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); @@ -381,7 +381,7 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsEmptyValue) { const int kPageID = 1; webkit_glue::FormField field; - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Card Number", "cardnumber", "", "text", &field); EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); @@ -425,7 +425,7 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsMatchCharacter) { const int kPageID = 1; webkit_glue::FormField field; - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Card Number", "cardnumber", "1", "text", &field); EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); @@ -463,7 +463,7 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsNonCCNumber) { const int kPageID = 1; webkit_glue::FormField field; - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Name on Card", "nameoncard", "", "text", &field); EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); @@ -496,11 +496,11 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsNonCCNumber) { TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsSemicolon) { // |profile| will be owned by the mock PersonalDataManager. AutoFillProfile* profile = new AutoFillProfile; - autofill_unittest::SetProfileInfo(profile, "Home; 8765", "Joe", "", "Ely", - "flatlander@gmail.com", "MCA", - "916 16th St.", "Apt. 6", "Lubbock", - "Texas", "79401", "USA", - "12345678901", ""); + autofill_test::SetProfileInfo(profile, "Home; 8765", "Joe", "", "Ely", + "flatlander@gmail.com", "MCA", + "916 16th St.", "Apt. 6", "Lubbock", + "Texas", "79401", "USA", + "12345678901", ""); autofill_manager_->AddProfile(profile); FormData form; @@ -516,7 +516,7 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsSemicolon) { const int kPageID = 1; webkit_glue::FormField field; - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Name on Card", "nameoncard", "", "text", &field); EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); @@ -565,7 +565,7 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsNonHTTPS) { const int kPageID = 1; webkit_glue::FormField field; - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Card Number", "cardnumber", "", "text", &field); EXPECT_FALSE( autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); @@ -585,7 +585,7 @@ TEST_F(AutoFillManagerTest, GetCombinedAutoFillAndAutocompleteSuggestions) { const int kPageID = 1; webkit_glue::FormField field; - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "First Name", "firstname", "", "text", &field); EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); @@ -628,7 +628,7 @@ TEST_F(AutoFillManagerTest, GetFieldSuggestionsFormIsAutoFilled) { const int kPageID = 1; webkit_glue::FormField field; - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "First Name", "firstname", "", "text", &field); EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, true, field)); @@ -664,7 +664,7 @@ TEST_F(AutoFillManagerTest, GetFieldSuggestionsForAutocompleteOnly) { const int kPageID = 1; webkit_glue::FormField field; - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Some Field", "somefield", "", "text", &field); EXPECT_FALSE(autofill_manager_->GetAutoFillSuggestions(kPageID, true, field)); @@ -702,8 +702,8 @@ TEST_F(AutoFillManagerTest, GetFieldSuggestionsWithDuplicateValues) { // |profile| will be owned by the mock PersonalDataManager. AutoFillProfile* profile = new AutoFillProfile; - autofill_unittest::SetProfileInfo(profile, "Duplicate", "Elvis", "", "", "", - "", "", "", "", "", "", "", "", ""); + autofill_test::SetProfileInfo(profile, "Duplicate", "Elvis", "", "", "", "", + "", "", "", "", "", "", "", ""); autofill_manager_->AddProfile(profile); // The page ID sent to the AutoFillManager from the RenderView, used to send @@ -711,7 +711,7 @@ TEST_F(AutoFillManagerTest, GetFieldSuggestionsWithDuplicateValues) { const int kPageID = 1; webkit_glue::FormField field; - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "First Name", "firstname", "", "text", &field); EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, true, field)); @@ -747,7 +747,7 @@ TEST_F(AutoFillManagerTest, GetBillingSuggestionsAddress1) { const int kPageID = 1; webkit_glue::FormField field; - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Address Line 1", "billingAddr1", "", "text", &field); EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); @@ -794,50 +794,50 @@ TEST_F(AutoFillManagerTest, FillCreditCardForm) { ASSERT_EQ(15U, results.fields.size()); webkit_glue::FormField field; - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "First Name", "firstname", "Elvis", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[0])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Middle Name", "middlename", "Aaron", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[1])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Last Name", "lastname", "Presley", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[2])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Address Line 1", "billingAddr1", - "3734 Elvis Presley Blvd.", "text", &field); + "3734 Elvis Presley Blvd.", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[3])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Address Line 2", "billingAddr2", "Apt. 10", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[4])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "City", "billingCity", "Memphis", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[5])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "State", "billingState", "Tennessee", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[6])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Postal Code", "billingZipcode", "38116", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[7])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Country", "billingCountry", "USA", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[8])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Phone Number", "phonenumber", "12345678901", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[9])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Email", "email", "theking@gmail.com", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[10])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Name on Card", "nameoncard", "Elvis Presley", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[11])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Card Number", "cardnumber", "1234567890123456", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[12])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Expiration Date", "ccmonth", "04", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[13])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "", "ccyear", "2012", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[14])); } @@ -845,11 +845,11 @@ TEST_F(AutoFillManagerTest, FillCreditCardForm) { TEST_F(AutoFillManagerTest, FillNonBillingFormSemicolon) { // |profile| will be owned by the mock PersonalDataManager. AutoFillProfile* profile = new AutoFillProfile; - autofill_unittest::SetProfileInfo(profile, "Home; 8765", "Joe", "", "Ely", - "flatlander@gmail.com", "MCA", - "916 16th St.", "Apt. 6", "Lubbock", - "Texas", "79401", "USA", - "12345678901", ""); + autofill_test::SetProfileInfo(profile, "Home; 8765", "Joe", "", "Ely", + "flatlander@gmail.com", "MCA", + "916 16th St.", "Apt. 6", "Lubbock", + "Texas", "79401", "USA", + "12345678901", ""); profile->set_unique_id(7); autofill_manager_->AddProfile(profile); @@ -877,37 +877,37 @@ TEST_F(AutoFillManagerTest, FillNonBillingFormSemicolon) { ASSERT_EQ(11U, results.fields.size()); webkit_glue::FormField field; - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "First Name", "firstname", "Joe", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[0])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Middle Name", "middlename", "", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[1])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Last Name", "lastname", "Ely", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[2])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Address Line 1", "addr1", "916 16th St.", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[3])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Address Line 2", "addr2", "Apt. 6", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[4])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "City", "city", "Lubbock", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[5])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "State", "state", "Texas", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[6])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Postal Code", "zipcode", "79401", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[7])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Country", "country", "USA", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[8])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Phone Number", "phonenumber", "12345678901", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[9])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Email", "email", "flatlander@gmail.com", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[10])); } @@ -915,11 +915,11 @@ TEST_F(AutoFillManagerTest, FillNonBillingFormSemicolon) { TEST_F(AutoFillManagerTest, FillBillFormSemicolon) { // |profile| will be owned by the mock PersonalDataManager. AutoFillProfile* profile = new AutoFillProfile; - autofill_unittest::SetProfileInfo(profile, "Home; 8765", "Joe", "", "Ely", - "flatlander@gmail.com", "MCA", - "916 16th St.", "Apt. 6", "Lubbock", - "Texas", "79401", "USA", - "12345678901", ""); + autofill_test::SetProfileInfo(profile, "Home; 8765", "Joe", "", "Ely", + "flatlander@gmail.com", "MCA", + "916 16th St.", "Apt. 6", "Lubbock", + "Texas", "79401", "USA", + "12345678901", ""); profile->set_unique_id(7); autofill_manager_->AddProfile(profile); @@ -947,50 +947,50 @@ TEST_F(AutoFillManagerTest, FillBillFormSemicolon) { ASSERT_EQ(15U, results.fields.size()); webkit_glue::FormField field; - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "First Name", "firstname", "Joe", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[0])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Middle Name", "middlename", "", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[1])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Last Name", "lastname", "Ely", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[2])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Address Line 1", "billingAddr1", - "3734 Elvis Presley Blvd.", "text", &field); + "3734 Elvis Presley Blvd.", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[3])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Address Line 2", "billingAddr2", "Apt. 10", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[4])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "City", "billingCity", "Memphis", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[5])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "State", "billingState", "Tennessee", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[6])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Postal Code", "billingZipcode", "38116", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[7])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Country", "billingCountry", "USA", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[8])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Phone Number", "phonenumber", "12345678901", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[9])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Email", "email", "flatlander@gmail.com", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[10])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Name on Card", "nameoncard", "Elvis Presley", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[11])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Card Number", "cardnumber", "1234567890123456", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[12])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Expiration Date", "ccmonth", "04", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[13])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "", "ccyear", "2012", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[14])); } @@ -1006,23 +1006,23 @@ TEST_F(AutoFillManagerTest, FillPhoneNumber) { webkit_glue::FormField field; - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "country code", "country code", "", "text", &field); field.set_size(1); form.fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "area code", "area code", "", "text", &field); field.set_size(3); form.fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "phone", "phone prefix", "1", "text", &field); field.set_size(3); form.fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "-", "phone suffix", "", "text", &field); field.set_size(4); form.fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Phone Extension", "ext", "", "text", &field); field.set_size(3); form.fields.push_back(field); @@ -1075,19 +1075,19 @@ TEST_F(AutoFillManagerTest, FormChangesRemoveField) { form.user_submitted = true; webkit_glue::FormField field; - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "First Name", "firstname", "", "text", &field); form.fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Middle Name", "middlename", "", "text", &field); form.fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Last Name", "lastname", "", "text", &field); form.fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Phone Number", "phonenumber", "", "text", &field); form.fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Email", "email", "", "text", &field); form.fields.push_back(field); @@ -1115,16 +1115,16 @@ TEST_F(AutoFillManagerTest, FormChangesRemoveField) { EXPECT_TRUE(results.user_submitted); ASSERT_EQ(4U, results.fields.size()); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "First Name", "firstname", "Elvis", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[0])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Middle Name", "middlename", "Aaron", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[1])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Last Name", "lastname", "Presley", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[2])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Email", "email", "theking@gmail.com", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[3])); } @@ -1138,17 +1138,17 @@ TEST_F(AutoFillManagerTest, FormChangesAddField) { form.user_submitted = true; webkit_glue::FormField field; - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "First Name", "firstname", "", "text", &field); form.fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Middle Name", "middlename", "", "text", &field); form.fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Last Name", "lastname", "", "text", &field); // Note: absent phone number. Adding this below. form.fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Email", "email", "", "text", &field); form.fields.push_back(field); @@ -1159,7 +1159,7 @@ TEST_F(AutoFillManagerTest, FormChangesAddField) { // Now, after the call to |FormsSeen| we add the phone number field before // filling. - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Phone Number", "phonenumber", "", "text", &field); form.fields.insert(form.fields.begin() + 3, field); @@ -1178,19 +1178,19 @@ TEST_F(AutoFillManagerTest, FormChangesAddField) { EXPECT_TRUE(results.user_submitted); ASSERT_EQ(5U, results.fields.size()); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "First Name", "firstname", "Elvis", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[0])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Middle Name", "middlename", "Aaron", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[1])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Last Name", "lastname", "Presley", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[2])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Phone Number", "phonenumber", "", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[3])); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Email", "email", "theking@gmail.com", "text", &field); EXPECT_TRUE(field.StrictlyEqualsHack(results.fields[4])); } @@ -1204,13 +1204,13 @@ TEST_F(AutoFillManagerTest, HiddenFields) { form.user_submitted = true; webkit_glue::FormField field; - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "E-mail", "one", "one", "hidden", &field); form.fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "E-mail", "two", "two", "hidden", &field); form.fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "E-mail", "three", "three", "hidden", &field); form.fields.push_back(field); diff --git a/chrome/browser/autofill/autofill_profile.cc b/chrome/browser/autofill/autofill_profile.cc index 4286847..29ff00a 100644 --- a/chrome/browser/autofill/autofill_profile.cc +++ b/chrome/browser/autofill/autofill_profile.cc @@ -19,7 +19,11 @@ #include "chrome/browser/autofill/fax_number.h" #include "chrome/browser/autofill/home_address.h" #include "chrome/browser/autofill/home_phone_number.h" +<<<<<<< HEAD #ifndef ANDROID +======= +#include "chrome/browser/guid.h" +>>>>>>> chromium.org at r63472 #include "grit/generated_resources.h" #endif @@ -36,7 +40,14 @@ void InitPersonalInfo(FormGroupMap* personal_info) { AutoFillProfile::AutoFillProfile(const string16& label, int unique_id) : label_(label), - unique_id_(unique_id) { + unique_id_(unique_id), + guid_(guid::GenerateGUID()) { + InitPersonalInfo(&personal_info_); +} + +AutoFillProfile::AutoFillProfile(const std::string& guid) + : unique_id_(0), + guid_(guid) { InitPersonalInfo(&personal_info_); } @@ -152,6 +163,7 @@ FormGroup* AutoFillProfile::Clone() const { AutoFillProfile* profile = new AutoFillProfile(); profile->label_ = label_; profile->unique_id_ = unique_id(); + profile->guid_ = guid(); FormGroupMap::const_iterator iter; for (iter = personal_info_.begin(); iter != personal_info_.end(); ++iter) { @@ -163,6 +175,10 @@ FormGroup* AutoFillProfile::Clone() const { return profile; } +const string16& AutoFillProfile::Label() const { + return label_; +} + string16 AutoFillProfile::PreviewSummary() const { // Fetch the components of the summary string. Any or all of these // may be an empty string. @@ -388,6 +404,7 @@ bool AutoFillProfile::IsEmpty() const { void AutoFillProfile::operator=(const AutoFillProfile& source) { label_ = source.label_; unique_id_ = source.unique_id_; + guid_ = source.guid_; STLDeleteContainerPairSecondPointers(personal_info_.begin(), personal_info_.end()); @@ -401,6 +418,33 @@ void AutoFillProfile::operator=(const AutoFillProfile& source) { } } +int AutoFillProfile::Compare(const AutoFillProfile& profile) const { + // The following AutoFill field types are the only types we store in the WebDB + // so far, so we're only concerned with matching these types in the profile. + const AutoFillFieldType types[] = { NAME_FIRST, + NAME_MIDDLE, + NAME_LAST, + EMAIL_ADDRESS, + COMPANY_NAME, + ADDRESS_HOME_LINE1, + ADDRESS_HOME_LINE2, + ADDRESS_HOME_CITY, + ADDRESS_HOME_STATE, + ADDRESS_HOME_ZIP, + ADDRESS_HOME_COUNTRY, + PHONE_HOME_NUMBER, + PHONE_FAX_NUMBER }; + + for (size_t index = 0; index < arraysize(types); ++index) { + int comparison = GetFieldText(AutoFillType(types[index])).compare( + profile.GetFieldText(AutoFillType(types[index]))); + if (comparison != 0) + return comparison; + } + + return 0; +} + bool AutoFillProfile::operator==(const AutoFillProfile& profile) const { // The following AutoFill field types are the only types we store in the WebDB // so far, so we're only concerned with matching these types in the profile. @@ -480,6 +524,8 @@ std::ostream& operator<<(std::ostream& os, const AutoFillProfile& profile) { << " " << profile.unique_id() << " " + << profile.guid() + << " " << UTF16ToUTF8(profile.GetFieldText(AutoFillType(NAME_FIRST))) << " " << UTF16ToUTF8(profile.GetFieldText(AutoFillType(NAME_MIDDLE))) diff --git a/chrome/browser/autofill/autofill_profile.h b/chrome/browser/autofill/autofill_profile.h index 676bc77..4336139 100644 --- a/chrome/browser/autofill/autofill_profile.h +++ b/chrome/browser/autofill/autofill_profile.h @@ -21,7 +21,11 @@ typedef std::map<FieldTypeGroup, FormGroup*> FormGroupMap; // to the requested form group type. class AutoFillProfile : public FormGroup { public: + // DEPRECATED + // TODO(dhollowa): Remove unique ID and label. http://crbug.com/58813 AutoFillProfile(const string16& label, int unique_id); + explicit AutoFillProfile(const std::string& guid); + // For use in STL containers. AutoFillProfile(); AutoFillProfile(const AutoFillProfile&); @@ -42,10 +46,14 @@ class AutoFillProfile : public FormGroup { // Returns a copy of the profile it is called on. The caller is responsible // for deleting profile when they are done with it. virtual FormGroup* Clone() const; - virtual const string16& Label() const { return label_; } + virtual const string16& Label() const; - void set_unique_id(int id) { unique_id_ = id; } int unique_id() const { return unique_id_; } + void set_unique_id(int id) { unique_id_ = id; } + + // This guid is the primary identifier for |AutoFillProfile| objects. + const std::string guid() const { return guid_; } + void set_guid(const std::string& guid) { guid_ = guid; } // Profile summary string for UI. // Constructs a summary string based on NAME_FIRST, NAME_LAST, and @@ -88,7 +96,17 @@ class AutoFillProfile : public FormGroup { // For use in STL containers. void operator=(const AutoFillProfile&); - // For WebData and Sync. + // Comparison for Sync. Returns 0 if the profile is the same as |this|, + // or < 0, or > 0 if it is different. The implied ordering can be used for + // culling duplicates. + // GUIDs, labels, and unique IDs are not compared, only the values of the + // profiles themselves. + int Compare(const AutoFillProfile& profile) const; + + // TODO(dhollowa): These operators need to be made private and then the unit + // tests that use them made friends. The public |Compare| method should be + // used by external clients (such as Sync). + // http://crbug.com/58813 bool operator==(const AutoFillProfile& profile) const; virtual bool operator!=(const AutoFillProfile& profile) const; void set_label(const string16& label) { label_ = label; } @@ -109,6 +127,9 @@ class AutoFillProfile : public FormGroup { // The unique ID of this profile. int unique_id_; + // The guid of this profile. + std::string guid_; + // Personal information for this profile. FormGroupMap personal_info_; }; diff --git a/chrome/browser/autofill/autofill_profile_unittest.cc b/chrome/browser/autofill/autofill_profile_unittest.cc index 81dadb5..5a1f27b 100644 --- a/chrome/browser/autofill/autofill_profile_unittest.cc +++ b/chrome/browser/autofill/autofill_profile_unittest.cc @@ -7,8 +7,9 @@ #include "base/stl_util-inl.h" #include "base/string16.h" #include "base/utf_string_conversions.h" -#include "chrome/browser/autofill/autofill_common_unittest.h" +#include "chrome/browser/autofill/autofill_common_test.h" #include "chrome/browser/autofill/autofill_profile.h" +#include "chrome/browser/guid.h" #include "grit/generated_resources.h" #include "testing/gtest/include/gtest/gtest.h" @@ -24,7 +25,7 @@ TEST(AutoFillProfileTest, PreviewSummaryString) { // Case 0/empty: "" AutoFillProfile profile00(string16(), 0); - autofill_unittest::SetProfileInfo(&profile00, "Billing", "", "Mitchell", "", + autofill_test::SetProfileInfo(&profile00, "Billing", "", "Mitchell", "", "johnwayne@me.xyz", "Fox", "", "unit 5", "Hollywood", "CA", "91601", "US", "12345678910", "01987654321"); string16 summary00 = profile00.PreviewSummary(); @@ -32,7 +33,7 @@ TEST(AutoFillProfileTest, PreviewSummaryString) { // Case 1: "<address>" AutoFillProfile profile1(string16(), 0); - autofill_unittest::SetProfileInfo(&profile1, "Billing", "", "Mitchell", "", + autofill_test::SetProfileInfo(&profile1, "Billing", "", "Mitchell", "", "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA", "91601", "US", "12345678910", "01987654321"); string16 summary1 = profile1.PreviewSummary(); @@ -40,7 +41,7 @@ TEST(AutoFillProfileTest, PreviewSummaryString) { // Case 2: "<lastname>" AutoFillProfile profile2(string16(), 0); - autofill_unittest::SetProfileInfo(&profile2, "Billing", "", "Mitchell", + autofill_test::SetProfileInfo(&profile2, "Billing", "", "Mitchell", "Morrison", "johnwayne@me.xyz", "Fox", "", "unit 5", "Hollywood", "CA", "91601", "US", "12345678910", "01987654321"); string16 summary2 = profile2.PreviewSummary(); @@ -48,7 +49,7 @@ TEST(AutoFillProfileTest, PreviewSummaryString) { // Case 3: "<lastname>, <address>" AutoFillProfile profile3(string16(), 0); - autofill_unittest::SetProfileInfo(&profile3, "Billing", "", "Mitchell", + autofill_test::SetProfileInfo(&profile3, "Billing", "", "Mitchell", "Morrison", "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA", "91601", "US", "12345678910", "01987654321"); string16 summary3 = profile3.PreviewSummary(); @@ -56,23 +57,23 @@ TEST(AutoFillProfileTest, PreviewSummaryString) { // Case 4: "<firstname>" AutoFillProfile profile4(string16(), 0); - autofill_unittest::SetProfileInfo(&profile4, "Billing", "Marion", "Mitchell", - "", "johnwayne@me.xyz", "Fox", "", "unit 5", "Hollywood", "CA", "91601", - "US", "12345678910", "01987654321"); + autofill_test::SetProfileInfo(&profile4, "Billing", "Marion", "Mitchell", "", + "johnwayne@me.xyz", "Fox", "", "unit 5", "Hollywood", "CA", "91601", "US", + "12345678910", "01987654321"); string16 summary4 = profile4.PreviewSummary(); EXPECT_EQ(string16(ASCIIToUTF16("Marion")), summary4); // Case 5: "<firstname>, <address>" AutoFillProfile profile5(string16(), 0); - autofill_unittest::SetProfileInfo(&profile5, "Billing", "Marion", "Mitchell", - "", "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA", + autofill_test::SetProfileInfo(&profile5, "Billing", "Marion", "Mitchell", "", + "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA", "91601", "US", "12345678910", "01987654321"); string16 summary5 = profile5.PreviewSummary(); EXPECT_EQ(string16(ASCIIToUTF16("Marion, 123 Zoo St.")), summary5); // Case 6: "<firstname> <lastname>" AutoFillProfile profile6(string16(), 0); - autofill_unittest::SetProfileInfo(&profile6, "Billing", "Marion", "Mitchell", + autofill_test::SetProfileInfo(&profile6, "Billing", "Marion", "Mitchell", "Morrison", "johnwayne@me.xyz", "Fox", "", "unit 5", "Hollywood", "CA", "91601", "US", "12345678910", "01987654321"); string16 summary6 = profile6.PreviewSummary(); @@ -80,7 +81,7 @@ TEST(AutoFillProfileTest, PreviewSummaryString) { // Case 7: "<firstname> <lastname>, <address>" AutoFillProfile profile7(string16(), 0); - autofill_unittest::SetProfileInfo(&profile7, "Billing", "Marion", "Mitchell", + autofill_test::SetProfileInfo(&profile7, "Billing", "Marion", "Mitchell", "Morrison", "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA", "91601", "US", "12345678910", "01987654321"); string16 summary7 = profile7.PreviewSummary(); @@ -90,7 +91,7 @@ TEST(AutoFillProfileTest, PreviewSummaryString) { TEST(AutoFillProfileTest, AdjustInferredLabels) { std::vector<AutoFillProfile*> profiles; profiles.push_back(new AutoFillProfile(string16(), 0)); - autofill_unittest::SetProfileInfo( + autofill_test::SetProfileInfo( profiles[0], "", "John", @@ -106,7 +107,7 @@ TEST(AutoFillProfileTest, AdjustInferredLabels) { "11111111111", "22222222222"); profiles.push_back(new AutoFillProfile(string16(), 0)); - autofill_unittest::SetProfileInfo( + autofill_test::SetProfileInfo( profiles[1], "", "Jane", @@ -131,7 +132,7 @@ TEST(AutoFillProfileTest, AdjustInferredLabels) { profiles[1]->Label()); profiles.push_back(new AutoFillProfile(string16(), 0)); - autofill_unittest::SetProfileInfo( + autofill_test::SetProfileInfo( profiles[2], "", "John", @@ -162,7 +163,7 @@ TEST(AutoFillProfileTest, AdjustInferredLabels) { profiles.pop_back(); profiles.push_back(new AutoFillProfile(string16(), 0)); - autofill_unittest::SetProfileInfo( + autofill_test::SetProfileInfo( profiles[2], "", "John", @@ -191,7 +192,7 @@ TEST(AutoFillProfileTest, AdjustInferredLabels) { profiles[2]->Label()); profiles.push_back(new AutoFillProfile(string16(), 0)); - autofill_unittest::SetProfileInfo( + autofill_test::SetProfileInfo( profiles[3], "", "John", @@ -223,7 +224,7 @@ TEST(AutoFillProfileTest, AdjustInferredLabels) { profiles[3]->Label()); profiles.push_back(new AutoFillProfile(string16(), 0)); - autofill_unittest::SetProfileInfo( + autofill_test::SetProfileInfo( profiles[4], "", "John", @@ -273,13 +274,12 @@ TEST(AutoFillProfileTest, IsSubsetOf) { // |a| is a subset of |b|. a.reset(new AutoFillProfile); b.reset(new AutoFillProfile); - autofill_unittest::SetProfileInfo(a.get(), "label1", "Thomas", NULL, - "Jefferson", "declaration_guy@gmail.com", NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL); - autofill_unittest::SetProfileInfo(b.get(), "label2", "Thomas", NULL, - "Jefferson", "declaration_guy@gmail.com", "United States Government", - "Monticello", NULL, "Charlottesville", "Virginia", "22902", NULL, NULL, - NULL); + autofill_test::SetProfileInfo(a.get(), "label1", "Thomas", NULL, "Jefferson", + "declaration_guy@gmail.com", NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL); + autofill_test::SetProfileInfo(b.get(), "label2", "Thomas", NULL, "Jefferson", + "declaration_guy@gmail.com", "United States Government", "Monticello", + NULL, "Charlottesville", "Virginia", "22902", NULL, NULL, NULL); EXPECT_TRUE(a->IsSubsetOf(*b)); // |b| is not a subset of |a|. @@ -291,12 +291,12 @@ TEST(AutoFillProfileTest, IsSubsetOf) { // One field in |b| is different. a.reset(new AutoFillProfile); b.reset(new AutoFillProfile); - autofill_unittest::SetProfileInfo(a.get(), "label1", "Thomas", NULL, - "Jefferson", "declaration_guy@gmail.com", NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL); - autofill_unittest::SetProfileInfo(a.get(), "label2", "Thomas", NULL, - "Adams", "declaration_guy@gmail.com", NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL); + autofill_test::SetProfileInfo(a.get(), "label1", "Thomas", NULL, "Jefferson", + "declaration_guy@gmail.com", NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL); + autofill_test::SetProfileInfo(a.get(), "label2", "Thomas", NULL, "Adams", + "declaration_guy@gmail.com", NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL); EXPECT_FALSE(a->IsSubsetOf(*b)); } @@ -308,35 +308,33 @@ TEST(AutoFillProfileTest, IntersectionOfTypesHasEqualValues) { // profiles. a.reset(new AutoFillProfile); b.reset(new AutoFillProfile); - autofill_unittest::SetProfileInfo(a.get(), "label1", "Thomas", NULL, - "Jefferson", "declaration_guy@gmail.com", NULL, NULL, NULL, NULL, NULL, - NULL, NULL, "12134759123", "19384284720"); - autofill_unittest::SetProfileInfo(b.get(), "label2", "Thomas", NULL, - "Jefferson", "declaration_guy@gmail.com", "United States Government", - "Monticello", NULL, "Charlottesville", "Virginia", "22902", NULL, NULL, - NULL); + autofill_test::SetProfileInfo(a.get(), "label1", "Thomas", NULL, "Jefferson", + "declaration_guy@gmail.com", NULL, NULL, NULL, NULL, NULL, NULL, NULL, + "12134759123", "19384284720"); + autofill_test::SetProfileInfo(b.get(), "label2", "Thomas", NULL, "Jefferson", + "declaration_guy@gmail.com", "United States Government", "Monticello", + NULL, "Charlottesville", "Virginia", "22902", NULL, NULL, NULL); EXPECT_TRUE(a->IntersectionOfTypesHasEqualValues(*b)); // Intersection of types contains the fields NAME_FIRST, NAME_LAST, // EMAIL_ADDRESS. The value of EMAIL_ADDRESS differs between the two profiles. a.reset(new AutoFillProfile); b.reset(new AutoFillProfile); - autofill_unittest::SetProfileInfo(a.get(), "label1", "Thomas", NULL, - "Jefferson", "poser@yahoo.com", NULL, NULL, NULL, NULL, NULL, - NULL, NULL, "12134759123", "19384284720"); - autofill_unittest::SetProfileInfo(b.get(), "label2", "Thomas", NULL, - "Jefferson", "declaration_guy@gmail.com", "United States Government", - "Monticello", NULL, "Charlottesville", "Virginia", "22902", NULL, NULL, - NULL); + autofill_test::SetProfileInfo(a.get(), "label1", "Thomas", NULL, "Jefferson", + "poser@yahoo.com", NULL, NULL, NULL, NULL, NULL, NULL, NULL, + "12134759123", "19384284720"); + autofill_test::SetProfileInfo(b.get(), "label2", "Thomas", NULL, "Jefferson",\ + "declaration_guy@gmail.com", "United States Government", "Monticello", + NULL, "Charlottesville", "Virginia", "22902", NULL, NULL, NULL); EXPECT_FALSE(a->IntersectionOfTypesHasEqualValues(*b)); // Intersection of types is empty. a.reset(new AutoFillProfile); b.reset(new AutoFillProfile); - autofill_unittest::SetProfileInfo(a.get(), "label1", "Thomas", NULL, - "Jefferson", "poser@yahoo.com", NULL, NULL, NULL, NULL, NULL, - NULL, NULL, "12134759123", "19384284720"); - autofill_unittest::SetProfileInfo(b.get(), "label2", NULL, NULL, NULL, NULL, + autofill_test::SetProfileInfo(a.get(), "label1", "Thomas", NULL, "Jefferson", + "poser@yahoo.com", NULL, NULL, NULL, NULL, NULL, NULL, NULL, + "12134759123", "19384284720"); + autofill_test::SetProfileInfo(b.get(), "label2", NULL, NULL, NULL, NULL, "United States Government", "Monticello", NULL, "Charlottesville", "Virginia", "22902", NULL, NULL, NULL); EXPECT_FALSE(a->IntersectionOfTypesHasEqualValues(*b)); @@ -348,23 +346,41 @@ TEST(AutoFillProfileTest, MergeWith) { // Merge |b| into |a|. a.reset(new AutoFillProfile); b.reset(new AutoFillProfile); - autofill_unittest::SetProfileInfo(a.get(), "label1", "Jimmy", NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, "12134759123", "19384284720"); - autofill_unittest::SetProfileInfo(b.get(), "label2", "James", NULL, - "Madison", "constitutionalist@gmail.com", "United States Government", - "Monticello", NULL, "Charlottesville", "Virginia", "22902", NULL, NULL, - NULL); + autofill_test::SetProfileInfo(a.get(), "label1", "Jimmy", NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, "12134759123", "19384284720"); + autofill_test::SetProfileInfo(b.get(), "label2", "James", NULL, "Madison", + "constitutionalist@gmail.com", "United States Government", "Monticello", + NULL, "Charlottesville", "Virginia", "22902", NULL, NULL, NULL); AutoFillProfile expected_b(*b); a->MergeWith(*b); AutoFillProfile expected_a; - autofill_unittest::SetProfileInfo(&expected_a, "label1", "Jimmy", NULL, - "Madison", "constitutionalist@gmail.com", "United States Government", - "Monticello", NULL, "Charlottesville", "Virginia", "22902", NULL, - "12134759123", "19384284720"); + autofill_test::SetProfileInfo(&expected_a, "label1", "Jimmy", NULL, "Madison", + "constitutionalist@gmail.com", "United States Government", "Monticello", + NULL, "Charlottesville", "Virginia", "22902", NULL, "12134759123", + "19384284720"); EXPECT_EQ(expected_a, *a); EXPECT_EQ(expected_b, *b); } +TEST(AutoFillProfileTest, Compare) { + AutoFillProfile a, b; + + // Empty profiles are the same. + EXPECT_EQ(0, a.Compare(b)); + + // GUIDs don't count. + a.set_guid(guid::GenerateGUID()); + b.set_guid(guid::GenerateGUID()); + EXPECT_EQ(0, a.Compare(b)); + + // Different values produce non-zero results. + autofill_test::SetProfileInfo(&a, "label1", "Jimmy", NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + autofill_test::SetProfileInfo(&b, "label1", "Ringo", NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); + EXPECT_GT(0, a.Compare(b)); + EXPECT_LT(0, b.Compare(a)); +} + } // namespace diff --git a/chrome/browser/autofill/contact_info.cc b/chrome/browser/autofill/contact_info.cc index f38f049..ce2e36e 100644 --- a/chrome/browser/autofill/contact_info.cc +++ b/chrome/browser/autofill/contact_info.cc @@ -23,6 +23,10 @@ static const AutoFillFieldType kAutoFillContactInfoTypes[] = { static const size_t kAutoFillContactInfoLength = arraysize(kAutoFillContactInfoTypes); +ContactInfo::ContactInfo() {} + +ContactInfo::~ContactInfo() {} + FormGroup* ContactInfo::Clone() const { return new ContactInfo(*this); } diff --git a/chrome/browser/autofill/contact_info.h b/chrome/browser/autofill/contact_info.h index 97c3119..d47ec8d 100644 --- a/chrome/browser/autofill/contact_info.h +++ b/chrome/browser/autofill/contact_info.h @@ -16,7 +16,8 @@ typedef std::vector<string16> NameTokens; // A form group that stores contact information. class ContactInfo : public FormGroup { public: - ContactInfo() {} + ContactInfo(); + virtual ~ContactInfo(); // FormGroup implementation: virtual FormGroup* Clone() const; diff --git a/chrome/browser/autofill/credit_card.cc b/chrome/browser/autofill/credit_card.cc index a42fcc9..4069b1a 100644 --- a/chrome/browser/autofill/credit_card.cc +++ b/chrome/browser/autofill/credit_card.cc @@ -18,7 +18,11 @@ #include "base/utf_string_conversions.h" #include "chrome/browser/autofill/autofill_type.h" #include "chrome/browser/autofill/field_types.h" +<<<<<<< HEAD #ifndef ANDROID +======= +#include "chrome/browser/guid.h" +>>>>>>> chromium.org at r63472 #include "grit/generated_resources.h" #endif @@ -131,25 +135,38 @@ std::string GetCreditCardType(const string16& number) { } // namespace -CreditCard::CreditCard(const string16& label, int unique_id) +CreditCard::CreditCard(const string16& label, + int unique_id) : expiration_month_(0), expiration_year_(0), label_(label), billing_address_id_(0), - unique_id_(unique_id) { + unique_id_(unique_id), + guid_(guid::GenerateGUID()) { } -CreditCard::CreditCard(const CreditCard& card) : FormGroup() { - operator=(card); +CreditCard::CreditCard(const std::string& guid) + : expiration_month_(0), + expiration_year_(0), + billing_address_id_(0), + unique_id_(0), + guid_(guid) { } CreditCard::CreditCard() : expiration_month_(0), expiration_year_(0), billing_address_id_(0), - unique_id_(0) { + unique_id_(0), + guid_(guid::GenerateGUID()) { } +CreditCard::CreditCard(const CreditCard& card) : FormGroup() { + operator=(card); +} + +CreditCard::~CreditCard() {} + FormGroup* CreditCard::Clone() const { return new CreditCard(*this); } @@ -385,6 +402,7 @@ void CreditCard::operator=(const CreditCard& source) { label_ = source.label_; billing_address_id_ = source.billing_address_id_; unique_id_ = source.unique_id_; + guid_ = source.guid_; } bool CreditCard::operator==(const CreditCard& creditcard) const { @@ -621,6 +639,8 @@ std::ostream& operator<<(std::ostream& os, const CreditCard& creditcard) { << " " << creditcard.unique_id() << " " + << creditcard.guid() + << " " << creditcard.billing_address_id() << " " << UTF16ToUTF8(creditcard.GetFieldText(AutoFillType(CREDIT_CARD_NAME))) diff --git a/chrome/browser/autofill/credit_card.h b/chrome/browser/autofill/credit_card.h index e078ab1..f437a90 100644 --- a/chrome/browser/autofill/credit_card.h +++ b/chrome/browser/autofill/credit_card.h @@ -14,10 +14,15 @@ // A form group that stores credit card information. class CreditCard : public FormGroup { public: + // DEPRECATED + // TODO(dhollowa): Remove unique ID and label. http://crbug.com/58813 CreditCard(const string16& label, int unique_id); + explicit CreditCard(const std::string& guid); + // For use in STL containers. - CreditCard(const CreditCard& card); CreditCard(); + CreditCard(const CreditCard& card); + virtual ~CreditCard(); // FormGroup implementation: FormGroup* Clone() const; @@ -41,13 +46,18 @@ class CreditCard : public FormGroup { const string16& type() const { return type_; } int billing_address_id() const { return billing_address_id_; } + int unique_id() const { return unique_id_; } + void set_unique_id(int id) { unique_id_ = id; } + + // The guid is the primary identifier for |CreditCard| objects. + const std::string guid() const { return guid_; } + void set_guid(const std::string& guid) { guid_ = guid; } // The caller should verify that the corresponding AutoFillProfile exists. void set_billing_address_id(int address_id) { billing_address_id_ = address_id; } - void set_unique_id(int id) { unique_id_ = id; } // For use in STL containers. void operator=(const CreditCard&); @@ -143,6 +153,9 @@ class CreditCard : public FormGroup { // The unique ID of this credit card. int unique_id_; + + // The guid of this credit card. + std::string guid_; }; // So we can compare CreditCards with EXPECT_EQ(). diff --git a/chrome/browser/autofill/credit_card_field.cc b/chrome/browser/autofill/credit_card_field.cc index 7bf8db6..6b85077 100644 --- a/chrome/browser/autofill/credit_card_field.cc +++ b/chrome/browser/autofill/credit_card_field.cc @@ -35,6 +35,10 @@ bool CreditCardField::GetFieldInfo(FieldTypeMap* field_type_map) const { return ok; } +FormFieldType CreditCardField::GetFormFieldType() const { + return kCreditCardType; +} + // static CreditCardField* CreditCardField::Parse( std::vector<AutoFillField*>::const_iterator* iter, @@ -66,9 +70,8 @@ CreditCardField* CreditCardField::Parse( } } - if (ParseText(&q, name_pattern, &credit_card_field->cardholder_)) { + if (ParseText(&q, name_pattern, &credit_card_field->cardholder_)) continue; - } // As a hard-coded hack for Expedia's billing pages (expedia_checkout.html // and ExpediaBilling.html in our test suite), recognize separate fields @@ -141,6 +144,14 @@ CreditCardField* CreditCardField::Parse( break; } + // Some pages have a billing address field after the cardholder name field. + // For that case, allow only just the cardholder name field. The remaining + // CC fields will be picked up in a following CreditCardField. + if (credit_card_field->cardholder_) { + *iter = q; + return credit_card_field.release(); + } + // On some pages, the user selects a card type using radio buttons // (e.g. test page Apple Store Billing.html). We can't handle that yet, // so we treat the card type as optional for now. diff --git a/chrome/browser/autofill/credit_card_field.h b/chrome/browser/autofill/credit_card_field.h index 68cc0db..e3b443d 100644 --- a/chrome/browser/autofill/credit_card_field.h +++ b/chrome/browser/autofill/credit_card_field.h @@ -16,7 +16,7 @@ class CreditCardField : public FormField { public: // FormField implementation: virtual bool GetFieldInfo(FieldTypeMap* field_type_map) const; - virtual FormFieldType GetFormFieldType() const { return kCreditCardType; } + virtual FormFieldType GetFormFieldType() const; static CreditCardField* Parse( std::vector<AutoFillField*>::const_iterator* iter, diff --git a/chrome/browser/autofill/credit_card_unittest.cc b/chrome/browser/autofill/credit_card_unittest.cc index 1c7f8ba..5a9a732 100644 --- a/chrome/browser/autofill/credit_card_unittest.cc +++ b/chrome/browser/autofill/credit_card_unittest.cc @@ -4,7 +4,7 @@ #include "base/basictypes.h" #include "base/utf_string_conversions.h" -#include "chrome/browser/autofill/autofill_common_unittest.h" +#include "chrome/browser/autofill/autofill_common_test.h" #include "chrome/browser/autofill/credit_card.h" #include "testing/gtest/include/gtest/gtest.h" @@ -23,7 +23,7 @@ TEST(CreditCardTest, PreviewSummaryAndObfuscatedNumberStrings) { // Case 00: Empty credit card with empty strings. CreditCard credit_card00(string16(), 0); - autofill_unittest::SetCreditCardInfo(&credit_card00, "Corporate", + autofill_test::SetCreditCardInfo(&credit_card00, "Corporate", "John Dillinger", "Visa", "", "", "", 1); string16 summary00 = credit_card00.PreviewSummary(); EXPECT_EQ(string16(), summary00); @@ -32,7 +32,7 @@ TEST(CreditCardTest, PreviewSummaryAndObfuscatedNumberStrings) { // Case 1: No credit card number. CreditCard credit_card1(string16(), 0); - autofill_unittest::SetCreditCardInfo(&credit_card1, "Corporate", + autofill_test::SetCreditCardInfo(&credit_card1, "Corporate", "John Dillinger", "Visa", "", "01", "2010", 1); string16 summary1 = credit_card1.PreviewSummary(); EXPECT_EQ(string16(), summary1); @@ -41,7 +41,7 @@ TEST(CreditCardTest, PreviewSummaryAndObfuscatedNumberStrings) { // Case 2: No month. CreditCard credit_card2(string16(), 0); - autofill_unittest::SetCreditCardInfo(&credit_card2, "Corporate", + autofill_test::SetCreditCardInfo(&credit_card2, "Corporate", "John Dillinger", "Visa", "123456789012", "", "2010", 1); string16 summary2 = credit_card2.PreviewSummary(); EXPECT_EQ(string16(ASCIIToUTF16("************9012")), summary2); @@ -50,7 +50,7 @@ TEST(CreditCardTest, PreviewSummaryAndObfuscatedNumberStrings) { // Case 3: No year. CreditCard credit_card3(string16(), 0); - autofill_unittest::SetCreditCardInfo(&credit_card3, "Corporate", + autofill_test::SetCreditCardInfo(&credit_card3, "Corporate", "John Dillinger", "Visa", "123456789012", "01", "", 1); string16 summary3 = credit_card3.PreviewSummary(); EXPECT_EQ(string16(ASCIIToUTF16("************9012")), summary3); @@ -59,7 +59,7 @@ TEST(CreditCardTest, PreviewSummaryAndObfuscatedNumberStrings) { // Case 4: Have everything. CreditCard credit_card4(string16(), 0); - autofill_unittest::SetCreditCardInfo(&credit_card4, "Corporate", + autofill_test::SetCreditCardInfo(&credit_card4, "Corporate", "John Dillinger", "Visa", "123456789012", "01", "2010", 1); string16 summary4 = credit_card4.PreviewSummary(); EXPECT_EQ(string16(ASCIIToUTF16("************9012, Exp: 01/2010")), summary4); diff --git a/chrome/browser/autofill/form_group.cc b/chrome/browser/autofill/form_group.cc index 83f3147..e99059b 100644 --- a/chrome/browser/autofill/form_group.cc +++ b/chrome/browser/autofill/form_group.cc @@ -4,6 +4,12 @@ #include "chrome/browser/autofill/form_group.h" +string16 FormGroup::GetPreviewText(const AutoFillType& type) const { + return GetFieldText(type); +} + +const string16& FormGroup::Label() const { return EmptyString16(); } + bool FormGroup::operator!=(const FormGroup& form_group) const { FieldTypeSet a, b, symmetric_difference; GetAvailableFieldTypes(&a); diff --git a/chrome/browser/autofill/form_group.h b/chrome/browser/autofill/form_group.h index 4a61c1a..68a7d3a 100644 --- a/chrome/browser/autofill/form_group.h +++ b/chrome/browser/autofill/form_group.h @@ -38,9 +38,7 @@ class FormGroup { virtual string16 GetFieldText(const AutoFillType& type) const = 0; // Returns the text for preview. - virtual string16 GetPreviewText(const AutoFillType& type) const { - return GetFieldText(type); - } + virtual string16 GetPreviewText(const AutoFillType& type) const; // Used to determine if the text being typed into a field matches the // information in this FormGroup object. This is used by the preview @@ -55,7 +53,7 @@ class FormGroup { // Returns the label for this FormGroup item. This should be overridden for // form group items that implement a label. - virtual const string16& Label() const { return EmptyString16(); } + virtual const string16& Label() const; // Returns true if the field data in |form_group| does not match the field // data in this FormGroup. diff --git a/chrome/browser/autofill/form_structure.cc b/chrome/browser/autofill/form_structure.cc index 93fd2d7..299c58b 100644 --- a/chrome/browser/autofill/form_structure.cc +++ b/chrome/browser/autofill/form_structure.cc @@ -111,6 +111,8 @@ FormStructure::FormStructure(const FormData& form) } } +FormStructure::~FormStructure() {} + bool FormStructure::EncodeUploadRequest(bool auto_fill_used, std::string* encoded_xml) const { bool auto_fillable = IsAutoFillable(); diff --git a/chrome/browser/autofill/form_structure.h b/chrome/browser/autofill/form_structure.h index bb583dc..7000056 100644 --- a/chrome/browser/autofill/form_structure.h +++ b/chrome/browser/autofill/form_structure.h @@ -36,6 +36,7 @@ enum UploadRequired { class FormStructure { public: explicit FormStructure(const webkit_glue::FormData& form); + ~FormStructure(); // Encodes the XML upload request from this FormStructure. bool EncodeUploadRequest(bool auto_fill_used, diff --git a/chrome/browser/autofill/form_structure_unittest.cc b/chrome/browser/autofill/form_structure_unittest.cc index 0eea0a6..f9f808a 100644 --- a/chrome/browser/autofill/form_structure_unittest.cc +++ b/chrome/browser/autofill/form_structure_unittest.cc @@ -15,7 +15,7 @@ using webkit_glue::FormData; using WebKit::WebInputElement; -namespace { +namespace webkit_glue { std::ostream& operator<<(std::ostream& os, const FormData& form) { os << UTF16ToUTF8(form.name) @@ -37,6 +37,10 @@ std::ostream& operator<<(std::ostream& os, const FormData& form) { return os; } +} // namespace webkit_glue + +namespace { + TEST(FormStructureTest, FieldCount) { FormData form; form.method = ASCIIToUTF16("post"); @@ -1114,4 +1118,53 @@ TEST(FormStructureTest, MatchSpecificInputTypes) { EXPECT_EQ(UNKNOWN_TYPE, form_structure->field(9)->heuristic_type()); } +TEST(FormStructureTest, HeuristicsInfernoCC) { + scoped_ptr<FormStructure> form_structure; + FormData form; + form.method = ASCIIToUTF16("post"); + form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Name on Card"), + ASCIIToUTF16("name_on_card"), + string16(), + ASCIIToUTF16("text"), + 0)); + form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Address"), + ASCIIToUTF16("billing_address"), + string16(), + ASCIIToUTF16("text"), + 0)); + form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Card Number"), + ASCIIToUTF16("card_number"), + string16(), + ASCIIToUTF16("text"), + 0)); + form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Expiration Date"), + ASCIIToUTF16("expiration_month"), + string16(), + ASCIIToUTF16("text"), + 0)); + form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Expiration Year"), + ASCIIToUTF16("expiration_year"), + string16(), + ASCIIToUTF16("text"), + 0)); + form_structure.reset(new FormStructure(form)); + EXPECT_TRUE(form_structure->IsAutoFillable()); + + // Expect the correct number of fields. + ASSERT_EQ(5U, form_structure->field_count()); + ASSERT_EQ(5U, form_structure->autofill_count()); + + // Name on Card. + EXPECT_EQ(CREDIT_CARD_NAME, form_structure->field(0)->heuristic_type()); + // Address. + EXPECT_EQ(ADDRESS_BILLING_LINE1, form_structure->field(1)->heuristic_type()); + // Card Number. + EXPECT_EQ(CREDIT_CARD_NUMBER, form_structure->field(2)->heuristic_type()); + // Expiration Date. + EXPECT_EQ(CREDIT_CARD_EXP_MONTH, form_structure->field(3)->heuristic_type()); + // Expiration Year. + EXPECT_EQ(CREDIT_CARD_EXP_4_DIGIT_YEAR, + form_structure->field(4)->heuristic_type()); +} + } // namespace diff --git a/chrome/browser/autofill/personal_data_manager.cc b/chrome/browser/autofill/personal_data_manager.cc index 9001627..f38cdfc 100644 --- a/chrome/browser/autofill/personal_data_manager.cc +++ b/chrome/browser/autofill/personal_data_manager.cc @@ -14,7 +14,7 @@ #include "chrome/browser/autofill/autofill_field.h" #include "chrome/browser/autofill/form_structure.h" #include "chrome/browser/autofill/phone_number.h" -#include "chrome/browser/chrome_thread.h" +#include "chrome/browser/browser_thread.h" #include "chrome/browser/profile.h" #include "chrome/browser/webdata/web_data_service.h" #include "chrome/browser/prefs/pref_service.h" @@ -331,7 +331,15 @@ void PersonalDataManager::SetProfiles(std::vector<AutoFillProfile>* profiles) { // Read our writes to ensure consistency with the database. Refresh(); - FOR_EACH_OBSERVER(Observer, observers_, OnPersonalDataChanged()); + { + // We're now done with the unique IDs, and observers might call into a + // method that needs the lock, so release it. For example, observers on Mac + // might call profiles() which calls LoadAuxiliaryProfiles(), which needs + // the lock. + AutoUnlock unlock(unique_ids_lock_); + + FOR_EACH_OBSERVER(Observer, observers_, OnPersonalDataChanged()); + } } void PersonalDataManager::SetCreditCards( @@ -410,7 +418,18 @@ void PersonalDataManager::SetCreditCards( credit_cards_.push_back(new CreditCard(*iter)); } - FOR_EACH_OBSERVER(Observer, observers_, OnPersonalDataChanged()); + // Read our writes to ensure consistency with the database. + Refresh(); + + { + // We're now done with the unique IDs, and observers might call into a + // method that needs the lock, so release it. For example, observers on Mac + // might call profiles() which calls LoadAuxiliaryProfiles(), which needs + // the lock. + AutoUnlock unlock(unique_ids_lock_); + + FOR_EACH_OBSERVER(Observer, observers_, OnPersonalDataChanged()); + } } // TODO(jhawkins): Refactor SetProfiles so this isn't so hacky. @@ -488,6 +507,15 @@ void PersonalDataManager::RemoveProfile(int unique_id) { SetProfiles(&profiles); } +AutoFillProfile* PersonalDataManager::GetProfileById(int unique_id) { + for (std::vector<AutoFillProfile*>::iterator iter = web_profiles_->begin(); + iter != web_profiles_->end(); ++iter) { + if ((*iter)->unique_id() == unique_id) + return *iter; + } + return NULL; +} + // TODO(jhawkins): Refactor SetCreditCards so this isn't so hacky. void PersonalDataManager::AddCreditCard(const CreditCard& credit_card) { std::vector<CreditCard> credit_cards(credit_cards_.size()); @@ -614,7 +642,7 @@ AutoFillProfile* PersonalDataManager::CreateNewEmptyAutoFillProfileForDBThread( return 0; #else // See comment in header for thread details. - DCHECK(ChromeThread::CurrentlyOn(ChromeThread::DB)); + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); AutoLock lock(unique_ids_lock_); AutoFillProfile* p = new AutoFillProfile(label, CreateNextUniqueIDFor(&unique_profile_ids_)); diff --git a/chrome/browser/autofill/personal_data_manager.h b/chrome/browser/autofill/personal_data_manager.h index 008cb2b..daf913b 100644 --- a/chrome/browser/autofill/personal_data_manager.h +++ b/chrome/browser/autofill/personal_data_manager.h @@ -86,9 +86,9 @@ class PersonalDataManager // newly-added profiles. // // The relationship between this and Refresh is subtle. - // A call to SetProfile could include out-of-date data that may conflict + // A call to |SetProfiles| could include out-of-date data that may conflict // if we didn't refresh-to-latest before an AutoFill window was opened for - // editing. SetProfile is implemented to make a "best effort" to apply the + // editing. |SetProfiles| is implemented to make a "best effort" to apply the // changes, but in extremely rare edge cases it is possible not all of the // updates in |profiles| make it to the DB. This is why SetProfiles will // invoke Refresh after finishing, to ensure we get into a @@ -109,6 +109,10 @@ class PersonalDataManager // Removes the profile represented by |unique_id|. void RemoveProfile(int unique_id); + // Returns the profile with the specified |unique_id|, or NULL if there is no + // profile with the specified |unique_id|. + AutoFillProfile* GetProfileById(int unique_id); + // Adds |credit_card| to the web database. void AddCreditCard(const CreditCard& credit_card); diff --git a/chrome/browser/autofill/personal_data_manager_unittest.cc b/chrome/browser/autofill/personal_data_manager_unittest.cc index 1709421..267933f 100644 --- a/chrome/browser/autofill/personal_data_manager_unittest.cc +++ b/chrome/browser/autofill/personal_data_manager_unittest.cc @@ -7,11 +7,11 @@ #include "base/ref_counted.h" #include "base/scoped_ptr.h" #include "base/utf_string_conversions.h" -#include "chrome/browser/autofill/autofill_common_unittest.h" +#include "chrome/browser/autofill/autofill_common_test.h" #include "chrome/browser/autofill/autofill_profile.h" #include "chrome/browser/autofill/form_structure.h" #include "chrome/browser/autofill/personal_data_manager.h" -#include "chrome/browser/chrome_thread.h" +#include "chrome/browser/browser_thread.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/password_manager/encryptor.h" #include "chrome/common/notification_details.h" @@ -28,7 +28,7 @@ using webkit_glue::FormData; ACTION(QuitUIMessageLoop) { - DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); MessageLoop::current()->Quit(); } @@ -43,20 +43,17 @@ class PersonalDataLoadedObserverMock : public PersonalDataManager::Observer { class PersonalDataManagerTest : public testing::Test { protected: PersonalDataManagerTest() - : ui_thread_(ChromeThread::UI, &message_loop_), - db_thread_(ChromeThread::DB) { + : ui_thread_(BrowserThread::UI, &message_loop_), + db_thread_(BrowserThread::DB) { } virtual void SetUp() { -#if defined(OS_MACOSX) - Encryptor::UseMockKeychain(true); -#endif - db_thread_.Start(); profile_.reset(new TestingProfile); profile_->CreateWebDataService(false); + autofill_test::DisableSystemServices(profile_.get()); ResetPersonalDataManager(); } @@ -73,11 +70,6 @@ class PersonalDataManagerTest : public testing::Test { personal_data_ = new PersonalDataManager(); personal_data_->Init(profile_.get()); personal_data_->SetObserver(&personal_data_observer_); - - // Disable auxiliary profiles for unit testing. These reach out to system - // services on the Mac. - profile_->GetPrefs()->SetBoolean( - prefs::kAutoFillAuxiliaryProfilesEnabled, false); } AutoFillProfile* MakeProfile() { @@ -88,8 +80,8 @@ class PersonalDataManagerTest : public testing::Test { } MessageLoopForUI message_loop_; - ChromeThread ui_thread_; - ChromeThread db_thread_; + BrowserThread ui_thread_; + BrowserThread db_thread_; scoped_ptr<TestingProfile> profile_; scoped_refptr<PersonalDataManager> personal_data_; NotificationRegistrar registrar_; @@ -100,19 +92,19 @@ class PersonalDataManagerTest : public testing::Test { // TODO(jhawkins): Test SetProfiles w/out a WebDataService in the profile. TEST_F(PersonalDataManagerTest, SetProfiles) { AutoFillProfile profile0(string16(), 0); - autofill_unittest::SetProfileInfo(&profile0, + autofill_test::SetProfileInfo(&profile0, "Billing", "Marion", "Mitchell", "Morrison", "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA", "91601", "US", "12345678910", "01987654321"); AutoFillProfile profile1(string16(), 0); - autofill_unittest::SetProfileInfo(&profile1, + autofill_test::SetProfileInfo(&profile1, "Home", "Josephine", "Alicia", "Saenz", "joewayne@me.xyz", "Fox", "903 Apple Ct.", NULL, "Orlando", "FL", "32801", "US", "19482937549", "13502849239"); AutoFillProfile profile2(string16(), 0); - autofill_unittest::SetProfileInfo(&profile2, + autofill_test::SetProfileInfo(&profile2, "Work", "Josephine", "Alicia", "Saenz", "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL", "32801", "US", "19482937549", "13502849239"); @@ -194,16 +186,16 @@ TEST_F(PersonalDataManagerTest, SetProfiles) { // TODO(jhawkins): Test SetCreditCards w/out a WebDataService in the profile. TEST_F(PersonalDataManagerTest, SetCreditCards) { CreditCard creditcard0(string16(), 0); - autofill_unittest::SetCreditCardInfo(&creditcard0, "Corporate", + autofill_test::SetCreditCardInfo(&creditcard0, "Corporate", "John Dillinger", "Visa", "123456789012", "01", "2010", 1); CreditCard creditcard1(string16(), 0); - autofill_unittest::SetCreditCardInfo(&creditcard1, "Personal", + autofill_test::SetCreditCardInfo(&creditcard1, "Personal", "Bonnie Parker", "Mastercard", "098765432109", "12", "2012", 2); CreditCard creditcard2(string16(), 0); - autofill_unittest::SetCreditCardInfo(&creditcard2, "Savings", "Clyde Barrow", - "American Express", "777666888555", "04", "2015", 3); + autofill_test::SetCreditCardInfo(&creditcard2, "Savings", + "Clyde Barrow", "American Express", "777666888555", "04", "2015", 3); // This will verify that the web database has been loaded and the notification // sent out. @@ -278,23 +270,23 @@ TEST_F(PersonalDataManagerTest, SetCreditCards) { TEST_F(PersonalDataManagerTest, SetProfilesAndCreditCards) { AutoFillProfile profile0(string16(), 0); - autofill_unittest::SetProfileInfo(&profile0, + autofill_test::SetProfileInfo(&profile0, "Billing", "Marion", "Mitchell", "Morrison", "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA", "91601", "US", "12345678910", "01987654321"); AutoFillProfile profile1(string16(), 0); - autofill_unittest::SetProfileInfo(&profile1, + autofill_test::SetProfileInfo(&profile1, "Home", "Josephine", "Alicia", "Saenz", "joewayne@me.xyz", "Fox", "903 Apple Ct.", NULL, "Orlando", "FL", "32801", "US", "19482937549", "13502849239"); CreditCard creditcard0(string16(), 0); - autofill_unittest::SetCreditCardInfo(&creditcard0, "Corporate", + autofill_test::SetCreditCardInfo(&creditcard0, "Corporate", "John Dillinger", "Visa", "123456789012", "01", "2010", 1); CreditCard creditcard1(string16(), 0); - autofill_unittest::SetCreditCardInfo(&creditcard1, "Personal", + autofill_test::SetCreditCardInfo(&creditcard1, "Personal", "Bonnie Parker", "Mastercard", "098765432109", "12", "2012", 2); // This will verify that the web database has been loaded and the notification @@ -358,7 +350,7 @@ TEST_F(PersonalDataManagerTest, SetProfilesAndCreditCards) { // load. TEST_F(PersonalDataManagerTest, PopulateUniqueIDsOnLoad) { AutoFillProfile profile0(string16(), 0); - autofill_unittest::SetProfileInfo(&profile0, + autofill_test::SetProfileInfo(&profile0, "", "y", "", "", "", "", "", "", "", "", "", "", "", ""); // This will verify that the web database has been loaded and the notification @@ -387,7 +379,7 @@ TEST_F(PersonalDataManagerTest, PopulateUniqueIDsOnLoad) { // Add a new profile. AutoFillProfile profile1(string16(), 0); - autofill_unittest::SetProfileInfo(&profile1, + autofill_test::SetProfileInfo(&profile1, "", "y", "", "", "", "", "", "", "", "", "", "", "", ""); update.clear(); update.push_back(*results2[0]); @@ -405,7 +397,7 @@ TEST_F(PersonalDataManagerTest, PopulateUniqueIDsOnLoad) { TEST_F(PersonalDataManagerTest, SetEmptyProfile) { AutoFillProfile profile0(string16(), 0); - autofill_unittest::SetProfileInfo(&profile0, + autofill_test::SetProfileInfo(&profile0, "", "", "", "", "", "", "", "", "", "", "", "", "", ""); // This will verify that the web database has been loaded and the notification @@ -445,7 +437,7 @@ TEST_F(PersonalDataManagerTest, SetEmptyProfile) { TEST_F(PersonalDataManagerTest, SetEmptyCreditCard) { CreditCard creditcard0(string16(), 0); - autofill_unittest::SetCreditCardInfo(&creditcard0, + autofill_test::SetCreditCardInfo(&creditcard0, "", "", "", "", "", "", 0); // This will verify that the web database has been loaded and the notification @@ -485,13 +477,13 @@ TEST_F(PersonalDataManagerTest, SetEmptyCreditCard) { TEST_F(PersonalDataManagerTest, Refresh) { AutoFillProfile profile0(string16(), 0); - autofill_unittest::SetProfileInfo(&profile0, + autofill_test::SetProfileInfo(&profile0, "Billing", "Marion", "Mitchell", "Morrison", "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5", "Hollywood", "CA", "91601", "US", "12345678910", "01987654321"); AutoFillProfile profile1(string16(), 0); - autofill_unittest::SetProfileInfo(&profile1, + autofill_test::SetProfileInfo(&profile1, "Home", "Josephine", "Alicia", "Saenz", "joewayne@me.xyz", "Fox", "903 Apple Ct.", NULL, "Orlando", "FL", "32801", "US", "19482937549", "13502849239"); @@ -524,7 +516,7 @@ TEST_F(PersonalDataManagerTest, Refresh) { EXPECT_EQ(profile1, *results1.at(1)); scoped_ptr<AutoFillProfile> profile2(MakeProfile()); - autofill_unittest::SetProfileInfo(profile2.get(), + autofill_test::SetProfileInfo(profile2.get(), "Work", "Josephine", "Alicia", "Saenz", "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5", "Orlando", "FL", "32801", "US", "19482937549", "13502849239"); @@ -576,13 +568,13 @@ TEST_F(PersonalDataManagerTest, Refresh) { TEST_F(PersonalDataManagerTest, ImportFormData) { FormData form; webkit_glue::FormField field; - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "First name:", "first_name", "George", "text", &field); form.fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Last name:", "last_name", "Washington", "text", &field); form.fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Email:", "email", "theprez@gmail.com", "text", &field); form.fields.push_back(field); FormStructure form_structure(form); @@ -597,7 +589,7 @@ TEST_F(PersonalDataManagerTest, ImportFormData) { MessageLoop::current()->Run(); AutoFillProfile expected(string16(), 1); - autofill_unittest::SetProfileInfo(&expected, NULL, "George", NULL, + autofill_test::SetProfileInfo(&expected, NULL, "George", NULL, "Washington", "theprez@gmail.com", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); const std::vector<AutoFillProfile*>& results = personal_data_->profiles(); @@ -638,6 +630,19 @@ TEST_F(PersonalDataManagerTest, SetUniqueCreditCardLabels) { update.push_back(credit_card5); personal_data_->SetCreditCards(&update); + // Reset the PersonalDataManager. This tests that the personal data was saved + // to the web database, and that we can load the credit cards from the web + // database. + ResetPersonalDataManager(); + + // This will verify that the web database has been loaded and the notification + // sent out. + EXPECT_CALL(personal_data_observer_, + OnPersonalDataLoaded()).WillOnce(QuitUIMessageLoop()); + + // The message loop will exit when the mock observer is notified. + MessageLoop::current()->Run(); + const std::vector<CreditCard*>& results = personal_data_->credit_cards(); ASSERT_EQ(6U, results.size()); EXPECT_EQ(ASCIIToUTF16("Home"), results[0]->Label()); @@ -652,13 +657,13 @@ TEST_F(PersonalDataManagerTest, AggregateProfileData) { scoped_ptr<FormData> form(new FormData); webkit_glue::FormField field; - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "First name:", "first_name", "George", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Last name:", "last_name", "Washington", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Email:", "email", "theprez@gmail.com", "text", &field); form->fields.push_back(field); @@ -676,7 +681,7 @@ TEST_F(PersonalDataManagerTest, AggregateProfileData) { scoped_ptr<AutoFillProfile> expected( new AutoFillProfile(string16(), 1)); - autofill_unittest::SetProfileInfo(expected.get(), NULL, "George", NULL, + autofill_test::SetProfileInfo(expected.get(), NULL, "George", NULL, "Washington", "theprez@gmail.com", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); const std::vector<AutoFillProfile*>& results = personal_data_->profiles(); @@ -686,13 +691,13 @@ TEST_F(PersonalDataManagerTest, AggregateProfileData) { // Now create a completely different profile. form.reset(new FormData); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "First name:", "first_name", "John", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Last name:", "last_name", "Adams", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Email:", "email", "second@gmail.com", "text", &field); form->fields.push_back(field); @@ -711,14 +716,14 @@ TEST_F(PersonalDataManagerTest, AggregateProfileData) { ASSERT_EQ(2U, results2.size()); expected.reset(new AutoFillProfile(string16(), 1)); - autofill_unittest::SetProfileInfo(expected.get(), NULL, "George", NULL, + autofill_test::SetProfileInfo(expected.get(), NULL, "George", NULL, "Washington", "theprez@gmail.com", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); expected->set_label(results2[0]->Label()); EXPECT_EQ(*expected, *results2[0]); expected.reset(new AutoFillProfile(string16(), 2)); - autofill_unittest::SetProfileInfo(expected.get(), NULL, "John", NULL, + autofill_test::SetProfileInfo(expected.get(), NULL, "John", NULL, "Adams", "second@gmail.com", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); expected->set_label(results2[1]->Label()); @@ -726,22 +731,22 @@ TEST_F(PersonalDataManagerTest, AggregateProfileData) { // Submit a form with new data for the first profile. form.reset(new FormData); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "First name:", "first_name", "George", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Last name:", "last_name", "Washington", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Address Line 1:", "address", "190 High Street", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "City:", "city", "Philadelphia", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "State:", "state", "Pennsylvania", "text", &field); form->fields.push_back(field); - autofill_unittest::CreateTestFormField( + autofill_test::CreateTestFormField( "Zip:", "zipcode", "19106", "text", &field); form->fields.push_back(field); @@ -760,14 +765,14 @@ TEST_F(PersonalDataManagerTest, AggregateProfileData) { ASSERT_EQ(2U, results3.size()); expected.reset(new AutoFillProfile(string16(), 1)); - autofill_unittest::SetProfileInfo(expected.get(), NULL, "George", NULL, + autofill_test::SetProfileInfo(expected.get(), NULL, "George", NULL, "Washington", "theprez@gmail.com", NULL, "190 High Street", NULL, "Philadelphia", "Pennsylvania", "19106", NULL, NULL, NULL); expected->set_label(results3[0]->Label()); EXPECT_EQ(*expected, *results3[0]); expected.reset(new AutoFillProfile(string16(), 2)); - autofill_unittest::SetProfileInfo(expected.get(), NULL, "John", NULL, + autofill_test::SetProfileInfo(expected.get(), NULL, "John", NULL, "Adams", "second@gmail.com", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); expected->set_label(results3[1]->Label()); diff --git a/chrome/browser/autofill/phone_number.cc b/chrome/browser/autofill/phone_number.cc index 997edd9..025f031 100644 --- a/chrome/browser/autofill/phone_number.cc +++ b/chrome/browser/autofill/phone_number.cc @@ -32,6 +32,10 @@ const int kAutoFillPhoneLength = arraysize(kAutoFillPhoneTypes); } // namespace +PhoneNumber::PhoneNumber() {} + +PhoneNumber::~PhoneNumber() {} + void PhoneNumber::GetPossibleFieldTypes(const string16& text, FieldTypeSet* possible_types) const { string16 stripped_text(text); diff --git a/chrome/browser/autofill/phone_number.h b/chrome/browser/autofill/phone_number.h index ef1bafc..1167683 100644 --- a/chrome/browser/autofill/phone_number.h +++ b/chrome/browser/autofill/phone_number.h @@ -14,8 +14,8 @@ // A form group that stores phone number information. class PhoneNumber : public FormGroup { public: - PhoneNumber() {} - virtual ~PhoneNumber() {} + PhoneNumber(); + virtual ~PhoneNumber(); // FormGroup implementation: virtual FormGroup* Clone() const = 0; |