autofill_manager.cc revision 78494470aa829a52d6709093dd00e7704053e806
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 <limits>
8#include <set>
9
10#include "app/l10n_util.h"
11#include "base/basictypes.h"
12#include "base/string16.h"
13#include "base/utf_string_conversions.h"
14#ifndef ANDROID
15#include "chrome/browser/autofill/autofill_cc_infobar_delegate.h"
16#endif
17#include "chrome/browser/autofill/autofill_dialog.h"
18#include "chrome/browser/autofill/form_structure.h"
19#include "chrome/browser/autofill/phone_number.h"
20#include "chrome/browser/autofill/select_control_handler.h"
21#include "chrome/browser/guid.h"
22#include "chrome/browser/prefs/pref_service.h"
23#include "chrome/browser/profile.h"
24#ifndef ANDROID
25#include "chrome/browser/renderer_host/render_view_host.h"
26#endif
27#include "chrome/browser/tab_contents/tab_contents.h"
28#include "chrome/common/chrome_switches.h"
29#include "chrome/common/pref_names.h"
30#include "chrome/common/url_constants.h"
31#ifndef ANDROID
32#include "grit/generated_resources.h"
33#endif
34#include "webkit/glue/form_data.h"
35#ifdef ANDROID
36#include <WebCoreSupport/autofill/FormFieldAndroid.h>
37#else
38#include "webkit/glue/form_field.h"
39#endif
40
41using webkit_glue::FormData;
42using webkit_glue::FormField;
43
44namespace {
45
46// We only send a fraction of the forms to upload server.
47// The rate for positive/negative matches potentially could be different.
48const double kAutoFillPositiveUploadRateDefaultValue = 0.01;
49const double kAutoFillNegativeUploadRateDefaultValue = 0.01;
50
51const string16::value_type kCreditCardPrefix[] = {'*',0};
52const string16::value_type kLabelSeparator[] = {';',' ','*',0};
53
54// Removes duplicate suggestions whilst preserving their original order.
55void RemoveDuplicateSuggestions(std::vector<string16>* values,
56                                std::vector<string16>* labels,
57                                std::vector<string16>* icons,
58                                std::vector<int>* unique_ids) {
59  DCHECK_EQ(values->size(), labels->size());
60  DCHECK_EQ(values->size(), icons->size());
61  DCHECK_EQ(values->size(), unique_ids->size());
62
63  std::set<std::pair<string16, string16> > seen_suggestions;
64  std::vector<string16> values_copy;
65  std::vector<string16> labels_copy;
66  std::vector<string16> icons_copy;
67  std::vector<int> unique_ids_copy;
68
69  for (size_t i = 0; i < values->size(); ++i) {
70    const std::pair<string16, string16> suggestion((*values)[i], (*labels)[i]);
71    if (seen_suggestions.insert(suggestion).second) {
72      values_copy.push_back((*values)[i]);
73      labels_copy.push_back((*labels)[i]);
74      icons_copy.push_back((*icons)[i]);
75      unique_ids_copy.push_back((*unique_ids)[i]);
76    }
77  }
78
79  values->swap(values_copy);
80  labels->swap(labels_copy);
81  icons->swap(icons_copy);
82  unique_ids->swap(unique_ids_copy);
83}
84
85// Precondition: |form_structure| and |form| should correspond to the same
86// logical form. Returns true if the relevant portion of |form| is auto-filled.
87// If |is_filling_credit_card|, the relevant portion is the credit card portion;
88// otherwise it is the address and contact info portion.
89bool FormIsAutoFilled(const FormStructure* form_structure,
90                      const webkit_glue::FormData& form,
91                      bool is_filling_credit_card) {
92  // TODO(isherman): It would be nice to share most of this code with the loop
93  // in |FillAutoFillFormData()|, but I don't see a particularly clean way to do
94  // that.
95
96  // The list of fields in |form_structure| and |form.fields| often match
97  // directly and we can fill these corresponding fields; however, when the
98  // |form_structure| and |form.fields| do not match directly we search
99  // ahead in the |form_structure| for the matching field.
100  for (size_t i = 0, j = 0;
101       i < form_structure->field_count() && j < form.fields.size();
102       j++) {
103    size_t k = i;
104
105    // Search forward in the |form_structure| for a corresponding field.
106    while (k < form_structure->field_count() &&
107           *form_structure->field(k) != form.fields[j]) {
108      k++;
109    }
110
111    // If we didn't find a match, continue on to the next |form| field.
112    if (k >= form_structure->field_count())
113      continue;
114
115    AutoFillType autofill_type(form_structure->field(k)->type());
116    bool is_credit_card_field =
117        autofill_type.group() == AutoFillType::CREDIT_CARD;
118    if (is_filling_credit_card == is_credit_card_field &&
119        form.fields[j].is_autofilled())
120      return true;
121
122    // We found a matching field in the |form_structure| so we
123    // proceed to the next |form| field, and the next |form_structure|.
124    ++i;
125  }
126
127  return false;
128}
129
130bool FormIsHTTPS(FormStructure* form) {
131  return form->source_url().SchemeIs(chrome::kHttpsScheme);
132}
133
134}  // namespace
135
136AutoFillManager::AutoFillManager(TabContents* tab_contents)
137    : tab_contents_(tab_contents),
138      personal_data_(NULL),
139      download_manager_(tab_contents_->profile()),
140      disable_download_manager_requests_(false),
141      cc_infobar_(NULL) {
142  DCHECK(tab_contents);
143
144  // |personal_data_| is NULL when using TestTabContents.
145  personal_data_ =
146      tab_contents_->profile()->GetOriginalProfile()->GetPersonalDataManager();
147  download_manager_.SetObserver(this);
148}
149
150AutoFillManager::~AutoFillManager() {
151  download_manager_.SetObserver(NULL);
152}
153
154// static
155void AutoFillManager::RegisterBrowserPrefs(PrefService* prefs) {
156  prefs->RegisterDictionaryPref(prefs::kAutoFillDialogPlacement);
157}
158
159// static
160void AutoFillManager::RegisterUserPrefs(PrefService* prefs) {
161  prefs->RegisterBooleanPref(prefs::kAutoFillEnabled, true);
162#if defined(OS_MACOSX)
163  prefs->RegisterBooleanPref(prefs::kAutoFillAuxiliaryProfilesEnabled, true);
164#else
165  prefs->RegisterBooleanPref(prefs::kAutoFillAuxiliaryProfilesEnabled, false);
166#endif
167  prefs->RegisterRealPref(prefs::kAutoFillPositiveUploadRate,
168                          kAutoFillPositiveUploadRateDefaultValue);
169  prefs->RegisterRealPref(prefs::kAutoFillNegativeUploadRate,
170                          kAutoFillNegativeUploadRateDefaultValue);
171}
172
173void AutoFillManager::FormSubmitted(const FormData& form) {
174  if (!IsAutoFillEnabled())
175    return;
176
177  if (tab_contents_->profile()->IsOffTheRecord())
178    return;
179
180  // Don't save data that was submitted through JavaScript.
181  if (!form.user_submitted)
182    return;
183
184  // Grab a copy of the form data.
185  upload_form_structure_.reset(new FormStructure(form));
186
187  if (!upload_form_structure_->IsAutoFillable(true))
188    return;
189
190  // Determine the possible field types and upload the form structure to the
191  // PersonalDataManager.
192  DeterminePossibleFieldTypes(upload_form_structure_.get());
193  HandleSubmit();
194}
195
196void AutoFillManager::FormsSeen(const std::vector<FormData>& forms) {
197  if (!IsAutoFillEnabled())
198    return;
199
200  ParseForms(forms);
201}
202
203bool AutoFillManager::GetAutoFillSuggestions(const FormData& form,
204                                             const FormField& field) {
205  RenderViewHost* host = NULL;
206  FormStructure* form_structure = NULL;
207  AutoFillField* autofill_field = NULL;
208  if (!GetHost(personal_data_->profiles(),
209               personal_data_->credit_cards(),
210               &host) ||
211      !FindCachedFormAndField(form, field, &form_structure, &autofill_field))
212    return false;
213
214  DCHECK(host);
215  DCHECK(form_structure);
216  DCHECK(autofill_field);
217
218  // Don't send suggestions for forms that aren't auto-fillable.
219  if (!form_structure->IsAutoFillable(false))
220    return false;
221
222  std::vector<string16> values;
223  std::vector<string16> labels;
224  std::vector<string16> icons;
225  std::vector<int> unique_ids;
226
227  AutoFillType type(autofill_field->type());
228  bool is_filling_credit_card = (type.group() == AutoFillType::CREDIT_CARD);
229  if (is_filling_credit_card) {
230    GetCreditCardSuggestions(
231        form_structure, field, type, &values, &labels, &icons, &unique_ids);
232  } else {
233    GetProfileSuggestions(
234        form_structure, field, type, &values, &labels, &icons, &unique_ids);
235  }
236
237  DCHECK_EQ(values.size(), labels.size());
238  DCHECK_EQ(values.size(), icons.size());
239  DCHECK_EQ(values.size(), unique_ids.size());
240
241  // No suggestions.
242  if (values.empty())
243    return false;
244
245#ifndef ANDROID
246  // Don't provide AutoFill suggestions when AutoFill is disabled, and don't
247  // provide credit card suggestions for non-HTTPS pages. However, provide a
248  // warning to the user in these cases.
249  int warning = 0;
250  if (!form_structure->IsAutoFillable(true))
251    warning = IDS_AUTOFILL_WARNING_FORM_DISABLED;
252  else if (is_filling_credit_card && !FormIsHTTPS(form_structure))
253    warning = IDS_AUTOFILL_WARNING_INSECURE_CONNECTION;
254  if (warning) {
255    values.assign(1, l10n_util::GetStringUTF16(warning));
256    labels.assign(1, string16());
257    icons.assign(1, string16());
258    unique_ids.assign(1, -1);
259    host->AutoFillSuggestionsReturned(values, labels, icons, unique_ids);
260    return true;
261  }
262#endif
263
264  // If the form is auto-filled and the renderer is querying for suggestions,
265  // then the user is editing the value of a field. In this case, mimick
266  // autocomplete: don't display or icons, as that information is redundant.
267  if (FormIsAutoFilled(form_structure, form, is_filling_credit_card)) {
268    labels.assign(labels.size(), string16());
269    icons.assign(icons.size(), string16());
270  }
271
272  RemoveDuplicateSuggestions(&values, &labels, &icons, &unique_ids);
273  host->AutoFillSuggestionsReturned(values, labels, icons, unique_ids);
274  return true;
275}
276
277bool AutoFillManager::FillAutoFillFormData(int query_id,
278                                           const FormData& form,
279                                           const FormField& field,
280                                           int unique_id) {
281  const std::vector<AutoFillProfile*>& profiles = personal_data_->profiles();
282  const std::vector<CreditCard*>& credit_cards = personal_data_->credit_cards();
283  RenderViewHost* host = NULL;
284  FormStructure* form_structure = NULL;
285  AutoFillField* autofill_field = NULL;
286  if (!GetHost(profiles, credit_cards, &host) ||
287      !FindCachedFormAndField(form, field, &form_structure, &autofill_field))
288    return false;
289
290  DCHECK(host);
291  DCHECK(form_structure);
292  DCHECK(autofill_field);
293
294  // Unpack the |unique_id| into component parts.
295  std::string cc_guid;
296  std::string profile_guid;
297  UnpackGUIDs(unique_id, &cc_guid, &profile_guid);
298  DCHECK(!guid::IsValidGUID(cc_guid) || !guid::IsValidGUID(profile_guid));
299
300  // Find the profile that matches the |profile_id|, if one is specified.
301  const AutoFillProfile* profile = NULL;
302  if (guid::IsValidGUID(profile_guid)) {
303    for (std::vector<AutoFillProfile*>::const_iterator iter = profiles.begin();
304         iter != profiles.end(); ++iter) {
305      if ((*iter)->guid() == profile_guid) {
306        profile = *iter;
307        break;
308      }
309    }
310    DCHECK(profile);
311  }
312
313  // Find the credit card that matches the |cc_id|, if one is specified.
314  const CreditCard* credit_card = NULL;
315  if (guid::IsValidGUID(cc_guid)) {
316    for (std::vector<CreditCard*>::const_iterator iter = credit_cards.begin();
317         iter != credit_cards.end(); ++iter) {
318      if ((*iter)->guid() == cc_guid) {
319        credit_card = *iter;
320        break;
321      }
322    }
323    DCHECK(credit_card);
324  }
325
326  if (!profile && !credit_card)
327    return false;
328
329  FormData result = form;
330
331  // If the form is auto-filled, we should fill |field| but not the rest of the
332  // form.
333  if (FormIsAutoFilled(form_structure, form, (credit_card != NULL))) {
334    for (std::vector<FormField>::iterator iter = result.fields.begin();
335         iter != result.fields.end(); ++iter) {
336      if ((*iter) == field) {
337        AutoFillType autofill_type(autofill_field->type());
338        if (credit_card &&
339            autofill_type.group() == AutoFillType::CREDIT_CARD) {
340          FillCreditCardFormField(credit_card, autofill_type, &(*iter));
341        } else if (profile &&
342                   autofill_type.group() != AutoFillType::CREDIT_CARD) {
343          FillFormField(profile, autofill_type, &(*iter));
344        }
345        break;
346      }
347    }
348
349    host->AutoFillFormDataFilled(query_id, result);
350    return true;
351  }
352
353  // The list of fields in |form_structure| and |result.fields| often match
354  // directly and we can fill these corresponding fields; however, when the
355  // |form_structure| and |result.fields| do not match directly we search
356  // ahead in the |form_structure| for the matching field.
357  // See unit tests: AutoFillManagerTest.FormChangesRemoveField and
358  // AutoFillManagerTest.FormChangesAddField for usage.
359  for (size_t i = 0, j = 0;
360       i < form_structure->field_count() && j < result.fields.size();
361       j++) {
362    size_t k = i;
363
364    // Search forward in the |form_structure| for a corresponding field.
365    while (k < form_structure->field_count() &&
366           *form_structure->field(k) != result.fields[j]) {
367      k++;
368    }
369
370    // If we've found a match then fill the |result| field with the found
371    // field in the |form_structure|.
372    if (k >= form_structure->field_count())
373      continue;
374
375    const AutoFillField* field = form_structure->field(k);
376    AutoFillType autofill_type(field->type());
377    if (credit_card &&
378        autofill_type.group() == AutoFillType::CREDIT_CARD) {
379      FillCreditCardFormField(credit_card, autofill_type, &result.fields[j]);
380    } else if (profile &&
381               autofill_type.group() != AutoFillType::CREDIT_CARD) {
382      FillFormField(profile, autofill_type, &result.fields[j]);
383    }
384
385    // We found a matching field in the |form_structure| so we
386    // proceed to the next |result| field, and the next |form_structure|.
387    ++i;
388  }
389  autofilled_forms_signatures_.push_front(form_structure->FormSignature());
390
391  host->AutoFillFormDataFilled(query_id, result);
392  return true;
393}
394
395void AutoFillManager::ShowAutoFillDialog() {
396#ifndef ANDROID
397  ::ShowAutoFillDialog(tab_contents_->GetContentNativeView(),
398                       personal_data_,
399                       tab_contents_->profile()->GetOriginalProfile());
400#endif
401}
402
403void AutoFillManager::Reset() {
404  upload_form_structure_.reset();
405  form_structures_.reset();
406}
407
408void AutoFillManager::OnLoadedAutoFillHeuristics(
409    const std::string& heuristic_xml) {
410  // TODO(jhawkins): Store |upload_required| in the AutoFillManager.
411  UploadRequired upload_required;
412  FormStructure::ParseQueryResponse(heuristic_xml,
413                                    form_structures_.get(),
414                                    &upload_required);
415}
416
417void AutoFillManager::OnUploadedAutoFillHeuristics(
418    const std::string& form_signature) {
419}
420
421void AutoFillManager::OnHeuristicsRequestError(
422    const std::string& form_signature,
423    AutoFillDownloadManager::AutoFillRequestType request_type,
424    int http_error) {
425}
426
427bool AutoFillManager::IsAutoFillEnabled() const {
428#ifdef ANDROID
429  // TODO: This should be a setting in the android UI.
430  return true;
431#endif
432  PrefService* prefs = tab_contents_->profile()->GetPrefs();
433
434  // Migrate obsolete AutoFill pref.
435  if (prefs->FindPreference(prefs::kFormAutofillEnabled)) {
436    bool enabled = prefs->GetBoolean(prefs::kFormAutofillEnabled);
437    prefs->ClearPref(prefs::kFormAutofillEnabled);
438    prefs->SetBoolean(prefs::kAutoFillEnabled, enabled);
439    return enabled;
440  }
441
442  return prefs->GetBoolean(prefs::kAutoFillEnabled);
443}
444
445void AutoFillManager::DeterminePossibleFieldTypes(
446    FormStructure* form_structure) {
447  for (size_t i = 0; i < form_structure->field_count(); i++) {
448    const AutoFillField* field = form_structure->field(i);
449    FieldTypeSet field_types;
450    personal_data_->GetPossibleFieldTypes(field->value(), &field_types);
451    form_structure->set_possible_types(i, field_types);
452  }
453}
454
455void AutoFillManager::HandleSubmit() {
456  // If there wasn't enough data to import then we don't want to send an upload
457  // to the server.
458  // TODO(jhawkins): Import form data from |form_structures_|.  That will
459  // require querying the FormManager for updated field values.
460  std::vector<FormStructure*> import;
461  import.push_back(upload_form_structure_.get());
462  if (!personal_data_->ImportFormData(import))
463    return;
464
465  // Did we get credit card info?
466  AutoFillProfile* profile;
467  CreditCard* credit_card;
468  personal_data_->GetImportedFormData(&profile, &credit_card);
469
470  if (!credit_card) {
471    UploadFormData();
472    return;
473  }
474
475#ifndef ANDROID
476  // Show an infobar to offer to save the credit card info.
477  if (tab_contents_) {
478    tab_contents_->AddInfoBar(new AutoFillCCInfoBarDelegate(tab_contents_,
479                                                            this));
480  }
481#endif
482}
483
484void AutoFillManager::UploadFormData() {
485  if (!disable_download_manager_requests_ && upload_form_structure_.get()) {
486    bool was_autofilled = false;
487    // Check if the form among last 3 forms that were auto-filled.
488    // Clear older signatures.
489    std::list<std::string>::iterator it;
490    int total_form_checked = 0;
491    for (it = autofilled_forms_signatures_.begin();
492         it != autofilled_forms_signatures_.end() && total_form_checked < 3;
493         ++it, ++total_form_checked) {
494      if (*it == upload_form_structure_->FormSignature())
495        was_autofilled = true;
496    }
497    // Remove outdated form signatures.
498    if (total_form_checked == 3 && it != autofilled_forms_signatures_.end()) {
499      autofilled_forms_signatures_.erase(it,
500                                         autofilled_forms_signatures_.end());
501    }
502    download_manager_.StartUploadRequest(*(upload_form_structure_.get()),
503                                         was_autofilled);
504  }
505}
506
507void AutoFillManager::OnInfoBarClosed(bool should_save) {
508  if (should_save)
509    personal_data_->SaveImportedCreditCard();
510  UploadFormData();
511}
512
513AutoFillManager::AutoFillManager()
514    : tab_contents_(NULL),
515      personal_data_(NULL),
516      download_manager_(NULL),
517      disable_download_manager_requests_(false),
518      cc_infobar_(NULL) {
519}
520
521AutoFillManager::AutoFillManager(TabContents* tab_contents,
522                                 PersonalDataManager* personal_data)
523    : tab_contents_(tab_contents),
524      personal_data_(personal_data),
525      download_manager_(NULL),
526      disable_download_manager_requests_(false),
527      cc_infobar_(NULL) {
528  DCHECK(tab_contents);
529}
530
531bool AutoFillManager::GetHost(const std::vector<AutoFillProfile*>& profiles,
532                              const std::vector<CreditCard*>& credit_cards,
533                              RenderViewHost** host) {
534  if (!IsAutoFillEnabled())
535    return false;
536
537  // No autofill data to return if the profiles are empty.
538  if (profiles.empty() && credit_cards.empty())
539    return false;
540
541#ifdef ANDROID
542  *host = tab_contents_->autofill_host();
543#else
544  *host = tab_contents_->render_view_host();
545#endif
546  if (!(*host))
547    return false;
548
549  return true;
550}
551
552bool AutoFillManager::FindCachedFormAndField(const FormData& form,
553                                             const FormField& field,
554                                             FormStructure** form_structure,
555                                             AutoFillField** autofill_field) {
556  // Find the FormStructure that corresponds to |form|.
557  *form_structure = NULL;
558  for (std::vector<FormStructure*>::const_iterator iter =
559       form_structures_.begin();
560       iter != form_structures_.end(); ++iter) {
561    if (**iter == form) {
562      *form_structure = *iter;
563      break;
564    }
565  }
566
567  if (!(*form_structure))
568    return false;
569
570  // No data to return if there are no auto-fillable fields.
571  if (!(*form_structure)->autofill_count())
572    return false;
573
574  // Find the AutoFillField that corresponds to |field|.
575  *autofill_field = NULL;
576  for (std::vector<AutoFillField*>::const_iterator iter =
577           (*form_structure)->begin();
578       iter != (*form_structure)->end(); ++iter) {
579    // The field list is terminated with a NULL AutoFillField, so don't try to
580    // dereference it.
581    if (!*iter)
582      break;
583
584    if ((**iter) == field) {
585      *autofill_field = *iter;
586      break;
587    }
588  }
589
590  if (!(*autofill_field))
591    return false;
592
593  return true;
594}
595
596void AutoFillManager::GetProfileSuggestions(FormStructure* form,
597                                            const FormField& field,
598                                            AutoFillType type,
599                                            std::vector<string16>* values,
600                                            std::vector<string16>* labels,
601                                            std::vector<string16>* icons,
602                                            std::vector<int>* unique_ids) {
603  const std::vector<AutoFillProfile*>& profiles = personal_data_->profiles();
604  std::vector<AutoFillProfile*> matched_profiles;
605  for (std::vector<AutoFillProfile*>::const_iterator iter = profiles.begin();
606       iter != profiles.end(); ++iter) {
607    AutoFillProfile* profile = *iter;
608
609    // The value of the stored data for this field type in the |profile|.
610    string16 profile_field_value = profile->GetFieldText(type);
611
612    if (!profile_field_value.empty() &&
613        StartsWith(profile_field_value, field.value(), false)) {
614      matched_profiles.push_back(profile);
615      values->push_back(profile_field_value);
616      unique_ids->push_back(PackGUIDs(std::string(), profile->guid()));
617    }
618  }
619
620  std::vector<AutoFillFieldType> form_fields;
621  form_fields.reserve(form->field_count());
622  for (std::vector<AutoFillField*>::const_iterator iter = form->begin();
623       iter != form->end(); ++iter) {
624    // The field list is terminated with a NULL AutoFillField, so don't try to
625    // dereference it.
626    if (!*iter)
627      break;
628    form_fields.push_back((*iter)->type());
629  }
630
631  AutoFillProfile::CreateInferredLabels(&matched_profiles, labels, 1,
632                                        type.field_type(), &form_fields);
633
634  // No icons for profile suggestions.
635  icons->resize(values->size());
636}
637
638void AutoFillManager::GetCreditCardSuggestions(FormStructure* form,
639                                               const FormField& field,
640                                               AutoFillType type,
641                                               std::vector<string16>* values,
642                                               std::vector<string16>* labels,
643                                               std::vector<string16>* icons,
644                                               std::vector<int>* unique_ids) {
645  for (std::vector<CreditCard*>::const_iterator iter =
646           personal_data_->credit_cards().begin();
647       iter != personal_data_->credit_cards().end(); ++iter) {
648    CreditCard* credit_card = *iter;
649
650    // The value of the stored data for this field type in the |credit_card|.
651    string16 creditcard_field_value = credit_card->GetFieldText(type);
652    if (!creditcard_field_value.empty() &&
653        StartsWith(creditcard_field_value, field.value(), false)) {
654      if (type.field_type() == CREDIT_CARD_NUMBER)
655        creditcard_field_value = credit_card->ObfuscatedNumber();
656
657      values->push_back(creditcard_field_value);
658      labels->push_back(kCreditCardPrefix + credit_card->LastFourDigits());
659      icons->push_back(credit_card->type());
660      unique_ids->push_back(PackGUIDs(credit_card->guid(), std::string()));
661    }
662  }
663}
664
665void AutoFillManager::FillCreditCardFormField(const CreditCard* credit_card,
666                                              AutoFillType type,
667                                              webkit_glue::FormField* field) {
668  DCHECK(credit_card);
669  DCHECK(type.group() == AutoFillType::CREDIT_CARD);
670  DCHECK(field);
671
672  if (field->form_control_type() == ASCIIToUTF16("select-one"))
673    autofill::FillSelectControl(credit_card, type, field);
674  else
675    field->set_value(credit_card->GetFieldText(type));
676}
677
678void AutoFillManager::FillFormField(const AutoFillProfile* profile,
679                                    AutoFillType type,
680                                    webkit_glue::FormField* field) {
681  DCHECK(profile);
682  DCHECK(type.group() != AutoFillType::CREDIT_CARD);
683  DCHECK(field);
684
685  if (type.subgroup() == AutoFillType::PHONE_NUMBER) {
686    FillPhoneNumberField(profile, field);
687  } else {
688    if (field->form_control_type() == ASCIIToUTF16("select-one"))
689      autofill::FillSelectControl(profile, type, field);
690    else
691      field->set_value(profile->GetFieldText(type));
692  }
693}
694
695void AutoFillManager::FillPhoneNumberField(const AutoFillProfile* profile,
696                                           webkit_glue::FormField* field) {
697  // If we are filling a phone number, check to see if the size field
698  // matches the "prefix" or "suffix" sizes and fill accordingly.
699  string16 number = profile->GetFieldText(AutoFillType(PHONE_HOME_NUMBER));
700  bool has_valid_suffix_and_prefix = (number.length() ==
701      static_cast<size_t>(PhoneNumber::kPrefixLength +
702                          PhoneNumber::kSuffixLength));
703  if (has_valid_suffix_and_prefix &&
704      field->max_length() == PhoneNumber::kPrefixLength) {
705    number = number.substr(PhoneNumber::kPrefixOffset,
706                           PhoneNumber::kPrefixLength);
707    field->set_value(number);
708  } else if (has_valid_suffix_and_prefix &&
709             field->max_length() == PhoneNumber::kSuffixLength) {
710    number = number.substr(PhoneNumber::kSuffixOffset,
711                           PhoneNumber::kSuffixLength);
712    field->set_value(number);
713  } else {
714    field->set_value(number);
715  }
716}
717
718void AutoFillManager::ParseForms(const std::vector<FormData>& forms) {
719  std::vector<FormStructure *> non_queryable_forms;
720  for (std::vector<FormData>::const_iterator iter = forms.begin();
721       iter != forms.end(); ++iter) {
722    scoped_ptr<FormStructure> form_structure(new FormStructure(*iter));
723    if (!form_structure->ShouldBeParsed(false))
724      continue;
725
726    DeterminePossibleFieldTypes(form_structure.get());
727
728    // Set aside forms with method GET so that they are not included in the
729    // query to the server.
730    if (form_structure->ShouldBeParsed(true))
731      form_structures_.push_back(form_structure.release());
732    else
733      non_queryable_forms.push_back(form_structure.release());
734  }
735
736  // If none of the forms were parsed, no use querying the server.
737  if (!form_structures_.empty() && !disable_download_manager_requests_)
738    download_manager_.StartQueryRequest(form_structures_);
739
740  for (std::vector<FormStructure *>::const_iterator iter =
741           non_queryable_forms.begin();
742       iter != non_queryable_forms.end(); ++iter) {
743    form_structures_.push_back(*iter);
744  }
745}
746
747// When sending IDs (across processes) to the renderer we pack credit card and
748// profile IDs into a single integer.  Credit card IDs are sent in the high
749// word and profile IDs are sent in the low word.
750int AutoFillManager::PackGUIDs(const std::string& cc_guid,
751                               const std::string& profile_guid) {
752  int cc_id = GUIDToID(cc_guid);
753  int profile_id = GUIDToID(profile_guid);
754
755  DCHECK(cc_id <= std::numeric_limits<unsigned short>::max());
756  DCHECK(profile_id <= std::numeric_limits<unsigned short>::max());
757
758  return cc_id << std::numeric_limits<unsigned short>::digits | profile_id;
759}
760
761// When receiving IDs (across processes) from the renderer we unpack credit card
762// and profile IDs from a single integer.  Credit card IDs are stored in the
763// high word and profile IDs are stored in the low word.
764void AutoFillManager::UnpackGUIDs(int id,
765                                  std::string* cc_guid,
766                                  std::string* profile_guid) {
767  int cc_id = id >> std::numeric_limits<unsigned short>::digits &
768      std::numeric_limits<unsigned short>::max();
769  int profile_id = id & std::numeric_limits<unsigned short>::max();
770
771  *cc_guid = IDToGUID(cc_id);
772  *profile_guid = IDToGUID(profile_id);
773}
774
775int AutoFillManager::GUIDToID(const std::string& guid) {
776  static int last_id = 1;
777
778  if (!guid::IsValidGUID(guid))
779    return 0;
780
781  std::map<std::string, int>::const_iterator iter = guid_id_map_.find(guid);
782  if (iter == guid_id_map_.end()) {
783    guid_id_map_[guid] = last_id;
784    id_guid_map_[last_id] = guid;
785    return last_id++;
786  } else {
787    return iter->second;
788  }
789}
790
791const std::string AutoFillManager::IDToGUID(int id) {
792  if (id == 0)
793    return std::string();
794
795  std::map<int, std::string>::const_iterator iter = id_guid_map_.find(id);
796  if (iter == id_guid_map_.end()) {
797    NOTREACHED();
798    return std::string();
799  }
800
801  return iter->second;
802}
803