autofill_manager.cc revision 6e1a1d3242a4de2a633c62ba45948dd2d0620990
1// Copyright (c) 2011 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 <map>
9#include <set>
10#include <utility>
11
12#include "base/basictypes.h"
13#include "base/command_line.h"
14#include "base/string16.h"
15#include "base/utf_string_conversions.h"
16#ifndef ANDROID
17#include "chrome/browser/autocomplete_history_manager.h"
18#include "chrome/browser/autofill/autofill_cc_infobar_delegate.h"
19#endif
20#include "chrome/browser/autofill/autofill_dialog.h"
21#include "chrome/browser/autofill/autofill_metrics.h"
22#include "chrome/browser/autofill/form_structure.h"
23#include "chrome/browser/autofill/phone_number.h"
24#include "chrome/browser/autofill/select_control_handler.h"
25#include "chrome/browser/prefs/pref_service.h"
26#include "chrome/browser/profiles/profile.h"
27#ifndef ANDROID
28#include "chrome/browser/renderer_host/render_view_host.h"
29#endif
30#include "chrome/browser/tab_contents/tab_contents.h"
31#ifndef ANDROID
32#include "chrome/browser/ui/browser_list.h"
33#include "chrome/common/autofill_messages.h"
34#endif
35#include "chrome/common/chrome_switches.h"
36#include "chrome/common/guid.h"
37#include "chrome/common/notification_details.h"
38#include "chrome/common/notification_service.h"
39#include "chrome/common/notification_type.h"
40#include "chrome/common/pref_names.h"
41#include "chrome/common/url_constants.h"
42#include "grit/generated_resources.h"
43#include "ui/base/l10n/l10n_util.h"
44#include "webkit/glue/form_data.h"
45#ifdef ANDROID
46#include <WebCoreSupport/autofill/FormFieldAndroid.h>
47#else
48#include "webkit/glue/form_field.h"
49#endif
50
51using webkit_glue::FormData;
52using webkit_glue::FormField;
53
54namespace {
55
56// We only send a fraction of the forms to upload server.
57// The rate for positive/negative matches potentially could be different.
58const double kAutoFillPositiveUploadRateDefaultValue = 0.01;
59const double kAutoFillNegativeUploadRateDefaultValue = 0.01;
60
61const string16::value_type kCreditCardPrefix[] = {'*', 0};
62const string16::value_type kLabelSeparator[] = {';', ' ', '*', 0};
63
64// Removes duplicate suggestions whilst preserving their original order.
65void RemoveDuplicateSuggestions(std::vector<string16>* values,
66                                std::vector<string16>* labels,
67                                std::vector<string16>* icons,
68                                std::vector<int>* unique_ids) {
69  DCHECK_EQ(values->size(), labels->size());
70  DCHECK_EQ(values->size(), icons->size());
71  DCHECK_EQ(values->size(), unique_ids->size());
72
73  std::set<std::pair<string16, string16> > seen_suggestions;
74  std::vector<string16> values_copy;
75  std::vector<string16> labels_copy;
76  std::vector<string16> icons_copy;
77  std::vector<int> unique_ids_copy;
78
79  for (size_t i = 0; i < values->size(); ++i) {
80    const std::pair<string16, string16> suggestion((*values)[i], (*labels)[i]);
81    if (seen_suggestions.insert(suggestion).second) {
82      values_copy.push_back((*values)[i]);
83      labels_copy.push_back((*labels)[i]);
84      icons_copy.push_back((*icons)[i]);
85      unique_ids_copy.push_back((*unique_ids)[i]);
86    }
87  }
88
89  values->swap(values_copy);
90  labels->swap(labels_copy);
91  icons->swap(icons_copy);
92  unique_ids->swap(unique_ids_copy);
93}
94
95// Precondition: |form| should be the cached version of the form that is to be
96// autofilled, and |field| should be the field in the |form| that corresponds to
97// the initiating field. |is_filling_credit_card| should be true if filling
98// credit card data, false otherwise.
99// Fills |section_start| and |section_end| so that [section_start, section_end)
100// gives the bounds of logical section within |form| that includes |field|.
101// Logical sections are identified by two heuristics:
102//  1. The fields in the section must all be profile or credit card fields,
103//     depending on whether |is_filling_credit_card| is true.
104//  2. A logical section should not include multiple fields of the same autofill
105//     type (except for phone/fax numbers, as described below).
106void FindSectionBounds(const FormStructure& form,
107                       const AutoFillField& field,
108                       bool is_filling_credit_card,
109                       size_t* section_start,
110                       size_t* section_end) {
111  DCHECK(section_start);
112  DCHECK(section_end);
113
114  // By default, the relevant section is the entire form.
115  *section_start = 0;
116  *section_end = form.field_count();
117
118  std::set<AutoFillFieldType> seen_types;
119  bool initiating_field_is_in_current_section = false;
120  for (size_t i = 0; i < form.field_count(); ++i) {
121    const AutoFillField* current_field = form.field(i);
122    const AutoFillFieldType current_type =
123        AutoFillType::GetEquivalentFieldType(current_field->type());
124
125    // Fields of unknown type don't help us to distinguish sections.
126    if (current_type == UNKNOWN_TYPE)
127      continue;
128
129    bool already_saw_current_type = seen_types.count(current_type) > 0;
130    // Forms often ask for multiple phone numbers -- e.g. both a daytime and
131    // evening phone number.  Our phone and fax number detection is also
132    // generally a little off.  Hence, ignore both field types as a signal here.
133    AutoFillType::FieldTypeGroup current_type_group =
134        AutoFillType(current_type).group();
135    if (current_type_group == AutoFillType::PHONE_HOME ||
136        current_type_group == AutoFillType::PHONE_FAX)
137      already_saw_current_type = false;
138
139    // If we are filling credit card data, the relevant section should include
140    // only credit card fields; and similarly for profile data.
141    bool is_credit_card_field = current_type_group == AutoFillType::CREDIT_CARD;
142    bool is_appropriate_type = is_credit_card_field == is_filling_credit_card;
143
144    if (already_saw_current_type || !is_appropriate_type) {
145      if (initiating_field_is_in_current_section) {
146        // We reached the end of the section containing the initiating field.
147        *section_end = i;
148        break;
149      }
150
151      // We reached the end of a section, so start a new section.
152      seen_types.clear();
153
154      // Only include the current field in the new section if it matches the
155      // type of data we are filling.
156      if (is_appropriate_type) {
157        *section_start = i;
158      } else {
159        *section_start = i + 1;
160        continue;
161      }
162    }
163
164    seen_types.insert(current_type);
165
166    if (current_field == &field)
167      initiating_field_is_in_current_section = true;
168  }
169
170  // We should have found the initiating field.
171  DCHECK(initiating_field_is_in_current_section);
172}
173
174// Precondition: |form_structure| and |form| should correspond to the same
175// logical form. Returns true if the relevant portion of |form| is auto-filled.
176// The "relevant" fields in |form| are ones corresponding to fields in
177// |form_structure| with indices in the range [section_start, section_end).
178bool SectionIsAutoFilled(const FormStructure* form_structure,
179                         const webkit_glue::FormData& form,
180                         size_t section_start,
181                         size_t section_end) {
182  // TODO(isherman): It would be nice to share most of this code with the loop
183  // in |FillAutoFillFormData()|, but I don't see a particularly clean way to do
184  // that.
185
186  // The list of fields in |form_structure| and |form.fields| often match
187  // directly and we can fill these corresponding fields; however, when the
188  // |form_structure| and |form.fields| do not match directly we search
189  // ahead in the |form_structure| for the matching field.
190  for (size_t i = section_start, j = 0;
191       i < section_end && j < form.fields.size();
192       j++) {
193    size_t k = i;
194
195    // Search forward in the |form_structure| for a corresponding field.
196    while (k < form_structure->field_count() &&
197           *form_structure->field(k) != form.fields[j]) {
198      k++;
199    }
200
201    // If we didn't find a match, continue on to the next |form| field.
202    if (k >= form_structure->field_count())
203      continue;
204
205    AutoFillType autofill_type(form_structure->field(k)->type());
206    if (form.fields[j].is_autofilled())
207      return true;
208
209    // We found a matching field in the |form_structure| so we
210    // proceed to the next |form| field, and the next |form_structure|.
211    ++i;
212  }
213
214  return false;
215}
216
217bool FormIsHTTPS(FormStructure* form) {
218  return form->source_url().SchemeIs(chrome::kHttpsScheme);
219}
220
221}  // namespace
222
223AutoFillManager::AutoFillManager(TabContents* tab_contents)
224    : tab_contents_(tab_contents),
225      personal_data_(NULL),
226      download_manager_(tab_contents_->profile()),
227      disable_download_manager_requests_(false),
228      metric_logger_(new AutoFillMetrics),
229      cc_infobar_(NULL) {
230  DCHECK(tab_contents);
231
232  // |personal_data_| is NULL when using TestTabContents.
233  personal_data_ =
234      tab_contents_->profile()->GetOriginalProfile()->GetPersonalDataManager();
235  download_manager_.SetObserver(this);
236}
237
238AutoFillManager::~AutoFillManager() {
239  download_manager_.SetObserver(NULL);
240}
241
242#ifndef ANDROID
243// static
244void AutoFillManager::RegisterBrowserPrefs(PrefService* prefs) {
245  prefs->RegisterDictionaryPref(prefs::kAutoFillDialogPlacement);
246}
247#endif
248
249#ifndef ANDROID
250// static
251void AutoFillManager::RegisterUserPrefs(PrefService* prefs) {
252  prefs->RegisterBooleanPref(prefs::kAutoFillEnabled, true);
253#if defined(OS_MACOSX)
254  prefs->RegisterBooleanPref(prefs::kAutoFillAuxiliaryProfilesEnabled, true);
255#else
256  prefs->RegisterBooleanPref(prefs::kAutoFillAuxiliaryProfilesEnabled, false);
257#endif
258  prefs->RegisterDoublePref(prefs::kAutoFillPositiveUploadRate,
259                            kAutoFillPositiveUploadRateDefaultValue);
260  prefs->RegisterDoublePref(prefs::kAutoFillNegativeUploadRate,
261                            kAutoFillNegativeUploadRateDefaultValue);
262}
263#endif
264
265#ifndef ANDROID
266void AutoFillManager::DidNavigateMainFramePostCommit(
267    const NavigationController::LoadCommittedDetails& details,
268    const ViewHostMsg_FrameNavigate_Params& params) {
269  Reset();
270}
271#endif
272
273#ifndef ANDROID
274bool AutoFillManager::OnMessageReceived(const IPC::Message& message) {
275  bool handled = true;
276  IPC_BEGIN_MESSAGE_MAP(AutoFillManager, message)
277    IPC_MESSAGE_HANDLER(AutoFillHostMsg_FormsSeen, OnFormsSeen)
278    IPC_MESSAGE_HANDLER(AutoFillHostMsg_FormSubmitted, OnFormSubmitted)
279    IPC_MESSAGE_HANDLER(AutoFillHostMsg_QueryFormFieldAutoFill,
280                        OnQueryFormFieldAutoFill)
281    IPC_MESSAGE_HANDLER(AutoFillHostMsg_ShowAutoFillDialog,
282                        OnShowAutoFillDialog)
283    IPC_MESSAGE_HANDLER(AutoFillHostMsg_FillAutoFillFormData,
284                        OnFillAutoFillFormData)
285    IPC_MESSAGE_HANDLER(AutoFillHostMsg_DidFillAutoFillFormData,
286                        OnDidFillAutoFillFormData)
287    IPC_MESSAGE_HANDLER(AutoFillHostMsg_DidShowAutoFillSuggestions,
288                        OnDidShowAutoFillSuggestions)
289    IPC_MESSAGE_UNHANDLED(handled = false)
290  IPC_END_MESSAGE_MAP()
291
292  return handled;
293}
294#endif
295
296void AutoFillManager::OnFormSubmitted(const FormData& form) {
297  // Let AutoComplete know as well.
298#ifndef ANDROID
299  tab_contents_->autocomplete_history_manager()->OnFormSubmitted(form);
300#endif
301
302  if (!IsAutoFillEnabled())
303    return;
304
305  if (tab_contents_->profile()->IsOffTheRecord())
306    return;
307
308  // Don't save data that was submitted through JavaScript.
309  if (!form.user_submitted)
310    return;
311
312  // Grab a copy of the form data.
313  FormStructure submitted_form(form);
314
315  // Disregard forms that we wouldn't ever autofill in the first place.
316  if (!submitted_form.ShouldBeParsed(true))
317    return;
318
319  DeterminePossibleFieldTypesForUpload(&submitted_form);
320  LogMetricsAboutSubmittedForm(form, &submitted_form);
321
322  UploadFormData(submitted_form);
323
324  if (!submitted_form.IsAutoFillable(true))
325    return;
326
327  ImportFormData(submitted_form);
328}
329
330void AutoFillManager::OnFormsSeen(const std::vector<FormData>& forms) {
331  if (!IsAutoFillEnabled())
332    return;
333
334  ParseForms(forms);
335}
336
337#ifdef ANDROID
338bool AutoFillManager::OnQueryFormFieldAutoFill(
339#else
340void AutoFillManager::OnQueryFormFieldAutoFill(
341#endif
342    int query_id,
343    const webkit_glue::FormData& form,
344    const webkit_glue::FormField& field) {
345  std::vector<string16> values;
346  std::vector<string16> labels;
347  std::vector<string16> icons;
348  std::vector<int> unique_ids;
349
350#ifdef ANDROID
351  AutoFillHost* host = NULL;
352#else
353  RenderViewHost* host = NULL;
354#endif
355  FormStructure* form_structure = NULL;
356  AutoFillField* autofill_field = NULL;
357  if (GetHost(
358          personal_data_->profiles(), personal_data_->credit_cards(), &host) &&
359      FindCachedFormAndField(form, field, &form_structure, &autofill_field) &&
360      // Don't send suggestions for forms that aren't auto-fillable.
361      form_structure->IsAutoFillable(false)) {
362    AutoFillType type(autofill_field->type());
363    bool is_filling_credit_card = (type.group() == AutoFillType::CREDIT_CARD);
364    if (is_filling_credit_card) {
365      GetCreditCardSuggestions(
366          form_structure, field, type, &values, &labels, &icons, &unique_ids);
367    } else {
368      GetProfileSuggestions(
369          form_structure, field, type, &values, &labels, &icons, &unique_ids);
370    }
371
372    DCHECK_EQ(values.size(), labels.size());
373    DCHECK_EQ(values.size(), icons.size());
374    DCHECK_EQ(values.size(), unique_ids.size());
375
376    if (!values.empty()) {
377#ifndef ANDROID
378      // Don't provide AutoFill suggestions when AutoFill is disabled, and don't
379      // provide credit card suggestions for non-HTTPS pages. However, provide a
380      // warning to the user in these cases.
381      int warning = 0;
382      if (!form_structure->IsAutoFillable(true))
383        warning = IDS_AUTOFILL_WARNING_FORM_DISABLED;
384      else if (is_filling_credit_card && !FormIsHTTPS(form_structure))
385        warning = IDS_AUTOFILL_WARNING_INSECURE_CONNECTION;
386      if (warning) {
387        values.assign(1, l10n_util::GetStringUTF16(warning));
388        labels.assign(1, string16());
389        icons.assign(1, string16());
390        unique_ids.assign(1, -1);
391      } else {
392        size_t section_start, section_end;
393        FindSectionBounds(*form_structure, *autofill_field,
394                          is_filling_credit_card, &section_start, &section_end);
395        if (SectionIsAutoFilled(form_structure, form, section_start,
396                                section_end)) {
397          // If the relevant section is auto-filled and the renderer is querying
398          // for suggestions, then the user is editing the value of a field.
399          // In this case, mimic autocomplete: don't display labels or icons,
400          // as that information is redundant.
401          labels.assign(labels.size(), string16());
402          icons.assign(icons.size(), string16());
403        }
404
405        RemoveDuplicateSuggestions(&values, &labels, &icons, &unique_ids);
406      }
407#endif
408    }
409#ifdef ANDROID
410    else {
411      return false;
412    }
413#endif
414  }
415#ifdef ANDROID
416  else {
417    return false;
418  }
419#endif
420
421#ifdef ANDROID
422  host->AutoFillSuggestionsReturned(values, labels, icons, unique_ids);
423  return true;
424#else
425  // Add the results from AutoComplete.  They come back asynchronously, so we
426  // hand off what we generated and they will send the results back to the
427  // renderer.
428  tab_contents_->autocomplete_history_manager()->OnGetAutocompleteSuggestions(
429      query_id, field.name(), field.value(), values, labels, icons, unique_ids);
430#endif
431}
432
433void AutoFillManager::OnFillAutoFillFormData(int query_id,
434                                             const FormData& form,
435                                             const FormField& field,
436                                             int unique_id) {
437  const std::vector<AutoFillProfile*>& profiles = personal_data_->profiles();
438  const std::vector<CreditCard*>& credit_cards = personal_data_->credit_cards();
439#ifdef ANDROID
440  AutoFillHost* host = NULL;
441#else
442  RenderViewHost* host = NULL;
443#endif
444  FormStructure* form_structure = NULL;
445  AutoFillField* autofill_field = NULL;
446  if (!GetHost(profiles, credit_cards, &host) ||
447      !FindCachedFormAndField(form, field, &form_structure, &autofill_field))
448    return;
449
450  DCHECK(host);
451  DCHECK(form_structure);
452  DCHECK(autofill_field);
453
454  // Unpack the |unique_id| into component parts.
455  std::string cc_guid;
456  std::string profile_guid;
457  UnpackGUIDs(unique_id, &cc_guid, &profile_guid);
458  DCHECK(!guid::IsValidGUID(cc_guid) || !guid::IsValidGUID(profile_guid));
459
460  // Find the profile that matches the |profile_id|, if one is specified.
461  const AutoFillProfile* profile = NULL;
462  if (guid::IsValidGUID(profile_guid)) {
463    for (std::vector<AutoFillProfile*>::const_iterator iter = profiles.begin();
464         iter != profiles.end(); ++iter) {
465      if ((*iter)->guid() == profile_guid) {
466        profile = *iter;
467        break;
468      }
469    }
470    DCHECK(profile);
471  }
472
473  // Find the credit card that matches the |cc_id|, if one is specified.
474  const CreditCard* credit_card = NULL;
475  if (guid::IsValidGUID(cc_guid)) {
476    for (std::vector<CreditCard*>::const_iterator iter = credit_cards.begin();
477         iter != credit_cards.end(); ++iter) {
478      if ((*iter)->guid() == cc_guid) {
479        credit_card = *iter;
480        break;
481      }
482    }
483    DCHECK(credit_card);
484  }
485
486  if (!profile && !credit_card)
487    return;
488
489  // Find the section of the form that we are autofilling.
490  size_t section_start, section_end;
491  FindSectionBounds(*form_structure, *autofill_field, (credit_card != NULL),
492                    &section_start, &section_end);
493
494  FormData result = form;
495
496  // If the relevant section is auto-filled, we should fill |field| but not the
497  // rest of the form.
498  if (SectionIsAutoFilled(form_structure, form, section_start, section_end)) {
499    for (std::vector<FormField>::iterator iter = result.fields.begin();
500         iter != result.fields.end(); ++iter) {
501      if ((*iter) == field) {
502        AutoFillType autofill_type(autofill_field->type());
503        if (profile) {
504          DCHECK(autofill_type.group() != AutoFillType::CREDIT_CARD);
505          FillFormField(profile, autofill_type, &(*iter));
506        } else {
507          DCHECK(autofill_type.group() == AutoFillType::CREDIT_CARD);
508          FillCreditCardFormField(credit_card, autofill_type, &(*iter));
509        }
510        break;
511      }
512    }
513
514#ifdef ANDROID
515    host->AutoFillFormDataFilled(query_id, result);
516#else
517    host->Send(new AutoFillMsg_FormDataFilled(host->routing_id(), query_id,
518                                              result));
519#endif
520    return;
521  }
522
523  // The list of fields in |form_structure| and |result.fields| often match
524  // directly and we can fill these corresponding fields; however, when the
525  // |form_structure| and |result.fields| do not match directly we search
526  // ahead in the |form_structure| for the matching field.
527  // See unit tests: AutoFillManagerTest.FormChangesRemoveField and
528  // AutoFillManagerTest.FormChangesAddField for usage.
529  for (size_t i = section_start, j = 0;
530       i < section_end && j < result.fields.size();
531       j++) {
532    size_t k = i;
533
534    // Search forward in the |form_structure| for a corresponding field.
535    while (k < section_end && *form_structure->field(k) != result.fields[j]) {
536      k++;
537    }
538
539    // If we've found a match then fill the |result| field with the found
540    // field in the |form_structure|.
541    if (k >= section_end)
542      continue;
543
544    AutoFillType autofill_type(form_structure->field(k)->type());
545    if (autofill_type.group() != AutoFillType::NO_GROUP) {
546      if (profile) {
547        DCHECK(autofill_type.group() != AutoFillType::CREDIT_CARD);
548        FillFormField(profile, autofill_type, &result.fields[j]);
549      } else {
550        DCHECK(autofill_type.group() == AutoFillType::CREDIT_CARD);
551        FillCreditCardFormField(credit_card, autofill_type, &result.fields[j]);
552      }
553    }
554
555    // We found a matching field in the |form_structure| so we
556    // proceed to the next |result| field, and the next |form_structure|.
557    ++i;
558  }
559  autofilled_forms_signatures_.push_front(form_structure->FormSignature());
560
561#ifdef ANDROID
562  host->AutoFillFormDataFilled(query_id, result);
563#else
564  host->Send(new AutoFillMsg_FormDataFilled(
565      host->routing_id(), query_id, result));
566#endif
567}
568
569void AutoFillManager::OnShowAutoFillDialog() {
570#ifndef ANDROID
571  if (!CommandLine::ForCurrentProcess()->HasSwitch(
572          switches::kDisableTabbedOptions)) {
573    Browser* browser = BrowserList::GetLastActive();
574    if (browser)
575      browser->ShowOptionsTab(chrome::kAutoFillSubPage);
576    return;
577  }
578
579  ShowAutoFillDialog(tab_contents_->GetContentNativeView(),
580                     personal_data_,
581                     tab_contents_->profile()->GetOriginalProfile());
582#endif
583}
584
585void AutoFillManager::OnDidFillAutoFillFormData() {
586#ifndef ANDROID
587  NotificationService::current()->Notify(
588      NotificationType::AUTOFILL_DID_FILL_FORM_DATA,
589      Source<RenderViewHost>(tab_contents_->render_view_host()),
590      NotificationService::NoDetails());
591#endif
592}
593
594void AutoFillManager::OnDidShowAutoFillSuggestions() {
595#ifndef ANDROID
596  NotificationService::current()->Notify(
597      NotificationType::AUTOFILL_DID_SHOW_SUGGESTIONS,
598      Source<RenderViewHost>(tab_contents_->render_view_host()),
599      NotificationService::NoDetails());
600#endif
601}
602
603void AutoFillManager::OnLoadedAutoFillHeuristics(
604    const std::string& heuristic_xml) {
605  // TODO(jhawkins): Store |upload_required| in the AutoFillManager.
606  UploadRequired upload_required;
607  FormStructure::ParseQueryResponse(heuristic_xml,
608                                    form_structures_.get(),
609                                    &upload_required,
610                                    *metric_logger_);
611}
612
613void AutoFillManager::OnUploadedAutoFillHeuristics(
614    const std::string& form_signature) {
615}
616
617void AutoFillManager::OnHeuristicsRequestError(
618    const std::string& form_signature,
619    AutoFillDownloadManager::AutoFillRequestType request_type,
620    int http_error) {
621}
622
623bool AutoFillManager::IsAutoFillEnabled() const {
624#ifdef ANDROID
625  // TODO: This should be a setting in the android UI.
626  return true;
627#endif
628  PrefService* prefs = tab_contents_->profile()->GetPrefs();
629
630  // Migrate obsolete AutoFill pref.
631  if (prefs->FindPreference(prefs::kFormAutofillEnabled)) {
632    bool enabled = prefs->GetBoolean(prefs::kFormAutofillEnabled);
633    prefs->ClearPref(prefs::kFormAutofillEnabled);
634    prefs->SetBoolean(prefs::kAutoFillEnabled, enabled);
635    return enabled;
636  }
637
638  return prefs->GetBoolean(prefs::kAutoFillEnabled);
639}
640
641void AutoFillManager::DeterminePossibleFieldTypesForUpload(
642    FormStructure* submitted_form) {
643  for (size_t i = 0; i < submitted_form->field_count(); i++) {
644    const AutoFillField* field = submitted_form->field(i);
645    FieldTypeSet field_types;
646    personal_data_->GetPossibleFieldTypes(field->value(), &field_types);
647
648    DCHECK(!field_types.empty());
649    submitted_form->set_possible_types(i, field_types);
650  }
651}
652
653void AutoFillManager::LogMetricsAboutSubmittedForm(
654    const FormData& form,
655    const FormStructure* submitted_form) {
656  FormStructure* cached_submitted_form;
657  if (!FindCachedForm(form, &cached_submitted_form)) {
658    NOTREACHED();
659    return;
660  }
661
662  // Map from field signatures to cached fields.
663  std::map<std::string, const AutoFillField*> cached_fields;
664  for (size_t i = 0; i < cached_submitted_form->field_count(); ++i) {
665    const AutoFillField* field = cached_submitted_form->field(i);
666    cached_fields[field->FieldSignature()] = field;
667  }
668
669  std::string experiment_id = cached_submitted_form->server_experiment_id();
670  for (size_t i = 0; i < submitted_form->field_count(); ++i) {
671    const AutoFillField* field = submitted_form->field(i);
672    FieldTypeSet field_types;
673    personal_data_->GetPossibleFieldTypes(field->value(), &field_types);
674    DCHECK(!field_types.empty());
675
676    if (field->form_control_type() == ASCIIToUTF16("select-one")) {
677      // TODO(isherman): <select> fields don't support |is_autofilled()|. Since
678      // this is heavily relied upon by our metrics, we just don't log anything
679      // for all <select> fields. Better to have less data than misleading data.
680      continue;
681    }
682
683    // Log various quality metrics.
684    metric_logger_->Log(AutoFillMetrics::FIELD_SUBMITTED, experiment_id);
685    if (field_types.find(EMPTY_TYPE) == field_types.end() &&
686        field_types.find(UNKNOWN_TYPE) == field_types.end()) {
687      if (field->is_autofilled()) {
688        metric_logger_->Log(AutoFillMetrics::FIELD_AUTOFILLED, experiment_id);
689      } else {
690        metric_logger_->Log(AutoFillMetrics::FIELD_AUTOFILL_FAILED,
691                            experiment_id);
692
693        AutoFillFieldType heuristic_type = UNKNOWN_TYPE;
694        AutoFillFieldType server_type = NO_SERVER_DATA;
695        std::map<std::string, const AutoFillField*>::const_iterator
696            cached_field = cached_fields.find(field->FieldSignature());
697        if (cached_field != cached_fields.end()) {
698          heuristic_type = cached_field->second->heuristic_type();
699          server_type = cached_field->second->server_type();
700        }
701
702        if (heuristic_type == UNKNOWN_TYPE) {
703          metric_logger_->Log(AutoFillMetrics::FIELD_HEURISTIC_TYPE_UNKNOWN,
704                              experiment_id);
705        } else if (field_types.count(heuristic_type)) {
706          metric_logger_->Log(AutoFillMetrics::FIELD_HEURISTIC_TYPE_MATCH,
707                              experiment_id);
708        } else {
709          metric_logger_->Log(AutoFillMetrics::FIELD_HEURISTIC_TYPE_MISMATCH,
710                              experiment_id);
711        }
712
713        if (server_type == NO_SERVER_DATA) {
714          metric_logger_->Log(AutoFillMetrics::FIELD_SERVER_TYPE_UNKNOWN,
715                              experiment_id);
716        } else if (field_types.count(server_type)) {
717          metric_logger_->Log(AutoFillMetrics::FIELD_SERVER_TYPE_MATCH,
718                              experiment_id);
719        } else {
720          metric_logger_->Log(AutoFillMetrics::FIELD_SERVER_TYPE_MISMATCH,
721                              experiment_id);
722        }
723      }
724
725      // TODO(isherman): Other things we might want to log here:
726      // * Per Vadim's email, a combination of (1) whether heuristics fired,
727      //   (2) whether the server returned something interesting, (3) whether
728      //   the user filled the field
729      // * Whether the server type matches the heursitic type
730      //   - Perhaps only if at least one of the types is not unknown/no data.
731    }
732  }
733}
734
735void AutoFillManager::ImportFormData(const FormStructure& submitted_form) {
736  std::vector<const FormStructure*> import;
737  import.push_back(&submitted_form);
738
739  const CreditCard* imported_credit_card;
740  if (!personal_data_->ImportFormData(import, &imported_credit_card))
741    return;
742
743#ifndef ANDROID
744  // If credit card information was submitted, show an infobar to offer to save
745  // it.
746  if (imported_credit_card && tab_contents_) {
747    imported_credit_card_.reset(imported_credit_card);
748    tab_contents_->AddInfoBar(new AutoFillCCInfoBarDelegate(tab_contents_,
749                                                            this));
750  }
751#endif
752}
753
754void AutoFillManager::UploadFormData(const FormStructure& submitted_form) {
755  if (!disable_download_manager_requests_) {
756    bool was_autofilled = false;
757    // Check if the form among last 3 forms that were auto-filled.
758    // Clear older signatures.
759    std::list<std::string>::iterator it;
760    int total_form_checked = 0;
761    for (it = autofilled_forms_signatures_.begin();
762         it != autofilled_forms_signatures_.end() && total_form_checked < 3;
763         ++it, ++total_form_checked) {
764      if (*it == submitted_form.FormSignature())
765        was_autofilled = true;
766    }
767    // Remove outdated form signatures.
768    if (total_form_checked == 3 && it != autofilled_forms_signatures_.end()) {
769      autofilled_forms_signatures_.erase(it,
770                                         autofilled_forms_signatures_.end());
771    }
772    download_manager_.StartUploadRequest(submitted_form, was_autofilled);
773  }
774}
775
776void AutoFillManager::Reset() {
777  form_structures_.reset();
778}
779
780void AutoFillManager::OnInfoBarClosed(bool should_save) {
781  if (should_save)
782    personal_data_->SaveImportedCreditCard(*imported_credit_card_);
783}
784
785AutoFillManager::AutoFillManager()
786    : tab_contents_(NULL),
787      personal_data_(NULL),
788      download_manager_(NULL),
789      disable_download_manager_requests_(true),
790      metric_logger_(new AutoFillMetrics),
791      cc_infobar_(NULL) {
792}
793
794AutoFillManager::AutoFillManager(TabContents* tab_contents,
795                                 PersonalDataManager* personal_data)
796    : tab_contents_(tab_contents),
797      personal_data_(personal_data),
798      download_manager_(NULL),
799      disable_download_manager_requests_(true),
800      metric_logger_(new AutoFillMetrics),
801      cc_infobar_(NULL) {
802  DCHECK(tab_contents);
803}
804
805void AutoFillManager::set_metric_logger(
806    const AutoFillMetrics* metric_logger) {
807  metric_logger_.reset(metric_logger);
808}
809
810bool AutoFillManager::GetHost(const std::vector<AutoFillProfile*>& profiles,
811                              const std::vector<CreditCard*>& credit_cards,
812#ifdef ANDROID
813                              AutoFillHost** host) {
814#else
815                              RenderViewHost** host) {
816#endif
817  if (!IsAutoFillEnabled())
818    return false;
819
820  // No autofill data to return if the profiles are empty.
821  if (profiles.empty() && credit_cards.empty())
822    return false;
823
824#ifdef ANDROID
825  *host = tab_contents_->autofill_host();
826#else
827  *host = tab_contents_->render_view_host();
828#endif
829  if (!*host)
830    return false;
831
832  return true;
833}
834
835bool AutoFillManager::FindCachedForm(const FormData& form,
836                                     FormStructure** form_structure) {
837  // Find the FormStructure that corresponds to |form|.
838  *form_structure = NULL;
839  for (std::vector<FormStructure*>::const_iterator iter =
840       form_structures_.begin();
841       iter != form_structures_.end(); ++iter) {
842    if (**iter == form) {
843      *form_structure = *iter;
844      break;
845    }
846  }
847
848  if (!(*form_structure))
849    return false;
850
851  return true;
852}
853
854bool AutoFillManager::FindCachedFormAndField(const FormData& form,
855                                             const FormField& field,
856                                             FormStructure** form_structure,
857                                             AutoFillField** autofill_field) {
858  // Find the FormStructure that corresponds to |form|.
859  if (!FindCachedForm(form, form_structure))
860    return false;
861
862  // No data to return if there are no auto-fillable fields.
863  if (!(*form_structure)->autofill_count())
864    return false;
865
866  // Find the AutoFillField that corresponds to |field|.
867  *autofill_field = NULL;
868  for (std::vector<AutoFillField*>::const_iterator iter =
869           (*form_structure)->begin();
870       iter != (*form_structure)->end(); ++iter) {
871    // The field list is terminated with a NULL AutoFillField, so don't try to
872    // dereference it.
873    if (!*iter)
874      break;
875
876    if ((**iter) == field) {
877      *autofill_field = *iter;
878      break;
879    }
880  }
881
882  if (!(*autofill_field))
883    return false;
884
885  return true;
886}
887
888void AutoFillManager::GetProfileSuggestions(FormStructure* form,
889                                            const FormField& field,
890                                            AutoFillType type,
891                                            std::vector<string16>* values,
892                                            std::vector<string16>* labels,
893                                            std::vector<string16>* icons,
894                                            std::vector<int>* unique_ids) {
895  const std::vector<AutoFillProfile*>& profiles = personal_data_->profiles();
896  std::vector<AutoFillProfile*> matched_profiles;
897  for (std::vector<AutoFillProfile*>::const_iterator iter = profiles.begin();
898       iter != profiles.end(); ++iter) {
899    AutoFillProfile* profile = *iter;
900
901    // The value of the stored data for this field type in the |profile|.
902    string16 profile_field_value = profile->GetFieldText(type);
903
904    if (!profile_field_value.empty() &&
905        StartsWith(profile_field_value, field.value(), false)) {
906      matched_profiles.push_back(profile);
907      values->push_back(profile_field_value);
908      unique_ids->push_back(PackGUIDs(std::string(), profile->guid()));
909    }
910  }
911
912  std::vector<AutoFillFieldType> form_fields;
913  form_fields.reserve(form->field_count());
914  for (std::vector<AutoFillField*>::const_iterator iter = form->begin();
915       iter != form->end(); ++iter) {
916    // The field list is terminated with a NULL AutoFillField, so don't try to
917    // dereference it.
918    if (!*iter)
919      break;
920    form_fields.push_back((*iter)->type());
921  }
922
923  AutoFillProfile::CreateInferredLabels(&matched_profiles, &form_fields,
924                                        type.field_type(), 1, labels);
925
926  // No icons for profile suggestions.
927  icons->resize(values->size());
928}
929
930void AutoFillManager::GetCreditCardSuggestions(FormStructure* form,
931                                               const FormField& field,
932                                               AutoFillType type,
933                                               std::vector<string16>* values,
934                                               std::vector<string16>* labels,
935                                               std::vector<string16>* icons,
936                                               std::vector<int>* unique_ids) {
937  for (std::vector<CreditCard*>::const_iterator iter =
938           personal_data_->credit_cards().begin();
939       iter != personal_data_->credit_cards().end(); ++iter) {
940    CreditCard* credit_card = *iter;
941
942    // The value of the stored data for this field type in the |credit_card|.
943    string16 creditcard_field_value = credit_card->GetFieldText(type);
944    if (!creditcard_field_value.empty() &&
945        StartsWith(creditcard_field_value, field.value(), false)) {
946      if (type.field_type() == CREDIT_CARD_NUMBER)
947        creditcard_field_value = credit_card->ObfuscatedNumber();
948
949      values->push_back(creditcard_field_value);
950      labels->push_back(kCreditCardPrefix + credit_card->LastFourDigits());
951      icons->push_back(credit_card->type());
952      unique_ids->push_back(PackGUIDs(credit_card->guid(), std::string()));
953    }
954  }
955}
956
957void AutoFillManager::FillCreditCardFormField(const CreditCard* credit_card,
958                                              AutoFillType type,
959                                              webkit_glue::FormField* field) {
960  DCHECK(credit_card);
961  DCHECK(type.group() == AutoFillType::CREDIT_CARD);
962  DCHECK(field);
963
964  if (field->form_control_type() == ASCIIToUTF16("select-one")) {
965    autofill::FillSelectControl(*credit_card, type, field);
966  } else if (field->form_control_type() == ASCIIToUTF16("month")) {
967    // HTML5 input="month" consists of year-month.
968    string16 year = credit_card->GetFieldText(
969        AutoFillType(CREDIT_CARD_EXP_4_DIGIT_YEAR));
970    string16 month = credit_card->GetFieldText(
971        AutoFillType(CREDIT_CARD_EXP_MONTH));
972    if (!year.empty() && !month.empty()) {
973      // Fill the value only if |credit_card| includes both year and month
974      // information.
975      field->set_value(year + ASCIIToUTF16("-") + month);
976    }
977  } else {
978    field->set_value(credit_card->GetFieldText(type));
979  }
980}
981
982void AutoFillManager::FillFormField(const AutoFillProfile* profile,
983                                    AutoFillType type,
984                                    webkit_glue::FormField* field) {
985  DCHECK(profile);
986  DCHECK(type.group() != AutoFillType::CREDIT_CARD);
987  DCHECK(field);
988
989  if (type.subgroup() == AutoFillType::PHONE_NUMBER) {
990    FillPhoneNumberField(profile, type, field);
991  } else {
992    if (field->form_control_type() == ASCIIToUTF16("select-one"))
993      autofill::FillSelectControl(*profile, type, field);
994    else
995      field->set_value(profile->GetFieldText(type));
996  }
997}
998
999void AutoFillManager::FillPhoneNumberField(const AutoFillProfile* profile,
1000                                           AutoFillType type,
1001                                           webkit_glue::FormField* field) {
1002  // If we are filling a phone number, check to see if the size field
1003  // matches the "prefix" or "suffix" sizes and fill accordingly.
1004  string16 number = profile->GetFieldText(AutoFillType(type));
1005  bool has_valid_suffix_and_prefix = (number.length() ==
1006      static_cast<size_t>(PhoneNumber::kPrefixLength +
1007                          PhoneNumber::kSuffixLength));
1008  if (has_valid_suffix_and_prefix &&
1009      field->max_length() == PhoneNumber::kPrefixLength) {
1010    number = number.substr(PhoneNumber::kPrefixOffset,
1011                           PhoneNumber::kPrefixLength);
1012    field->set_value(number);
1013  } else if (has_valid_suffix_and_prefix &&
1014             field->max_length() == PhoneNumber::kSuffixLength) {
1015    number = number.substr(PhoneNumber::kSuffixOffset,
1016                           PhoneNumber::kSuffixLength);
1017    field->set_value(number);
1018  } else {
1019    field->set_value(number);
1020  }
1021}
1022
1023void AutoFillManager::ParseForms(const std::vector<FormData>& forms) {
1024  std::vector<FormStructure*> non_queryable_forms;
1025  for (std::vector<FormData>::const_iterator iter = forms.begin();
1026       iter != forms.end(); ++iter) {
1027    scoped_ptr<FormStructure> form_structure(new FormStructure(*iter));
1028    if (!form_structure->ShouldBeParsed(false))
1029      continue;
1030
1031    // Set aside forms with method GET so that they are not included in the
1032    // query to the server.
1033    if (form_structure->ShouldBeParsed(true))
1034      form_structures_.push_back(form_structure.release());
1035    else
1036      non_queryable_forms.push_back(form_structure.release());
1037  }
1038
1039  // If none of the forms were parsed, no use querying the server.
1040  if (!form_structures_.empty() && !disable_download_manager_requests_)
1041    download_manager_.StartQueryRequest(form_structures_, *metric_logger_);
1042
1043  for (std::vector<FormStructure*>::const_iterator iter =
1044           non_queryable_forms.begin();
1045       iter != non_queryable_forms.end(); ++iter) {
1046    form_structures_.push_back(*iter);
1047  }
1048}
1049
1050// When sending IDs (across processes) to the renderer we pack credit card and
1051// profile IDs into a single integer.  Credit card IDs are sent in the high
1052// word and profile IDs are sent in the low word.
1053int AutoFillManager::PackGUIDs(const std::string& cc_guid,
1054                               const std::string& profile_guid) {
1055  int cc_id = GUIDToID(cc_guid);
1056  int profile_id = GUIDToID(profile_guid);
1057
1058  DCHECK(cc_id <= std::numeric_limits<unsigned short>::max());
1059  DCHECK(profile_id <= std::numeric_limits<unsigned short>::max());
1060
1061  return cc_id << std::numeric_limits<unsigned short>::digits | profile_id;
1062}
1063
1064// When receiving IDs (across processes) from the renderer we unpack credit card
1065// and profile IDs from a single integer.  Credit card IDs are stored in the
1066// high word and profile IDs are stored in the low word.
1067void AutoFillManager::UnpackGUIDs(int id,
1068                                  std::string* cc_guid,
1069                                  std::string* profile_guid) {
1070  int cc_id = id >> std::numeric_limits<unsigned short>::digits &
1071      std::numeric_limits<unsigned short>::max();
1072  int profile_id = id & std::numeric_limits<unsigned short>::max();
1073
1074  *cc_guid = IDToGUID(cc_id);
1075  *profile_guid = IDToGUID(profile_id);
1076}
1077
1078int AutoFillManager::GUIDToID(const std::string& guid) {
1079  static int last_id = 1;
1080
1081  if (!guid::IsValidGUID(guid))
1082    return 0;
1083
1084  std::map<std::string, int>::const_iterator iter = guid_id_map_.find(guid);
1085  if (iter == guid_id_map_.end()) {
1086    guid_id_map_[guid] = last_id;
1087    id_guid_map_[last_id] = guid;
1088    return last_id++;
1089  } else {
1090    return iter->second;
1091  }
1092}
1093
1094const std::string AutoFillManager::IDToGUID(int id) {
1095  if (id == 0)
1096    return std::string();
1097
1098  std::map<int, std::string>::const_iterator iter = id_guid_map_.find(id);
1099  if (iter == id_guid_map_.end()) {
1100    NOTREACHED();
1101    return std::string();
1102  }
1103
1104  return iter->second;
1105}
1106