autofill_dialog_i18n_input.cc revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
1// Copyright 2014 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/ui/autofill/autofill_dialog_i18n_input.h"
6
7#include "base/strings/string_split.h"
8#include "base/strings/utf_string_conversions.h"
9#include "chrome/browser/browser_process.h"
10#include "components/autofill/core/browser/address_i18n.h"
11#include "components/autofill/core/browser/autofill_profile.h"
12#include "components/autofill/core/browser/credit_card.h"
13#include "components/autofill/core/browser/field_types.h"
14#include "grit/components_strings.h"
15#include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_data.h"
16#include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_field.h"
17#include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_ui.h"
18#include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_ui_component.h"
19#include "ui/base/l10n/l10n_util.h"
20
21namespace autofill {
22namespace i18ninput {
23
24namespace {
25
26using base::UTF16ToUTF8;
27using ::i18n::addressinput::AddressData;
28using ::i18n::addressinput::AddressField;
29using ::i18n::addressinput::AddressUiComponent;
30
31DetailInput::Length LengthFromHint(AddressUiComponent::LengthHint hint) {
32  if (hint == AddressUiComponent::HINT_SHORT)
33    return DetailInput::SHORT;
34  DCHECK_EQ(hint, AddressUiComponent::HINT_LONG);
35  return DetailInput::LONG;
36}
37
38}  // namespace
39
40void BuildAddressInputs(common::AddressType address_type,
41                        const std::string& country_code,
42                        DetailInputs* inputs,
43                        std::string* language_code) {
44  std::vector<AddressUiComponent> components(
45      ::i18n::addressinput::BuildComponents(
46          country_code, g_browser_process->GetApplicationLocale(),
47          language_code));
48
49  const bool billing = address_type == common::ADDRESS_TYPE_BILLING;
50
51  for (size_t i = 0; i < components.size(); ++i) {
52    const AddressUiComponent& component = components[i];
53    if (component.field == ::i18n::addressinput::ORGANIZATION) {
54      // TODO(dbeam): figure out when we actually need this.
55      continue;
56    }
57
58    ServerFieldType server_type = TypeForField(component.field, address_type);
59    DetailInput::Length length = LengthFromHint(component.length_hint);
60    base::string16 placeholder = l10n_util::GetStringUTF16(component.name_id);
61    DetailInput input = { length, server_type, placeholder };
62    inputs->push_back(input);
63  }
64
65  ServerFieldType server_type =
66      billing ? ADDRESS_BILLING_COUNTRY : ADDRESS_HOME_COUNTRY;
67  base::string16 placeholder_text =
68      l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_COUNTRY);
69  DetailInput input = { DetailInput::LONG, server_type, placeholder_text };
70  inputs->push_back(input);
71}
72
73bool CardHasCompleteAndVerifiedData(const CreditCard& card) {
74  if (!card.IsVerified())
75    return false;
76
77  const ServerFieldType required_fields[] = {
78      CREDIT_CARD_NUMBER,
79      CREDIT_CARD_EXP_MONTH,
80      CREDIT_CARD_EXP_4_DIGIT_YEAR,
81  };
82
83  for (size_t i = 0; i < arraysize(required_fields); ++i) {
84    if (card.GetRawInfo(required_fields[i]).empty())
85      return false;
86  }
87
88  return true;
89}
90
91bool AddressHasCompleteAndVerifiedData(const AutofillProfile& profile,
92                                       const std::string& app_locale) {
93  if (!profile.IsVerified())
94    return false;
95
96  if (!i18n::CreateAddressDataFromAutofillProfile(profile, app_locale)->
97          HasAllRequiredFields()) {
98    return false;
99  }
100
101  const ServerFieldType more_required_fields[] = {
102      NAME_FULL,
103      PHONE_HOME_WHOLE_NUMBER
104  };
105
106  for (size_t i = 0; i < arraysize(more_required_fields); ++i) {
107    if (profile.GetRawInfo(more_required_fields[i]).empty())
108      return false;
109  }
110
111  return true;
112}
113
114ServerFieldType TypeForField(AddressField address_field,
115                             common::AddressType address_type) {
116  bool billing = address_type == common::ADDRESS_TYPE_BILLING;
117  switch (address_field) {
118    case ::i18n::addressinput::COUNTRY:
119      return billing ? ADDRESS_BILLING_COUNTRY : ADDRESS_HOME_COUNTRY;
120    case ::i18n::addressinput::ADMIN_AREA:
121      return billing ? ADDRESS_BILLING_STATE : ADDRESS_HOME_STATE;
122    case ::i18n::addressinput::LOCALITY:
123      return billing ? ADDRESS_BILLING_CITY : ADDRESS_HOME_CITY;
124    case ::i18n::addressinput::DEPENDENT_LOCALITY:
125      return billing ? ADDRESS_BILLING_DEPENDENT_LOCALITY :
126                       ADDRESS_HOME_DEPENDENT_LOCALITY;
127    case ::i18n::addressinput::POSTAL_CODE:
128      return billing ? ADDRESS_BILLING_ZIP : ADDRESS_HOME_ZIP;
129    case ::i18n::addressinput::SORTING_CODE:
130      return billing ? ADDRESS_BILLING_SORTING_CODE : ADDRESS_HOME_SORTING_CODE;
131    case ::i18n::addressinput::STREET_ADDRESS:
132      return billing ? ADDRESS_BILLING_STREET_ADDRESS :
133                       ADDRESS_HOME_STREET_ADDRESS;
134    case ::i18n::addressinput::RECIPIENT:
135      return billing ? NAME_BILLING_FULL : NAME_FULL;
136    case ::i18n::addressinput::ORGANIZATION:
137      return COMPANY_NAME;
138  }
139  NOTREACHED();
140  return UNKNOWN_TYPE;
141}
142
143bool FieldForType(ServerFieldType server_type,
144                  ::i18n::addressinput::AddressField* field) {
145  switch (server_type) {
146    case ADDRESS_BILLING_COUNTRY:
147    case ADDRESS_HOME_COUNTRY:
148      if (field)
149        *field = ::i18n::addressinput::COUNTRY;
150      return true;
151    case ADDRESS_BILLING_STATE:
152    case ADDRESS_HOME_STATE:
153      if (field)
154        *field = ::i18n::addressinput::ADMIN_AREA;
155      return true;
156    case ADDRESS_BILLING_CITY:
157    case ADDRESS_HOME_CITY:
158      if (field)
159        *field = ::i18n::addressinput::LOCALITY;
160      return true;
161    case ADDRESS_BILLING_DEPENDENT_LOCALITY:
162    case ADDRESS_HOME_DEPENDENT_LOCALITY:
163      if (field)
164        *field = ::i18n::addressinput::DEPENDENT_LOCALITY;
165      return true;
166    case ADDRESS_BILLING_SORTING_CODE:
167    case ADDRESS_HOME_SORTING_CODE:
168      if (field)
169        *field = ::i18n::addressinput::SORTING_CODE;
170      return true;
171    case ADDRESS_BILLING_ZIP:
172    case ADDRESS_HOME_ZIP:
173      if (field)
174        *field = ::i18n::addressinput::POSTAL_CODE;
175      return true;
176    case ADDRESS_BILLING_STREET_ADDRESS:
177    case ADDRESS_BILLING_LINE1:
178    case ADDRESS_BILLING_LINE2:
179    case ADDRESS_HOME_STREET_ADDRESS:
180    case ADDRESS_HOME_LINE1:
181    case ADDRESS_HOME_LINE2:
182      if (field)
183        *field = ::i18n::addressinput::STREET_ADDRESS;
184      return true;
185    case COMPANY_NAME:
186      if (field)
187        *field = ::i18n::addressinput::ORGANIZATION;
188      return true;
189    case NAME_BILLING_FULL:
190    case NAME_FULL:
191      if (field)
192        *field = ::i18n::addressinput::RECIPIENT;
193      return true;
194    default:
195      return false;
196  }
197}
198
199}  // namespace i18ninput
200}  // namespace autofill
201