autofill_dialog_i18n_input.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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 "components/autofill/core/browser/autofill_profile.h" 10#include "components/autofill/core/browser/credit_card.h" 11#include "components/autofill/core/browser/field_types.h" 12#include "grit/component_strings.h" 13#include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_data.h" 14#include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_field.h" 15#include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_ui.h" 16#include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_ui_component.h" 17#include "ui/base/l10n/l10n_util.h" 18 19namespace autofill { 20namespace i18ninput { 21 22namespace { 23 24using base::UTF16ToUTF8; 25using ::i18n::addressinput::AddressData; 26using ::i18n::addressinput::AddressField; 27using ::i18n::addressinput::AddressUiComponent; 28 29DetailInput::Length LengthFromHint(AddressUiComponent::LengthHint hint) { 30 if (hint == AddressUiComponent::HINT_SHORT) 31 return DetailInput::SHORT; 32 DCHECK_EQ(hint, AddressUiComponent::HINT_LONG); 33 return DetailInput::LONG; 34} 35 36} // namespace 37 38void BuildAddressInputs(common::AddressType address_type, 39 const std::string& country_code, 40 DetailInputs* inputs) { 41 std::vector<AddressUiComponent> components( 42 ::i18n::addressinput::BuildComponents(country_code)); 43 44 const bool billing = address_type == common::ADDRESS_TYPE_BILLING; 45 46 for (size_t i = 0; i < components.size(); ++i) { 47 const AddressUiComponent& component = components[i]; 48 if (component.field == ::i18n::addressinput::ORGANIZATION) { 49 // TODO(dbeam): figure out when we actually need this. 50 continue; 51 } 52 53 ServerFieldType server_type = TypeForField(component.field, address_type); 54 DetailInput::Length length = LengthFromHint(component.length_hint); 55 base::string16 placeholder = l10n_util::GetStringUTF16(component.name_id); 56 DetailInput input = { length, server_type, placeholder }; 57 inputs->push_back(input); 58 59 if (component.field == ::i18n::addressinput::STREET_ADDRESS && 60 component.length_hint == AddressUiComponent::HINT_LONG) { 61 // TODO(dbeam): support more than 2 address lines. http://crbug.com/324889 62 ServerFieldType server_type = 63 billing ? ADDRESS_BILLING_LINE2 : ADDRESS_HOME_LINE2; 64 base::string16 placeholder = l10n_util::GetStringUTF16(component.name_id); 65 DetailInput input = { length, server_type, placeholder }; 66 inputs->push_back(input); 67 } 68 } 69 70 ServerFieldType server_type = 71 billing ? ADDRESS_BILLING_COUNTRY : ADDRESS_HOME_COUNTRY; 72 base::string16 placeholder_text = 73 l10n_util::GetStringUTF16(IDS_AUTOFILL_FIELD_LABEL_COUNTRY); 74 DetailInput input = { DetailInput::LONG, server_type, placeholder_text }; 75 inputs->push_back(input); 76} 77 78bool CardHasCompleteAndVerifiedData(const CreditCard& card) { 79 if (!card.IsVerified()) 80 return false; 81 82 const ServerFieldType required_fields[] = { 83 CREDIT_CARD_NUMBER, 84 CREDIT_CARD_EXP_MONTH, 85 CREDIT_CARD_EXP_4_DIGIT_YEAR, 86 }; 87 88 for (size_t i = 0; i < arraysize(required_fields); ++i) { 89 if (card.GetRawInfo(required_fields[i]).empty()) 90 return false; 91 } 92 93 return true; 94} 95 96bool AddressHasCompleteAndVerifiedData(const AutofillProfile& profile) { 97 if (!profile.IsVerified()) 98 return false; 99 100 base::string16 country_code = profile.GetRawInfo(ADDRESS_HOME_COUNTRY); 101 if (country_code.empty()) 102 return false; 103 104 std::vector<AddressField> required_fields = 105 ::i18n::addressinput::GetRequiredFields(base::UTF16ToUTF8(country_code)); 106 107 for (size_t i = 0; i < required_fields.size(); ++i) { 108 ServerFieldType type = 109 TypeForField(required_fields[i], common::ADDRESS_TYPE_SHIPPING); 110 if (profile.GetRawInfo(type).empty()) 111 return false; 112 } 113 114 const ServerFieldType more_required_fields[] = { 115 NAME_FULL, 116 PHONE_HOME_WHOLE_NUMBER 117 }; 118 119 for (size_t i = 0; i < arraysize(more_required_fields); ++i) { 120 if (profile.GetRawInfo(more_required_fields[i]).empty()) 121 return false; 122 } 123 124 return true; 125} 126 127ServerFieldType TypeForField(AddressField address_field, 128 common::AddressType address_type) { 129 bool billing = address_type == common::ADDRESS_TYPE_BILLING; 130 switch (address_field) { 131 case ::i18n::addressinput::COUNTRY: 132 return billing ? ADDRESS_BILLING_COUNTRY : ADDRESS_HOME_COUNTRY; 133 case ::i18n::addressinput::ADMIN_AREA: 134 return billing ? ADDRESS_BILLING_STATE : ADDRESS_HOME_STATE; 135 case ::i18n::addressinput::LOCALITY: 136 return billing ? ADDRESS_BILLING_CITY : ADDRESS_HOME_CITY; 137 case ::i18n::addressinput::DEPENDENT_LOCALITY: 138 return billing ? ADDRESS_BILLING_DEPENDENT_LOCALITY : 139 ADDRESS_HOME_DEPENDENT_LOCALITY; 140 case ::i18n::addressinput::POSTAL_CODE: 141 return billing ? ADDRESS_BILLING_ZIP : ADDRESS_HOME_ZIP; 142 case ::i18n::addressinput::SORTING_CODE: 143 return billing ? ADDRESS_BILLING_SORTING_CODE : ADDRESS_HOME_SORTING_CODE; 144 case ::i18n::addressinput::STREET_ADDRESS: 145 return billing ? ADDRESS_BILLING_LINE1 : ADDRESS_HOME_LINE1; 146 case ::i18n::addressinput::RECIPIENT: 147 return billing ? NAME_BILLING_FULL : NAME_FULL; 148 case ::i18n::addressinput::ORGANIZATION: 149 return COMPANY_NAME; 150 } 151 NOTREACHED(); 152 return UNKNOWN_TYPE; 153} 154 155void CreateAddressData( 156 const base::Callback<base::string16(const AutofillType&)>& get_info, 157 AddressData* address_data) { 158 address_data->recipient = UTF16ToUTF8(get_info.Run(AutofillType(NAME_FULL))); 159 address_data->country_code = UTF16ToUTF8( 160 get_info.Run(AutofillType(HTML_TYPE_COUNTRY_CODE, HTML_MODE_SHIPPING))); 161 DCHECK_EQ(2U, address_data->country_code.size()); 162 address_data->administrative_area = UTF16ToUTF8( 163 get_info.Run(AutofillType(ADDRESS_HOME_STATE))); 164 address_data->locality = UTF16ToUTF8( 165 get_info.Run(AutofillType(ADDRESS_HOME_CITY))); 166 address_data->dependent_locality = UTF16ToUTF8( 167 get_info.Run(AutofillType(ADDRESS_HOME_DEPENDENT_LOCALITY))); 168 address_data->sorting_code = UTF16ToUTF8( 169 get_info.Run(AutofillType(ADDRESS_HOME_SORTING_CODE))); 170 address_data->postal_code = UTF16ToUTF8( 171 get_info.Run(AutofillType(ADDRESS_HOME_ZIP))); 172 base::SplitString( 173 UTF16ToUTF8(get_info.Run(AutofillType(ADDRESS_HOME_STREET_ADDRESS))), 174 '\n', 175 &address_data->address_lines); 176} 177 178bool CountryIsFullySupported(const std::string& country_code) { 179 DCHECK_EQ(2U, country_code.size()); 180 std::vector< ::i18n::addressinput::AddressUiComponent> components = 181 ::i18n::addressinput::BuildComponents(country_code); 182 for (size_t i = 0; i < components.size(); ++i) { 183 if (components[i].field == ::i18n::addressinput::DEPENDENT_LOCALITY) 184 return false; 185 } 186 return true; 187} 188 189} // namespace i18ninput 190} // namespace autofill 191