Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(257)

Unified Diff: chrome/browser/autofill/autofill_manager.cc

Issue 6213002: Propagate correct data to the Toolbar servers (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/autofill/autofill_manager.cc
===================================================================
--- chrome/browser/autofill/autofill_manager.cc (revision 71419)
+++ chrome/browser/autofill/autofill_manager.cc (working copy)
@@ -219,14 +219,15 @@
cached_upload_form_structure = NULL;
}
- DeterminePossibleFieldTypesForUpload(cached_upload_form_structure);
+ std::string data_present = DeterminePossibleFieldTypesForUpload(
+ cached_upload_form_structure);
// TODO(isherman): Consider uploading to server here rather than in
// HandleSubmit().
if (!upload_form_structure_->IsAutoFillable(true))
return;
- HandleSubmit();
+ HandleSubmit(data_present);
}
void AutoFillManager::OnFormsSeen(const std::vector<FormData>& forms) {
@@ -484,64 +485,82 @@
return prefs->GetBoolean(prefs::kAutoFillEnabled);
}
-void AutoFillManager::DeterminePossibleFieldTypesForUpload(
+std::string AutoFillManager::DeterminePossibleFieldTypesForUpload(
const FormStructure* cached_upload_form_structure) {
+ // Mark bits present for the upload for data_present field.
+ std::vector<uint8> presence_bitfield;
+ // Determine all of the field types that were autofilled. Pack bits into
+ // |presence_bitfield|. The necessary size for |presence_bitfield| is
+ // ceil((MAX_VALID_FIELD_TYPE + 7) / 8) bytes (uint8).
+ presence_bitfield.resize((MAX_VALID_FIELD_TYPE + 0x7) >> 3);
+ for (size_t i = 0; i < presence_bitfield.size(); ++i)
+ presence_bitfield[i] = 0;
+
for (size_t i = 0; i < upload_form_structure_->field_count(); i++) {
const AutoFillField* field = upload_form_structure_->field(i);
FieldTypeSet field_types;
personal_data_->GetPossibleFieldTypes(field->value(), &field_types);
- DCHECK(!field_types.empty());
- upload_form_structure_->set_possible_types(i, field_types);
if (field->form_control_type() == ASCIIToUTF16("select-one")) {
// TODO(isherman): <select> fields don't support |is_autofilled()|. Since
// this is heavily relied upon by our metrics, we just don't log anything
// for all <select> fields. Better to have less data than misleading data.
- continue;
- }
+ } else {
+ // Log various quality metrics.
+ metric_logger_->Log(AutoFillMetrics::FIELD_SUBMITTED);
+ if (field_types.find(EMPTY_TYPE) == field_types.end() &&
+ field_types.find(UNKNOWN_TYPE) == field_types.end()) {
+ if (field->is_autofilled()) {
+ metric_logger_->Log(AutoFillMetrics::FIELD_AUTOFILLED);
+ } else {
+ metric_logger_->Log(AutoFillMetrics::FIELD_AUTOFILL_FAILED);
- // Log various quality metrics.
- metric_logger_->Log(AutoFillMetrics::FIELD_SUBMITTED);
- if (field_types.find(EMPTY_TYPE) == field_types.end() &&
- field_types.find(UNKNOWN_TYPE) == field_types.end()) {
- if (field->is_autofilled()) {
- metric_logger_->Log(AutoFillMetrics::FIELD_AUTOFILLED);
- } else {
- metric_logger_->Log(AutoFillMetrics::FIELD_AUTOFILL_FAILED);
+ AutoFillFieldType heuristic_type = cached_upload_form_structure?
+ cached_upload_form_structure->field(i)->heuristic_type() :
+ UNKNOWN_TYPE;
+ if (heuristic_type == UNKNOWN_TYPE)
+ metric_logger_->Log(AutoFillMetrics::FIELD_HEURISTIC_TYPE_UNKNOWN);
+ else if (field_types.count(heuristic_type))
+ metric_logger_->Log(AutoFillMetrics::FIELD_HEURISTIC_TYPE_MATCH);
+ else
+ metric_logger_->Log(AutoFillMetrics::FIELD_HEURISTIC_TYPE_MISMATCH);
- AutoFillFieldType heuristic_type = cached_upload_form_structure?
- cached_upload_form_structure->field(i)->heuristic_type() :
- UNKNOWN_TYPE;
- if (heuristic_type == UNKNOWN_TYPE)
- metric_logger_->Log(AutoFillMetrics::FIELD_HEURISTIC_TYPE_UNKNOWN);
- else if (field_types.count(heuristic_type))
- metric_logger_->Log(AutoFillMetrics::FIELD_HEURISTIC_TYPE_MATCH);
- else
- metric_logger_->Log(AutoFillMetrics::FIELD_HEURISTIC_TYPE_MISMATCH);
+ AutoFillFieldType server_type = cached_upload_form_structure?
+ cached_upload_form_structure->field(i)->server_type() :
+ NO_SERVER_DATA;
+ if (server_type == NO_SERVER_DATA)
+ metric_logger_->Log(AutoFillMetrics::FIELD_SERVER_TYPE_UNKNOWN);
+ else if (field_types.count(server_type))
+ metric_logger_->Log(AutoFillMetrics::FIELD_SERVER_TYPE_MATCH);
+ else
+ metric_logger_->Log(AutoFillMetrics::FIELD_SERVER_TYPE_MISMATCH);
+ }
- AutoFillFieldType server_type = cached_upload_form_structure?
- cached_upload_form_structure->field(i)->server_type() :
- NO_SERVER_DATA;
- if (server_type == NO_SERVER_DATA)
- metric_logger_->Log(AutoFillMetrics::FIELD_SERVER_TYPE_UNKNOWN);
- else if (field_types.count(server_type))
- metric_logger_->Log(AutoFillMetrics::FIELD_SERVER_TYPE_MATCH);
- else
- metric_logger_->Log(AutoFillMetrics::FIELD_SERVER_TYPE_MISMATCH);
+
+ // TODO(isherman): Other things we might want to log here:
+ // * Per Vadim's email, a combination of (1) whether heuristics fired,
+ // (2) whether the server returned something interesting, (3) whether
+ // the user filled the field
+ // * Whether the server type matches the heursitic type
+ // - Perhaps only if at least one of the types is not unknown/no data.
}
+ }
+ DCHECK(!field_types.empty());
+ if (field_types.size() > 1) {
+ // If there is more than one possibility, do not poison the crowd-sourced
+ // data by returning UNKNOWN_TYPE.
+ field_types.clear();
+ field_types.insert(UNKNOWN_TYPE);
+ }
+ upload_form_structure_->set_possible_types(i, field_types);
+ SetPresenceBit(*(field_types.begin()), &presence_bitfield);
+ }
- // TODO(isherman): Other things we might want to log here:
- // * Per Vadim's email, a combination of (1) whether heuristics fired,
- // (2) whether the server returned something interesting, (3) whether
- // the user filled the field
- // * Whether the server type matches the heursitic type
- // - Perhaps only if at least one of the types is not unknown/no data.
- }
- }
+ return ConvertPresenceBitsToString(presence_bitfield);
}
-void AutoFillManager::HandleSubmit() {
+void AutoFillManager::HandleSubmit(std::string const& data_present) {
// If there wasn't enough data to import then we don't want to send an upload
// to the server.
// TODO(jhawkins): Import form data from |form_structures_|. That will
@@ -557,8 +576,11 @@
personal_data_->GetImportedFormData(&profile, &credit_card);
if (!credit_card) {
- UploadFormData();
+ data_autofilled_.clear();
+ UploadFormData(data_present);
return;
+ } else {
+ data_autofilled_ = data_present;
}
// Show an infobar to offer to save the credit card info.
@@ -568,7 +590,7 @@
}
}
-void AutoFillManager::UploadFormData() {
+void AutoFillManager::UploadFormData(std::string const& data_present) {
if (!disable_download_manager_requests_ && upload_form_structure_.get()) {
bool was_autofilled = false;
// Check if the form among last 3 forms that were auto-filled.
@@ -578,8 +600,9 @@
for (it = autofilled_forms_signatures_.begin();
it != autofilled_forms_signatures_.end() && total_form_checked < 3;
++it, ++total_form_checked) {
- if (*it == upload_form_structure_->FormSignature())
+ if (*it == upload_form_structure_->FormSignature()) {
was_autofilled = true;
+ }
}
// Remove outdated form signatures.
if (total_form_checked == 3 && it != autofilled_forms_signatures_.end()) {
@@ -587,7 +610,8 @@
autofilled_forms_signatures_.end());
}
download_manager_.StartUploadRequest(*(upload_form_structure_.get()),
- was_autofilled);
+ was_autofilled,
+ data_present.c_str());
}
}
@@ -596,10 +620,34 @@
form_structures_.reset();
}
+void AutoFillManager::SetPresenceBit(AutoFillFieldType field_type,
+ std::vector<uint8>* bitfield) {
+ DCHECK(bitfield);
+ DCHECK(bitfield->size() > (static_cast<size_t>(field_type) >> 3));
+ // Set bit in the bitfield: byte |field_type| / 8, bit in byte
+ // |field_type| % 8 from the left.
+ (*bitfield)[field_type >> 3] |= (0x80 >> (field_type & 7));
+}
+
+std::string AutoFillManager::ConvertPresenceBitsToString(
+ std::vector<uint8> const& bitfield) {
+ std::string present_data;
+ present_data.reserve(bitfield.size() * 2 + 1);
+ // Skip leading zeroes. If all mask is 0 - return empty string.
+ size_t data_end = bitfield.size();
+ for (; data_end > 0 && !bitfield[data_end - 1]; --data_end) {
+ }
+ // Print all non-zero bytes into the string.
+ for (size_t i = 0; i < data_end; ++i) {
+ base::StringAppendF(&present_data, "%02x", bitfield[i]);
+ }
+ return present_data;
+}
+
void AutoFillManager::OnInfoBarClosed(bool should_save) {
if (should_save)
personal_data_->SaveImportedCreditCard();
- UploadFormData();
+ UploadFormData(data_autofilled_);
}
AutoFillManager::AutoFillManager()

Powered by Google App Engine
This is Rietveld 408576698