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

Side by Side Diff: chrome/browser/autofill/autofill_manager.cc

Issue 5703002: Add some basic success/failure UMA logging for autofill. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Hopefully compile on Windows Created 10 years 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/autofill/autofill_manager.h" 5 #include "chrome/browser/autofill/autofill_manager.h"
6 6
7 #include <limits> 7 #include <limits>
8 #include <string> 8 #include <string>
9 9
10 #include "app/l10n_util.h" 10 #include "app/l10n_util.h"
11 #include "base/basictypes.h" 11 #include "base/basictypes.h"
12 #include "base/string16.h" 12 #include "base/string16.h"
13 #include "base/utf_string_conversions.h" 13 #include "base/utf_string_conversions.h"
14 #include "chrome/browser/autofill/autofill_cc_infobar_delegate.h" 14 #include "chrome/browser/autofill/autofill_cc_infobar_delegate.h"
15 #include "chrome/browser/autofill/autofill_dialog.h" 15 #include "chrome/browser/autofill/autofill_dialog.h"
16 #include "chrome/browser/autofill/autofill_metrics.h"
16 #include "chrome/browser/autofill/form_structure.h" 17 #include "chrome/browser/autofill/form_structure.h"
17 #include "chrome/browser/autofill/phone_number.h" 18 #include "chrome/browser/autofill/phone_number.h"
18 #include "chrome/browser/autofill/select_control_handler.h" 19 #include "chrome/browser/autofill/select_control_handler.h"
19 #include "chrome/browser/guid.h" 20 #include "chrome/browser/guid.h"
20 #include "chrome/browser/prefs/pref_service.h" 21 #include "chrome/browser/prefs/pref_service.h"
21 #include "chrome/browser/profiles/profile.h" 22 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/renderer_host/render_view_host.h" 23 #include "chrome/browser/renderer_host/render_view_host.h"
23 #include "chrome/browser/tab_contents/tab_contents.h" 24 #include "chrome/browser/tab_contents/tab_contents.h"
24 #include "chrome/common/chrome_switches.h" 25 #include "chrome/common/chrome_switches.h"
25 #include "chrome/common/pref_names.h" 26 #include "chrome/common/pref_names.h"
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 return form->source_url().SchemeIs(chrome::kHttpsScheme); 122 return form->source_url().SchemeIs(chrome::kHttpsScheme);
122 } 123 }
123 124
124 } // namespace 125 } // namespace
125 126
126 AutoFillManager::AutoFillManager(TabContents* tab_contents) 127 AutoFillManager::AutoFillManager(TabContents* tab_contents)
127 : tab_contents_(tab_contents), 128 : tab_contents_(tab_contents),
128 personal_data_(NULL), 129 personal_data_(NULL),
129 download_manager_(tab_contents_->profile()), 130 download_manager_(tab_contents_->profile()),
130 disable_download_manager_requests_(false), 131 disable_download_manager_requests_(false),
132 server_query_metric_logger_(new AutoFillServerQueryMetricLogger),
133 quality_metric_logger_(new AutoFillQualityMetricLogger),
131 cc_infobar_(NULL) { 134 cc_infobar_(NULL) {
132 DCHECK(tab_contents); 135 DCHECK(tab_contents);
133 136
134 // |personal_data_| is NULL when using TestTabContents. 137 // |personal_data_| is NULL when using TestTabContents.
135 personal_data_ = 138 personal_data_ =
136 tab_contents_->profile()->GetOriginalProfile()->GetPersonalDataManager(); 139 tab_contents_->profile()->GetOriginalProfile()->GetPersonalDataManager();
137 download_manager_.SetObserver(this); 140 download_manager_.SetObserver(this);
138 } 141 }
139 142
140 AutoFillManager::~AutoFillManager() { 143 AutoFillManager::~AutoFillManager() {
(...skipping 26 matching lines...) Expand all
167 if (tab_contents_->profile()->IsOffTheRecord()) 170 if (tab_contents_->profile()->IsOffTheRecord())
168 return; 171 return;
169 172
170 // Don't save data that was submitted through JavaScript. 173 // Don't save data that was submitted through JavaScript.
171 if (!form.user_submitted) 174 if (!form.user_submitted)
172 return; 175 return;
173 176
174 // Grab a copy of the form data. 177 // Grab a copy of the form data.
175 upload_form_structure_.reset(new FormStructure(form)); 178 upload_form_structure_.reset(new FormStructure(form));
176 179
180 // Disregard forms that we wouldn't ever autofill in the first place.
181 if (!upload_form_structure_->ShouldBeParsed(true))
182 return;
183
184 DeterminePossibleFieldTypesForUpload();
185 // TODO(isherman): Consider uploading to server here rather than in
186 // HandleSubmit().
187
177 if (!upload_form_structure_->IsAutoFillable(true)) 188 if (!upload_form_structure_->IsAutoFillable(true))
178 return; 189 return;
179 190
180 // Determine the possible field types and upload the form structure to the
181 // PersonalDataManager.
182 DeterminePossibleFieldTypes(upload_form_structure_.get());
183 HandleSubmit(); 191 HandleSubmit();
184 } 192 }
185 193
186 void AutoFillManager::FormsSeen(const std::vector<FormData>& forms) { 194 void AutoFillManager::FormsSeen(const std::vector<FormData>& forms) {
187 if (!IsAutoFillEnabled()) 195 if (!IsAutoFillEnabled())
188 return; 196 return;
189 197
190 ParseForms(forms); 198 ParseForms(forms);
191 } 199 }
192 200
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 upload_form_structure_.reset(); 399 upload_form_structure_.reset();
392 form_structures_.reset(); 400 form_structures_.reset();
393 } 401 }
394 402
395 void AutoFillManager::OnLoadedAutoFillHeuristics( 403 void AutoFillManager::OnLoadedAutoFillHeuristics(
396 const std::string& heuristic_xml) { 404 const std::string& heuristic_xml) {
397 // TODO(jhawkins): Store |upload_required| in the AutoFillManager. 405 // TODO(jhawkins): Store |upload_required| in the AutoFillManager.
398 UploadRequired upload_required; 406 UploadRequired upload_required;
399 FormStructure::ParseQueryResponse(heuristic_xml, 407 FormStructure::ParseQueryResponse(heuristic_xml,
400 form_structures_.get(), 408 form_structures_.get(),
401 &upload_required); 409 &upload_required,
410 *server_query_metric_logger_);
402 } 411 }
403 412
404 void AutoFillManager::OnUploadedAutoFillHeuristics( 413 void AutoFillManager::OnUploadedAutoFillHeuristics(
405 const std::string& form_signature) { 414 const std::string& form_signature) {
406 } 415 }
407 416
408 void AutoFillManager::OnHeuristicsRequestError( 417 void AutoFillManager::OnHeuristicsRequestError(
409 const std::string& form_signature, 418 const std::string& form_signature,
410 AutoFillDownloadManager::AutoFillRequestType request_type, 419 AutoFillDownloadManager::AutoFillRequestType request_type,
411 int http_error) { 420 int http_error) {
412 } 421 }
413 422
414 bool AutoFillManager::IsAutoFillEnabled() const { 423 bool AutoFillManager::IsAutoFillEnabled() const {
415 PrefService* prefs = tab_contents_->profile()->GetPrefs(); 424 PrefService* prefs = tab_contents_->profile()->GetPrefs();
416 425
417 // Migrate obsolete AutoFill pref. 426 // Migrate obsolete AutoFill pref.
418 if (prefs->FindPreference(prefs::kFormAutofillEnabled)) { 427 if (prefs->FindPreference(prefs::kFormAutofillEnabled)) {
419 bool enabled = prefs->GetBoolean(prefs::kFormAutofillEnabled); 428 bool enabled = prefs->GetBoolean(prefs::kFormAutofillEnabled);
420 prefs->ClearPref(prefs::kFormAutofillEnabled); 429 prefs->ClearPref(prefs::kFormAutofillEnabled);
421 prefs->SetBoolean(prefs::kAutoFillEnabled, enabled); 430 prefs->SetBoolean(prefs::kAutoFillEnabled, enabled);
422 return enabled; 431 return enabled;
423 } 432 }
424 433
425 return prefs->GetBoolean(prefs::kAutoFillEnabled); 434 return prefs->GetBoolean(prefs::kAutoFillEnabled);
426 } 435 }
427 436
428 void AutoFillManager::DeterminePossibleFieldTypes( 437 void AutoFillManager::DeterminePossibleFieldTypesForUpload() {
429 FormStructure* form_structure) { 438 for (size_t i = 0; i < upload_form_structure_->field_count(); i++) {
430 for (size_t i = 0; i < form_structure->field_count(); i++) { 439 const AutoFillField* field = upload_form_structure_->field(i);
431 const AutoFillField* field = form_structure->field(i);
432 FieldTypeSet field_types; 440 FieldTypeSet field_types;
433 personal_data_->GetPossibleFieldTypes(field->value(), &field_types); 441 personal_data_->GetPossibleFieldTypes(field->value(), &field_types);
434 form_structure->set_possible_types(i, field_types); 442 DCHECK(!field_types.empty());
443 upload_form_structure_->set_possible_types(i, field_types);
444
445 if (field->form_control_type() == ASCIIToUTF16("select-one")) {
446 // TODO(isherman): <select> fields don't support |is_autofilled()|. Since
447 // this is heavily relied upon by our metrics, we just don't log anything
448 // for all <select> fields. Better to have less data than misleading data.
449 continue;
450 }
451
452 // Log various quality metrics.
453 quality_metric_logger_->Log(AutoFillQualityMetricLogger::FIELD_SUBMITTED);
454 if (field_types.find(EMPTY_TYPE) == field_types.end() &&
455 field_types.find(UNKNOWN_TYPE) == field_types.end()) {
456 if (field->is_autofilled())
457 quality_metric_logger_->Log(
458 AutoFillQualityMetricLogger::FIELD_AUTOFILLED);
459 else
460 quality_metric_logger_->Log(
461 AutoFillQualityMetricLogger::FIELD_AUTOFILL_FAILED);
462
463 // TODO(isherman): Other things we might want to log here:
464 // * Did the field's heuristic type match the PDM type?
465 // * Per Vadim's email, a combination of (1) whether heuristics fired,
466 // (2) whether the server returned something interesting, (3) whether
467 // the user filled the field
468 // * Whether the server type matches the heursitic type
469 // - Perhaps only if at least one of the types is not unknown/no data.
470 }
435 } 471 }
436 } 472 }
437 473
438 void AutoFillManager::HandleSubmit() { 474 void AutoFillManager::HandleSubmit() {
439 // If there wasn't enough data to import then we don't want to send an upload 475 // If there wasn't enough data to import then we don't want to send an upload
440 // to the server. 476 // to the server.
441 // TODO(jhawkins): Import form data from |form_structures_|. That will 477 // TODO(jhawkins): Import form data from |form_structures_|. That will
442 // require querying the FormManager for updated field values. 478 // require querying the FormManager for updated field values.
443 std::vector<FormStructure*> import; 479 std::vector<FormStructure*> import;
444 import.push_back(upload_form_structure_.get()); 480 import.push_back(upload_form_structure_.get());
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 void AutoFillManager::OnInfoBarClosed(bool should_save) { 524 void AutoFillManager::OnInfoBarClosed(bool should_save) {
489 if (should_save) 525 if (should_save)
490 personal_data_->SaveImportedCreditCard(); 526 personal_data_->SaveImportedCreditCard();
491 UploadFormData(); 527 UploadFormData();
492 } 528 }
493 529
494 AutoFillManager::AutoFillManager() 530 AutoFillManager::AutoFillManager()
495 : tab_contents_(NULL), 531 : tab_contents_(NULL),
496 personal_data_(NULL), 532 personal_data_(NULL),
497 download_manager_(NULL), 533 download_manager_(NULL),
498 disable_download_manager_requests_(false), 534 disable_download_manager_requests_(true),
535 server_query_metric_logger_(new AutoFillServerQueryMetricLogger),
536 quality_metric_logger_(new AutoFillQualityMetricLogger),
499 cc_infobar_(NULL) { 537 cc_infobar_(NULL) {
500 } 538 }
501 539
502 AutoFillManager::AutoFillManager(TabContents* tab_contents, 540 AutoFillManager::AutoFillManager(TabContents* tab_contents,
503 PersonalDataManager* personal_data) 541 PersonalDataManager* personal_data)
504 : tab_contents_(tab_contents), 542 : tab_contents_(tab_contents),
505 personal_data_(personal_data), 543 personal_data_(personal_data),
506 download_manager_(NULL), 544 download_manager_(NULL),
507 disable_download_manager_requests_(false), 545 disable_download_manager_requests_(true),
546 server_query_metric_logger_(new AutoFillServerQueryMetricLogger),
547 quality_metric_logger_(new AutoFillQualityMetricLogger),
508 cc_infobar_(NULL) { 548 cc_infobar_(NULL) {
509 DCHECK(tab_contents); 549 DCHECK(tab_contents);
510 } 550 }
511 551
552 void AutoFillManager::set_server_query_metric_logger(
553 const AutoFillServerQueryMetricLogger* server_query_metric_logger) {
554 server_query_metric_logger_.reset(server_query_metric_logger);
555 }
556 void AutoFillManager::set_quality_metric_logger(
557 const AutoFillQualityMetricLogger* quality_metric_logger) {
558 quality_metric_logger_.reset(quality_metric_logger);
559 }
560
512 bool AutoFillManager::GetHost(const std::vector<AutoFillProfile*>& profiles, 561 bool AutoFillManager::GetHost(const std::vector<AutoFillProfile*>& profiles,
513 const std::vector<CreditCard*>& credit_cards, 562 const std::vector<CreditCard*>& credit_cards,
514 RenderViewHost** host) { 563 RenderViewHost** host) {
515 if (!IsAutoFillEnabled()) 564 if (!IsAutoFillEnabled())
516 return false; 565 return false;
517 566
518 // No autofill data to return if the profiles are empty. 567 // No autofill data to return if the profiles are empty.
519 if (profiles.empty() && credit_cards.empty()) 568 if (profiles.empty() && credit_cards.empty())
520 return false; 569 return false;
521 570
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
702 751
703 // Set aside forms with method GET so that they are not included in the 752 // Set aside forms with method GET so that they are not included in the
704 // query to the server. 753 // query to the server.
705 if (form_structure->ShouldBeParsed(true)) 754 if (form_structure->ShouldBeParsed(true))
706 form_structures_.push_back(form_structure.release()); 755 form_structures_.push_back(form_structure.release());
707 else 756 else
708 non_queryable_forms.push_back(form_structure.release()); 757 non_queryable_forms.push_back(form_structure.release());
709 } 758 }
710 759
711 // If none of the forms were parsed, no use querying the server. 760 // If none of the forms were parsed, no use querying the server.
712 if (!form_structures_.empty() && !disable_download_manager_requests_) 761 if (!form_structures_.empty() && !disable_download_manager_requests_) {
713 download_manager_.StartQueryRequest(form_structures_); 762 download_manager_.StartQueryRequest(form_structures_,
763 *server_query_metric_logger_);
764 }
714 765
715 for (std::vector<FormStructure *>::const_iterator iter = 766 for (std::vector<FormStructure *>::const_iterator iter =
716 non_queryable_forms.begin(); 767 non_queryable_forms.begin();
717 iter != non_queryable_forms.end(); ++iter) { 768 iter != non_queryable_forms.end(); ++iter) {
718 form_structures_.push_back(*iter); 769 form_structures_.push_back(*iter);
719 } 770 }
720 } 771 }
721 772
722 // When sending IDs (across processes) to the renderer we pack credit card and 773 // When sending IDs (across processes) to the renderer we pack credit card and
723 // profile IDs into a single integer. Credit card IDs are sent in the high 774 // profile IDs into a single integer. Credit card IDs are sent in the high
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
768 return std::string(); 819 return std::string();
769 820
770 std::map<int, std::string>::const_iterator iter = id_guid_map_.find(id); 821 std::map<int, std::string>::const_iterator iter = id_guid_map_.find(id);
771 if (iter == id_guid_map_.end()) { 822 if (iter == id_guid_map_.end()) {
772 NOTREACHED(); 823 NOTREACHED();
773 return std::string(); 824 return std::string();
774 } 825 }
775 826
776 return iter->second; 827 return iter->second;
777 } 828 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698