Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / autofill / autofill_dialog_i18n_input.cc
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/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"
20
21 namespace autofill {
22 namespace i18ninput {
23
24 namespace {
25
26 static int g_enabled_for_testing_ = 0;
27
28 using base::UTF16ToUTF8;
29 using ::i18n::addressinput::AddressData;
30 using ::i18n::addressinput::AddressField;
31 using ::i18n::addressinput::AddressUiComponent;
32
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;
38 }
39
40 }  // namespace
41
42 bool Enabled() {
43   if (g_enabled_for_testing_ > 0)
44     return true;
45
46   CommandLine* command_line = CommandLine::ForCurrentProcess();
47   return !command_line->HasSwitch(::switches::kDisableAutofillAddressI18n);
48 }
49
50 ScopedEnableForTesting::ScopedEnableForTesting() {
51   ++g_enabled_for_testing_;
52   DCHECK_GE(g_enabled_for_testing_, 1);
53 }
54
55 ScopedEnableForTesting::~ScopedEnableForTesting() {
56   --g_enabled_for_testing_;
57   DCHECK_GE(g_enabled_for_testing_, 0);
58 }
59
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));
65
66   const bool billing = address_type == common::ADDRESS_TYPE_BILLING;
67
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.
72       continue;
73     }
74
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);
80
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);
89     }
90   }
91
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);
98 }
99
100 bool CardHasCompleteAndVerifiedData(const CreditCard& card) {
101   if (!card.IsVerified())
102     return false;
103
104   const ServerFieldType required_fields[] = {
105       CREDIT_CARD_NUMBER,
106       CREDIT_CARD_EXP_MONTH,
107       CREDIT_CARD_EXP_4_DIGIT_YEAR,
108   };
109
110   for (size_t i = 0; i < arraysize(required_fields); ++i) {
111     if (card.GetRawInfo(required_fields[i]).empty())
112       return false;
113   }
114
115   return true;
116 }
117
118 bool AddressHasCompleteAndVerifiedData(const AutofillProfile& profile) {
119   if (!profile.IsVerified())
120     return false;
121
122   base::string16 country_code = profile.GetRawInfo(ADDRESS_HOME_COUNTRY);
123   if (country_code.empty())
124     return false;
125
126   std::vector<AddressField> required_fields =
127       ::i18n::addressinput::GetRequiredFields(base::UTF16ToUTF8(country_code));
128
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())
133       return false;
134   }
135
136   const ServerFieldType more_required_fields[] = {
137       NAME_FULL,
138       PHONE_HOME_WHOLE_NUMBER
139   };
140
141   for (size_t i = 0; i < arraysize(more_required_fields); ++i) {
142     if (profile.GetRawInfo(more_required_fields[i]).empty())
143       return false;
144   }
145
146   return true;
147 }
148
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:
171       return COMPANY_NAME;
172   }
173   NOTREACHED();
174   return UNKNOWN_TYPE;
175 }
176
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)));
194   base::SplitString(
195       UTF16ToUTF8(get_info.Run(AutofillType(ADDRESS_HOME_STREET_ADDRESS))),
196       '\n',
197       &address_data->address_lines);
198 }
199
200 }  // namespace i18ninput
201 }  // namespace autofill