| 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 "base/basictypes.h" | 11 #include "base/basictypes.h" |
| 11 #include "base/string16.h" | 12 #include "base/string16.h" |
| 12 #include "base/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
| 13 #include "chrome/browser/autofill/autofill_cc_infobar_delegate.h" | 14 #include "chrome/browser/autofill/autofill_cc_infobar_delegate.h" |
| 14 #include "chrome/browser/autofill/autofill_dialog.h" | 15 #include "chrome/browser/autofill/autofill_dialog.h" |
| 15 #include "chrome/browser/autofill/form_structure.h" | 16 #include "chrome/browser/autofill/form_structure.h" |
| 16 #include "chrome/browser/autofill/select_control_handler.h" | 17 #include "chrome/browser/autofill/select_control_handler.h" |
| 17 #include "chrome/browser/guid.h" | 18 #include "chrome/browser/guid.h" |
| 18 #include "chrome/browser/prefs/pref_service.h" | 19 #include "chrome/browser/prefs/pref_service.h" |
| 19 #include "chrome/browser/profile.h" | 20 #include "chrome/browser/profile.h" |
| 20 #include "chrome/browser/renderer_host/render_view_host.h" | 21 #include "chrome/browser/renderer_host/render_view_host.h" |
| 21 #include "chrome/browser/tab_contents/tab_contents.h" | 22 #include "chrome/browser/tab_contents/tab_contents.h" |
| 22 #include "chrome/common/chrome_switches.h" | 23 #include "chrome/common/chrome_switches.h" |
| 23 #include "chrome/common/pref_names.h" | 24 #include "chrome/common/pref_names.h" |
| 24 #include "chrome/common/url_constants.h" | 25 #include "chrome/common/url_constants.h" |
| 26 #include "grit/generated_resources.h" |
| 25 #include "webkit/glue/form_data.h" | 27 #include "webkit/glue/form_data.h" |
| 26 #include "webkit/glue/form_field.h" | 28 #include "webkit/glue/form_field.h" |
| 27 | 29 |
| 28 using webkit_glue::FormData; | 30 using webkit_glue::FormData; |
| 29 using webkit_glue::FormField; | 31 using webkit_glue::FormField; |
| 30 | 32 |
| 31 namespace { | 33 namespace { |
| 32 | 34 |
| 33 // We only send a fraction of the forms to upload server. | 35 // We only send a fraction of the forms to upload server. |
| 34 // The rate for positive/negative matches potentially could be different. | 36 // The rate for positive/negative matches potentially could be different. |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 if (tab_contents_->profile()->IsOffTheRecord()) | 127 if (tab_contents_->profile()->IsOffTheRecord()) |
| 126 return; | 128 return; |
| 127 | 129 |
| 128 // Don't save data that was submitted through JavaScript. | 130 // Don't save data that was submitted through JavaScript. |
| 129 if (!form.user_submitted) | 131 if (!form.user_submitted) |
| 130 return; | 132 return; |
| 131 | 133 |
| 132 // Grab a copy of the form data. | 134 // Grab a copy of the form data. |
| 133 upload_form_structure_.reset(new FormStructure(form)); | 135 upload_form_structure_.reset(new FormStructure(form)); |
| 134 | 136 |
| 135 if (!upload_form_structure_->IsAutoFillable()) | 137 if (!upload_form_structure_->IsAutoFillable(false)) |
| 136 return; | 138 return; |
| 137 | 139 |
| 138 // Determine the possible field types and upload the form structure to the | 140 // Determine the possible field types and upload the form structure to the |
| 139 // PersonalDataManager. | 141 // PersonalDataManager. |
| 140 DeterminePossibleFieldTypes(upload_form_structure_.get()); | 142 DeterminePossibleFieldTypes(upload_form_structure_.get()); |
| 141 HandleSubmit(); | 143 HandleSubmit(); |
| 142 } | 144 } |
| 143 | 145 |
| 144 void AutoFillManager::FormsSeen(const std::vector<FormData>& forms) { | 146 void AutoFillManager::FormsSeen(const std::vector<FormData>& forms) { |
| 145 if (!IsAutoFillEnabled()) | 147 if (!IsAutoFillEnabled()) |
| 146 return; | 148 return; |
| 147 | 149 |
| 148 ParseForms(forms); | 150 ParseForms(forms); |
| 149 } | 151 } |
| 150 | 152 |
| 151 bool AutoFillManager::GetAutoFillSuggestions(int query_id, | 153 bool AutoFillManager::GetAutoFillSuggestions(bool field_autofilled, |
| 152 bool field_autofilled, | 154 const FormField& field, |
| 153 const FormField& field) { | 155 bool autofill_disabled) { |
| 154 if (!IsAutoFillEnabled()) | 156 if (!IsAutoFillEnabled()) |
| 155 return false; | 157 return false; |
| 156 | 158 |
| 157 RenderViewHost* host = tab_contents_->render_view_host(); | 159 RenderViewHost* host = tab_contents_->render_view_host(); |
| 158 if (!host) | 160 if (!host) |
| 159 return false; | 161 return false; |
| 160 | 162 |
| 161 if (personal_data_->profiles().empty() && | 163 if (personal_data_->profiles().empty() && |
| 162 personal_data_->credit_cards().empty()) | 164 personal_data_->credit_cards().empty()) |
| 163 return false; | 165 return false; |
| 164 | 166 |
| 165 // Loops through the cached FormStructures looking for the FormStructure that | 167 // Loops through the cached FormStructures looking for the FormStructure that |
| 166 // contains |field| and the associated AutoFillFieldType. | 168 // contains |field| and the associated AutoFillFieldType. |
| 167 FormStructure* form = NULL; | 169 FormStructure* form = NULL; |
| 168 AutoFillField* autofill_field = NULL; | 170 AutoFillField* autofill_field = NULL; |
| 169 for (std::vector<FormStructure*>::iterator form_iter = | 171 for (std::vector<FormStructure*>::iterator form_iter = |
| 170 form_structures_.begin(); | 172 form_structures_.begin(); |
| 171 form_iter != form_structures_.end() && !autofill_field; ++form_iter) { | 173 form_iter != form_structures_.end() && !autofill_field; ++form_iter) { |
| 172 form = *form_iter; | 174 form = *form_iter; |
| 173 | 175 |
| 174 // Don't send suggestions for forms that aren't auto-fillable. | 176 // Don't send suggestions for forms that aren't auto-fillable. |
| 175 if (!form->IsAutoFillable()) | 177 if (!form->IsAutoFillable(false)) |
| 176 continue; | 178 continue; |
| 177 | 179 |
| 178 for (std::vector<AutoFillField*>::const_iterator iter = form->begin(); | 180 for (std::vector<AutoFillField*>::const_iterator iter = form->begin(); |
| 179 iter != form->end(); ++iter) { | 181 iter != form->end(); ++iter) { |
| 180 // The field list is terminated with a NULL AutoFillField, so don't try to | 182 // The field list is terminated with a NULL AutoFillField, so don't try to |
| 181 // dereference it. | 183 // dereference it. |
| 182 if (!*iter) | 184 if (!*iter) |
| 183 break; | 185 break; |
| 184 | 186 |
| 185 if ((**iter) == field) { | 187 if ((**iter) == field) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 207 } | 209 } |
| 208 | 210 |
| 209 DCHECK_EQ(values.size(), labels.size()); | 211 DCHECK_EQ(values.size(), labels.size()); |
| 210 DCHECK_EQ(values.size(), icons.size()); | 212 DCHECK_EQ(values.size(), icons.size()); |
| 211 DCHECK_EQ(values.size(), unique_ids.size()); | 213 DCHECK_EQ(values.size(), unique_ids.size()); |
| 212 | 214 |
| 213 // No suggestions. | 215 // No suggestions. |
| 214 if (values.empty()) | 216 if (values.empty()) |
| 215 return false; | 217 return false; |
| 216 | 218 |
| 219 // Don't provide autofill suggestions when autofill is disabled, but provide a |
| 220 // warning to the user. |
| 221 if (autofill_disabled || !form->IsAutoFillable(true)) { |
| 222 values.assign( |
| 223 1, l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_AUTOFILL_DISABLED)); |
| 224 labels.assign(1, string16()); |
| 225 icons.assign(1, string16()); |
| 226 unique_ids.assign(1, -1); |
| 227 host->AutoFillSuggestionsReturned(values, labels, icons, unique_ids); |
| 228 return true; |
| 229 } |
| 230 |
| 231 // Don't provide credit card suggestions for non-HTTPS pages, but provide a |
| 232 // warning to the user. |
| 233 if (!FormIsHTTPS(form) && type.group() == AutoFillType::CREDIT_CARD) { |
| 234 values.assign( |
| 235 1, l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_INSECURE_CONNECTION)); |
| 236 labels.assign(1, string16()); |
| 237 icons.assign(1, string16()); |
| 238 unique_ids.assign(1, -1); |
| 239 host->AutoFillSuggestionsReturned(values, labels, icons, unique_ids); |
| 240 return true; |
| 241 } |
| 242 |
| 217 // If the form is auto-filled and the renderer is querying for suggestions, | 243 // If the form is auto-filled and the renderer is querying for suggestions, |
| 218 // then the user is editing the value of a field. In this case, mimick | 244 // then the user is editing the value of a field. In this case, mimick |
| 219 // autocomplete. In particular, don't display labels, as that information is | 245 // autocomplete. In particular, don't display labels, as that information is |
| 220 // redundant. In addition, remove duplicate values. | 246 // redundant. In addition, remove duplicate values. |
| 221 if (field_autofilled) { | 247 if (field_autofilled) { |
| 222 RemoveDuplicateElements(&values, &unique_ids); | 248 RemoveDuplicateElements(&values, &unique_ids); |
| 223 labels.resize(values.size()); | 249 labels.resize(values.size()); |
| 224 icons.resize(values.size()); | 250 icons.resize(values.size()); |
| 225 unique_ids.resize(values.size()); | 251 unique_ids.resize(values.size()); |
| 226 | 252 |
| 227 for (size_t i = 0; i < labels.size(); ++i) { | 253 for (size_t i = 0; i < labels.size(); ++i) { |
| 228 labels[i] = string16(); | 254 labels[i] = string16(); |
| 229 icons[i] = string16(); | 255 icons[i] = string16(); |
| 230 unique_ids[i] = 0; | 256 unique_ids[i] = 0; |
| 231 } | 257 } |
| 232 } | 258 } |
| 233 | 259 |
| 234 host->AutoFillSuggestionsReturned( | 260 host->AutoFillSuggestionsReturned(values, labels, icons, unique_ids); |
| 235 query_id, values, labels, icons, unique_ids); | |
| 236 return true; | 261 return true; |
| 237 } | 262 } |
| 238 | 263 |
| 239 bool AutoFillManager::FillAutoFillFormData(int query_id, | 264 bool AutoFillManager::FillAutoFillFormData(int query_id, |
| 240 const FormData& form, | 265 const FormData& form, |
| 241 int unique_id) { | 266 int unique_id) { |
| 242 if (!IsAutoFillEnabled()) | 267 if (!IsAutoFillEnabled()) |
| 243 return false; | 268 return false; |
| 244 | 269 |
| 245 RenderViewHost* host = tab_contents_->render_view_host(); | 270 RenderViewHost* host = tab_contents_->render_view_host(); |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 icons->resize(values->size()); | 543 icons->resize(values->size()); |
| 519 } | 544 } |
| 520 | 545 |
| 521 void AutoFillManager::GetCreditCardSuggestions(FormStructure* form, | 546 void AutoFillManager::GetCreditCardSuggestions(FormStructure* form, |
| 522 const FormField& field, | 547 const FormField& field, |
| 523 AutoFillType type, | 548 AutoFillType type, |
| 524 std::vector<string16>* values, | 549 std::vector<string16>* values, |
| 525 std::vector<string16>* labels, | 550 std::vector<string16>* labels, |
| 526 std::vector<string16>* icons, | 551 std::vector<string16>* icons, |
| 527 std::vector<int>* unique_ids) { | 552 std::vector<int>* unique_ids) { |
| 528 // Don't return CC suggestions for non-HTTPS pages. | |
| 529 if (!FormIsHTTPS(form)) | |
| 530 return; | |
| 531 | |
| 532 for (std::vector<CreditCard*>::const_iterator iter = | 553 for (std::vector<CreditCard*>::const_iterator iter = |
| 533 personal_data_->credit_cards().begin(); | 554 personal_data_->credit_cards().begin(); |
| 534 iter != personal_data_->credit_cards().end(); ++iter) { | 555 iter != personal_data_->credit_cards().end(); ++iter) { |
| 535 CreditCard* credit_card = *iter; | 556 CreditCard* credit_card = *iter; |
| 536 | 557 |
| 537 // The value of the stored data for this field type in the |credit_card|. | 558 // The value of the stored data for this field type in the |credit_card|. |
| 538 string16 creditcard_field_value = credit_card->GetFieldText(type); | 559 string16 creditcard_field_value = credit_card->GetFieldText(type); |
| 539 if (!creditcard_field_value.empty() && | 560 if (!creditcard_field_value.empty() && |
| 540 StartsWith(creditcard_field_value, field.value(), false)) { | 561 StartsWith(creditcard_field_value, field.value(), false)) { |
| 541 if (type.field_type() == CREDIT_CARD_NUMBER) | 562 if (type.field_type() == CREDIT_CARD_NUMBER) |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 number = number.substr(kAutoFillPhoneNumberSuffixOffset, | 615 number = number.substr(kAutoFillPhoneNumberSuffixOffset, |
| 595 kAutoFillPhoneNumberSuffixCount); | 616 kAutoFillPhoneNumberSuffixCount); |
| 596 field->set_value(number); | 617 field->set_value(number); |
| 597 } else { | 618 } else { |
| 598 field->set_value(number); | 619 field->set_value(number); |
| 599 } | 620 } |
| 600 } | 621 } |
| 601 | 622 |
| 602 void AutoFillManager::ParseForms( | 623 void AutoFillManager::ParseForms( |
| 603 const std::vector<webkit_glue::FormData>& forms) { | 624 const std::vector<webkit_glue::FormData>& forms) { |
| 604 for (std::vector<FormData>::const_iterator iter = | 625 for (std::vector<FormData>::const_iterator iter = forms.begin(); |
| 605 forms.begin(); | |
| 606 iter != forms.end(); ++iter) { | 626 iter != forms.end(); ++iter) { |
| 607 scoped_ptr<FormStructure> form_structure(new FormStructure(*iter)); | 627 scoped_ptr<FormStructure> form_structure(new FormStructure(*iter)); |
| 608 if (!form_structure->ShouldBeParsed()) | 628 // TODO(isherman): Might want to set aside forms that have method != POST, |
| 629 // and not send those to the server. It seems like that might not work |
| 630 // though. |
| 631 if (!form_structure->ShouldBeParsed(false)) |
| 609 continue; | 632 continue; |
| 610 | 633 |
| 611 DeterminePossibleFieldTypes(form_structure.get()); | 634 DeterminePossibleFieldTypes(form_structure.get()); |
| 612 form_structures_.push_back(form_structure.release()); | 635 form_structures_.push_back(form_structure.release()); |
| 613 } | 636 } |
| 614 | 637 |
| 615 // If none of the forms were parsed, no use querying the server. | 638 // If none of the forms were parsed, no use querying the server. |
| 616 if (!form_structures_.empty() && !disable_download_manager_requests_) | 639 if (!form_structures_.empty() && !disable_download_manager_requests_) |
| 617 download_manager_.StartQueryRequest(form_structures_); | 640 download_manager_.StartQueryRequest(form_structures_); |
| 618 } | 641 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 666 return std::string(); | 689 return std::string(); |
| 667 | 690 |
| 668 std::map<int, std::string>::const_iterator iter = id_guid_map_.find(id); | 691 std::map<int, std::string>::const_iterator iter = id_guid_map_.find(id); |
| 669 if (iter == id_guid_map_.end()) { | 692 if (iter == id_guid_map_.end()) { |
| 670 NOTREACHED(); | 693 NOTREACHED(); |
| 671 return std::string(); | 694 return std::string(); |
| 672 } | 695 } |
| 673 | 696 |
| 674 return iter->second; | 697 return iter->second; |
| 675 } | 698 } |
| OLD | NEW |