diff options
author | amit@chromium.org <amit@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-26 22:53:53 +0000 |
---|---|---|
committer | amit@chromium.org <amit@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-26 22:53:53 +0000 |
commit | 643856b25d47fb70ef5b75b5670e6c24a66515f4 (patch) | |
tree | 9d0193551edf46873f12758518363f84908dcc83 | |
parent | a74f519a070b370fb18158018b37a7d3e4f4c160 (diff) | |
download | chromium_src-643856b25d47fb70ef5b75b5670e6c24a66515f4.zip chromium_src-643856b25d47fb70ef5b75b5670e6c24a66515f4.tar.gz chromium_src-643856b25d47fb70ef5b75b5670e6c24a66515f4.tar.bz2 |
Reverting due to test failures on Interactive tests on Mac and Linux
Revert 42846 - Second part of the integration with autofill servers.
1. Corrected signature calculations.
2. Added unittest
3. Fixed numerous issues, including multiple forms on the page, etc.
BUG=none
TEST=should work correctly with more servers.
Review URL: http://codereview.chromium.org/1337001
TBR=georgey@chromium.org
Review URL: http://codereview.chromium.org/1478001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@42850 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/autofill/autofill_download.cc | 122 | ||||
-rw-r--r-- | chrome/browser/autofill/autofill_download.h | 83 | ||||
-rw-r--r-- | chrome/browser/autofill/autofill_download_unittest.cc | 240 | ||||
-rw-r--r-- | chrome/browser/autofill/autofill_manager.cc | 85 | ||||
-rw-r--r-- | chrome/browser/autofill/autofill_manager.h | 11 | ||||
-rw-r--r-- | chrome/browser/autofill/form_structure.cc | 128 | ||||
-rw-r--r-- | chrome/browser/autofill/form_structure.h | 29 | ||||
-rw-r--r-- | chrome/chrome_tests.gypi | 1 |
8 files changed, 155 insertions, 544 deletions
diff --git a/chrome/browser/autofill/autofill_download.cc b/chrome/browser/autofill/autofill_download.cc index 9384474..0d650d1 100644 --- a/chrome/browser/autofill/autofill_download.cc +++ b/chrome/browser/autofill/autofill_download.cc @@ -4,8 +4,6 @@ #include "chrome/browser/autofill/autofill_download.h" -#include <algorithm> - #include "base/logging.h" #include "base/rand_util.h" #include "base/stl_util-inl.h" @@ -26,10 +24,7 @@ const double kAutoFillNegativeUploadRate = 0.01; } // namespace AutoFillDownloadManager::AutoFillDownloadManager() - : observer_(NULL), - positive_upload_rate_(kAutoFillPositiveUploadRate), - negative_upload_rate_(kAutoFillNegativeUploadRate), - fetcher_id_for_unittest_(0) { + : observer_(NULL) { } AutoFillDownloadManager::~AutoFillDownloadManager() { @@ -47,57 +42,48 @@ void AutoFillDownloadManager::SetObserver( } } -bool AutoFillDownloadManager::StartQueryRequest( - const ScopedVector<FormStructure>& forms) { - std::string form_xml; - FormStructure::EncodeQueryRequest(forms, &form_xml); - - FormRequestData request_data; - request_data.form_signatures.reserve(forms.size()); - for (ScopedVector<FormStructure>::const_iterator it = forms.begin(); - it != forms.end(); - ++it) { - request_data.form_signatures.push_back((*it)->FormSignature()); - } - - request_data.request_type = AutoFillDownloadManager::REQUEST_QUERY; - - return StartRequest(form_xml, request_data); -} - -bool AutoFillDownloadManager::StartUploadRequest( - const FormStructure& form, bool form_was_matched) { - // Check if we need to upload form. - // TODO(georgey): adjust this values from returned XML. - double upload_rate = form_was_matched ? positive_upload_rate_ : - negative_upload_rate_; - if (base::RandDouble() > upload_rate) { - LOG(INFO) << "AutoFillDownloadManager: Upload request is ignored"; - if (observer_) - observer_->OnUploadedAutoFillHeuristics(form.FormSignature()); - return true; +bool AutoFillDownloadManager::StartRequest(const std::string& form_xml, + const std::string& form_signature, + bool query_data, + bool form_was_matched) { + if (!query_data) { + // Check if we need to upload form. + double upload_rate = form_was_matched ? kAutoFillPositiveUploadRate : + kAutoFillNegativeUploadRate; + if (base::RandDouble() > upload_rate) { + LOG(INFO) << "AutoFillDownloadManager: Upload request is ignored"; + if (observer_) + observer_->OnUploadedAutoFillHeuristics(form_signature); + return true; + } } - std::string form_xml; - form.EncodeUploadRequest(form_was_matched, &form_xml); - FormRequestData request_data; - request_data.form_signatures.push_back(form.FormSignature()); - request_data.request_type = AutoFillDownloadManager::REQUEST_UPLOAD; + std::string request_url; + if (query_data) + request_url = AUTO_FILL_QUERY_SERVER_REQUEST_URL; + else + request_url = AUTO_FILL_UPLOAD_SERVER_REQUEST_URL; - return StartRequest(form_xml, request_data); + URLFetcher *fetcher = + URLFetcher::Create(0, GURL(request_url), URLFetcher::POST, this); + FormRequestData data; + data.form_signature = form_signature; + data.query = query_data; + url_fetchers_[fetcher] = data; + fetcher->set_request_context(Profile::GetDefaultRequestContext()); + fetcher->set_upload_data("text/plain", form_xml); + fetcher->Start(); + return true; } -bool AutoFillDownloadManager::CancelRequest( - const std::string& form_signature, - AutoFillDownloadManager::AutoFillRequestType request_type) { +bool AutoFillDownloadManager::CancelRequest(const std::string& form_signature, + bool query_data) { for (std::map<URLFetcher *, FormRequestData>::iterator it = url_fetchers_.begin(); it != url_fetchers_.end(); ++it) { - if (std::find(it->second.form_signatures.begin(), - it->second.form_signatures.end(), form_signature) != - it->second.form_signatures.end() && - it->second.request_type == request_type) { + if (it->second.form_signature == form_signature && + it->second.query == query_data) { delete it->first; url_fetchers_.erase(it); return true; @@ -106,29 +92,6 @@ bool AutoFillDownloadManager::CancelRequest( return false; } - -bool AutoFillDownloadManager::StartRequest( - const std::string& form_xml, - const FormRequestData& request_data) { - std::string request_url; - if (request_data.request_type == AutoFillDownloadManager::REQUEST_QUERY) - request_url = AUTO_FILL_QUERY_SERVER_REQUEST_URL; - else - request_url = AUTO_FILL_UPLOAD_SERVER_REQUEST_URL; - - // Id is ignored for regular chrome, in unit test id's for fake fetcher - // factory will be 0, 1, 2, ... - URLFetcher *fetcher = URLFetcher::Create(fetcher_id_for_unittest_++, - GURL(request_url), - URLFetcher::POST, - this); - url_fetchers_[fetcher] = request_data; - fetcher->set_request_context(Profile::GetDefaultRequestContext()); - fetcher->set_upload_data("text/plain", form_xml); - fetcher->Start(); - return true; -} - void AutoFillDownloadManager::OnURLFetchComplete(const URLFetcher* source, const GURL& url, const URLRequestStatus& status, @@ -138,33 +101,26 @@ void AutoFillDownloadManager::OnURLFetchComplete(const URLFetcher* source, std::map<URLFetcher *, FormRequestData>::iterator it = url_fetchers_.find(const_cast<URLFetcher*>(source)); DCHECK(it != url_fetchers_.end()); - std::string type_of_request( - it->second.request_type == AutoFillDownloadManager::REQUEST_QUERY ? - "query" : "upload"); + std::string type_of_request(it->second.query ? "query" : "upload"); const int kHttpResponseOk = 200; - DCHECK(it->second.form_signatures.size()); if (response_code != kHttpResponseOk) { LOG(INFO) << "AutoFillDownloadManager: " << type_of_request << " request has failed with response" << response_code; if (observer_) { - observer_->OnHeuristicsRequestError(it->second.form_signatures[0], - it->second.request_type, + observer_->OnHeuristicsRequestError(it->second.form_signature, response_code); } } else { LOG(INFO) << "AutoFillDownloadManager: " << type_of_request << " request has succeeded"; - if (it->second.request_type == AutoFillDownloadManager::REQUEST_QUERY) { + if (it->second.query) { if (observer_) - observer_->OnLoadedAutoFillHeuristics(it->second.form_signatures, data); + observer_->OnLoadedAutoFillHeuristics(it->second.form_signature, data); } else { - // TODO(georgey): adjust upload probabilities. if (observer_) - observer_->OnUploadedAutoFillHeuristics(it->second.form_signatures[0]); + observer_->OnUploadedAutoFillHeuristics(it->second.form_signature); } } - delete it->first; - url_fetchers_.erase(it); } diff --git a/chrome/browser/autofill/autofill_download.h b/chrome/browser/autofill/autofill_download.h index d064db7a..c9e6ed2 100644 --- a/chrome/browser/autofill/autofill_download.h +++ b/chrome/browser/autofill/autofill_download.h @@ -6,7 +6,6 @@ #define CHROME_BROWSER_AUTOFILL_AUTOFILL_DOWNLOAD_H_ #include <map> -#include <vector> #include <string> #include "base/scoped_ptr.h" @@ -20,18 +19,14 @@ // Handles getting and updating AutoFill heuristics. class AutoFillDownloadManager : public URLFetcher::Delegate { public: - enum AutoFillRequestType { - REQUEST_QUERY, - REQUEST_UPLOAD, - }; // An interface used to notify clients of AutoFillDownloadManager. class Observer { public: // Called when heuristic successfully received from server. - // |form_signatures| - the signatures of the requesting forms. + // |form_signature| - the signature of the requesting form. // |heuristic_xml| - server response. virtual void OnLoadedAutoFillHeuristics( - const std::vector<std::string>& form_signatures, + const std::string& form_signature, const std::string& heuristic_xml) = 0; // Called when heuristic either successfully considered for upload and // not send or uploaded. @@ -40,10 +35,8 @@ class AutoFillDownloadManager : public URLFetcher::Delegate { const std::string& form_signature) = 0; // Called when there was an error during the request. // |form_signature| - the signature of the requesting form. - // |request_type| - type of request that failed. // |http_error| - http error code. virtual void OnHeuristicsRequestError(const std::string& form_signature, - AutoFillRequestType request_type, int http_error) = 0; protected: virtual ~Observer() {} @@ -55,52 +48,21 @@ class AutoFillDownloadManager : public URLFetcher::Delegate { // |observer| - observer to notify on successful completion or error. void SetObserver(AutoFillDownloadManager::Observer *observer); - // Starts a query request to AutoFill servers. The observer is called with the - // list of the fields of all requested forms. - // |forms| - array of forms aggregated in this request. - bool StartQueryRequest(const ScopedVector<FormStructure>& forms); - - // Start upload request if necessary. The probability of request going - // over the wire are |positive_upload_rate_| if it was matched by - // AutoFill, |negative_download_rate_| otherwise. Observer will be called - // even if there was no actual trip over the wire. - // |form| - form sent in this request. - // |form_was_matched| - true if form was matched by the AutoFill. - bool StartUploadRequest(const FormStructure& form, bool form_was_matched); - - // Cancels pending request. - // |form_signature| - signature of the form being cancelled. Warning: - // for query request if more than one form sent in the request, all other - // forms will be cancelled as well. - // |request_type| - type of the request. - bool CancelRequest(const std::string& form_signature, - AutoFillRequestType request_type); - - void SetPositiveUploadRate(double rate) { - DCHECK(rate >= 0.0 && rate <= 1.0); - positive_upload_rate_ = rate; - } - - void SetNegativeUploadRate(double rate) { - DCHECK(rate >= 0.0 && rate <= 1.0); - negative_upload_rate_ = rate; - } - - private: - struct FormRequestData { - std::vector<std::string> form_signatures; - AutoFillRequestType request_type; - }; - - // Initiates request to AutoFill servers to download/upload heuristics. + // Initiates request to AutoFill servers to download/upload heuristics // |form_xml| - form structure XML to upload/download. - // |request_data| - form signature hash(es) and indicator if it was a query. - // |request_data.query| - if true the data is queried and observer notified - // with new data, if available. If false heuristic data is uploaded to our - // servers. + // |form_signature| - form signature hash. + // |query_data| - if true the data is queried and observer notified with new + // data, if available. If false heuristic data is uploaded to our servers. + // |form_was_matched| - if |query_data| is false indicates if the form was + // matched. Ignored otherwise. bool StartRequest(const std::string& form_xml, - const FormRequestData& request_data); + const std::string& form_signature, + bool query_data, + bool form_was_matched); + + bool CancelRequest(const std::string& form_signature, bool query_data); + protected: // URLFetcher::Delegate implementation: virtual void OnURLFetchComplete(const URLFetcher* source, const GURL& url, @@ -109,20 +71,17 @@ class AutoFillDownloadManager : public URLFetcher::Delegate { const ResponseCookies& cookies, const std::string& data); + private: + struct FormRequestData { + std::string form_signature; + bool query; + }; + // For each requested form for both query and upload we create a separate // request and save its info. As url fetcher is identified by its address // we use a map between fetchers and info. - std::map<URLFetcher*, FormRequestData> url_fetchers_; + std::map<URLFetcher *, FormRequestData> url_fetchers_; AutoFillDownloadManager::Observer *observer_; - - // Probability of the form upload. Between 0 (no upload) and 1 (upload all). - // |positive_upload_rate_| is for matched forms, - // |negative_upload_rate_| for non matched. - double positive_upload_rate_; - double negative_upload_rate_; - - // Needed for unit-test. - int fetcher_id_for_unittest_; }; #endif // CHROME_BROWSER_AUTOFILL_AUTOFILL_DOWNLOAD_H_ diff --git a/chrome/browser/autofill/autofill_download_unittest.cc b/chrome/browser/autofill/autofill_download_unittest.cc deleted file mode 100644 index 92be846..0000000 --- a/chrome/browser/autofill/autofill_download_unittest.cc +++ /dev/null @@ -1,240 +0,0 @@ -// 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 <list> - -#include "base/string_util.h" -#include "chrome/browser/autofill/autofill_download.h" -#include "chrome/browser/net/test_url_fetcher_factory.h" -#include "net/url_request/url_request_status.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/WebKit/WebKit/chromium/public/WebInputElement.h" -#include "webkit/glue/form_field_values.h" - -using WebKit::WebInputElement; - -namespace { - -// This tests AutoFillDownloadManager. AutoFillDownloadTestHelper implements -// AutoFillDownloadManager::Observer and creates instance of -// AutoFillDownloadManager. Then it records responses to different initiated -// requests, which are verified later. To mock network requests -// TestURLFetcherFactory is used, which creates URLFetchers that do not -// go over the wire, but allow calling back HTTP responses directly. -// The responses in test are out of order and verify: successful query request, -// successful upload request, failed upload request. -class AutoFillDownloadTestHelper : public AutoFillDownloadManager::Observer { - public: - AutoFillDownloadTestHelper() { - download_manager.SetObserver(this); - } - ~AutoFillDownloadTestHelper() { - download_manager.SetObserver(NULL); - } - - // AutoFillDownloadManager::Observer overridables: - virtual void OnLoadedAutoFillHeuristics( - const std::vector<std::string>& form_signatures, - const std::string& heuristic_xml) { - ResponseData response; - for (size_t i = 0; i < form_signatures.size(); ++i) { - if (i) - response.signature += ","; - response.signature += form_signatures[i]; - } - response.response = heuristic_xml; - response.type_of_response = QUERY_SUCCESSFULL; - responses_.push_back(response); - }; - - virtual void OnUploadedAutoFillHeuristics(const std::string& form_signature) { - ResponseData response; - response.signature = form_signature; - response.type_of_response = UPLOAD_SUCCESSFULL; - responses_.push_back(response); - } - virtual void OnHeuristicsRequestError( - const std::string& form_signature, - AutoFillDownloadManager::AutoFillRequestType request_type, - int http_error) { - ResponseData response; - response.signature = form_signature; - response.error = http_error; - response.type_of_response = - request_type == AutoFillDownloadManager::REQUEST_QUERY ? - REQUEST_QUERY_FAILED : REQUEST_UPLOAD_FAILED; - responses_.push_back(response); - } - - enum TYPE_OF_RESPONSE { - QUERY_SUCCESSFULL, - UPLOAD_SUCCESSFULL, - REQUEST_QUERY_FAILED, - REQUEST_UPLOAD_FAILED, - }; - - struct ResponseData { - TYPE_OF_RESPONSE type_of_response; - int error; - std::string signature; - std::string response; - ResponseData() : type_of_response(REQUEST_QUERY_FAILED), error(0) { - } - }; - std::list<AutoFillDownloadTestHelper::ResponseData> responses_; - - AutoFillDownloadManager download_manager; -}; - -TEST(AutoFillDownloadTest, QueryAndUploadTest) { - MessageLoopForUI message_loop; - // Create and register factory. - AutoFillDownloadTestHelper helper; - TestURLFetcherFactory factory; - URLFetcher::set_factory(&factory); - - webkit_glue::FormFieldValues values; - values.method = ASCIIToUTF16("post"); - values.elements.push_back(webkit_glue::FormField(ASCIIToUTF16("username"), - ASCIIToUTF16("username"), - string16(), - ASCIIToUTF16("text"), - WebInputElement::Text)); - values.elements.push_back(webkit_glue::FormField(ASCIIToUTF16("email"), - ASCIIToUTF16("email"), - string16(), - ASCIIToUTF16("text"), - WebInputElement::Text)); - values.elements.push_back(webkit_glue::FormField(ASCIIToUTF16("email2"), - ASCIIToUTF16("email2"), - string16(), - ASCIIToUTF16("text"), - WebInputElement::Text)); - values.elements.push_back(webkit_glue::FormField(ASCIIToUTF16("password"), - ASCIIToUTF16("password"), - string16(), - ASCIIToUTF16("password"), - WebInputElement::Password)); - values.elements.push_back(webkit_glue::FormField(string16(), - ASCIIToUTF16("Submit"), - string16(), - ASCIIToUTF16("submit"), - WebInputElement::Submit)); - - FormStructure *form = new FormStructure(values); - ScopedVector<FormStructure> form_structures; - form_structures.push_back(form); - - values.elements.clear(); - values.elements.push_back(webkit_glue::FormField(ASCIIToUTF16("address"), - ASCIIToUTF16("address"), - string16(), - ASCIIToUTF16("text"), - WebInputElement::Text)); - values.elements.push_back(webkit_glue::FormField(ASCIIToUTF16("address2"), - ASCIIToUTF16("address2"), - string16(), - ASCIIToUTF16("text"), - WebInputElement::Text)); - values.elements.push_back(webkit_glue::FormField(ASCIIToUTF16("city"), - ASCIIToUTF16("address2"), - string16(), - ASCIIToUTF16("text"), - WebInputElement::Text)); - values.elements.push_back(webkit_glue::FormField(string16(), - ASCIIToUTF16("Submit"), - string16(), - ASCIIToUTF16("submit"), - WebInputElement::Submit)); - form = new FormStructure(values); - form_structures.push_back(form); - - // Request with id 0. - EXPECT_TRUE(helper.download_manager.StartQueryRequest(form_structures)); - // Set upload to 100% so requests happen. - helper.download_manager.SetPositiveUploadRate(1.0); - helper.download_manager.SetNegativeUploadRate(1.0); - // Request with id 1. - EXPECT_TRUE(helper.download_manager.StartUploadRequest(*(form_structures[0]), - true)); - // Request with id 2. - EXPECT_TRUE(helper.download_manager.StartUploadRequest(*(form_structures[1]), - false)); - - const char *responses[] = { - "<autofillqueryresponse>" - "<field autofilltype=\"0\" />" - "<field autofilltype=\"9\" />" - "<field autofilltype=\"0\" />" - "<field autofilltype=\"30\" />" - "<field autofilltype=\"31\" />" - "<field autofilltype=\"33\" />" - "</autofillqueryresponse>", - "<autofilluploadresponse positiveuploadrate=\"0.5\" " - "negativeuploadrate=\"0.3\"/>", - "<html></html>", - }; - - // Return them out of sequence. - TestURLFetcher* fetcher = factory.GetFetcherByID(1); - ASSERT_TRUE(fetcher); - fetcher->delegate()->OnURLFetchComplete(fetcher, GURL(), URLRequestStatus(), - 200, ResponseCookies(), - std::string(responses[1])); - fetcher = factory.GetFetcherByID(2); - ASSERT_TRUE(fetcher); - fetcher->delegate()->OnURLFetchComplete(fetcher, GURL(), URLRequestStatus(), - 404, ResponseCookies(), - std::string(responses[2])); - fetcher = factory.GetFetcherByID(0); - ASSERT_TRUE(fetcher); - fetcher->delegate()->OnURLFetchComplete(fetcher, GURL(), URLRequestStatus(), - 200, ResponseCookies(), - std::string(responses[0])); - EXPECT_EQ(static_cast<size_t>(3), helper.responses_.size()); - - EXPECT_EQ(AutoFillDownloadTestHelper::UPLOAD_SUCCESSFULL, - helper.responses_.front().type_of_response); - EXPECT_EQ(0, helper.responses_.front().error); - EXPECT_EQ(form_structures[0]->FormSignature(), - helper.responses_.front().signature); - // Expected response on non-query request is an empty string. - EXPECT_EQ(std::string(""), helper.responses_.front().response); - helper.responses_.pop_front(); - - EXPECT_EQ(AutoFillDownloadTestHelper::REQUEST_UPLOAD_FAILED, - helper.responses_.front().type_of_response); - EXPECT_EQ(404, helper.responses_.front().error); - EXPECT_EQ(form_structures[1]->FormSignature(), - helper.responses_.front().signature); - // Expected response on non-query request is an empty string. - EXPECT_EQ(std::string(""), helper.responses_.front().response); - helper.responses_.pop_front(); - - EXPECT_EQ(helper.responses_.front().type_of_response, - AutoFillDownloadTestHelper::QUERY_SUCCESSFULL); - EXPECT_EQ(0, helper.responses_.front().error); - std::string signature(form_structures[0]->FormSignature()); - signature.append(","); - signature.append(form_structures[1]->FormSignature()); - EXPECT_EQ(signature, helper.responses_.front().signature); - EXPECT_EQ(responses[0], helper.responses_.front().response); - helper.responses_.pop_front(); - // Set upload to 0% so no new requests happen. - helper.download_manager.SetPositiveUploadRate(0.0); - helper.download_manager.SetNegativeUploadRate(0.0); - // No actual requests for the next two calls, as we set upload rate to 0%. - EXPECT_TRUE(helper.download_manager.StartUploadRequest(*(form_structures[0]), - true)); - EXPECT_TRUE(helper.download_manager.StartUploadRequest(*(form_structures[1]), - false)); - fetcher = factory.GetFetcherByID(4); - EXPECT_EQ(NULL, fetcher); - - // Make sure consumer of URLFetcher does the right thing. - URLFetcher::set_factory(NULL); -} - -} // namespace - diff --git a/chrome/browser/autofill/autofill_manager.cc b/chrome/browser/autofill/autofill_manager.cc index e630d9e..4ffdc20 100644 --- a/chrome/browser/autofill/autofill_manager.cc +++ b/chrome/browser/autofill/autofill_manager.cc @@ -90,8 +90,15 @@ void AutoFillManager::FormsSeen( FormStructure* form_structure = new FormStructure(*iter); DeterminePossibleFieldTypes(form_structure); form_structures_.push_back(form_structure); + std::string request_xml; + if (form_structure->IsAutoFillable() && + form_structure->EncodeUploadRequest(true, true, &request_xml)) { + download_manager_.StartRequest(request_xml, + form_structure->FormSignature(), + true, + false); + } } - download_manager_.StartQueryRequest(form_structures_); } bool AutoFillManager::GetAutoFillSuggestions( @@ -287,44 +294,36 @@ void AutoFillManager::Reset() { } void AutoFillManager::OnLoadedAutoFillHeuristics( - const std::vector<std::string>& form_signatures, + const std::string& form_signature, const std::string& heuristic_xml) { - // Create a vector of AutoFillFieldTypes, - // to assign the parsed field types to. - std::vector<AutoFillFieldType> field_types; - UploadRequired upload_required = USE_UPLOAD_RATES; - - // Create a parser. - AutoFillQueryXmlParser parse_handler(&field_types, &upload_required); - buzz::XmlParser parser(&parse_handler); - parser.Parse(heuristic_xml.c_str(), heuristic_xml.length(), true); - if (!parse_handler.succeeded()) { - return; - } - - // For multiple forms requested, returned field types are in one array. - // |field_shift| indicates start of the fields for current form. - size_t field_shift = 0; - // form_signatures should mirror form_structures_ unless new request is - // initiated. So if there is a discrepancy we just ignore data and return. - ScopedVector<FormStructure>::iterator it_forms; - std::vector<std::string>::const_iterator it_signatures; - for (it_forms = form_structures_.begin(), - it_signatures = form_signatures.begin(); - it_forms != form_structures_.end() && - it_signatures != form_signatures.end() && - (*it_forms)->FormSignature() == *it_signatures; - ++it_forms, ++it_signatures) { - DCHECK(field_types.size() - field_shift >= (*it_forms)->field_count()); - for (size_t i = 0; i < (*it_forms)->field_count(); ++i) { - if (field_types[i + field_shift] != NO_SERVER_DATA && - field_types[i + field_shift] != UNKNOWN_TYPE) { - FieldTypeSet types = (*it_forms)->field(i)->possible_types(); - types.insert(field_types[i]); - (*it_forms)->set_possible_types(i, types); + for (ScopedVector<FormStructure>::iterator it = form_structures_.begin(); + it != form_structures_.end(); + ++it) { + if ((*it)->FormSignature() == form_signature) { + // Create a vector of AutoFillFieldTypes, + // to assign the parsed field types to. + std::vector<AutoFillFieldType> field_types; + UploadRequired upload_required = USE_UPLOAD_RATES; + + // Create a parser. + AutoFillQueryXmlParser parse_handler(&field_types, &upload_required); + buzz::XmlParser parser(&parse_handler); + parser.Parse(heuristic_xml.c_str(), heuristic_xml.length(), true); + if (parse_handler.succeeded()) { + DCHECK(field_types.size() == (*it)->field_count()); + if (field_types.size() == (*it)->field_count()) { + for (size_t i = 0; i < (*it)->field_count(); ++i) { + if (field_types[i] != NO_SERVER_DATA && + field_types[i] != UNKNOWN_TYPE) { + FieldTypeSet types = (*it)->field(i)->possible_types(); + types.insert(field_types[i]); + (*it)->set_possible_types(i, types); + } + } + } + return; } } - field_shift += (*it_forms)->field_count(); } } @@ -333,9 +332,7 @@ void AutoFillManager::OnUploadedAutoFillHeuristics( } void AutoFillManager::OnHeuristicsRequestError( - const std::string& form_signature, - AutoFillDownloadManager::AutoFillRequestType request_type, - int http_error) { + const std::string& form_signature, int http_error) { } void AutoFillManager::DeterminePossibleFieldTypes( @@ -366,10 +363,16 @@ void AutoFillManager::HandleSubmit() { } void AutoFillManager::UploadFormData() { + std::string xml; + bool ok = upload_form_structure_->EncodeUploadRequest(false, false, &xml); + DCHECK(ok); + // TODO(georgey): enable upload request when we make sure that our data is in // line with toolbar data: - // download_manager_.StartUploadRequest(upload_form_structure_, - // form_is_autofilled); + // download_manager_.StartRequest(xml, + // upload_form_structure_->FormSignature(), + // false, + // form_is_autofilled); } bool AutoFillManager::IsAutoFillEnabled() { diff --git a/chrome/browser/autofill/autofill_manager.h b/chrome/browser/autofill/autofill_manager.h index d89d5da..f56a5f2 100644 --- a/chrome/browser/autofill/autofill_manager.h +++ b/chrome/browser/autofill/autofill_manager.h @@ -77,14 +77,11 @@ class AutoFillManager : public RenderViewHostDelegate::AutoFill, virtual void Reset(); // AutoFillDownloadManager::Observer implementation: - virtual void OnLoadedAutoFillHeuristics( - const std::vector<std::string>& form_signatures, - const std::string& heuristic_xml); + virtual void OnLoadedAutoFillHeuristics(const std::string& form_signature, + const std::string& heuristic_xml); virtual void OnUploadedAutoFillHeuristics(const std::string& form_signature); - virtual void OnHeuristicsRequestError( - const std::string& form_signature, - AutoFillDownloadManager::AutoFillRequestType request_type, - int http_error); + virtual void OnHeuristicsRequestError(const std::string& form_signature, + int http_error); // Uses heuristics and existing personal data to determine the possible field // types. diff --git a/chrome/browser/autofill/form_structure.cc b/chrome/browser/autofill/form_structure.cc index f96e5272..dd9cfaa 100644 --- a/chrome/browser/autofill/form_structure.cc +++ b/chrome/browser/autofill/form_structure.cc @@ -36,8 +36,6 @@ const char* const kAttributeAutoFillType = "autofilltype"; // The only form control type we handle currently. const char* const kControlTypeText = "text"; -// This type is required for AutoFill servers. -const char* const kControlTypeSingleSelect = "select-one"; // The number of fillable fields necessary for a form to be fillable. const size_t kRequiredFillableFields = 3; @@ -68,18 +66,9 @@ FormStructure::FormStructure(const FormFieldValues& values) std::vector<webkit_glue::FormField>::const_iterator field; for (field = values.elements.begin(); field != values.elements.end(); field++) { - // Add all form fields (including with empty names) to signature. - // This is requirement for AutoFill servers. - bool is_text_control = LowerCaseEqualsASCII(field->form_control_type(), - kControlTypeText); - if (is_text_control || LowerCaseEqualsASCII(field->form_control_type(), - kControlTypeSingleSelect)) { - form_signature_field_names_.append("&"); - form_signature_field_names_.append(UTF16ToUTF8(field->name())); - } // We currently only handle text fields. This prevents us from thinking we // can autofill other types of controls, e.g., select, password, hidden. - if (!is_text_control) + if (!LowerCaseEqualsASCII(field->form_control_type(), kControlTypeText)) continue; // Generate a unique name for this field by appending a counter to the name. @@ -101,61 +90,65 @@ FormStructure::FormStructure(const FormFieldValues& values) } bool FormStructure::EncodeUploadRequest(bool auto_fill_used, + bool query, std::string* encoded_xml) const { bool auto_fillable = IsAutoFillable(); DCHECK(auto_fillable); // Caller should've checked for search pages. if (!auto_fillable) return false; - buzz::XmlElement autofil_request_xml(buzz::QName("autofillupload")); + buzz::XmlElement autofil_request_xml(query ? buzz::QName("autofillquery") : + buzz::QName("autofillupload")); + buzz::XmlElement *encompassing_xml_element = &autofil_request_xml; + if (query) + encompassing_xml_element = new buzz::XmlElement(buzz::QName("form")); - // Attributes for the <autofillupload> element. + // Attributes for the <autofillupload>/<autofillquery> element. // // TODO(jhawkins): Work with toolbar devs to make a spec for autofill clients. // For now these values are hacked from the toolbar code. autofil_request_xml.SetAttr(buzz::QName(kAttributeClientVersion), "6.1.1715.1442/en (GGLL)"); - autofil_request_xml.SetAttr(buzz::QName(kAttributeFormSignature), - FormSignature()); - - autofil_request_xml.SetAttr(buzz::QName(kAttributeAutoFillUsed), - auto_fill_used ? "true" : "false"); - - // TODO(jhawkins): Hook this up to the personal data manager. - // personaldata_manager_->GetDataPresent(); - autofil_request_xml.SetAttr(buzz::QName(kAttributeDataPresent), ""); + encompassing_xml_element->SetAttr(query ? buzz::QName(kAttributeSignature) : + buzz::QName(kAttributeFormSignature), + FormSignature()); - EncodeFormRequest(FormStructure::UPLOAD, &autofil_request_xml); + if (!query) { + autofil_request_xml.SetAttr(buzz::QName(kAttributeAutoFillUsed), + auto_fill_used ? "true" : "false"); - // Obtain the XML structure as a string. - *encoded_xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; - *encoded_xml += autofil_request_xml.Str().c_str(); - - return true; -} - -bool FormStructure::EncodeQueryRequest(const ScopedVector<FormStructure>& forms, - std::string* encoded_xml) { - buzz::XmlElement autofil_request_xml(buzz::QName("autofillquery")); - // Attributes for the <autofillquery> element. - // - // TODO(jhawkins): Work with toolbar devs to make a spec for autofill clients. - // For now these values are hacked from the toolbar code. - autofil_request_xml.SetAttr(buzz::QName(kAttributeClientVersion), - "6.1.1715.1442/en (GGLL)"); - for (ScopedVector<FormStructure>::const_iterator it = forms.begin(); - it != forms.end(); - ++it) { - buzz::XmlElement* encompassing_xml_element = - new buzz::XmlElement(buzz::QName("form")); - encompassing_xml_element->SetAttr(buzz::QName(kAttributeSignature), - (*it)->FormSignature()); + // TODO(jhawkins): Hook this up to the personal data manager. + // personaldata_manager_->GetDataPresent(); + autofil_request_xml.SetAttr(buzz::QName(kAttributeDataPresent), ""); + } - (*it)->EncodeFormRequest(FormStructure::QUERY, encompassing_xml_element); + // Add the child nodes for the form fields. + for (size_t index = 0; index < field_count(); index++) { + const AutoFillField* field = fields_[index]; + if (!query) { + FieldTypeSet types = field->possible_types(); + for (FieldTypeSet::const_iterator type = types.begin(); + type != types.end(); type++) { + buzz::XmlElement *field_element = new buzz::XmlElement( + buzz::QName(kXMLElementField)); - autofil_request_xml.AddElement(encompassing_xml_element); + field_element->SetAttr(buzz::QName(kAttributeSignature), + field->FieldSignature()); + field_element->SetAttr(buzz::QName(kAttributeAutoFillType), + IntToString(*type)); + encompassing_xml_element->AddElement(field_element); + } + } else { + buzz::XmlElement *field_element = new buzz::XmlElement( + buzz::QName(kXMLElementField)); + field_element->SetAttr(buzz::QName(kAttributeSignature), + field->FieldSignature()); + encompassing_xml_element->AddElement(field_element); + } } + if (query) + autofil_request_xml.AddElement(encompassing_xml_element); // Obtain the XML structure as a string. *encoded_xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; @@ -192,9 +185,7 @@ void FormStructure::GetHeuristicAutoFillTypes() { } std::string FormStructure::FormSignature() const { - std::string form_string = target_url_.scheme() + - "://" + - target_url_.host() + + std::string form_string = target_url_.host() + "&" + form_name_ + form_signature_field_names_; @@ -262,36 +253,3 @@ void FormStructure::GetHeuristicFieldInfo(FieldTypeMap* field_type_map) { DCHECK(ok); } } - -bool FormStructure::EncodeFormRequest( - FormStructure::EncodeRequestType request_type, - buzz::XmlElement* encompassing_xml_element) const { - if (!field_count()) // Nothing to add. - return false; - // Add the child nodes for the form fields. - for (size_t index = 0; index < field_count(); index++) { - const AutoFillField* field = fields_[index]; - if (request_type == FormStructure::UPLOAD) { - FieldTypeSet types = field->possible_types(); - for (FieldTypeSet::const_iterator type = types.begin(); - type != types.end(); type++) { - buzz::XmlElement *field_element = new buzz::XmlElement( - buzz::QName(kXMLElementField)); - - field_element->SetAttr(buzz::QName(kAttributeSignature), - field->FieldSignature()); - field_element->SetAttr(buzz::QName(kAttributeAutoFillType), - IntToString(*type)); - encompassing_xml_element->AddElement(field_element); - } - } else { - buzz::XmlElement *field_element = new buzz::XmlElement( - buzz::QName(kXMLElementField)); - field_element->SetAttr(buzz::QName(kAttributeSignature), - field->FieldSignature()); - encompassing_xml_element->AddElement(field_element); - } - } - return true; -} - diff --git a/chrome/browser/autofill/form_structure.h b/chrome/browser/autofill/form_structure.h index bb20885..3802aed 100644 --- a/chrome/browser/autofill/form_structure.h +++ b/chrome/browser/autofill/form_structure.h @@ -14,14 +14,10 @@ #include "chrome/browser/autofill/field_types.h" #include "googleurl/src/gurl.h" -namespace buzz { - class XmlElement; -} // namespace buzz - namespace webkit_glue { struct FormData; class FormFieldValues; -} // namespace webkit_glue +} enum RequestMethod { GET, @@ -40,18 +36,11 @@ class FormStructure { public: explicit FormStructure(const webkit_glue::FormFieldValues& values); - // Encodes the XML upload request from this FormStructure. - bool EncodeUploadRequest(bool auto_fill_used, + // Encodes the XML query or upload request from this FormStructure. + // |query| - true means request is a query, upload otherwise. + bool EncodeUploadRequest(bool auto_fill_used, bool query, std::string* encoded_xml) const; - // Encodes the XML query request for the set of forms. - // All fields are returned in one XML. For example, there are three forms, - // with 2, 4, and 3 fields. The returned XML would have type info for 9 - // fields, first two of which would be for the first form, next 4 for the - // second, and the rest is for the third. - static bool EncodeQueryRequest(const ScopedVector<FormStructure>& forms, - std::string* encoded_xml); - // Runs several heuristics against the form fields to determine their possible // types. void GetHeuristicAutoFillTypes(); @@ -82,19 +71,9 @@ class FormStructure { bool operator!=(const webkit_glue::FormData& form) const; private: - enum EncodeRequestType { - QUERY, - UPLOAD, - }; - // Associates the field with the heuristic type for each of the field views. void GetHeuristicFieldInfo(FieldTypeMap* field_types_map); - // Adds form info to |encompassing_xml_element|. |request_type| indicates if - // it is a query or upload. - bool EncodeFormRequest(EncodeRequestType request_type, - buzz::XmlElement* encompassing_xml_element) const; - // The name of the form. // TODO(jhawkins): string16 std::string form_name_; diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 2e24d21..34cc702 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -547,7 +547,6 @@ 'browser/autofill/autofill_credit_card_model_mac_unittest.mm', 'browser/autofill/autofill_credit_card_view_controller_mac_unittest.mm', 'browser/autofill/autofill_dialog_controller_mac_unittest.mm', - 'browser/autofill/autofill_download_unittest.cc', 'browser/autofill/autofill_field_unittest.cc', 'browser/autofill/autofill_infobar_delegate_unittest.cc', 'browser/autofill/autofill_profile_unittest.cc', |