OLD | NEW |
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 Loading... |
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 metric_logger_(new AutoFillMetrics), |
131 cc_infobar_(NULL) { | 133 cc_infobar_(NULL) { |
132 DCHECK(tab_contents); | 134 DCHECK(tab_contents); |
133 | 135 |
134 // |personal_data_| is NULL when using TestTabContents. | 136 // |personal_data_| is NULL when using TestTabContents. |
135 personal_data_ = | 137 personal_data_ = |
136 tab_contents_->profile()->GetOriginalProfile()->GetPersonalDataManager(); | 138 tab_contents_->profile()->GetOriginalProfile()->GetPersonalDataManager(); |
137 download_manager_.SetObserver(this); | 139 download_manager_.SetObserver(this); |
138 } | 140 } |
139 | 141 |
140 AutoFillManager::~AutoFillManager() { | 142 AutoFillManager::~AutoFillManager() { |
(...skipping 26 matching lines...) Expand all Loading... |
167 if (tab_contents_->profile()->IsOffTheRecord()) | 169 if (tab_contents_->profile()->IsOffTheRecord()) |
168 return; | 170 return; |
169 | 171 |
170 // Don't save data that was submitted through JavaScript. | 172 // Don't save data that was submitted through JavaScript. |
171 if (!form.user_submitted) | 173 if (!form.user_submitted) |
172 return; | 174 return; |
173 | 175 |
174 // Grab a copy of the form data. | 176 // Grab a copy of the form data. |
175 upload_form_structure_.reset(new FormStructure(form)); | 177 upload_form_structure_.reset(new FormStructure(form)); |
176 | 178 |
| 179 // Disregard forms that we wouldn't ever autofill in the first place. |
| 180 if (!upload_form_structure_->ShouldBeParsed(true)) |
| 181 return; |
| 182 |
| 183 DeterminePossibleFieldTypesForUpload(); |
| 184 // TODO(isherman): Consider uploading to server here rather than in |
| 185 // HandleSubmit(). |
| 186 |
177 if (!upload_form_structure_->IsAutoFillable(true)) | 187 if (!upload_form_structure_->IsAutoFillable(true)) |
178 return; | 188 return; |
179 | 189 |
180 // Determine the possible field types and upload the form structure to the | |
181 // PersonalDataManager. | |
182 DeterminePossibleFieldTypes(upload_form_structure_.get()); | |
183 HandleSubmit(); | 190 HandleSubmit(); |
184 } | 191 } |
185 | 192 |
186 void AutoFillManager::FormsSeen(const std::vector<FormData>& forms) { | 193 void AutoFillManager::FormsSeen(const std::vector<FormData>& forms) { |
187 if (!IsAutoFillEnabled()) | 194 if (!IsAutoFillEnabled()) |
188 return; | 195 return; |
189 | 196 |
190 ParseForms(forms); | 197 ParseForms(forms); |
191 } | 198 } |
192 | 199 |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 upload_form_structure_.reset(); | 398 upload_form_structure_.reset(); |
392 form_structures_.reset(); | 399 form_structures_.reset(); |
393 } | 400 } |
394 | 401 |
395 void AutoFillManager::OnLoadedAutoFillHeuristics( | 402 void AutoFillManager::OnLoadedAutoFillHeuristics( |
396 const std::string& heuristic_xml) { | 403 const std::string& heuristic_xml) { |
397 // TODO(jhawkins): Store |upload_required| in the AutoFillManager. | 404 // TODO(jhawkins): Store |upload_required| in the AutoFillManager. |
398 UploadRequired upload_required; | 405 UploadRequired upload_required; |
399 FormStructure::ParseQueryResponse(heuristic_xml, | 406 FormStructure::ParseQueryResponse(heuristic_xml, |
400 form_structures_.get(), | 407 form_structures_.get(), |
401 &upload_required); | 408 &upload_required, |
| 409 *metric_logger_); |
402 } | 410 } |
403 | 411 |
404 void AutoFillManager::OnUploadedAutoFillHeuristics( | 412 void AutoFillManager::OnUploadedAutoFillHeuristics( |
405 const std::string& form_signature) { | 413 const std::string& form_signature) { |
406 } | 414 } |
407 | 415 |
408 void AutoFillManager::OnHeuristicsRequestError( | 416 void AutoFillManager::OnHeuristicsRequestError( |
409 const std::string& form_signature, | 417 const std::string& form_signature, |
410 AutoFillDownloadManager::AutoFillRequestType request_type, | 418 AutoFillDownloadManager::AutoFillRequestType request_type, |
411 int http_error) { | 419 int http_error) { |
412 } | 420 } |
413 | 421 |
414 bool AutoFillManager::IsAutoFillEnabled() const { | 422 bool AutoFillManager::IsAutoFillEnabled() const { |
415 PrefService* prefs = tab_contents_->profile()->GetPrefs(); | 423 PrefService* prefs = tab_contents_->profile()->GetPrefs(); |
416 | 424 |
417 // Migrate obsolete AutoFill pref. | 425 // Migrate obsolete AutoFill pref. |
418 if (prefs->FindPreference(prefs::kFormAutofillEnabled)) { | 426 if (prefs->FindPreference(prefs::kFormAutofillEnabled)) { |
419 bool enabled = prefs->GetBoolean(prefs::kFormAutofillEnabled); | 427 bool enabled = prefs->GetBoolean(prefs::kFormAutofillEnabled); |
420 prefs->ClearPref(prefs::kFormAutofillEnabled); | 428 prefs->ClearPref(prefs::kFormAutofillEnabled); |
421 prefs->SetBoolean(prefs::kAutoFillEnabled, enabled); | 429 prefs->SetBoolean(prefs::kAutoFillEnabled, enabled); |
422 return enabled; | 430 return enabled; |
423 } | 431 } |
424 | 432 |
425 return prefs->GetBoolean(prefs::kAutoFillEnabled); | 433 return prefs->GetBoolean(prefs::kAutoFillEnabled); |
426 } | 434 } |
427 | 435 |
428 void AutoFillManager::DeterminePossibleFieldTypes( | 436 void AutoFillManager::DeterminePossibleFieldTypesForUpload() { |
429 FormStructure* form_structure) { | 437 for (size_t i = 0; i < upload_form_structure_->field_count(); i++) { |
430 for (size_t i = 0; i < form_structure->field_count(); i++) { | 438 const AutoFillField* field = upload_form_structure_->field(i); |
431 const AutoFillField* field = form_structure->field(i); | |
432 FieldTypeSet field_types; | 439 FieldTypeSet field_types; |
433 personal_data_->GetPossibleFieldTypes(field->value(), &field_types); | 440 personal_data_->GetPossibleFieldTypes(field->value(), &field_types); |
434 form_structure->set_possible_types(i, field_types); | 441 DCHECK(!field_types.empty()); |
| 442 upload_form_structure_->set_possible_types(i, field_types); |
| 443 |
| 444 if (field->form_control_type() == ASCIIToUTF16("select-one")) { |
| 445 // TODO(isherman): <select> fields don't support |is_autofilled()|. Since |
| 446 // this is heavily relied upon by our metrics, we just don't log anything |
| 447 // for all <select> fields. Better to have less data than misleading data. |
| 448 continue; |
| 449 } |
| 450 |
| 451 // Log various quality metrics. |
| 452 metric_logger_->Log(AutoFillMetrics::FIELD_SUBMITTED); |
| 453 if (field_types.find(EMPTY_TYPE) == field_types.end() && |
| 454 field_types.find(UNKNOWN_TYPE) == field_types.end()) { |
| 455 if (field->is_autofilled()) |
| 456 metric_logger_->Log(AutoFillMetrics::FIELD_AUTOFILLED); |
| 457 else |
| 458 metric_logger_->Log(AutoFillMetrics::FIELD_AUTOFILL_FAILED); |
| 459 |
| 460 // TODO(isherman): Other things we might want to log here: |
| 461 // * Did the field's heuristic type match the PDM type? |
| 462 // * Per Vadim's email, a combination of (1) whether heuristics fired, |
| 463 // (2) whether the server returned something interesting, (3) whether |
| 464 // the user filled the field |
| 465 // * Whether the server type matches the heursitic type |
| 466 // - Perhaps only if at least one of the types is not unknown/no data. |
| 467 } |
435 } | 468 } |
436 } | 469 } |
437 | 470 |
438 void AutoFillManager::HandleSubmit() { | 471 void AutoFillManager::HandleSubmit() { |
439 // If there wasn't enough data to import then we don't want to send an upload | 472 // If there wasn't enough data to import then we don't want to send an upload |
440 // to the server. | 473 // to the server. |
441 // TODO(jhawkins): Import form data from |form_structures_|. That will | 474 // TODO(jhawkins): Import form data from |form_structures_|. That will |
442 // require querying the FormManager for updated field values. | 475 // require querying the FormManager for updated field values. |
443 std::vector<FormStructure*> import; | 476 std::vector<FormStructure*> import; |
444 import.push_back(upload_form_structure_.get()); | 477 import.push_back(upload_form_structure_.get()); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
488 void AutoFillManager::OnInfoBarClosed(bool should_save) { | 521 void AutoFillManager::OnInfoBarClosed(bool should_save) { |
489 if (should_save) | 522 if (should_save) |
490 personal_data_->SaveImportedCreditCard(); | 523 personal_data_->SaveImportedCreditCard(); |
491 UploadFormData(); | 524 UploadFormData(); |
492 } | 525 } |
493 | 526 |
494 AutoFillManager::AutoFillManager() | 527 AutoFillManager::AutoFillManager() |
495 : tab_contents_(NULL), | 528 : tab_contents_(NULL), |
496 personal_data_(NULL), | 529 personal_data_(NULL), |
497 download_manager_(NULL), | 530 download_manager_(NULL), |
498 disable_download_manager_requests_(false), | 531 disable_download_manager_requests_(true), |
| 532 metric_logger_(new AutoFillMetrics), |
499 cc_infobar_(NULL) { | 533 cc_infobar_(NULL) { |
500 } | 534 } |
501 | 535 |
502 AutoFillManager::AutoFillManager(TabContents* tab_contents, | 536 AutoFillManager::AutoFillManager(TabContents* tab_contents, |
503 PersonalDataManager* personal_data) | 537 PersonalDataManager* personal_data) |
504 : tab_contents_(tab_contents), | 538 : tab_contents_(tab_contents), |
505 personal_data_(personal_data), | 539 personal_data_(personal_data), |
506 download_manager_(NULL), | 540 download_manager_(NULL), |
507 disable_download_manager_requests_(false), | 541 disable_download_manager_requests_(true), |
| 542 metric_logger_(new AutoFillMetrics), |
508 cc_infobar_(NULL) { | 543 cc_infobar_(NULL) { |
509 DCHECK(tab_contents); | 544 DCHECK(tab_contents); |
510 } | 545 } |
511 | 546 |
| 547 void AutoFillManager::set_metric_logger( |
| 548 const AutoFillMetrics* metric_logger) { |
| 549 metric_logger_.reset(metric_logger); |
| 550 } |
| 551 |
512 bool AutoFillManager::GetHost(const std::vector<AutoFillProfile*>& profiles, | 552 bool AutoFillManager::GetHost(const std::vector<AutoFillProfile*>& profiles, |
513 const std::vector<CreditCard*>& credit_cards, | 553 const std::vector<CreditCard*>& credit_cards, |
514 RenderViewHost** host) { | 554 RenderViewHost** host) { |
515 if (!IsAutoFillEnabled()) | 555 if (!IsAutoFillEnabled()) |
516 return false; | 556 return false; |
517 | 557 |
518 // No autofill data to return if the profiles are empty. | 558 // No autofill data to return if the profiles are empty. |
519 if (profiles.empty() && credit_cards.empty()) | 559 if (profiles.empty() && credit_cards.empty()) |
520 return false; | 560 return false; |
521 | 561 |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
702 | 742 |
703 // Set aside forms with method GET so that they are not included in the | 743 // Set aside forms with method GET so that they are not included in the |
704 // query to the server. | 744 // query to the server. |
705 if (form_structure->ShouldBeParsed(true)) | 745 if (form_structure->ShouldBeParsed(true)) |
706 form_structures_.push_back(form_structure.release()); | 746 form_structures_.push_back(form_structure.release()); |
707 else | 747 else |
708 non_queryable_forms.push_back(form_structure.release()); | 748 non_queryable_forms.push_back(form_structure.release()); |
709 } | 749 } |
710 | 750 |
711 // If none of the forms were parsed, no use querying the server. | 751 // If none of the forms were parsed, no use querying the server. |
712 if (!form_structures_.empty() && !disable_download_manager_requests_) | 752 if (!form_structures_.empty() && !disable_download_manager_requests_) { |
713 download_manager_.StartQueryRequest(form_structures_); | 753 download_manager_.StartQueryRequest(form_structures_, |
| 754 *metric_logger_); |
| 755 } |
714 | 756 |
715 for (std::vector<FormStructure *>::const_iterator iter = | 757 for (std::vector<FormStructure *>::const_iterator iter = |
716 non_queryable_forms.begin(); | 758 non_queryable_forms.begin(); |
717 iter != non_queryable_forms.end(); ++iter) { | 759 iter != non_queryable_forms.end(); ++iter) { |
718 form_structures_.push_back(*iter); | 760 form_structures_.push_back(*iter); |
719 } | 761 } |
720 } | 762 } |
721 | 763 |
722 // When sending IDs (across processes) to the renderer we pack credit card and | 764 // 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 | 765 // 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 Loading... |
768 return std::string(); | 810 return std::string(); |
769 | 811 |
770 std::map<int, std::string>::const_iterator iter = id_guid_map_.find(id); | 812 std::map<int, std::string>::const_iterator iter = id_guid_map_.find(id); |
771 if (iter == id_guid_map_.end()) { | 813 if (iter == id_guid_map_.end()) { |
772 NOTREACHED(); | 814 NOTREACHED(); |
773 return std::string(); | 815 return std::string(); |
774 } | 816 } |
775 | 817 |
776 return iter->second; | 818 return iter->second; |
777 } | 819 } |
OLD | NEW |