autofill_manager.cc revision ec088f53b6595e64df8841a817706e6d086cb17c
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#ifdef ANDROID
206  AutoFillHost* host = NULL;
207#else
208  RenderViewHost* host = NULL;
209#endif
210  FormStructure* form_structure = NULL;
211  AutoFillField* autofill_field = NULL;
212  if (!GetHost(personal_data_->profiles(),
213               personal_data_->credit_cards(),
214               &host) ||
215      !FindCachedFormAndField(form, field, &form_structure, &autofill_field))
216    return false;
217
218  DCHECK(host);
219  DCHECK(form_structure);
220  DCHECK(autofill_field);
221
222  // Don't send suggestions for forms that aren't auto-fillable.
223  if (!form_structure->IsAutoFillable(false))
224    return false;
225
226  std::vector<string16> values;
227  std::vector<string16> labels;
228  std::vector<string16> icons;
229  std::vector<int> unique_ids;
230
231  AutoFillType type(autofill_field->type());
232  bool is_filling_credit_card = (type.group() == AutoFillType::CREDIT_CARD);
233  if (is_filling_credit_card) {
234    GetCreditCardSuggestions(
235        form_structure, field, type, &values, &labels, &icons, &unique_ids);
236  } else {
237    GetProfileSuggestions(
238        form_structure, field, type, &values, &labels, &icons, &unique_ids);
239  }
240
241  DCHECK_EQ(values.size(), labels.size());
242  DCHECK_EQ(values.size(), icons.size());
243  DCHECK_EQ(values.size(), unique_ids.size());
244
245  // No suggestions.
246  if (values.empty())
247    return false;
248
249#ifndef ANDROID
250  // Don't provide AutoFill suggestions when AutoFill is disabled, and don't
251  // provide credit card suggestions for non-HTTPS pages. However, provide a
252  // warning to the user in these cases.
253  int warning = 0;
254  if (!form_structure->IsAutoFillable(true))
255    warning = IDS_AUTOFILL_WARNING_FORM_DISABLED;
256  else if (is_filling_credit_card && !FormIsHTTPS(form_structure))
257    warning = IDS_AUTOFILL_WARNING_INSECURE_CONNECTION;
258  if (warning) {
259    values.assign(1, l10n_util::GetStringUTF16(warning));
260    labels.assign(1, string16());
261    icons.assign(1, string16());
262    unique_ids.assign(1, -1);
263    host->AutoFillSuggestionsReturned(values, labels, icons, unique_ids);
264    return true;
265  }
266#endif
267
268  // If the form is auto-filled and the renderer is querying for suggestions,
269  // then the user is editing the value of a field. In this case, mimick
270  // autocomplete: don't display or icons, as that information is redundant.
271  if (FormIsAutoFilled(form_structure, form, is_filling_credit_card)) {
272    labels.assign(labels.size(), string16());
273    icons.assign(icons.size(), string16());
274  }
275
276  RemoveDuplicateSuggestions(&values, &labels, &icons, &unique_ids);
277  host->AutoFillSuggestionsReturned(values, labels, icons, unique_ids);
278  return true;
279}
280
281bool AutoFillManager::FillAutoFillFormData(int query_id,
282                                           const FormData& form,
283                                           const FormField& field,
284                                           int unique_id) {
285  const std::vector<AutoFillProfile*>& profiles = personal_data_->profiles();
286  const std::vector<CreditCard*>& credit_cards = personal_data_->credit_cards();
287#ifdef ANDROID
288  AutoFillHost* host = NULL;
289#else
290  RenderViewHost* host = NULL;
291#endif
292  FormStructure* form_structure = NULL;
293  AutoFillField* autofill_field = NULL;
294  if (!GetHost(profiles, credit_cards, &host) ||
295      !FindCachedFormAndField(form, field, &form_structure, &autofill_field))
296    return false;
297
298  DCHECK(host);
299  DCHECK(form_structure);
300  DCHECK(autofill_field);
301
302  // Unpack the |unique_id| into component parts.
303  std::string cc_guid;
304  std::string profile_guid;
305  UnpackGUIDs(unique_id, &cc_guid, &profile_guid);
306  DCHECK(!guid::IsValidGUID(cc_guid) || !guid::IsValidGUID(profile_guid));
307
308  // Find the profile that matches the |profile_id|, if one is specified.
309  const AutoFillProfile* profile = NULL;
310  if (guid::IsValidGUID(profile_guid)) {
311    for (std::vector<AutoFillProfile*>::const_iterator iter = profiles.begin();
312         iter != profiles.end(); ++iter) {
313      if ((*iter)->guid() == profile_guid) {
314        profile = *iter;
315        break;
316      }
317    }
318    DCHECK(profile);
319  }
320
321  // Find the credit card that matches the |cc_id|, if one is specified.
322  const CreditCard* credit_card = NULL;
323  if (guid::IsValidGUID(cc_guid)) {
324    for (std::vector<CreditCard*>::const_iterator iter = credit_cards.begin();
325         iter != credit_cards.end(); ++iter) {
326      if ((*iter)->guid() == cc_guid) {
327        credit_card = *iter;
328        break;
329      }
330    }
331    DCHECK(credit_card);
332  }
333
334  if (!profile && !credit_card)
335    return false;
336
337  FormData result = form;
338
339  // If the form is auto-filled, we should fill |field| but not the rest of the
340  // form.
341  if (FormIsAutoFilled(form_structure, form, (credit_card != NULL))) {
342    for (std::vector<FormField>::iterator iter = result.fields.begin();
343         iter != result.fields.end(); ++iter) {
344      if ((*iter) == field) {
345        AutoFillType autofill_type(autofill_field->type());
346        if (credit_card &&
347            autofill_type.group() == AutoFillType::CREDIT_CARD) {
348          FillCreditCardFormField(credit_card, autofill_type, &(*iter));
349        } else if (profile &&
350                   autofill_type.group() != AutoFillType::CREDIT_CARD) {
351          FillFormField(profile, autofill_type, &(*iter));
352        }
353        break;
354      }
355    }
356
357    host->AutoFillFormDataFilled(query_id, result);
358    return true;
359  }
360
361  // The list of fields in |form_structure| and |result.fields| often match
362  // directly and we can fill these corresponding fields; however, when the
363  // |form_structure| and |result.fields| do not match directly we search
364  // ahead in the |form_structure| for the matching field.
365  // See unit tests: AutoFillManagerTest.FormChangesRemoveField and
366  // AutoFillManagerTest.FormChangesAddField for usage.
367  for (size_t i = 0, j = 0;
368       i < form_structure->field_count() && j < result.fields.size();
369       j++) {
370    size_t k = i;
371
372    // Search forward in the |form_structure| for a corresponding field.
373    while (k < form_structure->field_count() &&
374           *form_structure->field(k) != result.fields[j]) {
375      k++;
376    }
377
378    // If we've found a match then fill the |result| field with the found
379    // field in the |form_structure|.
380    if (k >= form_structure->field_count())
381      continue;
382
383    const AutoFillField* field = form_structure->field(k);
384    AutoFillType autofill_type(field->type());
385    if (credit_card &&
386        autofill_type.group() == AutoFillType::CREDIT_CARD) {
387      FillCreditCardFormField(credit_card, autofill_type, &result.fields[j]);
388    } else if (profile &&
389               autofill_type.group() != AutoFillType::CREDIT_CARD) {
390      FillFormField(profile, autofill_type, &result.fields[j]);
391    }
392
393    // We found a matching field in the |form_structure| so we
394    // proceed to the next |result| field, and the next |form_structure|.
395    ++i;
396  }
397  autofilled_forms_signatures_.push_front(form_structure->FormSignature());
398
399  host->AutoFillFormDataFilled(query_id, result);
400  return true;
401}
402
403void AutoFillManager::ShowAutoFillDialog() {
404#ifndef ANDROID
405  ::ShowAutoFillDialog(tab_contents_->GetContentNativeView(),
406                       personal_data_,
407                       tab_contents_->profile()->GetOriginalProfile());
408#endif
409}
410
411void AutoFillManager::Reset() {
412  upload_form_structure_.reset();
413  form_structures_.reset();
414}
415
416void AutoFillManager::OnLoadedAutoFillHeuristics(
417    const std::string& heuristic_xml) {
418  // TODO(jhawkins): Store |upload_required| in the AutoFillManager.
419  UploadRequired upload_required;
420  FormStructure::ParseQueryResponse(heuristic_xml,
421                                    form_structures_.get(),
422                                    &upload_required);
423}
424
425void AutoFillManager::OnUploadedAutoFillHeuristics(
426    const std::string& form_signature) {
427}
428
429void AutoFillManager::OnHeuristicsRequestError(
430    const std::string& form_signature,
431    AutoFillDownloadManager::AutoFillRequestType request_type,
432    int http_error) {
433}
434
435bool AutoFillManager::IsAutoFillEnabled() const {
436#ifdef ANDROID
437  // TODO: This should be a setting in the android UI.
438  return true;
439#endif
440  PrefService* prefs = tab_contents_->profile()->GetPrefs();
441
442  // Migrate obsolete AutoFill pref.
443  if (prefs->FindPreference(prefs::kFormAutofillEnabled)) {
444    bool enabled = prefs->GetBoolean(prefs::kFormAutofillEnabled);
445    prefs->ClearPref(prefs::kFormAutofillEnabled);
446    prefs->SetBoolean(prefs::kAutoFillEnabled, enabled);
447    return enabled;
448  }
449
450  return prefs->GetBoolean(prefs::kAutoFillEnabled);
451}
452
453void AutoFillManager::DeterminePossibleFieldTypes(
454    FormStructure* form_structure) {
455  for (size_t i = 0; i < form_structure->field_count(); i++) {
456    const AutoFillField* field = form_structure->field(i);
457    FieldTypeSet field_types;
458    personal_data_->GetPossibleFieldTypes(field->value(), &field_types);
459    form_structure->set_possible_types(i, field_types);
460  }
461}
462
463void AutoFillManager::HandleSubmit() {
464  // If there wasn't enough data to import then we don't want to send an upload
465  // to the server.
466  // TODO(jhawkins): Import form data from |form_structures_|.  That will
467  // require querying the FormManager for updated field values.
468  std::vector<FormStructure*> import;
469  import.push_back(upload_form_structure_.get());
470  if (!personal_data_->ImportFormData(import))
471    return;
472
473  // Did we get credit card info?
474  AutoFillProfile* profile;
475  CreditCard* credit_card;
476  personal_data_->GetImportedFormData(&profile, &credit_card);
477
478  if (!credit_card) {
479    UploadFormData();
480    return;
481  }
482
483#ifndef ANDROID
484  // Show an infobar to offer to save the credit card info.
485  if (tab_contents_) {
486    tab_contents_->AddInfoBar(new AutoFillCCInfoBarDelegate(tab_contents_,
487                                                            this));
488  }
489#endif
490}
491
492void AutoFillManager::UploadFormData() {
493  if (!disable_download_manager_requests_ && upload_form_structure_.get()) {
494    bool was_autofilled = false;
495    // Check if the form among last 3 forms that were auto-filled.
496    // Clear older signatures.
497    std::list<std::string>::iterator it;
498    int total_form_checked = 0;
499    for (it = autofilled_forms_signatures_.begin();
500         it != autofilled_forms_signatures_.end() && total_form_checked < 3;
501         ++it, ++total_form_checked) {
502      if (*it == upload_form_structure_->FormSignature())
503        was_autofilled = true;
504    }
505    // Remove outdated form signatures.
506    if (total_form_checked == 3 && it != autofilled_forms_signatures_.end()) {
507      autofilled_forms_signatures_.erase(it,
508                                         autofilled_forms_signatures_.end());
509    }
510    download_manager_.StartUploadRequest(*(upload_form_structure_.get()),
511                                         was_autofilled);
512  }
513}
514
515void AutoFillManager::OnInfoBarClosed(bool should_save) {
516  if (should_save)
517    personal_data_->SaveImportedCreditCard();
518  UploadFormData();
519}
520
521AutoFillManager::AutoFillManager()
522    : tab_contents_(NULL),
523      personal_data_(NULL),
524      download_manager_(NULL),
525      disable_download_manager_requests_(false),
526      cc_infobar_(NULL) {
527}
528
529AutoFillManager::AutoFillManager(TabContents* tab_contents,
530                                 PersonalDataManager* personal_data)
531    : tab_contents_(tab_contents),
532      personal_data_(personal_data),
533      download_manager_(NULL),
534      disable_download_manager_requests_(false),
535      cc_infobar_(NULL) {
536  DCHECK(tab_contents);
537}
538
539bool AutoFillManager::GetHost(const std::vector<AutoFillProfile*>& profiles,
540                              const std::vector<CreditCard*>& credit_cards,
541#ifdef ANDROID
542                              AutoFillHost** host) {
543#else
544                              RenderViewHost** host) {
545#endif
546  if (!IsAutoFillEnabled())
547    return false;
548
549  // No autofill data to return if the profiles are empty.
550  if (profiles.empty() && credit_cards.empty())
551    return false;
552
553#ifdef ANDROID
554  *host = tab_contents_->autofill_host();
555#else
556  *host = tab_contents_->render_view_host();
557#endif
558  if (!(*host))
559    return false;
560
561  return true;
562}
563
564bool AutoFillManager::FindCachedFormAndField(const FormData& form,
565                                             const FormField& field,
566                                             FormStructure** form_structure,
567                                             AutoFillField** autofill_field) {
568  // Find the FormStructure that corresponds to |form|.
569  *form_structure = NULL;
570  for (std::vector<FormStructure*>::const_iterator iter =
571       form_structures_.begin();
572       iter != form_structures_.end(); ++iter) {
573    if (**iter == form) {
574      *form_structure = *iter;
575      break;
576    }
577  }
578
579  if (!(*form_structure))
580    return false;
581
582  // No data to return if there are no auto-fillable fields.
583  if (!(*form_structure)->autofill_count())
584    return false;
585
586  // Find the AutoFillField that corresponds to |field|.
587  *autofill_field = NULL;
588  for (std::vector<AutoFillField*>::const_iterator iter =
589           (*form_structure)->begin();
590       iter != (*form_structure)->end(); ++iter) {
591    // The field list is terminated with a NULL AutoFillField, so don't try to
592    // dereference it.
593    if (!*iter)
594      break;
595
596    if ((**iter) == field) {
597      *autofill_field = *iter;
598      break;
599    }
600  }
601
602  if (!(*autofill_field))
603    return false;
604
605  return true;
606}
607
608void AutoFillManager::GetProfileSuggestions(FormStructure* form,
609                                            const FormField& field,
610                                            AutoFillType type,
611                                            std::vector<string16>* values,
612                                            std::vector<string16>* labels,
613                                            std::vector<string16>* icons,
614                                            std::vector<int>* unique_ids) {
615  const std::vector<AutoFillProfile*>& profiles = personal_data_->profiles();
616  std::vector<AutoFillProfile*> matched_profiles;
617  for (std::vector<AutoFillProfile*>::const_iterator iter = profiles.begin();
618       iter != profiles.end(); ++iter) {
619    AutoFillProfile* profile = *iter;
620
621    // The value of the stored data for this field type in the |profile|.
622    string16 profile_field_value = profile->GetFieldText(type);
623
624    if (!profile_field_value.empty() &&
625        StartsWith(profile_field_value, field.value(), false)) {
626      matched_profiles.push_back(profile);
627      values->push_back(profile_field_value);
628      unique_ids->push_back(PackGUIDs(std::string(), profile->guid()));
629    }
630  }
631
632  std::vector<AutoFillFieldType> form_fields;
633  form_fields.reserve(form->field_count());
634  for (std::vector<AutoFillField*>::const_iterator iter = form->begin();
635       iter != form->end(); ++iter) {
636    // The field list is terminated with a NULL AutoFillField, so don't try to
637    // dereference it.
638    if (!*iter)
639      break;
640    form_fields.push_back((*iter)->type());
641  }
642
643  AutoFillProfile::CreateInferredLabels(&matched_profiles, labels, 1,
644                                        type.field_type(), &form_fields);
645
646  // No icons for profile suggestions.
647  icons->resize(values->size());
648}
649
650void AutoFillManager::GetCreditCardSuggestions(FormStructure* form,
651                                               const FormField& field,
652                                               AutoFillType type,
653                                               std::vector<string16>* values,
654                                               std::vector<string16>* labels,
655                                               std::vector<string16>* icons,
656                                               std::vector<int>* unique_ids) {
657  for (std::vector<CreditCard*>::const_iterator iter =
658           personal_data_->credit_cards().begin();
659       iter != personal_data_->credit_cards().end(); ++iter) {
660    CreditCard* credit_card = *iter;
661
662    // The value of the stored data for this field type in the |credit_card|.
663    string16 creditcard_field_value = credit_card->GetFieldText(type);
664    if (!creditcard_field_value.empty() &&
665        StartsWith(creditcard_field_value, field.value(), false)) {
666      if (type.field_type() == CREDIT_CARD_NUMBER)
667        creditcard_field_value = credit_card->ObfuscatedNumber();
668
669      values->push_back(creditcard_field_value);
670      labels->push_back(kCreditCardPrefix + credit_card->LastFourDigits());
671      icons->push_back(credit_card->type());
672      unique_ids->push_back(PackGUIDs(credit_card->guid(), std::string()));
673    }
674  }
675}
676
677void AutoFillManager::FillCreditCardFormField(const CreditCard* credit_card,
678                                              AutoFillType type,
679                                              webkit_glue::FormField* field) {
680  DCHECK(credit_card);
681  DCHECK(type.group() == AutoFillType::CREDIT_CARD);
682  DCHECK(field);
683
684  if (field->form_control_type() == ASCIIToUTF16("select-one"))
685    autofill::FillSelectControl(credit_card, type, field);
686  else
687    field->set_value(credit_card->GetFieldText(type));
688}
689
690void AutoFillManager::FillFormField(const AutoFillProfile* profile,
691                                    AutoFillType type,
692                                    webkit_glue::FormField* field) {
693  DCHECK(profile);
694  DCHECK(type.group() != AutoFillType::CREDIT_CARD);
695  DCHECK(field);
696
697  if (type.subgroup() == AutoFillType::PHONE_NUMBER) {
698    FillPhoneNumberField(profile, field);
699  } else {
700    if (field->form_control_type() == ASCIIToUTF16("select-one"))
701      autofill::FillSelectControl(profile, type, field);
702    else
703      field->set_value(profile->GetFieldText(type));
704  }
705}
706
707void AutoFillManager::FillPhoneNumberField(const AutoFillProfile* profile,
708                                           webkit_glue::FormField* field) {
709  // If we are filling a phone number, check to see if the size field
710  // matches the "prefix" or "suffix" sizes and fill accordingly.
711  string16 number = profile->GetFieldText(AutoFillType(PHONE_HOME_NUMBER));
712  bool has_valid_suffix_and_prefix = (number.length() ==
713      static_cast<size_t>(PhoneNumber::kPrefixLength +
714                          PhoneNumber::kSuffixLength));
715  if (has_valid_suffix_and_prefix &&
716      field->max_length() == PhoneNumber::kPrefixLength) {
717    number = number.substr(PhoneNumber::kPrefixOffset,
718                           PhoneNumber::kPrefixLength);
719    field->set_value(number);
720  } else if (has_valid_suffix_and_prefix &&
721             field->max_length() == PhoneNumber::kSuffixLength) {
722    number = number.substr(PhoneNumber::kSuffixOffset,
723                           PhoneNumber::kSuffixLength);
724    field->set_value(number);
725  } else {
726    field->set_value(number);
727  }
728}
729
730void AutoFillManager::ParseForms(const std::vector<FormData>& forms) {
731  std::vector<FormStructure *> non_queryable_forms;
732  for (std::vector<FormData>::const_iterator iter = forms.begin();
733       iter != forms.end(); ++iter) {
734    scoped_ptr<FormStructure> form_structure(new FormStructure(*iter));
735    if (!form_structure->ShouldBeParsed(false))
736      continue;
737
738    DeterminePossibleFieldTypes(form_structure.get());
739
740    // Set aside forms with method GET so that they are not included in the
741    // query to the server.
742    if (form_structure->ShouldBeParsed(true))
743      form_structures_.push_back(form_structure.release());
744    else
745      non_queryable_forms.push_back(form_structure.release());
746  }
747
748  // If none of the forms were parsed, no use querying the server.
749  if (!form_structures_.empty() && !disable_download_manager_requests_)
750    download_manager_.StartQueryRequest(form_structures_);
751
752  for (std::vector<FormStructure *>::const_iterator iter =
753           non_queryable_forms.begin();
754       iter != non_queryable_forms.end(); ++iter) {
755    form_structures_.push_back(*iter);
756  }
757}
758
759// When sending IDs (across processes) to the renderer we pack credit card and
760// profile IDs into a single integer.  Credit card IDs are sent in the high
761// word and profile IDs are sent in the low word.
762int AutoFillManager::PackGUIDs(const std::string& cc_guid,
763                               const std::string& profile_guid) {
764  int cc_id = GUIDToID(cc_guid);
765  int profile_id = GUIDToID(profile_guid);
766
767  DCHECK(cc_id <= std::numeric_limits<unsigned short>::max());
768  DCHECK(profile_id <= std::numeric_limits<unsigned short>::max());
769
770  return cc_id << std::numeric_limits<unsigned short>::digits | profile_id;
771}
772
773// When receiving IDs (across processes) from the renderer we unpack credit card
774// and profile IDs from a single integer.  Credit card IDs are stored in the
775// high word and profile IDs are stored in the low word.
776void AutoFillManager::UnpackGUIDs(int id,
777                                  std::string* cc_guid,
778                                  std::string* profile_guid) {
779  int cc_id = id >> std::numeric_limits<unsigned short>::digits &
780      std::numeric_limits<unsigned short>::max();
781  int profile_id = id & std::numeric_limits<unsigned short>::max();
782
783  *cc_guid = IDToGUID(cc_id);
784  *profile_guid = IDToGUID(profile_id);
785}
786
787int AutoFillManager::GUIDToID(const std::string& guid) {
788  static int last_id = 1;
789
790  if (!guid::IsValidGUID(guid))
791    return 0;
792
793  std::map<std::string, int>::const_iterator iter = guid_id_map_.find(guid);
794  if (iter == guid_id_map_.end()) {
795    guid_id_map_[guid] = last_id;
796    id_guid_map_[last_id] = guid;
797    return last_id++;
798  } else {
799    return iter->second;
800  }
801}
802
803const std::string AutoFillManager::IDToGUID(int id) {
804  if (id == 0)
805    return std::string();
806
807  std::map<int, std::string>::const_iterator iter = id_guid_map_.find(id);
808  if (iter == id_guid_map_.end()) {
809    NOTREACHED();
810    return std::string();
811  }
812
813  return iter->second;
814}
815