autofill_manager.cc revision c407dc5cd9bdc5668497f21b26b09d988ab439de
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
3// found in the LICENSE file.
4
5#include "chrome/browser/autofill/autofill_manager.h"
6
7#include <string>
8
9#include "base/basictypes.h"
10#include "base/string16.h"
11#include "chrome/browser/autofill/autofill_dialog.h"
12#include "chrome/browser/autofill/autofill_cc_infobar_delegate.h"
13#include "chrome/browser/autofill/form_structure.h"
14#include "chrome/browser/pref_service.h"
15#include "chrome/browser/profile.h"
16#include "chrome/browser/renderer_host/render_view_host.h"
17#include "chrome/browser/tab_contents/tab_contents.h"
18#include "chrome/common/chrome_switches.h"
19#include "chrome/common/pref_names.h"
20#include "chrome/common/url_constants.h"
21#include "webkit/glue/form_data.h"
22#include "webkit/glue/form_field.h"
23
24using webkit_glue::FormData;
25using webkit_glue::FormField;
26
27namespace {
28
29// We only send a fraction of the forms to upload server.
30// The rate for positive/negative matches potentially could be different.
31const double kAutoFillPositiveUploadRateDefaultValue = 0.01;
32const double kAutoFillNegativeUploadRateDefaultValue = 0.01;
33
34// Size and offset of the prefix and suffix portions of phone numbers.
35const int kAutoFillPhoneNumberPrefixOffset = 0;
36const int kAutoFillPhoneNumberPrefixCount = 3;
37const int kAutoFillPhoneNumberSuffixOffset = 3;
38const int kAutoFillPhoneNumberSuffixCount = 4;
39
40const string16::value_type kLabelSeparator[] = {';',' ',0};
41
42// Removes duplicate elements whilst preserving original order of |elements| and
43// |unique_ids|.
44void RemoveDuplicateElements(
45    std::vector<string16>* elements, std::vector<int>* unique_ids) {
46  std::vector<string16> copy;
47  for (size_t i = 0; i < elements->size(); ++i) {
48    const string16& element = (*elements)[i];
49
50    bool unique = true;
51    for (std::vector<string16>::const_iterator copy_iter = copy.begin();
52         copy_iter != copy.end(); ++copy_iter) {
53      if (element == *copy_iter) {
54        unique = false;
55        break;
56      }
57    }
58
59    if (unique)
60      copy.push_back(element);
61    else
62      unique_ids->erase(unique_ids->begin() + i);
63  }
64
65  elements->assign(copy.begin(), copy.end());
66}
67
68bool FormIsHTTPS(FormStructure* form) {
69  return form->ConvertToFormData().origin.SchemeIs(chrome::kHttpsScheme);
70}
71
72}  // namespace
73
74// TODO(jhawkins): Maybe this should be in a grd file?
75const char* kAutoFillLearnMoreUrl =
76    "http://www.google.com/support/chrome/bin/answer.py?answer=142893";
77
78AutoFillManager::AutoFillManager(TabContents* tab_contents)
79    : tab_contents_(tab_contents),
80      personal_data_(NULL),
81      download_manager_(tab_contents_->profile()) {
82  DCHECK(tab_contents);
83
84  // |personal_data_| is NULL when using TestTabContents.
85  personal_data_ =
86      tab_contents_->profile()->GetOriginalProfile()->GetPersonalDataManager();
87  download_manager_.SetObserver(this);
88}
89
90AutoFillManager::~AutoFillManager() {
91  download_manager_.SetObserver(NULL);
92}
93
94// static
95void AutoFillManager::RegisterBrowserPrefs(PrefService* prefs) {
96  prefs->RegisterDictionaryPref(prefs::kAutoFillDialogPlacement);
97}
98
99// static
100void AutoFillManager::RegisterUserPrefs(PrefService* prefs) {
101  prefs->RegisterBooleanPref(prefs::kAutoFillEnabled, true);
102#if defined(OS_MACOSX)
103  prefs->RegisterBooleanPref(prefs::kAutoFillAuxiliaryProfilesEnabled, true);
104#else
105  prefs->RegisterBooleanPref(prefs::kAutoFillAuxiliaryProfilesEnabled, false);
106#endif
107  prefs->RegisterRealPref(prefs::kAutoFillPositiveUploadRate,
108                          kAutoFillPositiveUploadRateDefaultValue);
109  prefs->RegisterRealPref(prefs::kAutoFillNegativeUploadRate,
110                          kAutoFillNegativeUploadRateDefaultValue);
111}
112
113void AutoFillManager::FormSubmitted(const FormData& form) {
114  if (!IsAutoFillEnabled())
115    return;
116
117  if (tab_contents_->profile()->IsOffTheRecord())
118    return;
119
120  // Grab a copy of the form data.
121  upload_form_structure_.reset(new FormStructure(form));
122
123  if (!upload_form_structure_->IsAutoFillable())
124    return;
125
126  // Determine the possible field types and upload the form structure to the
127  // PersonalDataManager.
128  DeterminePossibleFieldTypes(upload_form_structure_.get());
129  HandleSubmit();
130}
131
132void AutoFillManager::FormsSeen(const std::vector<FormData>& forms) {
133  if (!IsAutoFillEnabled())
134    return;
135
136  // No profiles or credit cards, no need to parse the forms.
137  if (personal_data_->profiles().empty() &&
138      personal_data_->credit_cards().empty())
139    return;
140
141  ParseForms(forms);
142}
143
144bool AutoFillManager::GetAutoFillSuggestions(int query_id,
145                                             bool form_autofilled,
146                                             const FormField& field) {
147  if (!IsAutoFillEnabled())
148    return false;
149
150  RenderViewHost* host = tab_contents_->render_view_host();
151  if (!host)
152    return false;
153
154  if (personal_data_->profiles().empty() &&
155      personal_data_->credit_cards().empty())
156    return false;
157
158  // Loops through the cached FormStructures looking for the FormStructure that
159  // contains |field| and the associated AutoFillFieldType.
160  FormStructure* form = NULL;
161  AutoFillField* autofill_field = NULL;
162  for (std::vector<FormStructure*>::iterator form_iter =
163           form_structures_.begin();
164       form_iter != form_structures_.end(); ++form_iter) {
165    form = *form_iter;
166
167    // Don't send suggestions for forms that aren't auto-fillable.
168    if (!form->IsAutoFillable())
169      continue;
170
171    for (std::vector<AutoFillField*>::const_iterator iter = form->begin();
172         iter != form->end(); ++iter) {
173      // The field list is terminated with a NULL AutoFillField, so don't try to
174      // dereference it.
175      if (!*iter)
176        break;
177
178      if ((**iter) == field) {
179        autofill_field = *iter;
180        break;
181      }
182    }
183  }
184
185  if (autofill_field == NULL)
186    return false;
187
188  std::vector<string16> values;
189  std::vector<string16> labels;
190  std::vector<int> unique_ids;
191  AutoFillType type(autofill_field->type());
192
193  // If this form is non-HTTPS, treat billing address fields as regular address
194  // fields.
195  bool handle_billing = FormIsHTTPS(form);
196
197  if (type.group() == AutoFillType::CREDIT_CARD)
198    GetCreditCardSuggestions(form, field, type, &values, &labels, &unique_ids);
199  else if (type.group() == AutoFillType::ADDRESS_BILLING)
200    GetBillingProfileSuggestions(
201        form, field, type, &values, &labels, &unique_ids);
202  else
203    GetProfileSuggestions(
204        form, field, type, handle_billing, &values, &labels, &unique_ids);
205
206  DCHECK_EQ(values.size(), labels.size());
207  DCHECK_EQ(values.size(), unique_ids.size());
208
209  // No suggestions.
210  if (values.empty())
211    return false;
212
213  // If the form is auto-filled and the renderer is querying for suggestions,
214  // then the user is editing the value of a field.  In this case, don't display
215  // labels, as that information is redundant. In addition, remove duplicate
216  // values.
217  if (form_autofilled) {
218    RemoveDuplicateElements(&values, &unique_ids);
219    labels.resize(values.size());
220
221    for (size_t i = 0; i < labels.size(); ++i)
222      labels[i] = string16();
223  }
224
225  host->AutoFillSuggestionsReturned(query_id, values, labels, unique_ids);
226  return true;
227}
228
229// TODO(jhawkins): Remove the |value| parameter.
230bool AutoFillManager::FillAutoFillFormData(int query_id,
231                                           const FormData& form,
232                                           const string16& value,
233                                           const string16& label,
234                                           int unique_id) {
235  if (!IsAutoFillEnabled())
236    return false;
237
238  RenderViewHost* host = tab_contents_->render_view_host();
239  if (!host)
240    return false;
241
242  const std::vector<AutoFillProfile*>& profiles = personal_data_->profiles();
243  const std::vector<CreditCard*>& credit_cards = personal_data_->credit_cards();
244
245  // No data to return if the profiles are empty.
246  if (profiles.empty() && credit_cards.empty())
247    return false;
248
249  // Find the FormStructure that corresponds to |form|.
250  FormData result = form;
251  FormStructure* form_structure = NULL;
252  for (std::vector<FormStructure*>::const_iterator iter =
253           form_structures_.begin();
254       iter != form_structures_.end(); ++iter) {
255    if (**iter == form) {
256      form_structure = *iter;
257      break;
258    }
259  }
260
261  if (!form_structure)
262    return false;
263
264  // No data to return if there are no auto-fillable fields.
265  if (!form_structure->autofill_count())
266    return false;
267
268  // |cc_digits| will contain the last four digits of a credit card number only
269  // if the form has billing fields.
270  string16 cc_digits;
271
272  // If the form has billing fields, |label| will contain at least one "; "
273  // followed by the last four digits of a credit card number.
274  if (form_structure->HasBillingFields()) {
275    // We must search for the last "; " as it's possible the profile label
276    // proper can contain this sequence of characters.
277    size_t index = label.find_last_of(kLabelSeparator);
278    if (index != string16::npos) {
279      size_t cc_index = index + 1;
280      cc_digits = label.substr(cc_index);
281    }
282  }
283
284  // Find the profile that matches the |unique_id|.
285  const AutoFillProfile* profile = NULL;
286  for (std::vector<AutoFillProfile*>::const_iterator iter = profiles.begin();
287       iter != profiles.end(); ++iter) {
288    if ((*iter)->unique_id() == unique_id) {
289      profile = *iter;
290    }
291  }
292
293  // Don't look for a matching credit card if we fully-matched the profile using
294  // the entire label.
295  const CreditCard* credit_card = NULL;
296  if (!cc_digits.empty()) {
297    // Find the credit card that matches the |cc_label|.
298    for (std::vector<CreditCard*>::const_iterator iter = credit_cards.begin();
299         iter != credit_cards.end(); ++iter) {
300      if ((*iter)->LastFourDigits() == cc_digits) {
301        credit_card = *iter;
302        break;
303      }
304    }
305  }
306
307  if (!profile && !credit_card)
308    return false;
309
310  // The list of fields in |form_structure| and |result.fields| often match
311  // directly and we can fill these corresponding fields; however, when the
312  // |form_structure| and |result.fields| do not match directly we search
313  // ahead in the |form_structure| for the matching field.
314  // See unit tests: AutoFillManagerTest.FormChangesRemoveField and
315  // AutoFillManagerTest.FormChangesAddField for usage.
316  for (size_t i = 0, j = 0;
317       i < form_structure->field_count() && j < result.fields.size();
318       j++) {
319    size_t k = i;
320
321    // Search forward in the |form_structure| for a corresponding field.
322    while (k < form_structure->field_count() &&
323           *form_structure->field(k) != result.fields[j]) {
324      k++;
325    }
326
327    // If we've found a match then fill the |result| field with the found
328    // field in the |form_structure|.
329    if (k >= form_structure->field_count())
330      continue;
331
332    const AutoFillField* field = form_structure->field(k);
333    AutoFillType autofill_type(field->type());
334    if (credit_card &&
335        autofill_type.group() == AutoFillType::CREDIT_CARD) {
336      result.fields[i].set_value(
337          credit_card->GetFieldText(autofill_type));
338    } else if (credit_card &&
339               autofill_type.group() == AutoFillType::ADDRESS_BILLING) {
340      FillBillingFormField(credit_card, autofill_type, &result.fields[j]);
341    } else if (profile) {
342      FillFormField(profile, autofill_type, &result.fields[j]);
343    }
344
345    // We found a matching field in the |form_structure| so we
346    // proceed to the next |result| field, and the next |form_structure|.
347    ++i;
348  }
349
350  host->AutoFillFormDataFilled(query_id, result);
351  return true;
352}
353
354void AutoFillManager::ShowAutoFillDialog() {
355  ::ShowAutoFillDialog(tab_contents_->GetContentNativeView(),
356                       personal_data_,
357                       tab_contents_->profile()->GetOriginalProfile());
358}
359
360void AutoFillManager::Reset() {
361  upload_form_structure_.reset();
362  form_structures_.reset();
363}
364
365void AutoFillManager::OnLoadedAutoFillHeuristics(
366    const std::string& heuristic_xml) {
367  // TODO(jhawkins): Store |upload_required| in the AutoFillManager.
368  UploadRequired upload_required;
369  FormStructure::ParseQueryResponse(heuristic_xml,
370                                    form_structures_.get(),
371                                    &upload_required);
372}
373
374void AutoFillManager::OnUploadedAutoFillHeuristics(
375    const std::string& form_signature) {
376}
377
378void AutoFillManager::OnHeuristicsRequestError(
379    const std::string& form_signature,
380    AutoFillDownloadManager::AutoFillRequestType request_type,
381    int http_error) {
382}
383
384bool AutoFillManager::IsAutoFillEnabled() const {
385  PrefService* prefs = tab_contents_->profile()->GetPrefs();
386
387  // Migrate obsolete AutoFill pref.
388  if (prefs->FindPreference(prefs::kFormAutofillEnabled)) {
389    bool enabled = prefs->GetBoolean(prefs::kFormAutofillEnabled);
390    prefs->ClearPref(prefs::kFormAutofillEnabled);
391    prefs->SetBoolean(prefs::kAutoFillEnabled, enabled);
392    return enabled;
393  }
394
395  return prefs->GetBoolean(prefs::kAutoFillEnabled);
396}
397
398void AutoFillManager::DeterminePossibleFieldTypes(
399    FormStructure* form_structure) {
400  for (size_t i = 0; i < form_structure->field_count(); i++) {
401    const AutoFillField* field = form_structure->field(i);
402    FieldTypeSet field_types;
403    personal_data_->GetPossibleFieldTypes(field->value(), &field_types);
404    form_structure->set_possible_types(i, field_types);
405  }
406}
407
408void AutoFillManager::HandleSubmit() {
409  // If there wasn't enough data to import then we don't want to send an upload
410  // to the server.
411  // TODO(jhawkins): Import form data from |form_structures_|.  That will
412  // require querying the FormManager for updated field values.
413  std::vector<FormStructure*> import;
414  import.push_back(upload_form_structure_.get());
415  if (!personal_data_->ImportFormData(import, this))
416    return;
417
418  // Did we get credit card info?
419  AutoFillProfile* profile;
420  CreditCard* credit_card;
421  personal_data_->GetImportedFormData(&profile, &credit_card);
422
423  if (credit_card) {
424    cc_infobar_.reset(new AutoFillCCInfoBarDelegate(tab_contents_, this));
425  } else {
426    UploadFormData();
427  }
428}
429
430void AutoFillManager::UploadFormData() {
431  // TODO(georgey): enable upload request when we make sure that our data is in
432  // line with toolbar data:
433  // download_manager_.StartUploadRequest(upload_form_structure_,
434  //                                      form_is_autofilled);
435}
436
437void AutoFillManager::OnInfoBarClosed(bool should_save) {
438  if (should_save)
439    personal_data_->SaveImportedCreditCard();
440  UploadFormData();
441}
442
443AutoFillManager::AutoFillManager()
444    : tab_contents_(NULL),
445      personal_data_(NULL),
446      download_manager_(NULL) {
447}
448
449AutoFillManager::AutoFillManager(TabContents* tab_contents,
450                                 PersonalDataManager* personal_data)
451    : tab_contents_(tab_contents),
452      personal_data_(personal_data),
453      download_manager_(NULL) {
454  DCHECK(tab_contents);
455}
456
457void AutoFillManager::GetProfileSuggestions(FormStructure* form,
458                                            const FormField& field,
459                                            AutoFillType type,
460                                            bool include_cc_labels,
461                                            std::vector<string16>* values,
462                                            std::vector<string16>* labels,
463                                            std::vector<int>* unique_ids) {
464  const std::vector<AutoFillProfile*>& profiles = personal_data_->profiles();
465  std::vector<AutoFillProfile*> matched_profiles;
466  for (std::vector<AutoFillProfile*>::const_iterator iter = profiles.begin();
467       iter != profiles.end(); ++iter) {
468    AutoFillProfile* profile = *iter;
469
470    // The value of the stored data for this field type in the |profile|.
471    string16 profile_field_value = profile->GetFieldText(type);
472
473    if (!profile_field_value.empty() &&
474        StartsWith(profile_field_value, field.value(), false)) {
475      matched_profiles.push_back(profile);
476      values->push_back(profile_field_value);
477      unique_ids->push_back(profile->unique_id());
478    }
479  }
480
481  AutoFillProfile::CreateInferredLabels(&matched_profiles, labels, 0,
482                                        type.field_type());
483
484  if (!include_cc_labels || !form->HasBillingFields() || !FormIsHTTPS(form))
485    return;
486
487  size_t i = 0;
488  std::vector<string16> expanded_values;
489  std::vector<string16> expanded_labels;
490  for (std::vector<AutoFillProfile*>::const_iterator iter =
491       matched_profiles.begin(); iter != matched_profiles.end();
492       ++iter, ++i) {
493    AutoFillProfile* profile = *iter;
494    for (std::vector<CreditCard*>::const_iterator cc =
495         personal_data_->credit_cards().begin();
496         cc != personal_data_->credit_cards().end(); ++cc) {
497      expanded_values.push_back((*values)[i]);
498      string16 label = (*labels)[i] + kLabelSeparator +
499          (*cc)->LastFourDigits();
500      expanded_labels.push_back(label);
501      unique_ids->push_back(profile->unique_id());
502    }
503  }
504  expanded_labels.swap(*labels);
505  expanded_values.swap(*values);
506}
507
508void AutoFillManager::GetBillingProfileSuggestions(
509    FormStructure* form,
510    const FormField& field,
511    AutoFillType type,
512    std::vector<string16>* values,
513    std::vector<string16>* labels,
514    std::vector<int>* unique_ids) {
515  std::vector<CreditCard*> matching_creditcards;
516  std::vector<AutoFillProfile*> matching_profiles;
517  std::vector<string16> cc_values;
518  std::vector<string16> cc_labels;
519
520  // If the form is non-HTTPS, no CC suggestions are provided; however, give the
521  // user the option of filling the billing address fields with regular address
522  // data.
523  if (!FormIsHTTPS(form)) {
524    GetProfileSuggestions(form, field, type, false, values, labels, unique_ids);
525    return;
526  }
527
528  for (std::vector<CreditCard*>::const_iterator cc =
529           personal_data_->credit_cards().begin();
530       cc != personal_data_->credit_cards().end(); ++cc) {
531    string16 label = (*cc)->billing_address();
532    AutoFillProfile* billing_profile = NULL;
533
534    // The value of the stored data for this field type in the |profile|.
535    string16 profile_field_value;
536
537    for (std::vector<AutoFillProfile*>::const_iterator iter =
538             personal_data_->profiles().begin();
539         iter != personal_data_->profiles().end(); ++iter) {
540      AutoFillProfile* profile = *iter;
541
542      // This assumes that labels are unique.
543      if (profile->Label() == label &&
544          !profile->GetFieldText(type).empty() &&
545          StartsWith(profile->GetFieldText(type), field.value(), false)) {
546        billing_profile = profile;
547        break;
548      }
549    }
550
551    if (!billing_profile)
552      continue;
553
554    for (std::vector<AutoFillProfile*>::const_iterator iter =
555             personal_data_->profiles().begin();
556         iter != personal_data_->profiles().end(); ++iter) {
557      values->push_back(billing_profile->GetFieldText(type));
558
559      string16 label = (*iter)->Label() +
560                       ASCIIToUTF16("; ") +
561                       (*cc)->LastFourDigits();
562      labels->push_back(label);
563      unique_ids->push_back((*iter)->unique_id());
564    }
565  }
566}
567
568void AutoFillManager::GetCreditCardSuggestions(FormStructure* form,
569                                               const FormField& field,
570                                               AutoFillType type,
571                                               std::vector<string16>* values,
572                                               std::vector<string16>* labels,
573                                               std::vector<int>* unique_ids) {
574  // Don't return CC suggestions for non-HTTPS pages.
575  if (!FormIsHTTPS(form))
576    return;
577
578  for (std::vector<CreditCard*>::const_iterator iter =
579           personal_data_->credit_cards().begin();
580       iter != personal_data_->credit_cards().end(); ++iter) {
581    CreditCard* credit_card = *iter;
582
583    // The value of the stored data for this field type in the |credit_card|.
584    string16 creditcard_field_value =
585        credit_card->GetFieldText(type);
586    if (!creditcard_field_value.empty() &&
587        StartsWith(creditcard_field_value, field.value(), false)) {
588      if (type.field_type() == CREDIT_CARD_NUMBER)
589        creditcard_field_value = credit_card->ObfuscatedNumber();
590
591      if (!form->HasNonBillingFields()) {
592        values->push_back(creditcard_field_value);
593        labels->push_back(credit_card->Label());
594        unique_ids->push_back(credit_card->unique_id());
595      } else {
596        for (std::vector<AutoFillProfile*>::const_iterator iter =
597                 personal_data_->profiles().begin();
598             iter != personal_data_->profiles().end(); ++iter) {
599          values->push_back(creditcard_field_value);
600
601          string16 label = (*iter)->Label() +
602                           ASCIIToUTF16("; ") +
603                           credit_card->LastFourDigits();
604          labels->push_back(label);
605          unique_ids->push_back((*iter)->unique_id());
606        }
607      }
608    }
609  }
610}
611
612void AutoFillManager::FillBillingFormField(const CreditCard* credit_card,
613                                           AutoFillType type,
614                                           webkit_glue::FormField* field) {
615  DCHECK(credit_card);
616  DCHECK(type.group() == AutoFillType::ADDRESS_BILLING);
617  DCHECK(field);
618
619  string16 billing_address = credit_card->billing_address();
620  if (!billing_address.empty()) {
621    AutoFillProfile* profile = NULL;
622    const std::vector<AutoFillProfile*>& profiles = personal_data_->profiles();
623    for (std::vector<AutoFillProfile*>::const_iterator iter = profiles.begin();
624         iter != profiles.end(); ++iter) {
625      if ((*iter)->Label() == billing_address) {
626        profile = *iter;
627        break;
628      }
629    }
630
631    if (profile) {
632      FillFormField(profile, type, field);
633    }
634  }
635}
636
637void AutoFillManager::FillFormField(const AutoFillProfile* profile,
638                                    AutoFillType type,
639                                    webkit_glue::FormField* field) {
640  DCHECK(profile);
641  DCHECK(field);
642
643  if (type.subgroup() == AutoFillType::PHONE_NUMBER) {
644    FillPhoneNumberField(profile, field);
645  } else {
646    if (field->form_control_type() == ASCIIToUTF16("select-one"))
647      FillSelectOneField(profile, type, field);
648    else
649      field->set_value(profile->GetFieldText(type));
650  }
651}
652
653void AutoFillManager::FillSelectOneField(const AutoFillProfile* profile,
654                                         AutoFillType type,
655                                         webkit_glue::FormField* field) {
656  DCHECK(profile);
657  DCHECK(field);
658  DCHECK(field->form_control_type() == ASCIIToUTF16("select-one"));
659  string16 selected_string = profile->GetFieldText(type);
660  std::string ascii_value = UTF16ToASCII(selected_string);
661  for (size_t i = 0; i < field->option_strings().size(); ++i) {
662    if (profile->GetFieldText(type) == field->option_strings()[i]) {
663      // An exact match - use it.
664      selected_string = profile->GetFieldText(type);
665      break;
666    }
667    if (!base::strcasecmp(UTF16ToASCII(field->option_strings()[i]).c_str(),
668                          ascii_value.c_str())) {
669      // A match, but not in the same case - save it for the case we won't
670      // find an exact match.
671      selected_string = field->option_strings()[i];
672    }
673  }
674  field->set_value(selected_string);
675}
676
677
678void AutoFillManager::FillPhoneNumberField(const AutoFillProfile* profile,
679                                           webkit_glue::FormField* field) {
680  // If we are filling a phone number, check to see if the size field
681  // matches the "prefix" or "suffix" sizes and fill accordingly.
682  string16 number = profile->GetFieldText(AutoFillType(PHONE_HOME_NUMBER));
683  bool has_valid_suffix_and_prefix = (number.length() ==
684      (kAutoFillPhoneNumberPrefixCount + kAutoFillPhoneNumberSuffixCount));
685  if (has_valid_suffix_and_prefix &&
686      field->size() == kAutoFillPhoneNumberPrefixCount) {
687    number = number.substr(kAutoFillPhoneNumberPrefixOffset,
688                           kAutoFillPhoneNumberPrefixCount);
689    field->set_value(number);
690  } else if (has_valid_suffix_and_prefix &&
691             field->size() == kAutoFillPhoneNumberSuffixCount) {
692    number = number.substr(kAutoFillPhoneNumberSuffixOffset,
693                           kAutoFillPhoneNumberSuffixCount);
694    field->set_value(number);
695  } else {
696    field->set_value(number);
697  }
698}
699
700void AutoFillManager::ParseForms(
701    const std::vector<webkit_glue::FormData>& forms) {
702  for (std::vector<FormData>::const_iterator iter =
703           forms.begin();
704       iter != forms.end(); ++iter) {
705    FormStructure* form_structure = new FormStructure(*iter);
706    if (!form_structure->ShouldBeParsed())
707      continue;
708
709    DeterminePossibleFieldTypes(form_structure);
710    form_structures_.push_back(form_structure);
711  }
712
713  // If none of the forms were parsed, no use querying the server.
714  if (!form_structures_.empty())
715    download_manager_.StartQueryRequest(form_structures_);
716}
717