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/strings/string_split.h" 8 #include "base/strings/utf_string_conversions.h" 9 #include "chrome/browser/browser_process.h" 10 #include "components/autofill/core/browser/address_i18n.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/components_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 using base::UTF16ToUTF8; 27 using ::i18n::addressinput::AddressData; 28 using ::i18n::addressinput::AddressField; 29 using ::i18n::addressinput::AddressUiComponent; 30 31 DetailInput::Length LengthFromHint(AddressUiComponent::LengthHint hint) { 32 if (hint == AddressUiComponent::HINT_SHORT) 33 return DetailInput::SHORT; 34 DCHECK_EQ(hint, AddressUiComponent::HINT_LONG); 35 return DetailInput::LONG; 36 } 37 38 } // namespace 39 40 void BuildAddressInputs(common::AddressType address_type, 41 const std::string& country_code, 42 DetailInputs* inputs, 43 std::string* language_code) { 44 std::vector<AddressUiComponent> components( 45 ::i18n::addressinput::BuildComponents( 46 country_code, g_browser_process->GetApplicationLocale(), 47 language_code)); 48 49 const bool billing = address_type == common::ADDRESS_TYPE_BILLING; 50 51 for (size_t i = 0; i < components.size(); ++i) { 52 const AddressUiComponent& component = components[i]; 53 if (component.field == ::i18n::addressinput::ORGANIZATION) { 54 // TODO(dbeam): figure out when we actually need this. 55 continue; 56 } 57 58 ServerFieldType server_type = TypeForField(component.field, address_type); 59 DetailInput::Length length = LengthFromHint(component.length_hint); 60 base::string16 placeholder = l10n_util::GetStringUTF16(component.name_id); 61 DetailInput input = { length, server_type, placeholder }; 62 inputs->push_back(input); 63 } 64 65 ServerFieldType server_type = 66 billing ? ADDRESS_BILLING_COUNTRY : ADDRESS_HOME_COUNTRY; 67 base::string16 placeholder_text = 68 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_COUNTRY); 69 DetailInput input = { DetailInput::LONG, server_type, placeholder_text }; 70 inputs->push_back(input); 71 } 72 73 bool CardHasCompleteAndVerifiedData(const CreditCard& card) { 74 if (!card.IsVerified()) 75 return false; 76 77 const ServerFieldType required_fields[] = { 78 CREDIT_CARD_NUMBER, 79 CREDIT_CARD_EXP_MONTH, 80 CREDIT_CARD_EXP_4_DIGIT_YEAR, 81 }; 82 83 for (size_t i = 0; i < arraysize(required_fields); ++i) { 84 if (card.GetRawInfo(required_fields[i]).empty()) 85 return false; 86 } 87 88 return true; 89 } 90 91 bool AddressHasCompleteAndVerifiedData(const AutofillProfile& profile, 92 const std::string& app_locale) { 93 if (!profile.IsVerified()) 94 return false; 95 96 if (!i18n::CreateAddressDataFromAutofillProfile(profile, app_locale)-> 97 HasAllRequiredFields()) { 98 return false; 99 } 100 101 const ServerFieldType more_required_fields[] = { 102 NAME_FULL, 103 PHONE_HOME_WHOLE_NUMBER 104 }; 105 106 for (size_t i = 0; i < arraysize(more_required_fields); ++i) { 107 if (profile.GetRawInfo(more_required_fields[i]).empty()) 108 return false; 109 } 110 111 return true; 112 } 113 114 ServerFieldType TypeForField(AddressField address_field, 115 common::AddressType address_type) { 116 bool billing = address_type == common::ADDRESS_TYPE_BILLING; 117 switch (address_field) { 118 case ::i18n::addressinput::COUNTRY: 119 return billing ? ADDRESS_BILLING_COUNTRY : ADDRESS_HOME_COUNTRY; 120 case ::i18n::addressinput::ADMIN_AREA: 121 return billing ? ADDRESS_BILLING_STATE : ADDRESS_HOME_STATE; 122 case ::i18n::addressinput::LOCALITY: 123 return billing ? ADDRESS_BILLING_CITY : ADDRESS_HOME_CITY; 124 case ::i18n::addressinput::DEPENDENT_LOCALITY: 125 return billing ? ADDRESS_BILLING_DEPENDENT_LOCALITY : 126 ADDRESS_HOME_DEPENDENT_LOCALITY; 127 case ::i18n::addressinput::POSTAL_CODE: 128 return billing ? ADDRESS_BILLING_ZIP : ADDRESS_HOME_ZIP; 129 case ::i18n::addressinput::SORTING_CODE: 130 return billing ? ADDRESS_BILLING_SORTING_CODE : ADDRESS_HOME_SORTING_CODE; 131 case ::i18n::addressinput::STREET_ADDRESS: 132 return billing ? ADDRESS_BILLING_STREET_ADDRESS : 133 ADDRESS_HOME_STREET_ADDRESS; 134 case ::i18n::addressinput::RECIPIENT: 135 return billing ? NAME_BILLING_FULL : NAME_FULL; 136 case ::i18n::addressinput::ORGANIZATION: 137 return COMPANY_NAME; 138 } 139 NOTREACHED(); 140 return UNKNOWN_TYPE; 141 } 142 143 bool FieldForType(ServerFieldType server_type, 144 ::i18n::addressinput::AddressField* field) { 145 switch (server_type) { 146 case ADDRESS_BILLING_COUNTRY: 147 case ADDRESS_HOME_COUNTRY: 148 if (field) 149 *field = ::i18n::addressinput::COUNTRY; 150 return true; 151 case ADDRESS_BILLING_STATE: 152 case ADDRESS_HOME_STATE: 153 if (field) 154 *field = ::i18n::addressinput::ADMIN_AREA; 155 return true; 156 case ADDRESS_BILLING_CITY: 157 case ADDRESS_HOME_CITY: 158 if (field) 159 *field = ::i18n::addressinput::LOCALITY; 160 return true; 161 case ADDRESS_BILLING_DEPENDENT_LOCALITY: 162 case ADDRESS_HOME_DEPENDENT_LOCALITY: 163 if (field) 164 *field = ::i18n::addressinput::DEPENDENT_LOCALITY; 165 return true; 166 case ADDRESS_BILLING_SORTING_CODE: 167 case ADDRESS_HOME_SORTING_CODE: 168 if (field) 169 *field = ::i18n::addressinput::SORTING_CODE; 170 return true; 171 case ADDRESS_BILLING_ZIP: 172 case ADDRESS_HOME_ZIP: 173 if (field) 174 *field = ::i18n::addressinput::POSTAL_CODE; 175 return true; 176 case ADDRESS_BILLING_STREET_ADDRESS: 177 case ADDRESS_BILLING_LINE1: 178 case ADDRESS_BILLING_LINE2: 179 case ADDRESS_HOME_STREET_ADDRESS: 180 case ADDRESS_HOME_LINE1: 181 case ADDRESS_HOME_LINE2: 182 if (field) 183 *field = ::i18n::addressinput::STREET_ADDRESS; 184 return true; 185 case COMPANY_NAME: 186 if (field) 187 *field = ::i18n::addressinput::ORGANIZATION; 188 return true; 189 case NAME_BILLING_FULL: 190 case NAME_FULL: 191 if (field) 192 *field = ::i18n::addressinput::RECIPIENT; 193 return true; 194 default: 195 return false; 196 } 197 } 198 199 } // namespace i18ninput 200 } // namespace autofill 201