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