autofill_dialog_common.cc revision effb81e5f8246d0db0270817048dc992db66e9fb
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 26bool ServerTypeEncompassesFieldType(ServerFieldType type, 27 const AutofillType& field_type) { 28 // If any credit card expiration info is asked for, show both month and year 29 // inputs. 30 ServerFieldType server_type = field_type.GetStorableType(); 31 if (server_type == CREDIT_CARD_EXP_4_DIGIT_YEAR || 32 server_type == CREDIT_CARD_EXP_2_DIGIT_YEAR || 33 server_type == CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR || 34 server_type == CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR || 35 server_type == CREDIT_CARD_EXP_MONTH) { 36 return type == CREDIT_CARD_EXP_4_DIGIT_YEAR || 37 type == CREDIT_CARD_EXP_MONTH; 38 } 39 40 if (server_type == CREDIT_CARD_TYPE) 41 return type == CREDIT_CARD_NUMBER; 42 43 // Check the groups to distinguish billing types from shipping ones. 44 AutofillType autofill_type = AutofillType(type); 45 if (autofill_type.group() != field_type.group()) 46 return false; 47 48#if defined(OS_MACOSX) || defined(OS_ANDROID) 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#else 53 // The page may ask for individual address lines; this roughly matches the 54 // street address blob. 55 if (server_type == ADDRESS_HOME_LINE1 || server_type == ADDRESS_HOME_LINE2) 56 return autofill_type.GetStorableType() == ADDRESS_HOME_STREET_ADDRESS; 57#endif 58 59 return autofill_type.GetStorableType() == server_type; 60} 61 62bool ServerTypeMatchesField(DialogSection section, 63 ServerFieldType type, 64 const AutofillField& field) { 65 AutofillType field_type = field.Type(); 66 67 // 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#if defined(OS_ANDROID) 101 NOTREACHED(); 102#else 103 i18ninput::BuildAddressInputs(address_type, country_code, inputs); 104#endif 105} 106 107// Constructs |inputs| from template data for a given |dialog_section|. 108void BuildInputsForSection(DialogSection dialog_section, 109 const std::string& country_code, 110 DetailInputs* inputs) { 111 using l10n_util::GetStringUTF16; 112 113 const DetailInput kCCInputs[] = { 114 { DetailInput::LONG, 115 CREDIT_CARD_NUMBER, 116 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CARD_NUMBER) }, 117 { DetailInput::SHORT, 118 CREDIT_CARD_EXP_MONTH, 119 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_EXPIRY_MONTH) }, 120 { DetailInput::SHORT, 121 CREDIT_CARD_EXP_4_DIGIT_YEAR, 122 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_EXPIRY_YEAR) }, 123 { DetailInput::SHORT_EOL, 124 CREDIT_CARD_VERIFICATION_CODE, 125 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC), 126 1.5 }, 127 }; 128 129 const DetailInput kBillingInputs[] = { 130 { DetailInput::LONG, 131 NAME_BILLING_FULL, 132 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CARDHOLDER_NAME) }, 133 { DetailInput::LONG, 134 ADDRESS_BILLING_LINE1, 135 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESS_LINE_1) }, 136 { DetailInput::LONG, 137 ADDRESS_BILLING_LINE2, 138 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESS_LINE_2) }, 139 { DetailInput::LONG, 140 ADDRESS_BILLING_CITY, 141 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_LOCALITY) }, 142 { DetailInput::SHORT, 143 ADDRESS_BILLING_STATE, 144 GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_STATE) }, 145 { DetailInput::SHORT_EOL, 146 ADDRESS_BILLING_ZIP, 147 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_POSTAL_CODE) }, 148 // We don't allow the user to change the country: http://crbug.com/247518 149 { DetailInput::NONE, ADDRESS_BILLING_COUNTRY }, 150 }; 151 152 const DetailInput kBillingPhoneInputs[] = { 153 { DetailInput::LONG, 154 PHONE_BILLING_WHOLE_NUMBER, 155 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_PHONE_NUMBER) }, 156 }; 157 158 const DetailInput kEmailInputs[] = { 159 { DetailInput::LONG, 160 EMAIL_ADDRESS, 161 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_EMAIL) }, 162 }; 163 164 const DetailInput kShippingInputs[] = { 165 { DetailInput::LONG, 166 NAME_FULL, 167 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESSEE_NAME) }, 168 { DetailInput::LONG, 169 ADDRESS_HOME_LINE1, 170 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESS_LINE_1) }, 171 { DetailInput::LONG, 172 ADDRESS_HOME_LINE2, 173 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_ADDRESS_LINE_2) }, 174 { DetailInput::LONG, 175 ADDRESS_HOME_CITY, 176 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_LOCALITY) }, 177 { DetailInput::SHORT, 178 ADDRESS_HOME_STATE, 179 GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_STATE) }, 180 { DetailInput::SHORT_EOL, 181 ADDRESS_HOME_ZIP, 182 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_POSTAL_CODE) }, 183 { DetailInput::NONE, ADDRESS_HOME_COUNTRY }, 184 }; 185 186 const DetailInput kShippingPhoneInputs[] = { 187 { DetailInput::LONG, 188 PHONE_HOME_WHOLE_NUMBER, 189 GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_PHONE_NUMBER) }, 190 }; 191 192 switch (dialog_section) { 193 case SECTION_CC: 194 BuildInputs(kCCInputs, arraysize(kCCInputs), inputs); 195 break; 196 197 case SECTION_BILLING: 198 if (IsI18nInputEnabled()) 199 BuildI18nAddressInputs(ADDRESS_TYPE_BILLING, country_code, inputs); 200 else 201 BuildInputs(kBillingInputs, arraysize(kBillingInputs), inputs); 202 203 BuildInputs(kBillingPhoneInputs, arraysize(kBillingPhoneInputs), inputs); 204 BuildInputs(kEmailInputs, arraysize(kEmailInputs), inputs); 205 break; 206 207 case SECTION_CC_BILLING: 208 BuildInputs(kCCInputs, arraysize(kCCInputs), inputs); 209 210 if (IsI18nInputEnabled()) { 211 // Wallet only supports US billing addresses. 212 const std::string hardcoded_country_code = "US"; 213 BuildI18nAddressInputs(ADDRESS_TYPE_BILLING, 214 hardcoded_country_code, 215 inputs); 216 DCHECK_EQ(inputs->back().type, ADDRESS_BILLING_COUNTRY); 217 inputs->back().length = DetailInput::NONE; 218 const std::string& app_locale = 219 g_browser_process->GetApplicationLocale(); 220 inputs->back().initial_value = 221 AutofillCountry(hardcoded_country_code, app_locale).name(); 222 } else { 223 BuildInputs(kBillingInputs, arraysize(kBillingInputs), inputs); 224 } 225 226 BuildInputs(kBillingPhoneInputs, arraysize(kBillingPhoneInputs), inputs); 227 break; 228 229 case SECTION_SHIPPING: 230 if (IsI18nInputEnabled()) 231 BuildI18nAddressInputs(ADDRESS_TYPE_SHIPPING, country_code, inputs); 232 else 233 BuildInputs(kShippingInputs, arraysize(kShippingInputs), inputs); 234 235 BuildInputs( 236 kShippingPhoneInputs, arraysize(kShippingPhoneInputs), inputs); 237 break; 238 } 239} 240 241AutofillMetrics::DialogUiEvent DialogSectionToUiItemAddedEvent( 242 DialogSection section) { 243 switch (section) { 244 case SECTION_BILLING: 245 return AutofillMetrics::DIALOG_UI_BILLING_ITEM_ADDED; 246 247 case SECTION_CC_BILLING: 248 return AutofillMetrics::DIALOG_UI_CC_BILLING_ITEM_ADDED; 249 250 case SECTION_SHIPPING: 251 return AutofillMetrics::DIALOG_UI_SHIPPING_ITEM_ADDED; 252 253 case SECTION_CC: 254 return AutofillMetrics::DIALOG_UI_CC_ITEM_ADDED; 255 } 256 257 NOTREACHED(); 258 return AutofillMetrics::NUM_DIALOG_UI_EVENTS; 259} 260 261AutofillMetrics::DialogUiEvent DialogSectionToUiSelectionChangedEvent( 262 DialogSection section) { 263 switch (section) { 264 case SECTION_BILLING: 265 return AutofillMetrics::DIALOG_UI_BILLING_SELECTED_SUGGESTION_CHANGED; 266 267 case SECTION_CC_BILLING: 268 return AutofillMetrics::DIALOG_UI_CC_BILLING_SELECTED_SUGGESTION_CHANGED; 269 270 case SECTION_SHIPPING: 271 return AutofillMetrics::DIALOG_UI_SHIPPING_SELECTED_SUGGESTION_CHANGED; 272 273 case SECTION_CC: 274 return AutofillMetrics::DIALOG_UI_CC_SELECTED_SUGGESTION_CHANGED; 275 } 276 277 NOTREACHED(); 278 return AutofillMetrics::NUM_DIALOG_UI_EVENTS; 279} 280 281std::vector<ServerFieldType> TypesFromInputs(const DetailInputs& inputs) { 282 std::vector<ServerFieldType> types; 283 for (size_t i = 0; i < inputs.size(); ++i) { 284 types.push_back(inputs[i].type); 285 } 286 return types; 287} 288 289} // namespace common 290} // namespace autofill 291