diff options
author | georgey@chromium.org <georgey@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-12 02:36:46 +0000 |
---|---|---|
committer | georgey@chromium.org <georgey@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-12 02:36:46 +0000 |
commit | f69c8856f8de9aeb109363da9eca25f781323ff8 (patch) | |
tree | 699413c984eb7aaa4baa0f0afedf918017435e8a /chrome | |
parent | 005bb5f499ad3282ffb6ad7d14167e1801796ef0 (diff) | |
download | chromium_src-f69c8856f8de9aeb109363da9eca25f781323ff8.zip chromium_src-f69c8856f8de9aeb109363da9eca25f781323ff8.tar.gz chromium_src-f69c8856f8de9aeb109363da9eca25f781323ff8.tar.bz2 |
Import locally saved IE Tolbar Autofill data
BUG=49084
TEST=Should automatically import the data on fresh install of Chrome.
Review URL: http://codereview.chromium.org/3367016
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@62232 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/autofill/autofill_ie_toolbar_import_win.cc | 240 | ||||
-rw-r--r-- | chrome/browser/autofill/autofill_ie_toolbar_import_win.h | 23 | ||||
-rw-r--r-- | chrome/browser/autofill/autofill_ie_toolbar_import_win_unittest.cc | 231 | ||||
-rw-r--r-- | chrome/browser/browser.cc | 13 | ||||
-rw-r--r-- | chrome/browser/first_run/first_run.cc | 15 | ||||
-rw-r--r-- | chrome/browser/first_run/first_run.h | 5 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 2 | ||||
-rw-r--r-- | chrome/chrome_tests.gypi | 1 | ||||
-rw-r--r-- | chrome/common/pref_names.cc | 3 | ||||
-rw-r--r-- | chrome/common/pref_names.h | 1 |
10 files changed, 534 insertions, 0 deletions
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..de151e3 --- /dev/null +++ b/chrome/browser/autofill/autofill_ie_toolbar_import_win.cc @@ -0,0 +1,240 @@ +// 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/registry.h" +#include "base/string16.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" + +// 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; + } + + 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)) { + 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..9aa7649 --- /dev/null +++ b/chrome/browser/autofill/autofill_ie_toolbar_import_win_unittest.cc @@ -0,0 +1,231 @@ +// 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/registry.h" +#include "base/string16.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" + +// 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/browser.cc b/chrome/browser/browser.cc index 7ee7a36..3fcd4d3 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -25,6 +25,9 @@ #include "gfx/point.h" #include "chrome/app/chrome_dll_resource.h" #include "chrome/browser/autofill/autofill_manager.h" +#if defined(OS_WIN) +#include "chrome/browser/autofill/autofill_ie_toolbar_import_win.h" +#endif // defined(OS_WIN) #include "chrome/browser/bookmarks/bookmark_model.h" #include "chrome/browser/bookmarks/bookmark_utils.h" #include "chrome/browser/browser_list.h" @@ -413,6 +416,16 @@ void Browser::CreateBrowserWindow() { local_state->ClearPref(prefs::kShouldShowFirstRunBubble); window_->GetLocationBar()->ShowFirstRunBubble(bubble_type); } + if (local_state->FindPreference( + prefs::kAutoFillPersonalDataManagerFirstRun) && + local_state->GetBoolean(prefs::kAutoFillPersonalDataManagerFirstRun)) { + // Notify PDM that this is a first run. +#if defined(OS_WIN) + ImportAutofillDataWin(profile_->GetPersonalDataManager()); +#endif // defined(OS_WIN) + // Reset the preference so we don't call it again for subsequent windows. + local_state->ClearPref(prefs::kAutoFillPersonalDataManagerFirstRun); + } } /////////////////////////////////////////////////////////////////////////////// diff --git a/chrome/browser/first_run/first_run.cc b/chrome/browser/first_run/first_run.cc index 602e25b..596419f 100644 --- a/chrome/browser/first_run/first_run.cc +++ b/chrome/browser/first_run/first_run.cc @@ -358,6 +358,20 @@ bool FirstRun::SetShowWelcomePagePref() { } // static +bool FirstRun::SetPersonalDataManagerFirstRunPref() { + PrefService* local_state = g_browser_process->local_state(); + if (!local_state) + return false; + if (!local_state->FindPreference( + prefs::kAutoFillPersonalDataManagerFirstRun)) { + local_state->RegisterBooleanPref( + prefs::kAutoFillPersonalDataManagerFirstRun, false); + local_state->SetBoolean(prefs::kAutoFillPersonalDataManagerFirstRun, true); + } + return true; +} + +// static bool FirstRun::SetOEMFirstRunBubblePref() { PrefService* local_state = g_browser_process->local_state(); if (!local_state) @@ -565,6 +579,7 @@ void FirstRun::AutoImport( // Set the first run bubble to minimal. FirstRun::SetMinimalFirstRunBubblePref(); FirstRun::SetShowWelcomePagePref(); + FirstRun::SetPersonalDataManagerFirstRunPref(); process_singleton->Unlock(); FirstRun::CreateSentinel(); diff --git a/chrome/browser/first_run/first_run.h b/chrome/browser/first_run/first_run.h index a152a0c..c131756 100644 --- a/chrome/browser/first_run/first_run.h +++ b/chrome/browser/first_run/first_run.h @@ -146,6 +146,11 @@ class FirstRun { // if the pref could not be set. static bool SetShowWelcomePagePref(); + // Sets the kAutoFillPersonalDataManagerFirstRun local state pref so that the + // browser loads PersonalDataManager once the main message loop gets going. + // Returns false if the pref could not be set. + static bool SetPersonalDataManagerFirstRunPref(); + private: friend class FirstRunTest; FRIEND_TEST_ALL_PREFIXES(Toolbar5ImporterTest, BookmarkParse); diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index c2b5387..434f030 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -156,6 +156,8 @@ 'browser/autofill/autofill_download.h', 'browser/autofill/autofill_field.cc', 'browser/autofill/autofill_field.h', + 'browser/autofill/autofill_ie_toolbar_import_win.cc', + 'browser/autofill/autofill_ie_toolbar_import_win.h', 'browser/autofill/autofill_manager.cc', 'browser/autofill/autofill_manager.h', 'browser/autofill/autofill_profile.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 90de7e6..326655a 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -996,6 +996,7 @@ 'browser/autofill/autofill_dialog_controller_mac_unittest.mm', 'browser/autofill/autofill_download_unittest.cc', 'browser/autofill/autofill_field_unittest.cc', + 'browser/autofill/autofill_ie_toolbar_import_win_unittest.cc', 'browser/autofill/autofill_manager_unittest.cc', 'browser/autofill/autofill_profile_unittest.cc', 'browser/autofill/autofill_type_unittest.cc', diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index e0a0844..81da3dd 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc @@ -554,6 +554,9 @@ const char kAutoFillPositiveUploadRate[] = "autofill.positive_upload_rate"; // Double that indicates negative (for not matched forms) upload rate. const char kAutoFillNegativeUploadRate[] = "autofill.negative_upload_rate"; +// Boolean option set to true on the first run. Non-persistent. +const char kAutoFillPersonalDataManagerFirstRun[] = "autofill.pdm.first_run"; + // Boolean that is true when the tabstrip is to be laid out vertically down the // side of the browser window. const char kUseVerticalTabs[] = "tabs.use_vertical_tabs"; diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 41ee3ed..fb3f7bc 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h @@ -206,6 +206,7 @@ extern const char kAutoFillAuxiliaryProfilesEnabled[]; extern const char kAutoFillDialogPlacement[]; extern const char kAutoFillPositiveUploadRate[]; extern const char kAutoFillNegativeUploadRate[]; +extern const char kAutoFillPersonalDataManagerFirstRun[]; extern const char kUseVerticalTabs[]; extern const char kEnableTranslate[]; |