diff options
author | isherman@chromium.org <isherman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-16 06:19:56 +0000 |
---|---|---|
committer | isherman@chromium.org <isherman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-16 06:19:56 +0000 |
commit | 1866d061a07ad56c082f439d5f50301944be4170 (patch) | |
tree | 2983cc377e5fe79f41f93fa7354258bee17ec07d /chrome/browser | |
parent | e41c1da3c9b54efaa715b86aeec81a50ee86bfd4 (diff) | |
download | chromium_src-1866d061a07ad56c082f439d5f50301944be4170.zip chromium_src-1866d061a07ad56c082f439d5f50301944be4170.tar.gz chromium_src-1866d061a07ad56c082f439d5f50301944be4170.tar.bz2 |
Display a warning when autofill is disabled for a website.
This depends on a WebKit change being tracked at https://bugs.webkit.org/show_bug.cgi?id=49291
BUG=58509
TEST=unit_tests --gtest_filter=AutoFillManagerTest.*:AutoFillHelperTest.*
Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=66214
Review URL: http://codereview.chromium.org/4591001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@66237 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r-- | chrome/browser/autocomplete_history_manager.cc | 24 | ||||
-rw-r--r-- | chrome/browser/autocomplete_history_manager.h | 4 | ||||
-rw-r--r-- | chrome/browser/autofill/autofill_manager.cc | 63 | ||||
-rw-r--r-- | chrome/browser/autofill/autofill_manager.h | 3 | ||||
-rw-r--r-- | chrome/browser/autofill/autofill_manager_unittest.cc | 273 | ||||
-rw-r--r-- | chrome/browser/autofill/form_structure.cc | 55 | ||||
-rw-r--r-- | chrome/browser/autofill/form_structure.h | 19 | ||||
-rw-r--r-- | chrome/browser/autofill/form_structure_unittest.cc | 48 | ||||
-rw-r--r-- | chrome/browser/chromeos/login/account_creation_view.cc | 4 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_view_host.cc | 53 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_view_host.h | 16 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_view_host_delegate.h | 17 |
12 files changed, 381 insertions, 198 deletions
diff --git a/chrome/browser/autocomplete_history_manager.cc b/chrome/browser/autocomplete_history_manager.cc index 2243bcb..763445b 100644 --- a/chrome/browser/autocomplete_history_manager.cc +++ b/chrome/browser/autocomplete_history_manager.cc @@ -73,8 +73,7 @@ bool IsSSN(const string16& text) { AutocompleteHistoryManager::AutocompleteHistoryManager( TabContents* tab_contents) : tab_contents_(tab_contents), - pending_query_handle_(0), - query_id_(0) { + pending_query_handle_(0) { DCHECK(tab_contents); profile_ = tab_contents_->profile(); @@ -94,17 +93,17 @@ void AutocompleteHistoryManager::FormSubmitted(const FormData& form) { StoreFormEntriesInWebDatabase(form); } -bool AutocompleteHistoryManager::GetAutocompleteSuggestions( - int query_id, const string16& name, const string16& prefix) { - if (!*autofill_enabled_) - return false; +void AutocompleteHistoryManager::GetAutocompleteSuggestions( + const string16& name, const string16& prefix) { + if (!*autofill_enabled_) { + SendSuggestions(NULL); + return; + } CancelPendingQuery(); - query_id_ = query_id; pending_query_handle_ = web_data_service_->GetFormValuesForElementName( name, prefix, kMaxAutocompleteMenuItems, this); - return true; } void AutocompleteHistoryManager::RemoveAutocompleteEntry( @@ -130,8 +129,7 @@ AutocompleteHistoryManager::AutocompleteHistoryManager( Profile* profile, WebDataService* wds) : tab_contents_(NULL), profile_(profile), web_data_service_(wds), - pending_query_handle_(0), - query_id_(0) { + pending_query_handle_(0) { autofill_enabled_.Init( prefs::kAutoFillEnabled, profile_->GetPrefs(), NULL); } @@ -187,10 +185,8 @@ void AutocompleteHistoryManager::SendSuggestions(const WDTypedResult* result) { DCHECK(result->GetType() == AUTOFILL_VALUE_RESULT); const WDResult<std::vector<string16> >* autofill_result = static_cast<const WDResult<std::vector<string16> >*>(result); - host->AutocompleteSuggestionsReturned( - query_id_, autofill_result->GetValue()); + host->AutocompleteSuggestionsReturned(autofill_result->GetValue()); } else { - host->AutocompleteSuggestionsReturned( - query_id_, std::vector<string16>()); + host->AutocompleteSuggestionsReturned(std::vector<string16>()); } } diff --git a/chrome/browser/autocomplete_history_manager.h b/chrome/browser/autocomplete_history_manager.h index 23493b3..5752942 100644 --- a/chrome/browser/autocomplete_history_manager.h +++ b/chrome/browser/autocomplete_history_manager.h @@ -28,8 +28,7 @@ class AutocompleteHistoryManager // RenderViewHostDelegate::Autocomplete implementation. virtual void FormSubmitted(const webkit_glue::FormData& form); - virtual bool GetAutocompleteSuggestions(int query_id, - const string16& name, + virtual void GetAutocompleteSuggestions(const string16& name, const string16& prefix); virtual void RemoveAutocompleteEntry(const string16& name, const string16& value); @@ -59,7 +58,6 @@ class AutocompleteHistoryManager // is queried on another thread, we record the query handle until we // get called back. WebDataService::Handle pending_query_handle_; - int query_id_; DISALLOW_COPY_AND_ASSIGN(AutocompleteHistoryManager); }; diff --git a/chrome/browser/autofill/autofill_manager.cc b/chrome/browser/autofill/autofill_manager.cc index 6f89173..50b31a0 100644 --- a/chrome/browser/autofill/autofill_manager.cc +++ b/chrome/browser/autofill/autofill_manager.cc @@ -7,6 +7,7 @@ #include <limits> #include <string> +#include "app/l10n_util.h" #include "base/basictypes.h" #include "base/string16.h" #include "base/utf_string_conversions.h" @@ -22,6 +23,7 @@ #include "chrome/common/chrome_switches.h" #include "chrome/common/pref_names.h" #include "chrome/common/url_constants.h" +#include "grit/generated_resources.h" #include "webkit/glue/form_data.h" #include "webkit/glue/form_field.h" @@ -132,7 +134,7 @@ void AutoFillManager::FormSubmitted(const FormData& form) { // Grab a copy of the form data. upload_form_structure_.reset(new FormStructure(form)); - if (!upload_form_structure_->IsAutoFillable()) + if (!upload_form_structure_->IsAutoFillable(true)) return; // Determine the possible field types and upload the form structure to the @@ -148,8 +150,7 @@ void AutoFillManager::FormsSeen(const std::vector<FormData>& forms) { ParseForms(forms); } -bool AutoFillManager::GetAutoFillSuggestions(int query_id, - bool field_autofilled, +bool AutoFillManager::GetAutoFillSuggestions(bool field_autofilled, const FormField& field) { if (!IsAutoFillEnabled()) return false; @@ -172,7 +173,7 @@ bool AutoFillManager::GetAutoFillSuggestions(int query_id, form = *form_iter; // Don't send suggestions for forms that aren't auto-fillable. - if (!form->IsAutoFillable()) + if (!form->IsAutoFillable(false)) continue; for (std::vector<AutoFillField*>::const_iterator iter = form->begin(); @@ -214,6 +215,30 @@ bool AutoFillManager::GetAutoFillSuggestions(int query_id, if (values.empty()) return false; + // Don't provide AutoFill suggestions when AutoFill is disabled, but provide a + // warning to the user. + if (!form->IsAutoFillable(true)) { + values.assign( + 1, l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_FORM_DISABLED)); + labels.assign(1, string16()); + icons.assign(1, string16()); + unique_ids.assign(1, -1); + host->AutoFillSuggestionsReturned(values, labels, icons, unique_ids); + return true; + } + + // Don't provide credit card suggestions for non-HTTPS pages, but provide a + // warning to the user. + if (!FormIsHTTPS(form) && type.group() == AutoFillType::CREDIT_CARD) { + values.assign( + 1, l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_INSECURE_CONNECTION)); + labels.assign(1, string16()); + icons.assign(1, string16()); + unique_ids.assign(1, -1); + host->AutoFillSuggestionsReturned(values, labels, icons, unique_ids); + return true; + } + // If the form is auto-filled and the renderer is querying for suggestions, // then the user is editing the value of a field. In this case, mimick // autocomplete. In particular, don't display labels, as that information is @@ -231,8 +256,7 @@ bool AutoFillManager::GetAutoFillSuggestions(int query_id, } } - host->AutoFillSuggestionsReturned( - query_id, values, labels, icons, unique_ids); + host->AutoFillSuggestionsReturned(values, labels, icons, unique_ids); return true; } @@ -525,10 +549,6 @@ void AutoFillManager::GetCreditCardSuggestions(FormStructure* form, std::vector<string16>* labels, std::vector<string16>* icons, std::vector<int>* unique_ids) { - // Don't return CC suggestions for non-HTTPS pages. - if (!FormIsHTTPS(form)) - return; - for (std::vector<CreditCard*>::const_iterator iter = personal_data_->credit_cards().begin(); iter != personal_data_->credit_cards().end(); ++iter) { @@ -599,22 +619,33 @@ void AutoFillManager::FillPhoneNumberField(const AutoFillProfile* profile, } } -void AutoFillManager::ParseForms( - const std::vector<webkit_glue::FormData>& forms) { - for (std::vector<FormData>::const_iterator iter = - forms.begin(); +void AutoFillManager::ParseForms(const std::vector<FormData>& forms) { + std::vector<FormStructure *> non_queryable_forms; + for (std::vector<FormData>::const_iterator iter = forms.begin(); iter != forms.end(); ++iter) { scoped_ptr<FormStructure> form_structure(new FormStructure(*iter)); - if (!form_structure->ShouldBeParsed()) + if (!form_structure->ShouldBeParsed(false)) continue; DeterminePossibleFieldTypes(form_structure.get()); - form_structures_.push_back(form_structure.release()); + + // Set aside forms with method GET so that they are not included in the + // query to the server. + if (form_structure->ShouldBeParsed(true)) + form_structures_.push_back(form_structure.release()); + else + non_queryable_forms.push_back(form_structure.release()); } // If none of the forms were parsed, no use querying the server. if (!form_structures_.empty() && !disable_download_manager_requests_) download_manager_.StartQueryRequest(form_structures_); + + for (std::vector<FormStructure *>::const_iterator iter = + non_queryable_forms.begin(); + iter != non_queryable_forms.end(); ++iter) { + form_structures_.push_back(*iter); + } } // When sending IDs (across processes) to the renderer we pack credit card and diff --git a/chrome/browser/autofill/autofill_manager.h b/chrome/browser/autofill/autofill_manager.h index b0b87bb..60e1468 100644 --- a/chrome/browser/autofill/autofill_manager.h +++ b/chrome/browser/autofill/autofill_manager.h @@ -50,8 +50,7 @@ class AutoFillManager : public RenderViewHostDelegate::AutoFill, // RenderViewHostDelegate::AutoFill implementation: virtual void FormSubmitted(const webkit_glue::FormData& form); virtual void FormsSeen(const std::vector<webkit_glue::FormData>& forms); - virtual bool GetAutoFillSuggestions(int query_id, - bool field_autofilled, + virtual bool GetAutoFillSuggestions(bool field_autofilled, const webkit_glue::FormField& field); virtual bool FillAutoFillFormData(int query_id, const webkit_glue::FormData& form, diff --git a/chrome/browser/autofill/autofill_manager_unittest.cc b/chrome/browser/autofill/autofill_manager_unittest.cc index 264dc80..182148d 100644 --- a/chrome/browser/autofill/autofill_manager_unittest.cc +++ b/chrome/browser/autofill/autofill_manager_unittest.cc @@ -4,6 +4,7 @@ #include <vector> +#include "app/l10n_util.h" #include "base/ref_counted.h" #include "base/scoped_ptr.h" #include "base/scoped_vector.h" @@ -23,6 +24,7 @@ #include "chrome/common/pref_names.h" #include "chrome/common/render_messages.h" #include "googleurl/src/gurl.h" +#include "grit/generated_resources.h" #include "testing/gtest/include/gtest/gtest.h" #include "webkit/glue/form_data.h" #include "webkit/glue/form_field.h" @@ -59,6 +61,14 @@ class TestPersonalDataManager : public PersonalDataManager { web_profiles_->push_back(profile); } + void ClearAutoFillProfiles() { + web_profiles_.reset(); + } + + void ClearCreditCards() { + credit_cards_.reset(); + } + private: void CreateTestAutoFillProfiles(ScopedVector<AutoFillProfile>* profiles) { AutoFillProfile* profile = new AutoFillProfile; @@ -110,7 +120,8 @@ class TestAutoFillManager : public AutoFillManager { public: TestAutoFillManager(TabContents* tab_contents, TestPersonalDataManager* personal_manager) - : AutoFillManager(tab_contents, NULL) { + : AutoFillManager(tab_contents, NULL), + autofill_enabled_(true) { test_personal_data_ = personal_manager; set_personal_data_manager(personal_manager); // Download manager requests are disabled for purposes of this unit-test. @@ -118,7 +129,11 @@ class TestAutoFillManager : public AutoFillManager { set_disable_download_manager_requests(true); } - virtual bool IsAutoFillEnabled() const { return true; } + virtual bool IsAutoFillEnabled() const { return autofill_enabled_; } + + void set_autofill_enabled(bool autofill_enabled) { + autofill_enabled_ = autofill_enabled; + } AutoFillProfile* GetLabeledProfile(const char* label) { return test_personal_data_->GetLabeledProfile(label); @@ -130,6 +145,7 @@ class TestAutoFillManager : public AutoFillManager { private: TestPersonalDataManager* test_personal_data_; + bool autofill_enabled_; DISALLOW_COPY_AND_ASSIGN(TestAutoFillManager); }; @@ -293,11 +309,12 @@ TEST_F(AutoFillManagerTest, GetProfileSuggestionsEmptyValue) { webkit_glue::FormField field; autofill_test::CreateTestFormField( "First Name", "firstname", "", "text", &field); - EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); + rvh()->ResetAutoFillState(kPageID); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field)); // No suggestions provided, so send an empty vector as the results. // This triggers the combined message send. - rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>()); + rvh()->AutocompleteSuggestionsReturned(std::vector<string16>()); // Test that we sent the right message to the renderer. int page_id = 0; @@ -338,11 +355,12 @@ TEST_F(AutoFillManagerTest, GetProfileSuggestionsMatchCharacter) { webkit_glue::FormField field; autofill_test::CreateTestFormField( "First Name", "firstname", "E", "text", &field); - EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); + rvh()->ResetAutoFillState(kPageID); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field)); // No suggestions provided, so send an empty vector as the results. // This triggers the combined message send. - rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>()); + rvh()->AutocompleteSuggestionsReturned(std::vector<string16>()); // Test that we sent the right message to the renderer. int page_id = 0; @@ -394,8 +412,109 @@ TEST_F(AutoFillManagerTest, GetProfileSuggestionsUnknownFields) { autofill_test::CreateTestFormField( "Username", "username", "", "text", &field); + rvh()->ResetAutoFillState(kPageID); EXPECT_FALSE( - autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); + autofill_manager_->GetAutoFillSuggestions(false, field)); +} + +// Test that we return no suggestions when autofill is disabled. +TEST_F(AutoFillManagerTest, GetProfileSuggestionsAutofillDisabledByUser) { + FormData form; + CreateTestAddressFormData(&form); + + // Set up our FormStructures. + std::vector<FormData> forms; + forms.push_back(form); + autofill_manager_->FormsSeen(forms); + + // Disable AutoFill. + autofill_manager_->set_autofill_enabled(false); + + // The page ID sent to the AutoFillManager from the RenderView, used to send + // an IPC message back to the renderer. + const int kPageID = 1; + + webkit_glue::FormField field; + autofill_test::CreateTestFormField( + "First Name", "firstname", "", "text", &field); + rvh()->ResetAutoFillState(kPageID); + EXPECT_FALSE(autofill_manager_->GetAutoFillSuggestions(false, field)); +} + +// Test that we return a warning explaining that autofill suggestions are +// unavailable when the form method is GET rather than POST. +TEST_F(AutoFillManagerTest, GetProfileSuggestionsMethodGet) { + FormData form; + CreateTestAddressFormData(&form); + form.method = ASCIIToUTF16("GET"); + + // Set up our FormStructures. + std::vector<FormData> forms; + forms.push_back(form); + autofill_manager_->FormsSeen(forms); + + // The page ID sent to the AutoFillManager from the RenderView, used to send + // an IPC message back to the renderer. + const int kPageID = 1; + + webkit_glue::FormField field; + autofill_test::CreateTestFormField( + "First Name", "firstname", "", "text", &field); + rvh()->ResetAutoFillState(kPageID); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field)); + + // No suggestions provided, so send an empty vector as the results. + // This triggers the combined message send. + rvh()->AutocompleteSuggestionsReturned(std::vector<string16>()); + + // Test that we sent the right message to the renderer. + int page_id = 0; + std::vector<string16> values; + std::vector<string16> labels; + std::vector<string16> icons; + EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, + &icons)); + EXPECT_EQ(kPageID, page_id); + ASSERT_EQ(1U, values.size()); + EXPECT_EQ(l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_FORM_DISABLED), + values[0]); + ASSERT_EQ(1U, labels.size()); + EXPECT_EQ(string16(), labels[0]); + ASSERT_EQ(1U, icons.size()); + EXPECT_EQ(string16(), icons[0]); + + // Now add some Autocomplete suggestions. We should return the autocomplete + // suggestions and the warning; these will be culled by the renderer. + process()->sink().ClearMessages(); + const int kPageID2 = 2; + rvh()->ResetAutoFillState(kPageID2); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field)); + + std::vector<string16> suggestions; + suggestions.push_back(ASCIIToUTF16("Jay")); + suggestions.push_back(ASCIIToUTF16("Jason")); + rvh()->AutocompleteSuggestionsReturned(suggestions); + + EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, + &icons)); + EXPECT_EQ(kPageID2, page_id); + ASSERT_EQ(3U, values.size()); + EXPECT_EQ(l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_FORM_DISABLED), + values[0]); + EXPECT_EQ(ASCIIToUTF16("Jay"), values[1]); + EXPECT_EQ(ASCIIToUTF16("Jason"), values[2]); + ASSERT_EQ(3U, labels.size()); + EXPECT_EQ(string16(), labels[0]); + EXPECT_EQ(string16(), labels[1]); + EXPECT_EQ(string16(), labels[2]); + ASSERT_EQ(3U, icons.size()); + EXPECT_EQ(string16(), icons[0]); + EXPECT_EQ(string16(), icons[1]); + EXPECT_EQ(string16(), icons[2]); + + // Now clear the test profiles and try again -- we shouldn't return a warning. + test_personal_data_->ClearAutoFillProfiles(); + EXPECT_FALSE(autofill_manager_->GetAutoFillSuggestions(false, field)); } // Test that we return all credit card profile suggestions when all form fields @@ -416,11 +535,12 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsEmptyValue) { webkit_glue::FormField field; autofill_test::CreateTestFormField( "Card Number", "cardnumber", "", "text", &field); - EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); + rvh()->ResetAutoFillState(kPageID); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field)); // No suggestions provided, so send an empty vector as the results. // This triggers the combined message send. - rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>()); + rvh()->AutocompleteSuggestionsReturned(std::vector<string16>()); // Test that we sent the right message to the renderer. int page_id = 0; @@ -459,11 +579,12 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsMatchCharacter) { webkit_glue::FormField field; autofill_test::CreateTestFormField( "Card Number", "cardnumber", "4", "text", &field); - EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); + rvh()->ResetAutoFillState(kPageID); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field)); // No suggestions provided, so send an empty vector as the results. // This triggers the combined message send. - rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>()); + rvh()->AutocompleteSuggestionsReturned(std::vector<string16>()); // Test that we sent the right message to the renderer. int page_id = 0; @@ -499,11 +620,12 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsNonCCNumber) { webkit_glue::FormField field; autofill_test::CreateTestFormField( "Name on Card", "nameoncard", "", "text", &field); - EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); + rvh()->ResetAutoFillState(kPageID); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field)); // No suggestions provided, so send an empty vector as the results. // This triggers the combined message send. - rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>()); + rvh()->AutocompleteSuggestionsReturned(std::vector<string16>()); // Test that we sent the right message to the renderer. int page_id = 0; @@ -524,8 +646,8 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsNonCCNumber) { EXPECT_EQ(ASCIIToUTF16("masterCardCC"), icons[1]); } -// Test that we return no credit card profile suggestions when the form is not -// https. +// Test that we return a warning explaining that credit card profile suggestions +// are unavailable when the form is not https. TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsNonHTTPS) { FormData form; CreateTestCreditCardFormData(&form, false); @@ -542,8 +664,61 @@ TEST_F(AutoFillManagerTest, GetCreditCardSuggestionsNonHTTPS) { webkit_glue::FormField field; autofill_test::CreateTestFormField( "Card Number", "cardnumber", "", "text", &field); - EXPECT_FALSE( - autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); + rvh()->ResetAutoFillState(kPageID); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field)); + + // No suggestions provided, so send an empty vector as the results. + // This triggers the combined message send. + rvh()->AutocompleteSuggestionsReturned(std::vector<string16>()); + + // Test that we sent the right message to the renderer. + int page_id = 0; + std::vector<string16> values; + std::vector<string16> labels; + std::vector<string16> icons; + EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, + &icons)); + EXPECT_EQ(kPageID, page_id); + ASSERT_EQ(1U, values.size()); + EXPECT_EQ(l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_INSECURE_CONNECTION), + values[0]); + ASSERT_EQ(1U, labels.size()); + EXPECT_EQ(string16(), labels[0]); + ASSERT_EQ(1U, icons.size()); + EXPECT_EQ(string16(), icons[0]); + + // Now add some Autocomplete suggestions. We should show the autocomplete + // suggestions and the warning. + process()->sink().ClearMessages(); + const int kPageID2 = 2; + rvh()->ResetAutoFillState(kPageID2); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field)); + + std::vector<string16> suggestions; + suggestions.push_back(ASCIIToUTF16("Jay")); + suggestions.push_back(ASCIIToUTF16("Jason")); + rvh()->AutocompleteSuggestionsReturned(suggestions); + + EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, + &icons)); + EXPECT_EQ(kPageID2, page_id); + ASSERT_EQ(3U, values.size()); + EXPECT_EQ(l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_INSECURE_CONNECTION), + values[0]); + EXPECT_EQ(ASCIIToUTF16("Jay"), values[1]); + EXPECT_EQ(ASCIIToUTF16("Jason"), values[2]); + ASSERT_EQ(3U, labels.size()); + EXPECT_EQ(string16(), labels[0]); + EXPECT_EQ(string16(), labels[1]); + EXPECT_EQ(string16(), labels[2]); + ASSERT_EQ(3U, icons.size()); + EXPECT_EQ(string16(), icons[0]); + EXPECT_EQ(string16(), icons[1]); + EXPECT_EQ(string16(), icons[2]); + + // Clear the test credit cards and try again -- we shouldn't return a warning. + test_personal_data_->ClearCreditCards(); + EXPECT_FALSE(autofill_manager_->GetAutoFillSuggestions(false, field)); } // Test that we return profile and credit card suggestions for combined forms. @@ -564,11 +739,12 @@ TEST_F(AutoFillManagerTest, GetAddressAndCreditCardSuggestions) { webkit_glue::FormField field; autofill_test::CreateTestFormField( "First Name", "firstname", "", "text", &field); - EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); + rvh()->ResetAutoFillState(kPageID); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field)); // No suggestions provided, so send an empty vector as the results. // This triggers the combined message send. - rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>()); + rvh()->AutocompleteSuggestionsReturned(std::vector<string16>()); // Test that we sent the right address suggestions to the renderer. int page_id = 0; @@ -593,11 +769,12 @@ TEST_F(AutoFillManagerTest, GetAddressAndCreditCardSuggestions) { process()->sink().ClearMessages(); autofill_test::CreateTestFormField( "Card Number", "cardnumber", "", "text", &field); - EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); + rvh()->ResetAutoFillState(kPageID); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field)); // No suggestions provided, so send an empty vector as the results. // This triggers the combined message send. - rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>()); + rvh()->AutocompleteSuggestionsReturned(std::vector<string16>()); // Test that we sent the credit card suggestions to the renderer. page_id = 0; @@ -616,7 +793,9 @@ TEST_F(AutoFillManagerTest, GetAddressAndCreditCardSuggestions) { } // Test that for non-https forms with both address and credit card fields, we -// only return address suggestions. +// only return address suggestions. Instead of credit card suggestions, we +// should return a warning explaining that credit card profile suggestions are +// unavailable when the form is not https. TEST_F(AutoFillManagerTest, GetAddressAndCreditCardSuggestionsNonHttps) { FormData form; CreateTestAddressFormData(&form); @@ -634,11 +813,12 @@ TEST_F(AutoFillManagerTest, GetAddressAndCreditCardSuggestionsNonHttps) { webkit_glue::FormField field; autofill_test::CreateTestFormField( "First Name", "firstname", "", "text", &field); - EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); + rvh()->ResetAutoFillState(kPageID); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field)); // No suggestions provided, so send an empty vector as the results. // This triggers the combined message send. - rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>()); + rvh()->AutocompleteSuggestionsReturned(std::vector<string16>()); // Test that we sent the right address suggestions to the renderer. int page_id = 0; @@ -660,10 +840,31 @@ TEST_F(AutoFillManagerTest, GetAddressAndCreditCardSuggestionsNonHttps) { EXPECT_EQ(string16(), icons[0]); EXPECT_EQ(string16(), icons[1]); + process()->sink().ClearMessages(); autofill_test::CreateTestFormField( "Card Number", "cardnumber", "", "text", &field); - EXPECT_FALSE( - autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); + rvh()->ResetAutoFillState(kPageID); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field)); + + // No suggestions provided, so send an empty vector as the results. + // This triggers the combined message send. + rvh()->AutocompleteSuggestionsReturned(std::vector<string16>()); + + // Test that we sent the right message to the renderer. + EXPECT_TRUE(GetAutoFillSuggestionsMessage(&page_id, &values, &labels, + &icons)); + EXPECT_EQ(kPageID, page_id); + ASSERT_EQ(1U, values.size()); + EXPECT_EQ(l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_INSECURE_CONNECTION), + values[0]); + ASSERT_EQ(1U, labels.size()); + EXPECT_EQ(string16(), labels[0]); + ASSERT_EQ(1U, icons.size()); + EXPECT_EQ(string16(), icons[0]); + + // Clear the test credit cards and try again -- we shouldn't return a warning. + test_personal_data_->ClearCreditCards(); + EXPECT_FALSE(autofill_manager_->GetAutoFillSuggestions(false, field)); } // Test that we correctly combine autofill and autocomplete suggestions. @@ -683,14 +884,15 @@ TEST_F(AutoFillManagerTest, GetCombinedAutoFillAndAutocompleteSuggestions) { webkit_glue::FormField field; autofill_test::CreateTestFormField( "First Name", "firstname", "", "text", &field); - EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, false, field)); + rvh()->ResetAutoFillState(kPageID); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(false, field)); // Add some Autocomplete suggestions. // This triggers the combined message send. std::vector<string16> suggestions; suggestions.push_back(ASCIIToUTF16("Jay")); suggestions.push_back(ASCIIToUTF16("Jason")); - rvh()->AutocompleteSuggestionsReturned(kPageID, suggestions); + rvh()->AutocompleteSuggestionsReturned(suggestions); // Test that we sent the right message to the renderer. int page_id = 0; @@ -735,11 +937,12 @@ TEST_F(AutoFillManagerTest, GetFieldSuggestionsFieldIsAutoFilled) { webkit_glue::FormField field; autofill_test::CreateTestFormField( "First Name", "firstname", "", "text", &field); - EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, true, field)); + rvh()->ResetAutoFillState(kPageID); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(true, field)); // No suggestions provided, so send an empty vector as the results. // This triggers the combined message send. - rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>()); + rvh()->AutocompleteSuggestionsReturned(std::vector<string16>()); // Test that we sent the right message to the renderer. int page_id = 0; @@ -778,14 +981,15 @@ TEST_F(AutoFillManagerTest, GetFieldSuggestionsForAutocompleteOnly) { webkit_glue::FormField field; autofill_test::CreateTestFormField( "Some Field", "somefield", "", "text", &field); - EXPECT_FALSE(autofill_manager_->GetAutoFillSuggestions(kPageID, true, field)); + rvh()->ResetAutoFillState(kPageID); + EXPECT_FALSE(autofill_manager_->GetAutoFillSuggestions(true, field)); // Add some Autocomplete suggestions. // This triggers the combined message send. std::vector<string16> suggestions; suggestions.push_back(ASCIIToUTF16("one")); suggestions.push_back(ASCIIToUTF16("two")); - rvh()->AutocompleteSuggestionsReturned(kPageID, suggestions); + rvh()->AutocompleteSuggestionsReturned(suggestions); // Test that we sent the right message to the renderer. int page_id = 0; @@ -830,11 +1034,12 @@ TEST_F(AutoFillManagerTest, GetFieldSuggestionsWithDuplicateValues) { webkit_glue::FormField field; autofill_test::CreateTestFormField( "First Name", "firstname", "", "text", &field); - EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(kPageID, true, field)); + rvh()->ResetAutoFillState(kPageID); + EXPECT_TRUE(autofill_manager_->GetAutoFillSuggestions(true, field)); // No suggestions provided, so send an empty vector as the results. // This triggers the combined message send. - rvh()->AutocompleteSuggestionsReturned(kPageID, std::vector<string16>()); + rvh()->AutocompleteSuggestionsReturned(std::vector<string16>()); // Test that we sent the right message to the renderer. int page_id = 0; diff --git a/chrome/browser/autofill/form_structure.cc b/chrome/browser/autofill/form_structure.cc index 0eab86b..b5b2db7 100644 --- a/chrome/browser/autofill/form_structure.cc +++ b/chrome/browser/autofill/form_structure.cc @@ -107,7 +107,7 @@ bool FormStructure::EncodeUploadRequest(bool auto_fill_used, std::string* encoded_xml) const { DCHECK(encoded_xml); encoded_xml->clear(); - bool auto_fillable = IsAutoFillable(); + bool auto_fillable = IsAutoFillable(false); DCHECK(auto_fillable); // Caller should've checked for search pages. if (!auto_fillable) return false; @@ -232,8 +232,6 @@ void FormStructure::ParseQueryResponse(const std::string& response_xml, form->UpdateAutoFillCount(); } - - return; } std::string FormStructure::FormSignature() const { @@ -247,11 +245,11 @@ std::string FormStructure::FormSignature() const { return Hash64Bit(form_string); } -bool FormStructure::IsAutoFillable() const { +bool FormStructure::IsAutoFillable(bool require_method_post) const { if (autofill_count() < kRequiredFillableFields) return false; - return ShouldBeParsed(); + return ShouldBeParsed(require_method_post); } bool FormStructure::HasAutoFillableValues() const { @@ -268,46 +266,6 @@ bool FormStructure::HasAutoFillableValues() const { return false; } -// TODO(jhawkins): Cache this result. -bool FormStructure::HasBillingFields() const { - for (std::vector<AutoFillField*>::const_iterator iter = begin(); - iter != end(); ++iter) { - if (!*iter) - return false; - - AutoFillField* field = *iter; - if (!field) - continue; - - AutoFillType type(field->type()); - if (type.group() == AutoFillType::ADDRESS_BILLING || - type.group() == AutoFillType::CREDIT_CARD) - return true; - } - - return false; -} - -// TODO(jhawkins): Cache this result. -bool FormStructure::HasNonBillingFields() const { - for (std::vector<AutoFillField*>::const_iterator iter = begin(); - iter != end(); ++iter) { - if (!*iter) - return false; - - AutoFillField* field = *iter; - if (!field) - continue; - - AutoFillType type(field->type()); - if (type.group() != AutoFillType::ADDRESS_BILLING && - type.group() != AutoFillType::CREDIT_CARD) - return true; - } - - return false; -} - void FormStructure::UpdateAutoFillCount() { autofill_count_ = 0; for (std::vector<AutoFillField*>::const_iterator iter = begin(); @@ -318,7 +276,7 @@ void FormStructure::UpdateAutoFillCount() { } } -bool FormStructure::ShouldBeParsed() const { +bool FormStructure::ShouldBeParsed(bool require_method_post) const { if (field_count() < kRequiredFillableFields) return false; @@ -328,10 +286,7 @@ bool FormStructure::ShouldBeParsed() const { if (target_url_.path() == "/search") return false; - if (method_ == GET) - return false; - - return true; + return !require_method_post || (method_ == POST); } void FormStructure::set_possible_types(int index, const FieldTypeSet& types) { diff --git a/chrome/browser/autofill/form_structure.h b/chrome/browser/autofill/form_structure.h index 77e106f4..fe4c5da 100644 --- a/chrome/browser/autofill/form_structure.h +++ b/chrome/browser/autofill/form_structure.h @@ -61,22 +61,15 @@ class FormStructure { // the form name, and the form field names in a 64-bit hash. std::string FormSignature() const; - // Runs a quick heuristic to rule out pages but obviously not auto-fillable, - // like google/yahoo/msn search, etc. - bool IsAutoFillable() const; + // Runs a quick heuristic to rule out forms that are obviously not + // auto-fillable, like google/yahoo/msn search, etc. The requirement that the + // form's method be POST is only applied if |require_method_post| is true. + bool IsAutoFillable(bool require_method_post) const; // Returns true if at least one of the form fields relevant for AutoFill // is not empty. bool HasAutoFillableValues() const; - // Returns true if at least one of the form fields is a billing field, which - // includes billing address fields and credit card fields. - bool HasBillingFields() const; - - // Returns true if at least one of the form fields is a non-billing field, - // which includes billing address fields and credit card fields. - bool HasNonBillingFields() const; - // Resets |autofill_count_| and counts the number of auto-fillable fields. // This is used when we receive server data for form fields. At that time, // we may have more known fields than just the number of fields we matched @@ -84,7 +77,9 @@ class FormStructure { void UpdateAutoFillCount(); // Returns true if this form matches the structural requirements for AutoFill. - bool ShouldBeParsed() const; + // The requirement that the form's method be POST is only applied if + // |require_method_post| is true. + bool ShouldBeParsed(bool require_method_post) const; // Sets the possible types for the field at |index|. void set_possible_types(int index, const FieldTypeSet& types); diff --git a/chrome/browser/autofill/form_structure_unittest.cc b/chrome/browser/autofill/form_structure_unittest.cc index b5881d6..8eb03fd 100644 --- a/chrome/browser/autofill/form_structure_unittest.cc +++ b/chrome/browser/autofill/form_structure_unittest.cc @@ -199,7 +199,7 @@ TEST(FormStructureTest, IsAutoFillable) { ASCIIToUTF16("submit"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_FALSE(form_structure->IsAutoFillable()); + EXPECT_FALSE(form_structure->IsAutoFillable(true)); // We now have three text fields, but only two auto-fillable fields. form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("First Name"), @@ -213,7 +213,7 @@ TEST(FormStructureTest, IsAutoFillable) { ASCIIToUTF16("text"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_FALSE(form_structure->IsAutoFillable()); + EXPECT_FALSE(form_structure->IsAutoFillable(true)); // We now have three auto-fillable fields. form.fields.push_back(webkit_glue::FormField(ASCIIToUTF16("Email"), @@ -222,23 +222,25 @@ TEST(FormStructureTest, IsAutoFillable) { ASCIIToUTF16("text"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable()); + EXPECT_TRUE(form_structure->IsAutoFillable(true)); - // The method must be 'post'. + // The method must be 'post', though we can intentionally ignore this + // criterion for the sake of providing a helpful warning message to the user. form.method = ASCIIToUTF16("get"); form_structure.reset(new FormStructure(form)); - EXPECT_FALSE(form_structure->IsAutoFillable()); + EXPECT_FALSE(form_structure->IsAutoFillable(true)); + EXPECT_TRUE(form_structure->IsAutoFillable(false)); // The target cannot include http(s)://*/search... form.method = ASCIIToUTF16("post"); form.action = GURL("http://google.com/search?q=hello"); form_structure.reset(new FormStructure(form)); - EXPECT_FALSE(form_structure->IsAutoFillable()); + EXPECT_FALSE(form_structure->IsAutoFillable(true)); // But search can be in the URL. form.action = GURL("http://search.com/?q=hello"); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable()); + EXPECT_TRUE(form_structure->IsAutoFillable(true)); } TEST(FormStructureTest, HeuristicsContactInfo) { @@ -292,7 +294,7 @@ TEST(FormStructureTest, HeuristicsContactInfo) { ASCIIToUTF16("submit"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable()); + EXPECT_TRUE(form_structure->IsAutoFillable(true)); // Expect the correct number of fields. ASSERT_EQ(9U, form_structure->field_count()); @@ -410,7 +412,7 @@ TEST(FormStructureTest, HeuristicsHiddenFields) { ASCIIToUTF16("submit"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable()); + EXPECT_TRUE(form_structure->IsAutoFillable(true)); // Expect the correct number of fields. ASSERT_EQ(17U, form_structure->field_count()); @@ -503,7 +505,7 @@ TEST(FormStructureTest, HeuristicsSample8) { ASCIIToUTF16("submit"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable()); + EXPECT_TRUE(form_structure->IsAutoFillable(true)); ASSERT_EQ(10U, form_structure->field_count()); ASSERT_EQ(9U, form_structure->autofill_count()); @@ -581,7 +583,7 @@ TEST(FormStructureTest, HeuristicsSample6) { ASCIIToUTF16("submit"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable()); + EXPECT_TRUE(form_structure->IsAutoFillable(true)); ASSERT_EQ(7U, form_structure->field_count()); ASSERT_EQ(6U, form_structure->autofill_count()); @@ -655,7 +657,7 @@ TEST(FormStructureTest, HeuristicsLabelsOnly) { ASCIIToUTF16("submit"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable()); + EXPECT_TRUE(form_structure->IsAutoFillable(true)); ASSERT_EQ(9U, form_structure->field_count()); ASSERT_EQ(8U, form_structure->autofill_count()); @@ -716,7 +718,7 @@ TEST(FormStructureTest, HeuristicsCreditCardInfo) { ASCIIToUTF16("submit"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable()); + EXPECT_TRUE(form_structure->IsAutoFillable(true)); ASSERT_EQ(6U, form_structure->field_count()); ASSERT_EQ(4U, form_structure->autofill_count()); @@ -778,7 +780,7 @@ TEST(FormStructureTest, HeuristicsCreditCardInfoWithUnknownCardField) { ASCIIToUTF16("submit"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable()); + EXPECT_TRUE(form_structure->IsAutoFillable(true)); ASSERT_EQ(7U, form_structure->field_count()); ASSERT_EQ(4U, form_structure->autofill_count()); @@ -829,7 +831,7 @@ TEST(FormStructureTest, ThreeAddressLines) { ASCIIToUTF16("text"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable()); + EXPECT_TRUE(form_structure->IsAutoFillable(true)); ASSERT_EQ(4U, form_structure->field_count()); ASSERT_EQ(3U, form_structure->autofill_count()); @@ -875,7 +877,7 @@ TEST(FormStructureTest, BillingAndShippingAddresses) { ASCIIToUTF16("text"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable()); + EXPECT_TRUE(form_structure->IsAutoFillable(true)); ASSERT_EQ(4U, form_structure->field_count()); ASSERT_EQ(4U, form_structure->autofill_count()); @@ -925,7 +927,7 @@ TEST(FormStructureTest, ThreeAddressLinesExpedia) { ASCIIToUTF16("text"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable()); + EXPECT_TRUE(form_structure->IsAutoFillable(true)); ASSERT_EQ(4U, form_structure->field_count()); ASSERT_EQ(3U, form_structure->autofill_count()); @@ -966,7 +968,7 @@ TEST(FormStructureTest, TwoAddressLinesEbay) { ASCIIToUTF16("text"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable()); + EXPECT_TRUE(form_structure->IsAutoFillable(true)); ASSERT_EQ(3U, form_structure->field_count()); ASSERT_EQ(3U, form_structure->autofill_count()); @@ -1002,7 +1004,7 @@ TEST(FormStructureTest, HeuristicsStateWithProvince) { ASCIIToUTF16("text"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable()); + EXPECT_TRUE(form_structure->IsAutoFillable(true)); ASSERT_EQ(3U, form_structure->field_count()); ASSERT_EQ(3U, form_structure->autofill_count()); @@ -1087,7 +1089,7 @@ TEST(FormStructureTest, HeuristicsWithBilling) { ASCIIToUTF16("text"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable()); + EXPECT_TRUE(form_structure->IsAutoFillable(true)); ASSERT_EQ(11U, form_structure->field_count()); ASSERT_EQ(11U, form_structure->autofill_count()); @@ -1136,7 +1138,7 @@ TEST(FormStructureTest, ThreePartPhoneNumber) { ASCIIToUTF16("text"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable()); + EXPECT_TRUE(form_structure->IsAutoFillable(true)); ASSERT_EQ(4U, form_structure->field_count()); ASSERT_EQ(3U, form_structure->autofill_count()); @@ -1207,7 +1209,7 @@ TEST(FormStructureTest, MatchSpecificInputTypes) { ASCIIToUTF16("submit"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable()); + EXPECT_TRUE(form_structure->IsAutoFillable(true)); // Expect the correct number of fields. ASSERT_EQ(10U, form_structure->field_count()); @@ -1266,7 +1268,7 @@ TEST(FormStructureTest, HeuristicsInfernoCC) { ASCIIToUTF16("text"), 0)); form_structure.reset(new FormStructure(form)); - EXPECT_TRUE(form_structure->IsAutoFillable()); + EXPECT_TRUE(form_structure->IsAutoFillable(true)); // Expect the correct number of fields. ASSERT_EQ(5U, form_structure->field_count()); diff --git a/chrome/browser/chromeos/login/account_creation_view.cc b/chrome/browser/chromeos/login/account_creation_view.cc index 82ff793..0719c4e 100644 --- a/chrome/browser/chromeos/login/account_creation_view.cc +++ b/chrome/browser/chromeos/login/account_creation_view.cc @@ -54,8 +54,8 @@ class AccountCreationTabContents : public WizardWebPageViewTabContents, virtual void FormsSeen(const std::vector<FormData>& forms) { } - virtual bool GetAutoFillSuggestions( - int query_id, bool form_autofilled, const webkit_glue::FormField& field) { + virtual bool GetAutoFillSuggestions(bool field_autofilled, + const webkit_glue::FormField& field) { return false; } diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index aaebf9f..f2bffa7 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -1690,33 +1690,27 @@ void RenderViewHost::OnMsgShouldCloseACK(bool proceed) { } void RenderViewHost::OnQueryFormFieldAutoFill( - int query_id, bool form_autofilled, const webkit_glue::FormField& field) { + int query_id, bool field_autofilled, const webkit_glue::FormField& field) { + ResetAutoFillState(query_id); + + // We first query the autofill delegate for suggestions. We keep track of the + // results it gives us, which we will later combine with the autocomplete + // suggestions. RenderViewHostDelegate::AutoFill* autofill_delegate = delegate_->GetAutoFillDelegate(); - // We first save the AutoFill delegate's suggestions. Then we fetch the - // Autocomplete delegate's suggestions and send the combined results back to - // the render view. - if (autofill_delegate && - autofill_delegate->GetAutoFillSuggestions(query_id, - form_autofilled, - field)) { - } else { - // No suggestions provided, so supply an empty vector as the results. - AutoFillSuggestionsReturned(query_id, - std::vector<string16>(), - std::vector<string16>(), - std::vector<string16>(), - std::vector<int>()); + if (autofill_delegate) { + autofill_delegate->GetAutoFillSuggestions(field_autofilled, field); } + // Now query the Autocomplete delegate for suggestions. These will be combined + // with the saved autofill suggestions in |AutocompleteSuggestionsReturned()|. RenderViewHostDelegate::Autocomplete* autocomplete_delegate = delegate_->GetAutocompleteDelegate(); - if (autocomplete_delegate && - autocomplete_delegate->GetAutocompleteSuggestions( - query_id, field.name(), field.value())) { + if (autocomplete_delegate) { + autocomplete_delegate->GetAutocompleteSuggestions(field.name(), + field.value()); } else { - // No suggestions provided, so send an empty vector as the results. - AutocompleteSuggestionsReturned(query_id, std::vector<string16>()); + AutocompleteSuggestionsReturned(std::vector<string16>()); } } @@ -1770,24 +1764,33 @@ void RenderViewHost::OnDidFillAutoFillFormData() { NotificationService::NoDetails()); } +void RenderViewHost::ResetAutoFillState(int query_id) { + autofill_query_id_ = query_id; + + autofill_values_.clear(); + autofill_labels_.clear(); + autofill_icons_.clear(); + autofill_unique_ids_.clear(); +} + void RenderViewHost::AutoFillSuggestionsReturned( - int query_id, - const std::vector<string16>& names, + const std::vector<string16>& values, const std::vector<string16>& labels, const std::vector<string16>& icons, const std::vector<int>& unique_ids) { - autofill_values_.assign(names.begin(), names.end()); + autofill_values_.assign(values.begin(), values.end()); autofill_labels_.assign(labels.begin(), labels.end()); autofill_icons_.assign(icons.begin(), icons.end()); autofill_unique_ids_.assign(unique_ids.begin(), unique_ids.end()); } void RenderViewHost::AutocompleteSuggestionsReturned( - int query_id, const std::vector<string16>& suggestions) { + const std::vector<string16>& suggestions) { // Combine AutoFill and Autocomplete values into values and labels. for (size_t i = 0; i < suggestions.size(); ++i) { bool unique = true; for (size_t j = 0; j < autofill_values_.size(); ++j) { + // TODO(isherman): Why just when the label is empty? // If the AutoFill label is empty, we need to make sure we don't add a // duplicate value. if (autofill_labels_[j].empty() && @@ -1806,7 +1809,7 @@ void RenderViewHost::AutocompleteSuggestionsReturned( } Send(new ViewMsg_AutoFillSuggestionsReturned(routing_id(), - query_id, + autofill_query_id_, autofill_values_, autofill_labels_, autofill_icons_, diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h index 97d1f5b..ba7f552 100644 --- a/chrome/browser/renderer_host/render_view_host.h +++ b/chrome/browser/renderer_host/render_view_host.h @@ -411,18 +411,18 @@ class RenderViewHost : public RenderWidgetHost { // set to false when creating a renderer-initiated window via window.open. void AllowScriptToClose(bool visible); + // Resets the stored AutoFill state. + void ResetAutoFillState(int query_id); + // Called by the AutoFillManager when the list of suggestions is ready. - void AutoFillSuggestionsReturned( - int query_id, - const std::vector<string16>& values, - const std::vector<string16>& labels, - const std::vector<string16>& icons, - const std::vector<int>& unique_ids); + void AutoFillSuggestionsReturned(const std::vector<string16>& values, + const std::vector<string16>& labels, + const std::vector<string16>& icons, + const std::vector<int>& unique_ids); // Called by the AutocompleteHistoryManager when the list of suggestions is // ready. void AutocompleteSuggestionsReturned( - int query_id, const std::vector<string16>& suggestions); // Called by the AutoFillManager when the FormData has been filled out. @@ -802,12 +802,14 @@ class RenderViewHost : public RenderWidgetHost { // what process type we use. bool is_extension_process_; + // TODO(isherman): Consider splitting these off into a helper class. // AutoFill and Autocomplete suggestions. We accumulate these separately and // send them back to the renderer together. std::vector<string16> autofill_values_; std::vector<string16> autofill_labels_; std::vector<string16> autofill_icons_; std::vector<int> autofill_unique_ids_; + int autofill_query_id_; // Whether the accessibility tree should be saved, for unit testing. bool save_accessibility_tree_for_testing_; diff --git a/chrome/browser/renderer_host/render_view_host_delegate.h b/chrome/browser/renderer_host/render_view_host_delegate.h index 020fadc..c3049e1 100644 --- a/chrome/browser/renderer_host/render_view_host_delegate.h +++ b/chrome/browser/renderer_host/render_view_host_delegate.h @@ -521,10 +521,7 @@ class RenderViewHostDelegate { // query. When the database thread is finished, the AutocompleteHistory // manager retrieves the calling RenderViewHost and then passes the vector // of suggestions to RenderViewHost::AutocompleteSuggestionsReturned. - // Returns true to indicate that FormFieldHistorySuggestionsReturned will be - // called. - virtual bool GetAutocompleteSuggestions(int query_id, - const string16& field_name, + virtual void GetAutocompleteSuggestions(const string16& field_name, const string16& user_text) = 0; // Called when the user has indicated that she wants to remove the specified @@ -549,13 +546,13 @@ class RenderViewHostDelegate { virtual void FormsSeen(const std::vector<webkit_glue::FormData>& forms) = 0; // Called to retrieve a list of AutoFill suggestions from the web database - // given the name of the field and what the user has already typed in the - // field. |form_autofilled| is true if the form containing |field| has any - // auto-filled fields. Returns true to indicate that - // RenderViewHost::AutoFillSuggestionsReturned has been called. + // given the name of the field, whether it is auto-filled, and what the user + // has already typed in it. If there is a warning to be returned to the + // user, it is stored into |values|, with corresponding unique id -1. + // Returns true to indicate that RenderViewHost::AutoFillSuggestionsReturned + // has been called. virtual bool GetAutoFillSuggestions( - int query_id, - bool form_autofilled, + bool field_autofilled, const webkit_glue::FormField& field) = 0; // Called to fill the FormData object with AutoFill profile information that |