autofill_dialog_common.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
1// Copyright 2013 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_common.h" 6 7#include "base/strings/utf_string_conversions.h" 8#include "chrome/browser/browser_process.h" 9#include "components/autofill/core/browser/autofill_country.h" 10#include "components/autofill/core/browser/autofill_field.h" 11#include "components/autofill/core/browser/autofill_type.h" 12#include "grit/chromium_strings.h" 13#include "grit/component_strings.h" 14#include "grit/generated_resources.h" 15#include "grit/theme_resources.h" 16#include "grit/webkit_resources.h" 17#include "ui/base/l10n/l10n_util.h" 18 19#if !defined(OS_ANDROID) 20#include "chrome/browser/ui/autofill/autofill_dialog_i18n_input.h" 21#endif // !defined(OS_ANDROID) 22 23namespace autofill { 24namespace common { 25 26// Returns true if |input| should be shown when |field_type| has been requested. 27bool ServerTypeMatchesFieldType(ServerFieldType type, 28 const AutofillType& field_type) { 29 // If any credit card expiration info is asked for, show both month and year 30 // inputs. 31 ServerFieldType server_type = field_type.GetStorableType(); 32 if (server_type == CREDIT_CARD_EXP_4_DIGIT_YEAR || 33 server_type == CREDIT_CARD_EXP_2_DIGIT_YEAR || 34 server_type == CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR || 35 server_type == CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR || 36 server_type == CREDIT_CARD_EXP_MONTH) { 37 return type == CREDIT_CARD_EXP_4_DIGIT_YEAR || 38 type == CREDIT_CARD_EXP_MONTH; 39 } 40 41 if (server_type == CREDIT_CARD_TYPE) 42 return type == CREDIT_CARD_NUMBER; 43 44 // Check the groups to distinguish billing types from shipping ones. 45 AutofillType autofill_type = AutofillType(type); 46 if (autofill_type.group() != field_type.group()) 47 return false; 48 49 // Street address (all lines) is matched to the first input address line. 50 if (server_type == ADDRESS_HOME_STREET_ADDRESS) 51 return autofill_type.GetStorableType() == ADDRESS_HOME_LINE1; 52 53 return autofill_type.GetStorableType() == server_type; 54} 55 56// Returns true if |input| in the given |section| should be used for a 57// site-requested |field|. 58bool ServerTypeMatchesField(DialogSection section, 59 ServerFieldType type, 60 const AutofillField& field) { 61 AutofillType field_type = field.Type(); 62 63 // The credit card name is filled from the billing section's data. 64 if (field_type.GetStorableType() == CREDIT_CARD_NAME && 65 (section == SECTION_BILLING || section == SECTION_CC_BILLING)) { 66 return type == NAME_BILLING_FULL; 67 } 68 69 return ServerTypeMatchesFieldType(type, field_type); 70} 71 72bool IsCreditCardType(ServerFieldType type) { 73 return AutofillType(type).group() == CREDIT_CARD; 74} 75 76// Constructs |inputs| from template data. 77void BuildInputs(const DetailInput* input_template, 78 size_t template_size, 79 DetailInputs* inputs) { 80 for (size_t i = 0; i < template_size; ++i) { 81 const DetailInput* input = &input_template[i]; 82 inputs->push_back(*input); 83 } 84} 85 86bool IsI18nInputEnabled() { 87#if defined(OS_ANDROID) 88 return false; 89#else 90 return i18ninput::Enabled(); 91#endif 92} 93 94void BuildI18nAddressInputs(AddressType address_type, 95 const std::string& country_code, 96 DetailInputs* inputs) { 97#if defined(OS_ANDROID) 98 NOTREACHED(); 99#else 100 i18ninput::BuildAddressInputs(address_type, country_code, inputs); 101#endif 102} 103 104// Constructs |inputs| from template data for a given |dialog_section|. 105void BuildInputsForSection(DialogSection dialog_section, 106 const std::string& country_code, 107 DetailInputs* inputs) { 108 using l10n_util::GetStringUTF16; 109 110 const DetailInput kCCInputs[] = { 111 { DetailInput::LONG, 112 CREDIT_CARD_NUMBER, 113 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CARD_NUMBER) }, 114 { DetailInput::SHORT, 115 CREDIT_CARD_EXP_MONTH, 116 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_EXPIRY_MONTH) }, 117 { DetailInput::SHORT, 118 CREDIT_CARD_EXP_4_DIGIT_YEAR, 119 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_EXPIRY_YEAR) }, 120 { DetailInput::SHORT_EOL, 121 CREDIT_CARD_VERIFICATION_CODE, 122 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC), 123 1.5 }, 124 }; 125 126 const DetailInput kBillingInputs[] = { 127 { DetailInput::LONG, 128 NAME_BILLING_FULL, 129 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CARDHOLDER_NAME) }, 130 { DetailInput::LONG, 131 ADDRESS_BILLING_LINE1, 132 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESS_LINE_1) }, 133 { DetailInput::LONG, 134 ADDRESS_BILLING_LINE2, 135 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESS_LINE_2) }, 136 { DetailInput::LONG, 137 ADDRESS_BILLING_CITY, 138 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_LOCALITY) }, 139 { DetailInput::SHORT, 140 ADDRESS_BILLING_STATE, 141 GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_STATE) }, 142 { DetailInput::SHORT_EOL, 143 ADDRESS_BILLING_ZIP, 144 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_POSTAL_CODE) }, 145 // We don't allow the user to change the country: http://crbug.com/247518 146 { DetailInput::NONE, ADDRESS_BILLING_COUNTRY }, 147 }; 148 149 const DetailInput kBillingPhoneInputs[] = { 150 { DetailInput::LONG, 151 PHONE_BILLING_WHOLE_NUMBER, 152 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_PHONE_NUMBER) }, 153 }; 154 155 const DetailInput kEmailInputs[] = { 156 { DetailInput::LONG, 157 EMAIL_ADDRESS, 158 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_EMAIL) }, 159 }; 160 161 const DetailInput kShippingInputs[] = { 162 { DetailInput::LONG, 163 NAME_FULL, 164 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESSEE_NAME) }, 165 { DetailInput::LONG, 166 ADDRESS_HOME_LINE1, 167 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESS_LINE_1) }, 168 { DetailInput::LONG, 169 ADDRESS_HOME_LINE2, 170 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESS_LINE_2) }, 171 { DetailInput::LONG, 172 ADDRESS_HOME_CITY, 173 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_LOCALITY) }, 174 { DetailInput::SHORT, 175 ADDRESS_HOME_STATE, 176 GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_STATE) }, 177 { DetailInput::SHORT_EOL, 178 ADDRESS_HOME_ZIP, 179 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_POSTAL_CODE) }, 180 { DetailInput::NONE, ADDRESS_HOME_COUNTRY }, 181 }; 182 183 const DetailInput kShippingPhoneInputs[] = { 184 { DetailInput::LONG, 185 PHONE_HOME_WHOLE_NUMBER, 186 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_PHONE_NUMBER) }, 187 }; 188 189 switch (dialog_section) { 190 case SECTION_CC: 191 BuildInputs(kCCInputs, arraysize(kCCInputs), inputs); 192 break; 193 194 case SECTION_BILLING: 195 if (IsI18nInputEnabled()) 196 BuildI18nAddressInputs(ADDRESS_TYPE_BILLING, country_code, inputs); 197 else 198 BuildInputs(kBillingInputs, arraysize(kBillingInputs), inputs); 199 200 BuildInputs(kBillingPhoneInputs, arraysize(kBillingPhoneInputs), inputs); 201 BuildInputs(kEmailInputs, arraysize(kEmailInputs), inputs); 202 break; 203 204 case SECTION_CC_BILLING: 205 BuildInputs(kCCInputs, arraysize(kCCInputs), inputs); 206 207 if (IsI18nInputEnabled()) { 208 // Wallet only supports US billing addresses. 209 const std::string hardcoded_country_code = "US"; 210 BuildI18nAddressInputs(ADDRESS_TYPE_BILLING, 211 hardcoded_country_code, 212 inputs); 213 DCHECK_EQ(inputs->back().type, ADDRESS_BILLING_COUNTRY); 214 inputs->back().length = DetailInput::NONE; 215 inputs->back().initial_value = 216 base::ASCIIToUTF16(hardcoded_country_code); 217 } else { 218 BuildInputs(kBillingInputs, arraysize(kBillingInputs), inputs); 219 } 220 221 BuildInputs(kBillingPhoneInputs, arraysize(kBillingPhoneInputs), inputs); 222 break; 223 224 case SECTION_SHIPPING: 225 if (IsI18nInputEnabled()) 226 BuildI18nAddressInputs(ADDRESS_TYPE_SHIPPING, country_code, inputs); 227 else 228 BuildInputs(kShippingInputs, arraysize(kShippingInputs), inputs); 229 230 BuildInputs( 231 kShippingPhoneInputs, arraysize(kShippingPhoneInputs), inputs); 232 break; 233 } 234} 235 236AutofillMetrics::DialogUiEvent DialogSectionToUiItemAddedEvent( 237 DialogSection section) { 238 switch (section) { 239 case SECTION_BILLING: 240 return AutofillMetrics::DIALOG_UI_BILLING_ITEM_ADDED; 241 242 case SECTION_CC_BILLING: 243 return AutofillMetrics::DIALOG_UI_CC_BILLING_ITEM_ADDED; 244 245 case SECTION_SHIPPING: 246 return AutofillMetrics::DIALOG_UI_SHIPPING_ITEM_ADDED; 247 248 case SECTION_CC: 249 return AutofillMetrics::DIALOG_UI_CC_ITEM_ADDED; 250 } 251 252 NOTREACHED(); 253 return AutofillMetrics::NUM_DIALOG_UI_EVENTS; 254} 255 256AutofillMetrics::DialogUiEvent DialogSectionToUiSelectionChangedEvent( 257 DialogSection section) { 258 switch (section) { 259 case SECTION_BILLING: 260 return AutofillMetrics::DIALOG_UI_BILLING_SELECTED_SUGGESTION_CHANGED; 261 262 case SECTION_CC_BILLING: 263 return AutofillMetrics::DIALOG_UI_CC_BILLING_SELECTED_SUGGESTION_CHANGED; 264 265 case SECTION_SHIPPING: 266 return AutofillMetrics::DIALOG_UI_SHIPPING_SELECTED_SUGGESTION_CHANGED; 267 268 case SECTION_CC: 269 return AutofillMetrics::DIALOG_UI_CC_SELECTED_SUGGESTION_CHANGED; 270 } 271 272 NOTREACHED(); 273 return AutofillMetrics::NUM_DIALOG_UI_EVENTS; 274} 275 276base::string16 GetHardcodedValueForType(ServerFieldType type) { 277 // TODO(dbeam): remove this entire function when i18n inputs are the default. 278 if (IsI18nInputEnabled()) 279 return base::string16(); 280 281 if (AutofillType(type).GetStorableType() == ADDRESS_HOME_COUNTRY) { 282 AutofillCountry country("US", g_browser_process->GetApplicationLocale()); 283 return country.name(); 284 } 285 286 return base::string16(); 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