diff options
31 files changed, 373 insertions, 35 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index c5f8dc4..30a9034 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -7364,6 +7364,9 @@ Keep your key file in a safe place. You will need it to create new versions of y <message name="IDS_IMPORT_SEARCH_ENGINES_CHKBOX" desc="Checkbox for importing search engines"> Search engines </message> + <message name="IDS_IMPORT_AUTOFILL_FORM_DATA_CHKBOX" desc="Checkbox for importing form data for autofill"> + Autofill form data + </message> <message name="IDS_IMPORT_LOADING_PROFILES" desc="Status text to notify the user that profiles are being loaded"> Loading... </message> diff --git a/chrome/browser/importer/external_process_importer_client.cc b/chrome/browser/importer/external_process_importer_client.cc index 4394611..523d2f8 100644 --- a/chrome/browser/importer/external_process_importer_client.cc +++ b/chrome/browser/importer/external_process_importer_client.cc @@ -106,6 +106,10 @@ bool ExternalProcessImporterClient::OnMessageReceived( OnKeywordsImportReady) IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyFirefoxSearchEngData, OnFirefoxSearchEngineDataReceived) + IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_AutofillFormDataImportStart, + OnAutofillFormDataImportStart) + IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_AutofillFormDataImportGroup, + OnAutofillFormDataImportGroup) #if defined(OS_WIN) IPC_MESSAGE_HANDLER(ProfileImportProcessHostMsg_NotifyIE7PasswordInfo, OnIE7PasswordReceived) @@ -250,6 +254,28 @@ void ExternalProcessImporterClient::OnFirefoxSearchEngineDataReceived( bridge_->SetFirefoxSearchEnginesXMLData(search_engine_data); } +void ExternalProcessImporterClient::OnAutofillFormDataImportStart( + size_t total_autofill_form_data_entry_count) { + if (cancelled_) + return; + + total_autofill_form_data_entry_count_ = total_autofill_form_data_entry_count; + autofill_form_data_.reserve(total_autofill_form_data_entry_count); +} + +void ExternalProcessImporterClient::OnAutofillFormDataImportGroup( + const std::vector<ImporterAutofillFormDataEntry>& + autofill_form_data_entry_group) { + if (cancelled_) + return; + + autofill_form_data_.insert(autofill_form_data_.end(), + autofill_form_data_entry_group.begin(), + autofill_form_data_entry_group.end()); + if (autofill_form_data_.size() == total_autofill_form_data_entry_count_) + bridge_->SetAutofillFormData(autofill_form_data_); +} + #if defined(OS_WIN) void ExternalProcessImporterClient::OnIE7PasswordReceived( const importer::ImporterIE7PasswordInfo& importer_password_info) { diff --git a/chrome/browser/importer/external_process_importer_client.h b/chrome/browser/importer/external_process_importer_client.h index 5d54092..300f398 100644 --- a/chrome/browser/importer/external_process_importer_client.h +++ b/chrome/browser/importer/external_process_importer_client.h @@ -13,6 +13,7 @@ #include "base/memory/weak_ptr.h" #include "base/strings/string16.h" #include "chrome/browser/history/history_types.h" +#include "chrome/common/importer/importer_autofill_form_data_entry.h" #include "chrome/common/importer/importer_data_types.h" #include "chrome/common/importer/importer_url_row.h" #include "content/public/browser/browser_thread.h" @@ -35,6 +36,7 @@ namespace importer { #if defined(OS_WIN) struct ImporterIE7PasswordInfo; #endif +struct ImporterAutofillFormDataEntry; struct URLKeywordInfo; } @@ -82,6 +84,10 @@ class ExternalProcessImporterClient : public content::UtilityProcessHostClient { bool unique_on_host_and_path); void OnFirefoxSearchEngineDataReceived( const std::vector<std::string> search_engine_data); + void OnAutofillFormDataImportStart( + size_t total_autofill_form_data_entry_count); + void OnAutofillFormDataImportGroup(const std::vector< + ImporterAutofillFormDataEntry>& autofill_form_data_entry_group); #if defined(OS_WIN) void OnIE7PasswordReceived( const importer::ImporterIE7PasswordInfo& importer_password_info); @@ -108,6 +114,7 @@ class ExternalProcessImporterClient : public content::UtilityProcessHostClient { std::vector<ImporterURLRow> history_rows_; std::vector<ImportedBookmarkEntry> bookmarks_; std::vector<ImportedFaviconUsage> favicons_; + std::vector<ImporterAutofillFormDataEntry> autofill_form_data_; // Usually some variation on IDS_BOOKMARK_GROUP_...; the name of the folder // under which imported bookmarks will be placed. @@ -122,6 +129,9 @@ class ExternalProcessImporterClient : public content::UtilityProcessHostClient { // Total number of favicons to import. size_t total_favicons_count_; + // Total number of autofill form data entries to import. + size_t total_autofill_form_data_entry_count_; + // Notifications received from the ProfileImportProcessHost are passed back // to process_importer_host_, which calls the ProfileWriter to record the // import data. When the import process is done, process_importer_host_ diff --git a/chrome/browser/importer/firefox_importer_browsertest.cc b/chrome/browser/importer/firefox_importer_browsertest.cc index 8ae0237..3df0e4e 100644 --- a/chrome/browser/importer/firefox_importer_browsertest.cc +++ b/chrome/browser/importer/firefox_importer_browsertest.cc @@ -20,6 +20,7 @@ #include "chrome/common/importer/imported_favicon_usage.h" #include "chrome/common/importer/importer_data_types.h" #include "chrome/test/base/in_process_browser_test.h" +#include "components/autofill/core/browser/webdata/autofill_entry.h" #include "components/autofill/core/common/password_form.h" #include "components/search_engines/template_url.h" #include "testing/gtest/include/gtest/gtest.h" @@ -51,6 +52,11 @@ struct KeywordInfo { const char* url; }; +struct AutofillFormDataInfo { + const char* name; + const char* value; +}; + const BookmarkInfo kFirefoxBookmarks[] = { {true, 1, {"Bookmarks Toolbar"}, L"Toolbar", @@ -94,6 +100,21 @@ const KeywordInfo kFirefoxKeywords[] = { {L"\x4E2D\x6587", L"\x4E2D\x6587", "http://www.google.com/"}, }; +const AutofillFormDataInfo kFirefoxAutofillEntries[] = { + {"name", "John"}, + {"address", "#123 Cherry Ave"}, + {"city", "Mountain View"}, + {"zip", "94043"}, + {"n300", "+1 (408) 871-4567"}, + {"name", "john"}, + {"name", "aguantó"}, + {"address", "télévision@example.com"}, + {"city", "&$%$$$ TESTO *&*&^&^& MOKO"}, + {"zip", "WOHOOOO$$$$$$$$****"}, + {"n300", "\xe0\xa4\x9f\xe2\x97\x8c\xe0\xa4\xbe\xe0\xa4\xaf\xe0\xa4\xb0"}, + {"n300", "\xe4\xbb\xa5\xe7\x8e\xa9\xe4\xb8\xba\xe4\xb8\xbb"} +}; + class FirefoxObserver : public ProfileWriter, public importer::ImporterProgressObserver { public: @@ -167,6 +188,17 @@ class FirefoxObserver : public ProfileWriter, } } + virtual void AddAutofillFormDataEntries( + const std::vector<autofill::AutofillEntry>& autofill_entries) OVERRIDE { + EXPECT_EQ(arraysize(kFirefoxAutofillEntries), autofill_entries.size()); + for (size_t i = 0; i < arraysize(kFirefoxAutofillEntries); ++i) { + EXPECT_EQ(kFirefoxAutofillEntries[i].name, + base::UTF16ToUTF8(autofill_entries[i].key().name())); + EXPECT_EQ(kFirefoxAutofillEntries[i].value, + base::UTF16ToUTF8(autofill_entries[i].key().value())); + } + } + virtual void AddKeywords(ScopedVector<TemplateURL> template_urls, bool unique_on_host_and_path) OVERRIDE { for (size_t i = 0; i < template_urls.size(); ++i) { @@ -271,7 +303,7 @@ class FirefoxProfileImporterBrowserTest : public InProcessBrowserTest { source_profile.locale = "en-US"; int items = importer::HISTORY | importer::PASSWORDS | importer::FAVORITES | - importer::SEARCH_ENGINES; + importer::SEARCH_ENGINES | importer::AUTOFILL_FORM_DATA; // Deletes itself. ExternalProcessImporterHost* host = new ExternalProcessImporterHost; diff --git a/chrome/browser/importer/importer_list.cc b/chrome/browser/importer/importer_list.cc index d42ef4e..de8987d 100644 --- a/chrome/browser/importer/importer_list.cc +++ b/chrome/browser/importer/importer_list.cc @@ -93,7 +93,8 @@ void DetectFirefoxProfiles(const std::string locale, if (firefox->app_path.empty()) firefox->app_path = app_path; firefox->services_supported = importer::HISTORY | importer::FAVORITES | - importer::PASSWORDS | importer::SEARCH_ENGINES; + importer::PASSWORDS | importer::SEARCH_ENGINES | + importer::AUTOFILL_FORM_DATA; firefox->locale = locale; profiles->push_back(firefox); } diff --git a/chrome/browser/importer/in_process_importer_bridge.cc b/chrome/browser/importer/in_process_importer_bridge.cc index 61480ae..c5c5927 100644 --- a/chrome/browser/importer/in_process_importer_bridge.cc +++ b/chrome/browser/importer/in_process_importer_bridge.cc @@ -12,6 +12,8 @@ #include "chrome/browser/search_engines/ui_thread_search_terms_data.h" #include "chrome/common/importer/imported_bookmark_entry.h" #include "chrome/common/importer/imported_favicon_usage.h" +#include "chrome/common/importer/importer_autofill_form_data_entry.h" +#include "components/autofill/core/browser/webdata/autofill_entry.h" #include "components/autofill/core/common/password_form.h" #include "components/search_engines/template_url.h" #include "components/search_engines/template_url_parser.h" @@ -254,6 +256,23 @@ void InProcessImporterBridge::SetPasswordForm( base::Bind(&ProfileWriter::AddPasswordForm, writer_, form)); } +void InProcessImporterBridge::SetAutofillFormData( + const std::vector<ImporterAutofillFormDataEntry>& entries) { + std::vector<autofill::AutofillEntry> autofill_entries; + for (size_t i = 0; i < entries.size(); ++i) { + autofill_entries.push_back(autofill::AutofillEntry( + autofill::AutofillKey(entries[i].name, entries[i].value), + entries[i].first_used, + entries[i].last_used)); + } + + BrowserThread::PostTask(BrowserThread::UI, + FROM_HERE, + base::Bind(&ProfileWriter::AddAutofillFormDataEntries, + writer_, + autofill_entries)); +} + void InProcessImporterBridge::NotifyStarted() { BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, diff --git a/chrome/browser/importer/in_process_importer_bridge.h b/chrome/browser/importer/in_process_importer_bridge.h index e0de744..5f5def8 100644 --- a/chrome/browser/importer/in_process_importer_bridge.h +++ b/chrome/browser/importer/in_process_importer_bridge.h @@ -61,6 +61,9 @@ class InProcessImporterBridge : public ImporterBridge { virtual void SetPasswordForm( const autofill::PasswordForm& form) OVERRIDE; + virtual void SetAutofillFormData( + const std::vector<ImporterAutofillFormDataEntry>& entries) OVERRIDE; + virtual void NotifyStarted() OVERRIDE; virtual void NotifyItemStarted(importer::ImportItem item) OVERRIDE; virtual void NotifyItemEnded(importer::ImportItem item) OVERRIDE; diff --git a/chrome/browser/importer/profile_writer.cc b/chrome/browser/importer/profile_writer.cc index 6bf93dc..e94344a 100644 --- a/chrome/browser/importer/profile_writer.cc +++ b/chrome/browser/importer/profile_writer.cc @@ -22,9 +22,11 @@ #include "chrome/browser/password_manager/password_store_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/search_engines/template_url_service_factory.h" +#include "chrome/browser/webdata/web_data_service_factory.h" #include "chrome/common/importer/imported_bookmark_entry.h" #include "chrome/common/importer/imported_favicon_usage.h" #include "chrome/common/pref_names.h" +#include "components/autofill/core/browser/webdata/autofill_webdata_service.h" #include "components/bookmarks/browser/bookmark_model.h" #include "components/password_manager/core/browser/password_store.h" #include "components/search_engines/template_url.h" @@ -329,4 +331,13 @@ void ProfileWriter::AddKeywords(ScopedVector<TemplateURL> template_urls, } } +void ProfileWriter::AddAutofillFormDataEntries( + const std::vector<autofill::AutofillEntry>& autofill_entries) { + scoped_refptr<autofill::AutofillWebDataService> web_data_service = + WebDataServiceFactory::GetAutofillWebDataForProfile( + profile_, Profile::EXPLICIT_ACCESS); + if (web_data_service.get()) + web_data_service->UpdateAutofillEntries(autofill_entries); +} + ProfileWriter::~ProfileWriter() {} diff --git a/chrome/browser/importer/profile_writer.h b/chrome/browser/importer/profile_writer.h index 3c036b3..6adea3c 100644 --- a/chrome/browser/importer/profile_writer.h +++ b/chrome/browser/importer/profile_writer.h @@ -23,6 +23,7 @@ class TemplateURL; namespace autofill { struct PasswordForm; +class AutofillEntry; } #if defined(OS_WIN) @@ -89,6 +90,10 @@ class ProfileWriter : public base::RefCountedThreadSafe<ProfileWriter> { virtual void AddKeywords(ScopedVector<TemplateURL> template_urls, bool unique_on_host_and_path); + // Adds the imported autofill entries to the autofill database. + virtual void AddAutofillFormDataEntries( + const std::vector<autofill::AutofillEntry>& autofill_entries); + protected: friend class base::RefCountedThreadSafe<ProfileWriter>; diff --git a/chrome/browser/resources/options/import_data_overlay.html b/chrome/browser/resources/options/import_data_overlay.html index ecaa91e..ce7bdb6 100644 --- a/chrome/browser/resources/options/import_data_overlay.html +++ b/chrome/browser/resources/options/import_data_overlay.html @@ -50,6 +50,16 @@ <span class="controlled-setting-indicator" pref="import_search_engine"></span> </div> + <div class="checkbox controlled-setting-with-label" + id="import-autofill-form-data-with-label"> + <label> + <input id="import-autofill-form-data" type="checkbox" + pref="import_autofill_form_data"> + <span i18n-content="importAutofillFormData"></span> + </label> + <span class="controlled-setting-indicator" + pref="import_autofill_form_data"></span> + </div> </div> </div> <div class="import-data-success" hidden> diff --git a/chrome/browser/resources/options/import_data_overlay.js b/chrome/browser/resources/options/import_data_overlay.js index 3afca32..4f40707 100644 --- a/chrome/browser/resources/options/import_data_overlay.js +++ b/chrome/browser/resources/options/import_data_overlay.js @@ -49,7 +49,8 @@ cr.define('options', function() { String($('import-history').checked), String($('import-favorites').checked), String($('import-passwords').checked), - String($('import-search').checked)]); + String($('import-search').checked), + String($('import-autofill-form-data').checked)]); }; $('import-data-cancel').onclick = function() { @@ -75,7 +76,8 @@ cr.define('options', function() { validateCommitButton_: function() { var somethingToImport = $('import-history').checked || $('import-favorites').checked || - $('import-passwords').checked || $('import-search').checked; + $('import-passwords').checked || $('import-search').checked || + $('import-autofill-form-data').checked; $('import-data-commit').disabled = !somethingToImport; $('import-choose-file').disabled = !$('import-favorites').checked; }, @@ -120,7 +122,11 @@ cr.define('options', function() { var browserProfile; if (this.browserProfiles.length > index) browserProfile = this.browserProfiles[index]; - var importOptions = ['history', 'favorites', 'passwords', 'search']; + var importOptions = ['history', + 'favorites', + 'passwords', + 'search', + 'autofill-form-data']; for (var i = 0; i < importOptions.length; i++) { var checkbox = $('import-' + importOptions[i]); var enable = browserProfile && browserProfile[importOptions[i]]; @@ -186,7 +192,8 @@ cr.define('options', function() { var importPrefs = ['import_history', 'import_bookmarks', 'import_saved_passwords', - 'import_search_engine']; + 'import_search_engine', + 'import_autofill_form_data']; for (var i = 0; i < importPrefs.length; i++) Preferences.clearPref(importPrefs[i], true); }, diff --git a/chrome/browser/ui/browser_ui_prefs.cc b/chrome/browser/ui/browser_ui_prefs.cc index 68215e4..958e05e 100644 --- a/chrome/browser/ui/browser_ui_prefs.cc +++ b/chrome/browser/ui/browser_ui_prefs.cc @@ -126,6 +126,10 @@ void RegisterBrowserUserPrefs(user_prefs::PrefRegistrySyncable* registry) { prefs::kBrowserWindowPlacementPopup, user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); registry->RegisterBooleanPref( + prefs::kImportAutofillFormData, + true, + user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); + registry->RegisterBooleanPref( prefs::kImportBookmarks, true, user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); @@ -138,11 +142,11 @@ void RegisterBrowserUserPrefs(user_prefs::PrefRegistrySyncable* registry) { true, user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); registry->RegisterBooleanPref( - prefs::kImportSearchEngine, + prefs::kImportSavedPasswords, true, user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); registry->RegisterBooleanPref( - prefs::kImportSavedPasswords, + prefs::kImportSearchEngine, true, user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); registry->RegisterBooleanPref( diff --git a/chrome/browser/ui/webui/options/import_data_handler.cc b/chrome/browser/ui/webui/options/import_data_handler.cc index 5481cf8..c868277 100644 --- a/chrome/browser/ui/webui/options/import_data_handler.cc +++ b/chrome/browser/ui/webui/options/import_data_handler.cc @@ -55,20 +55,21 @@ void ImportDataHandler::GetLocalizedValues( DCHECK(localized_strings); static OptionsStringResource resources[] = { - { "importFromLabel", IDS_IMPORT_FROM_LABEL }, - { "importLoading", IDS_IMPORT_LOADING_PROFILES }, - { "importDescription", IDS_IMPORT_ITEMS_LABEL }, - { "importHistory", IDS_IMPORT_HISTORY_CHKBOX }, - { "importFavorites", IDS_IMPORT_FAVORITES_CHKBOX }, - { "importSearch", IDS_IMPORT_SEARCH_ENGINES_CHKBOX }, - { "importPasswords", IDS_IMPORT_PASSWORDS_CHKBOX }, - { "importChooseFile", IDS_IMPORT_CHOOSE_FILE }, - { "importCommit", IDS_IMPORT_COMMIT }, - { "noProfileFound", IDS_IMPORT_NO_PROFILE_FOUND }, - { "importSucceeded", IDS_IMPORT_SUCCEEDED }, - { "findYourImportedBookmarks", IDS_IMPORT_FIND_YOUR_BOOKMARKS }, + {"importFromLabel", IDS_IMPORT_FROM_LABEL}, + {"importLoading", IDS_IMPORT_LOADING_PROFILES}, + {"importDescription", IDS_IMPORT_ITEMS_LABEL}, + {"importHistory", IDS_IMPORT_HISTORY_CHKBOX}, + {"importFavorites", IDS_IMPORT_FAVORITES_CHKBOX}, + {"importSearch", IDS_IMPORT_SEARCH_ENGINES_CHKBOX}, + {"importPasswords", IDS_IMPORT_PASSWORDS_CHKBOX}, + {"importAutofillFormData", IDS_IMPORT_AUTOFILL_FORM_DATA_CHKBOX}, + {"importChooseFile", IDS_IMPORT_CHOOSE_FILE}, + {"importCommit", IDS_IMPORT_COMMIT}, + {"noProfileFound", IDS_IMPORT_NO_PROFILE_FOUND}, + {"importSucceeded", IDS_IMPORT_SUCCEEDED}, + {"findYourImportedBookmarks", IDS_IMPORT_FIND_YOUR_BOOKMARKS}, #if defined(OS_MACOSX) - { "macPasswordKeychain", IDS_IMPORT_PASSWORD_KEYCHAIN_WARNING }, + {"macPasswordKeychain", IDS_IMPORT_PASSWORD_KEYCHAIN_WARNING}, #endif }; @@ -152,6 +153,9 @@ void ImportDataHandler::ImportData(const base::ListValue* args) { if (args->GetString(4, &string_value) && string_value == "true") { selected_items |= importer::SEARCH_ENGINES; } + if (args->GetString(5, &string_value) && string_value == "true") { + selected_items |= importer::AUTOFILL_FORM_DATA; + } const importer::SourceProfile& source_profile = importer_list_->GetSourceProfileAt(browser_index); @@ -186,6 +190,8 @@ void ImportDataHandler::InitializePage() { (browser_services & importer::PASSWORDS) != 0); browser_profile->SetBoolean("search", (browser_services & importer::SEARCH_ENGINES) != 0); + browser_profile->SetBoolean("autofill-form-data", + (browser_services & importer::AUTOFILL_FORM_DATA) != 0); browser_profile->SetBoolean("show_bottom_bar", #if defined(OS_MACOSX) diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi index 2eb68fd..e0aa62dbf 100644 --- a/chrome/chrome_common.gypi +++ b/chrome/chrome_common.gypi @@ -237,6 +237,8 @@ 'common/importer/imported_bookmark_entry.h', 'common/importer/imported_favicon_usage.cc', 'common/importer/imported_favicon_usage.h', + 'common/importer/importer_autofill_form_data_entry.cc', + 'common/importer/importer_autofill_form_data_entry.h', 'common/importer/importer_bridge.cc', 'common/importer/importer_bridge.h', 'common/importer/importer_data_types.cc', diff --git a/chrome/common/importer/importer_autofill_form_data_entry.cc b/chrome/common/importer/importer_autofill_form_data_entry.cc new file mode 100644 index 0000000..5dd4c5a --- /dev/null +++ b/chrome/common/importer/importer_autofill_form_data_entry.cc @@ -0,0 +1,11 @@ +// Copyright 2014 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/common/importer/importer_autofill_form_data_entry.h" + +ImporterAutofillFormDataEntry::ImporterAutofillFormDataEntry() : times_used(0) { +} + +ImporterAutofillFormDataEntry::~ImporterAutofillFormDataEntry() { +} diff --git a/chrome/common/importer/importer_autofill_form_data_entry.h b/chrome/common/importer/importer_autofill_form_data_entry.h new file mode 100644 index 0000000..af35195 --- /dev/null +++ b/chrome/common/importer/importer_autofill_form_data_entry.h @@ -0,0 +1,33 @@ +// Copyright 2014 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_COMMON_IMPORTER_IMPORTER_AUTOFILL_FORM_DATA_ENTRY_H_ +#define CHROME_COMMON_IMPORTER_IMPORTER_AUTOFILL_FORM_DATA_ENTRY_H_ + +#include "base/strings/string16.h" +#include "base/time/time.h" + +// Used as the target for importing form history from other browsers' profiles +// in the utility process. +struct ImporterAutofillFormDataEntry { + ImporterAutofillFormDataEntry(); + ~ImporterAutofillFormDataEntry(); + + // Name of input element. + base::string16 name; + + // Value of input element. + base::string16 value; + + // Number of times this name-value pair has been used. + int times_used; + + // The date of the first time when this name-value pair was used. + base::Time first_used; + + // The date of the last time when this name-value pair was used. + base::Time last_used; +}; + +#endif // CHROME_COMMON_IMPORTER_IMPORTER_AUTOFILL_FORM_DATA_ENTRY_H_ diff --git a/chrome/common/importer/importer_bridge.h b/chrome/common/importer/importer_bridge.h index c0903ff..3e6dbde 100644 --- a/chrome/common/importer/importer_bridge.h +++ b/chrome/common/importer/importer_bridge.h @@ -18,6 +18,7 @@ class GURL; struct ImportedBookmarkEntry; struct ImportedFaviconUsage; +struct ImporterAutofillFormDataEntry; namespace autofill { struct PasswordForm; @@ -63,6 +64,9 @@ class ImporterBridge : public base::RefCountedThreadSafe<ImporterBridge> { virtual void SetPasswordForm(const autofill::PasswordForm& form) = 0; + virtual void SetAutofillFormData( + const std::vector<ImporterAutofillFormDataEntry>& entries) = 0; + // Notifies the coordinator that the import operation has begun. virtual void NotifyStarted() = 0; diff --git a/chrome/common/importer/importer_data_types.h b/chrome/common/importer/importer_data_types.h index 5790209..d9594e7 100644 --- a/chrome/common/importer/importer_data_types.h +++ b/chrome/common/importer/importer_data_types.h @@ -21,14 +21,15 @@ namespace importer { // An enumeration of the type of data that can be imported. enum ImportItem { - NONE = 0, - HISTORY = 1 << 0, - FAVORITES = 1 << 1, - COOKIES = 1 << 2, // Not supported yet. - PASSWORDS = 1 << 3, - SEARCH_ENGINES = 1 << 4, - HOME_PAGE = 1 << 5, - ALL = (1 << 6) - 1 // All the bits should be 1, hence the -1. + NONE = 0, + HISTORY = 1 << 0, + FAVORITES = 1 << 1, + COOKIES = 1 << 2, // Not supported yet. + PASSWORDS = 1 << 3, + SEARCH_ENGINES = 1 << 4, + HOME_PAGE = 1 << 5, + AUTOFILL_FORM_DATA = 1 << 6, + ALL = (1 << 7) - 1 // All the bits should be 1, hence the -1. }; // Information about a profile needed by an importer to do import work. diff --git a/chrome/common/importer/profile_import_process_messages.h b/chrome/common/importer/profile_import_process_messages.h index dc09e4d3..325b552 100644 --- a/chrome/common/importer/profile_import_process_messages.h +++ b/chrome/common/importer/profile_import_process_messages.h @@ -12,6 +12,7 @@ #include "chrome/common/common_param_traits_macros.h" #include "chrome/common/importer/imported_bookmark_entry.h" #include "chrome/common/importer/imported_favicon_usage.h" +#include "chrome/common/importer/importer_autofill_form_data_entry.h" #include "chrome/common/importer/importer_data_types.h" #include "chrome/common/importer/importer_url_row.h" #include "components/autofill/content/common/autofill_param_traits_macros.h" @@ -220,6 +221,40 @@ struct ParamTraits<importer::URLKeywordInfo> { } }; // ParamTraits<importer::URLKeywordInfo> +// Traits for ImporterAutofillFormDataEntry to pack/unpack. +template <> +struct ParamTraits<ImporterAutofillFormDataEntry> { + typedef ImporterAutofillFormDataEntry param_type; + static void Write(Message* m, const param_type& p) { + WriteParam(m, p.name); + WriteParam(m, p.value); + WriteParam(m, p.times_used); + WriteParam(m, p.first_used); + WriteParam(m, p.last_used); + } + static bool Read(const Message* m, PickleIterator* iter, param_type* p) { + return + (ReadParam(m, iter, &p->name)) && + (ReadParam(m, iter, &p->value)) && + (ReadParam(m, iter, &p->times_used)) && + (ReadParam(m, iter, &p->first_used)) && + (ReadParam(m, iter, &p->last_used)); + } + static void Log(const param_type& p, std::string* l) { + l->append("("); + LogParam(p.name, l); + l->append(", "); + LogParam(p.value, l); + l->append(", "); + LogParam(p.times_used, l); + l->append(", "); + LogParam(p.first_used, l); + l->append(", "); + LogParam(p.last_used, l); + l->append(")"); + } +}; // ParamTraits<ImporterAutofillFormDataEntry> + #if defined(OS_WIN) // Traits for importer::ImporterIE7PasswordInfo template <> @@ -322,6 +357,12 @@ IPC_MESSAGE_CONTROL2(ProfileImportProcessHostMsg_NotifyKeywordsReady, IPC_MESSAGE_CONTROL1(ProfileImportProcessHostMsg_NotifyFirefoxSearchEngData, std::vector<std::string>) // search_engine_data +IPC_MESSAGE_CONTROL1(ProfileImportProcessHostMsg_AutofillFormDataImportStart, + int /* total number of entries to be imported */) + +IPC_MESSAGE_CONTROL1(ProfileImportProcessHostMsg_AutofillFormDataImportGroup, + std::vector<ImporterAutofillFormDataEntry>) + #if defined(OS_WIN) IPC_MESSAGE_CONTROL1(ProfileImportProcessHostMsg_NotifyIE7PasswordInfo, importer::ImporterIE7PasswordInfo) // password_info diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index c726956..9ab4ef1 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc @@ -1107,6 +1107,10 @@ const char kGLRendererString[] = "gl_renderer_string"; // GL_VERSION string. const char kGLVersionString[] = "gl_version_string"; +// Boolean that specifies whether to import the form data for autofill from the +// default browser on first run. +const char kImportAutofillFormData[] = "import_autofill_form_data"; + // Boolean that specifies whether to import bookmarks from the default browser // on first run. const char kImportBookmarks[] = "import_bookmarks"; @@ -1119,14 +1123,14 @@ const char kImportHistory[] = "import_history"; // browser on first run. const char kImportHomepage[] = "import_home_page"; -// Boolean that specifies whether to import the search engine from the default -// browser on first run. -const char kImportSearchEngine[] = "import_search_engine"; - // Boolean that specifies whether to import the saved passwords from the default // browser on first run. const char kImportSavedPasswords[] = "import_saved_passwords"; +// Boolean that specifies whether to import the search engine from the default +// browser on first run. +const char kImportSearchEngine[] = "import_search_engine"; + // Profile avatar and name const char kProfileAvatarIndex[] = "profile.avatar_index"; const char kProfileName[] = "profile.name"; diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 8bed38e..9fbb150 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h @@ -347,11 +347,12 @@ extern const char kEnableHyperlinkAuditing[]; extern const char kEnableReferrers[]; extern const char kEnableDoNotTrack[]; +extern const char kImportAutofillFormData[]; extern const char kImportBookmarks[]; extern const char kImportHistory[]; extern const char kImportHomepage[]; -extern const char kImportSearchEngine[]; extern const char kImportSavedPasswords[]; +extern const char kImportSearchEngine[]; extern const char kProfileAvatarIndex[]; extern const char kProfileUsingDefaultName[]; diff --git a/chrome/test/data/firefox_profile/formhistory.sqlite b/chrome/test/data/firefox_profile/formhistory.sqlite Binary files differnew file mode 100644 index 0000000..a820ae8 --- /dev/null +++ b/chrome/test/data/firefox_profile/formhistory.sqlite diff --git a/chrome/utility/importer/external_process_importer_bridge.cc b/chrome/utility/importer/external_process_importer_bridge.cc index c399d52..56c82be 100644 --- a/chrome/utility/importer/external_process_importer_bridge.cc +++ b/chrome/utility/importer/external_process_importer_bridge.cc @@ -25,7 +25,7 @@ namespace { const int kNumBookmarksToSend = 100; const int kNumHistoryRowsToSend = 100; const int kNumFaviconsToSend = 100; - +const int kNumAutofillFormDataToSend = 100; } ExternalProcessImporterBridge::ExternalProcessImporterBridge( @@ -141,6 +141,33 @@ void ExternalProcessImporterBridge::SetPasswordForm( Send(new ProfileImportProcessHostMsg_NotifyPasswordFormReady(form)); } +void ExternalProcessImporterBridge::SetAutofillFormData( + const std::vector<ImporterAutofillFormDataEntry>& entries) { + Send(new ProfileImportProcessHostMsg_AutofillFormDataImportStart( + entries.size())); + + // |autofill_form_data_entries_left| is required for the checks below as + // Windows has a Debug bounds-check which prevents pushing an iterator beyond + // its end() (i.e., |it + 2 < s.end()| crashes in debug mode if |i + 1 == + // s.end()|). + int autofill_form_data_entries_left = entries.end() - entries.begin(); + for (std::vector<ImporterAutofillFormDataEntry>::const_iterator it = + entries.begin(); + it < entries.end();) { + std::vector<ImporterAutofillFormDataEntry> autofill_form_data_entry_group; + std::vector<ImporterAutofillFormDataEntry>::const_iterator end_group = + it + + std::min(autofill_form_data_entries_left, kNumAutofillFormDataToSend); + autofill_form_data_entry_group.assign(it, end_group); + + Send(new ProfileImportProcessHostMsg_AutofillFormDataImportGroup( + autofill_form_data_entry_group)); + autofill_form_data_entries_left -= end_group - it; + it = end_group; + } + DCHECK_EQ(0, autofill_form_data_entries_left); +} + void ExternalProcessImporterBridge::NotifyStarted() { Send(new ProfileImportProcessHostMsg_Import_Started()); } diff --git a/chrome/utility/importer/external_process_importer_bridge.h b/chrome/utility/importer/external_process_importer_bridge.h index 57efe35..f1f1a46 100644 --- a/chrome/utility/importer/external_process_importer_bridge.h +++ b/chrome/utility/importer/external_process_importer_bridge.h @@ -73,6 +73,9 @@ class ExternalProcessImporterBridge : public ImporterBridge { virtual void SetPasswordForm( const autofill::PasswordForm& form) OVERRIDE; + virtual void SetAutofillFormData( + const std::vector<ImporterAutofillFormDataEntry>& entries) OVERRIDE; + virtual void NotifyStarted() OVERRIDE; virtual void NotifyItemStarted(importer::ImportItem item) OVERRIDE; virtual void NotifyItemEnded(importer::ImportItem item) OVERRIDE; diff --git a/chrome/utility/importer/firefox_importer.cc b/chrome/utility/importer/firefox_importer.cc index 6f37095..6444e29 100644 --- a/chrome/utility/importer/firefox_importer.cc +++ b/chrome/utility/importer/firefox_importer.cc @@ -18,6 +18,7 @@ #include "chrome/common/importer/firefox_importer_utils.h" #include "chrome/common/importer/imported_bookmark_entry.h" #include "chrome/common/importer/imported_favicon_usage.h" +#include "chrome/common/importer/importer_autofill_form_data_entry.h" #include "chrome/common/importer/importer_bridge.h" #include "chrome/common/importer/importer_url_row.h" #include "chrome/grit/generated_resources.h" @@ -140,6 +141,11 @@ void FirefoxImporter::StartImport( ImportPasswords(); bridge_->NotifyItemEnded(importer::PASSWORDS); } + if ((items & importer::AUTOFILL_FORM_DATA) && !cancelled()) { + bridge_->NotifyItemStarted(importer::AUTOFILL_FORM_DATA); + ImportAutofillFormData(); + bridge_->NotifyItemEnded(importer::AUTOFILL_FORM_DATA); + } bridge_->NotifyEnded(); } @@ -382,6 +388,41 @@ void FirefoxImporter::ImportHomepage() { } } +void FirefoxImporter::ImportAutofillFormData() { + base::FilePath file = source_path_.AppendASCII("formhistory.sqlite"); + if (!base::PathExists(file)) + return; + + sql::Connection db; + if (!db.Open(file)) + return; + + const char query[] = + "SELECT fieldname, value, timesUsed, firstUsed, lastUsed FROM " + "moz_formhistory"; + + sql::Statement s(db.GetUniqueStatement(query)); + + std::vector<ImporterAutofillFormDataEntry> form_entries; + while (s.Step() && !cancelled()) { + ImporterAutofillFormDataEntry form_entry; + form_entry.name = s.ColumnString16(0); + form_entry.value = s.ColumnString16(1); + form_entry.times_used = s.ColumnInt(2); + form_entry.first_used = base::Time::FromTimeT(s.ColumnInt64(3) / 1000000); + form_entry.last_used = base::Time::FromTimeT(s.ColumnInt64(4) / 1000000); + + // Don't import search bar history. + if (base::UTF16ToUTF8(form_entry.name) == "searchbar-history") + continue; + + form_entries.push_back(form_entry); + } + + if (!form_entries.empty() && !cancelled()) + bridge_->SetAutofillFormData(form_entries); +} + void FirefoxImporter::GetSearchEnginesXMLData( std::vector<std::string>* search_engine_data) { base::FilePath file = source_path_.AppendASCII("search.sqlite"); diff --git a/chrome/utility/importer/firefox_importer.h b/chrome/utility/importer/firefox_importer.h index 0ad10d6..9402024 100644 --- a/chrome/utility/importer/firefox_importer.h +++ b/chrome/utility/importer/firefox_importer.h @@ -46,6 +46,7 @@ class FirefoxImporter : public Importer { // Import the user's home page, unless it is set to default home page as // defined in browserconfig.properties. void ImportHomepage(); + void ImportAutofillFormData(); void GetSearchEnginesXMLData(std::vector<std::string>* search_engine_data); void GetSearchEnginesXMLDataFromJSON( std::vector<std::string>* search_engine_data); diff --git a/components/autofill/core/browser/webdata/autofill_webdata.h b/components/autofill/core/browser/webdata/autofill_webdata.h index fbd4107..4b9daea 100644 --- a/components/autofill/core/browser/webdata/autofill_webdata.h +++ b/components/autofill/core/browser/webdata/autofill_webdata.h @@ -23,6 +23,7 @@ class WebDataServiceConsumer; namespace autofill { +class AutofillEntry; class AutofillProfile; class CreditCard; struct FormFieldData; @@ -75,6 +76,10 @@ class AutofillWebData { virtual WebDataServiceBase::Handle GetAutofillProfiles( WebDataServiceConsumer* consumer) = 0; + // Schedules a task to update autofill entries in the web database. + virtual void UpdateAutofillEntries( + const std::vector<AutofillEntry>& autofill_entries) = 0; + // Schedules a task to add credit card to the web database. virtual void AddCreditCard(const CreditCard& credit_card) = 0; diff --git a/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc b/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc index ad6c132..5b64579 100644 --- a/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc +++ b/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.cc @@ -245,6 +245,17 @@ scoped_ptr<WDTypedResult> AutofillWebDataBackendImpl::GetAutofillProfiles( base::Unretained(this)))); } +WebDatabase::State AutofillWebDataBackendImpl::UpdateAutofillEntries( + const std::vector<autofill::AutofillEntry>& autofill_entries, + WebDatabase* db) { + DCHECK(db_thread_->BelongsToCurrentThread()); + if (!AutofillTable::FromWebDatabase(db) + ->UpdateAutofillEntries(autofill_entries)) + return WebDatabase::COMMIT_NOT_NEEDED; + + return WebDatabase::COMMIT_NEEDED; +} + WebDatabase::State AutofillWebDataBackendImpl::AddCreditCard( const CreditCard& credit_card, WebDatabase* db) { DCHECK(db_thread_->BelongsToCurrentThread()); diff --git a/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h b/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h index 6db3f99..8cf3ead 100644 --- a/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h +++ b/components/autofill/core/browser/webdata/autofill_webdata_backend_impl.h @@ -113,6 +113,11 @@ class AutofillWebDataBackendImpl // Returns all Autofill profiles from the web database. scoped_ptr<WDTypedResult> GetAutofillProfiles(WebDatabase* db); + // Updates Autofill entries in the web database. + WebDatabase::State UpdateAutofillEntries( + const std::vector<autofill::AutofillEntry>& autofill_entries, + WebDatabase* db); + // Adds a credit card to the web database. WebDatabase::State AddCreditCard(const CreditCard& credit_card, WebDatabase* db); diff --git a/components/autofill/core/browser/webdata/autofill_webdata_service.cc b/components/autofill/core/browser/webdata/autofill_webdata_service.cc index 9ba3fed..08f4c03 100644 --- a/components/autofill/core/browser/webdata/autofill_webdata_service.cc +++ b/components/autofill/core/browser/webdata/autofill_webdata_service.cc @@ -129,6 +129,14 @@ WebDataServiceBase::Handle AutofillWebDataService::GetAutofillProfiles( consumer); } +void AutofillWebDataService::UpdateAutofillEntries( + const std::vector<autofill::AutofillEntry>& autofill_entries) { + wdbs_->ScheduleDBTask(FROM_HERE, + Bind(&AutofillWebDataBackendImpl::UpdateAutofillEntries, + autofill_backend_, + autofill_entries)); +} + void AutofillWebDataService::AddCreditCard(const CreditCard& credit_card) { wdbs_->ScheduleDBTask( FROM_HERE, diff --git a/components/autofill/core/browser/webdata/autofill_webdata_service.h b/components/autofill/core/browser/webdata/autofill_webdata_service.h index 9131a8c..d2353ca 100644 --- a/components/autofill/core/browser/webdata/autofill_webdata_service.h +++ b/components/autofill/core/browser/webdata/autofill_webdata_service.h @@ -27,6 +27,7 @@ class MessageLoopProxy; namespace autofill { class AutofillChange; +class AutofillEntry; class AutofillProfile; class AutofillWebDataBackend; class AutofillWebDataBackendImpl; @@ -69,6 +70,8 @@ class AutofillWebDataService : public AutofillWebData, virtual void RemoveAutofillProfile(const std::string& guid) OVERRIDE; virtual WebDataServiceBase::Handle GetAutofillProfiles( WebDataServiceConsumer* consumer) OVERRIDE; + virtual void UpdateAutofillEntries( + const std::vector<AutofillEntry>& autofill_entries) OVERRIDE; virtual void AddCreditCard(const CreditCard& credit_card) OVERRIDE; virtual void UpdateCreditCard(const CreditCard& credit_card) OVERRIDE; virtual void RemoveCreditCard(const std::string& guid) OVERRIDE; |