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.
5 #include "chrome/browser/ui/autofill/autofill_dialog_i18n_input.h"
7 #include "base/command_line.h"
8 #include "base/strings/string_split.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/common/chrome_switches.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/component_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"
26 static int g_enabled_for_testing_ = 0;
28 using base::UTF16ToUTF8;
29 using ::i18n::addressinput::AddressData;
30 using ::i18n::addressinput::AddressField;
31 using ::i18n::addressinput::AddressUiComponent;
33 DetailInput::Length LengthFromHint(AddressUiComponent::LengthHint hint) {
34 if (hint == AddressUiComponent::HINT_SHORT)
35 return DetailInput::SHORT;
36 DCHECK_EQ(hint, AddressUiComponent::HINT_LONG);
37 return DetailInput::LONG;
43 if (g_enabled_for_testing_ > 0)
46 CommandLine* command_line = CommandLine::ForCurrentProcess();
47 return !command_line->HasSwitch(::switches::kDisableAutofillAddressI18n);
50 ScopedEnableForTesting::ScopedEnableForTesting() {
51 ++g_enabled_for_testing_;
52 DCHECK_GE(g_enabled_for_testing_, 1);
55 ScopedEnableForTesting::~ScopedEnableForTesting() {
56 --g_enabled_for_testing_;
57 DCHECK_GE(g_enabled_for_testing_, 0);
60 void BuildAddressInputs(common::AddressType address_type,
61 const std::string& country_code,
62 DetailInputs* inputs) {
63 std::vector<AddressUiComponent> components(
64 ::i18n::addressinput::BuildComponents(country_code));
66 const bool billing = address_type == common::ADDRESS_TYPE_BILLING;
68 for (size_t i = 0; i < components.size(); ++i) {
69 const AddressUiComponent& component = components[i];
70 if (component.field == ::i18n::addressinput::ORGANIZATION) {
71 // TODO(dbeam): figure out when we actually need this.
75 ServerFieldType server_type = TypeForField(component.field, address_type);
76 DetailInput::Length length = LengthFromHint(component.length_hint);
77 base::string16 placeholder = l10n_util::GetStringUTF16(component.name_id);
78 DetailInput input = { length, server_type, placeholder };
79 inputs->push_back(input);
81 if (component.field == ::i18n::addressinput::STREET_ADDRESS &&
82 component.length_hint == AddressUiComponent::HINT_LONG) {
83 // TODO(dbeam): support more than 2 address lines. http://crbug.com/324889
84 ServerFieldType server_type =
85 billing ? ADDRESS_BILLING_LINE2 : ADDRESS_HOME_LINE2;
86 base::string16 placeholder = l10n_util::GetStringUTF16(component.name_id);
87 DetailInput input = { length, server_type, placeholder };
88 inputs->push_back(input);
92 ServerFieldType server_type =
93 billing ? ADDRESS_BILLING_COUNTRY : ADDRESS_HOME_COUNTRY;
94 base::string16 placeholder_text =
95 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_COUNTRY);
96 DetailInput input = { DetailInput::LONG, server_type, placeholder_text };
97 inputs->push_back(input);
100 bool CardHasCompleteAndVerifiedData(const CreditCard& card) {
101 if (!card.IsVerified())
104 const ServerFieldType required_fields[] = {
106 CREDIT_CARD_EXP_MONTH,
107 CREDIT_CARD_EXP_4_DIGIT_YEAR,
110 for (size_t i = 0; i < arraysize(required_fields); ++i) {
111 if (card.GetRawInfo(required_fields[i]).empty())
118 bool AddressHasCompleteAndVerifiedData(const AutofillProfile& profile) {
119 if (!profile.IsVerified())
122 base::string16 country_code = profile.GetRawInfo(ADDRESS_HOME_COUNTRY);
123 if (country_code.empty())
126 std::vector<AddressField> required_fields =
127 ::i18n::addressinput::GetRequiredFields(base::UTF16ToUTF8(country_code));
129 for (size_t i = 0; i < required_fields.size(); ++i) {
130 ServerFieldType type =
131 TypeForField(required_fields[i], common::ADDRESS_TYPE_SHIPPING);
132 if (profile.GetRawInfo(type).empty())
136 const ServerFieldType more_required_fields[] = {
138 PHONE_HOME_WHOLE_NUMBER
141 for (size_t i = 0; i < arraysize(more_required_fields); ++i) {
142 if (profile.GetRawInfo(more_required_fields[i]).empty())
149 ServerFieldType TypeForField(AddressField address_field,
150 common::AddressType address_type) {
151 bool billing = address_type == common::ADDRESS_TYPE_BILLING;
152 switch (address_field) {
153 case ::i18n::addressinput::COUNTRY:
154 return billing ? ADDRESS_BILLING_COUNTRY : ADDRESS_HOME_COUNTRY;
155 case ::i18n::addressinput::ADMIN_AREA:
156 return billing ? ADDRESS_BILLING_STATE : ADDRESS_HOME_STATE;
157 case ::i18n::addressinput::LOCALITY:
158 return billing ? ADDRESS_BILLING_CITY : ADDRESS_HOME_CITY;
159 case ::i18n::addressinput::DEPENDENT_LOCALITY:
160 return billing ? ADDRESS_BILLING_DEPENDENT_LOCALITY :
161 ADDRESS_HOME_DEPENDENT_LOCALITY;
162 case ::i18n::addressinput::POSTAL_CODE:
163 return billing ? ADDRESS_BILLING_ZIP : ADDRESS_HOME_ZIP;
164 case ::i18n::addressinput::SORTING_CODE:
165 return billing ? ADDRESS_BILLING_SORTING_CODE : ADDRESS_HOME_SORTING_CODE;
166 case ::i18n::addressinput::STREET_ADDRESS:
167 return billing ? ADDRESS_BILLING_LINE1 : ADDRESS_HOME_LINE1;
168 case ::i18n::addressinput::RECIPIENT:
169 return billing ? NAME_BILLING_FULL : NAME_FULL;
170 case ::i18n::addressinput::ORGANIZATION:
177 void CreateAddressData(
178 const base::Callback<base::string16(const AutofillType&)>& get_info,
179 AddressData* address_data) {
180 address_data->recipient = UTF16ToUTF8(get_info.Run(AutofillType(NAME_FULL)));
181 address_data->country_code = UTF16ToUTF8(
182 get_info.Run(AutofillType(HTML_TYPE_COUNTRY_CODE, HTML_MODE_SHIPPING)));
183 DCHECK_EQ(2U, address_data->country_code.size());
184 address_data->administrative_area = UTF16ToUTF8(
185 get_info.Run(AutofillType(ADDRESS_HOME_STATE)));
186 address_data->locality = UTF16ToUTF8(
187 get_info.Run(AutofillType(ADDRESS_HOME_CITY)));
188 address_data->dependent_locality = UTF16ToUTF8(
189 get_info.Run(AutofillType(ADDRESS_HOME_DEPENDENT_LOCALITY)));
190 address_data->sorting_code = UTF16ToUTF8(
191 get_info.Run(AutofillType(ADDRESS_HOME_SORTING_CODE)));
192 address_data->postal_code = UTF16ToUTF8(
193 get_info.Run(AutofillType(ADDRESS_HOME_ZIP)));
195 UTF16ToUTF8(get_info.Run(AutofillType(ADDRESS_HOME_STREET_ADDRESS))),
197 &address_data->address_lines);
200 } // namespace i18ninput
201 } // namespace autofill