autofill_dialog_common.cc revision 0529e5d033099cbfc42635f6f6183833b09dff6e
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/autofill/autofill_dialog_common.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "components/autofill/core/browser/autofill_country.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "components/autofill/core/browser/autofill_field.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "components/autofill/core/browser/autofill_type.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/chromium_strings.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/component_strings.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/webkit_resources.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_ANDROID)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/autofill/autofill_dialog_i18n_input.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // !defined(OS_ANDROID)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace autofill {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace common {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ServerTypeEncompassesFieldType(ServerFieldType type,
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                    const AutofillType& field_type) {
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // If any credit card expiration info is asked for, show both month and year
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // inputs.
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ServerFieldType server_type = field_type.GetStorableType();
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (server_type == CREDIT_CARD_EXP_4_DIGIT_YEAR ||
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      server_type == CREDIT_CARD_EXP_2_DIGIT_YEAR ||
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      server_type == CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR ||
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      server_type == CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR ||
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      server_type == CREDIT_CARD_EXP_MONTH) {
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return type == CREDIT_CARD_EXP_4_DIGIT_YEAR ||
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)           type == CREDIT_CARD_EXP_MONTH;
387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (server_type == CREDIT_CARD_TYPE)
41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return type == CREDIT_CARD_NUMBER;
42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Check the groups to distinguish billing types from shipping ones.
447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  AutofillType autofill_type = AutofillType(type);
457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (autofill_type.group() != field_type.group())
467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return false;
477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_ANDROID)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Street address (all lines) is matched to the first input address line.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (server_type == ADDRESS_HOME_STREET_ADDRESS)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return autofill_type.GetStorableType() == ADDRESS_HOME_LINE1;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The page may ask for individual address lines; this roughly matches the
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // street address blob.
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (server_type == ADDRESS_HOME_LINE1 || server_type == ADDRESS_HOME_LINE2)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return autofill_type.GetStorableType() == ADDRESS_HOME_STREET_ADDRESS;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return autofill_type.GetStorableType() == server_type;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ServerTypeMatchesField(DialogSection section,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            ServerFieldType type,
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            const AutofillField& field) {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AutofillType field_type = field.Type();
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The credit card name is filled from the billing section's data.
68  if (field_type.GetStorableType() == CREDIT_CARD_NAME &&
69      (section == SECTION_BILLING || section == SECTION_CC_BILLING)) {
70    return type == NAME_BILLING_FULL;
71  }
72
73  return ServerTypeEncompassesFieldType(type, field_type);
74}
75
76bool IsCreditCardType(ServerFieldType type) {
77  return AutofillType(type).group() == CREDIT_CARD;
78}
79
80void BuildInputs(const DetailInput* input_template,
81                 size_t template_size,
82                 DetailInputs* inputs) {
83  for (size_t i = 0; i < template_size; ++i) {
84    const DetailInput* input = &input_template[i];
85    inputs->push_back(*input);
86  }
87}
88
89bool IsI18nInputEnabled() {
90#if defined(OS_ANDROID)
91  return false;
92#else
93  return true;
94#endif
95}
96
97void BuildI18nAddressInputs(AddressType address_type,
98                            const std::string& country_code,
99                            DetailInputs* inputs,
100                            std::string* language_code) {
101#if defined(OS_ANDROID)
102  NOTREACHED();
103#else
104  i18ninput::BuildAddressInputs(address_type, country_code, inputs,
105                                language_code);
106#endif
107}
108
109// Constructs |inputs| from template data for a given |dialog_section|.
110void BuildInputsForSection(DialogSection dialog_section,
111                           const std::string& country_code,
112                           DetailInputs* inputs,
113                           std::string* language_code) {
114  using l10n_util::GetStringUTF16;
115
116  const DetailInput kCCInputs[] = {
117    { DetailInput::LONG,
118      CREDIT_CARD_NUMBER,
119      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CARD_NUMBER) },
120    { DetailInput::SHORT,
121      CREDIT_CARD_EXP_MONTH,
122      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_EXPIRY_MONTH) },
123    { DetailInput::SHORT,
124      CREDIT_CARD_EXP_4_DIGIT_YEAR,
125      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_EXPIRY_YEAR) },
126    { DetailInput::SHORT_EOL,
127      CREDIT_CARD_VERIFICATION_CODE,
128      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC),
129      1.5 },
130  };
131
132  const DetailInput kBillingInputs[] = {
133    { DetailInput::LONG,
134      NAME_BILLING_FULL,
135      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CARDHOLDER_NAME) },
136    { DetailInput::LONG,
137      ADDRESS_BILLING_LINE1,
138      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESS_LINE_1) },
139    { DetailInput::LONG,
140      ADDRESS_BILLING_LINE2,
141      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESS_LINE_2) },
142    { DetailInput::LONG,
143      ADDRESS_BILLING_CITY,
144      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_LOCALITY) },
145    { DetailInput::SHORT,
146      ADDRESS_BILLING_STATE,
147      GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_STATE) },
148    { DetailInput::SHORT_EOL,
149      ADDRESS_BILLING_ZIP,
150      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_POSTAL_CODE) },
151    // We don't allow the user to change the country: http://crbug.com/247518
152    { DetailInput::NONE, ADDRESS_BILLING_COUNTRY },
153  };
154
155  const DetailInput kBillingPhoneInputs[] = {
156    { DetailInput::LONG,
157      PHONE_BILLING_WHOLE_NUMBER,
158      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_PHONE_NUMBER) },
159  };
160
161  const DetailInput kEmailInputs[] = {
162    { DetailInput::LONG,
163      EMAIL_ADDRESS,
164      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_EMAIL) },
165  };
166
167  const DetailInput kShippingInputs[] = {
168    { DetailInput::LONG,
169      NAME_FULL,
170      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESSEE_NAME) },
171    { DetailInput::LONG,
172      ADDRESS_HOME_LINE1,
173      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESS_LINE_1) },
174    { DetailInput::LONG,
175      ADDRESS_HOME_LINE2,
176      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESS_LINE_2) },
177    { DetailInput::LONG,
178      ADDRESS_HOME_CITY,
179      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_LOCALITY) },
180    { DetailInput::SHORT,
181      ADDRESS_HOME_STATE,
182      GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_STATE) },
183    { DetailInput::SHORT_EOL,
184      ADDRESS_HOME_ZIP,
185      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_POSTAL_CODE) },
186    { DetailInput::NONE, ADDRESS_HOME_COUNTRY },
187  };
188
189  const DetailInput kShippingPhoneInputs[] = {
190    { DetailInput::LONG,
191      PHONE_HOME_WHOLE_NUMBER,
192      GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_PHONE_NUMBER) },
193  };
194
195  switch (dialog_section) {
196    case SECTION_CC:
197      BuildInputs(kCCInputs, arraysize(kCCInputs), inputs);
198      break;
199
200    case SECTION_BILLING:
201      if (IsI18nInputEnabled()) {
202        BuildI18nAddressInputs(ADDRESS_TYPE_BILLING, country_code, inputs,
203                               language_code);
204      } else {
205        BuildInputs(kBillingInputs, arraysize(kBillingInputs), inputs);
206      }
207
208      BuildInputs(kBillingPhoneInputs, arraysize(kBillingPhoneInputs), inputs);
209      BuildInputs(kEmailInputs, arraysize(kEmailInputs), inputs);
210      break;
211
212    case SECTION_CC_BILLING:
213      BuildInputs(kCCInputs, arraysize(kCCInputs), inputs);
214
215      if (IsI18nInputEnabled()) {
216        // Wallet only supports US billing addresses.
217        const std::string hardcoded_country_code = "US";
218        BuildI18nAddressInputs(ADDRESS_TYPE_BILLING,
219                               hardcoded_country_code,
220                               inputs,
221                               language_code);
222        DCHECK_EQ(inputs->back().type, ADDRESS_BILLING_COUNTRY);
223        inputs->back().length = DetailInput::NONE;
224        const std::string& app_locale =
225            g_browser_process->GetApplicationLocale();
226        inputs->back().initial_value =
227            AutofillCountry(hardcoded_country_code, app_locale).name();
228      } else {
229        BuildInputs(kBillingInputs, arraysize(kBillingInputs), inputs);
230      }
231
232      BuildInputs(kBillingPhoneInputs, arraysize(kBillingPhoneInputs), inputs);
233      break;
234
235    case SECTION_SHIPPING:
236      if (IsI18nInputEnabled()) {
237        BuildI18nAddressInputs(ADDRESS_TYPE_SHIPPING, country_code, inputs,
238                               language_code);
239      } else {
240        BuildInputs(kShippingInputs, arraysize(kShippingInputs), inputs);
241      }
242
243      BuildInputs(
244          kShippingPhoneInputs, arraysize(kShippingPhoneInputs), inputs);
245      break;
246  }
247}
248
249AutofillMetrics::DialogUiEvent DialogSectionToUiItemAddedEvent(
250    DialogSection section) {
251  switch (section) {
252    case SECTION_BILLING:
253      return AutofillMetrics::DIALOG_UI_BILLING_ITEM_ADDED;
254
255    case SECTION_CC_BILLING:
256      return AutofillMetrics::DIALOG_UI_CC_BILLING_ITEM_ADDED;
257
258    case SECTION_SHIPPING:
259      return AutofillMetrics::DIALOG_UI_SHIPPING_ITEM_ADDED;
260
261    case SECTION_CC:
262      return AutofillMetrics::DIALOG_UI_CC_ITEM_ADDED;
263  }
264
265  NOTREACHED();
266  return AutofillMetrics::NUM_DIALOG_UI_EVENTS;
267}
268
269AutofillMetrics::DialogUiEvent DialogSectionToUiSelectionChangedEvent(
270    DialogSection section) {
271  switch (section) {
272    case SECTION_BILLING:
273      return AutofillMetrics::DIALOG_UI_BILLING_SELECTED_SUGGESTION_CHANGED;
274
275    case SECTION_CC_BILLING:
276      return AutofillMetrics::DIALOG_UI_CC_BILLING_SELECTED_SUGGESTION_CHANGED;
277
278    case SECTION_SHIPPING:
279      return AutofillMetrics::DIALOG_UI_SHIPPING_SELECTED_SUGGESTION_CHANGED;
280
281    case SECTION_CC:
282      return AutofillMetrics::DIALOG_UI_CC_SELECTED_SUGGESTION_CHANGED;
283  }
284
285  NOTREACHED();
286  return AutofillMetrics::NUM_DIALOG_UI_EVENTS;
287}
288
289std::vector<ServerFieldType> TypesFromInputs(const DetailInputs& inputs) {
290  std::vector<ServerFieldType> types;
291  for (size_t i = 0; i < inputs.size(); ++i) {
292    types.push_back(inputs[i].type);
293  }
294  return types;
295}
296
297}  // namespace common
298}  // namespace autofill
299