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 "components/autofill/content/browser/wallet/wallet_address.h" 6 7 #include "base/logging.h" 8 #include "base/strings/string_util.h" 9 #include "base/strings/utf_string_conversions.h" 10 #include "base/values.h" 11 #include "components/autofill/core/browser/autofill_country.h" 12 #include "components/autofill/core/browser/autofill_profile.h" 13 #include "components/autofill/core/browser/autofill_type.h" 14 #include "components/autofill/core/browser/state_names.h" 15 16 namespace autofill { 17 namespace wallet { 18 19 // Server specified type for address with complete details. 20 const char kFullAddress[] = "FULL"; 21 22 namespace { 23 24 Address* CreateAddressInternal(const base::DictionaryValue& dictionary, 25 const std::string& object_id) { 26 std::string country_name_code; 27 if (!dictionary.GetString("postal_address.country_name_code", 28 &country_name_code)) { 29 DLOG(ERROR) << "Response from Google Wallet missing country name"; 30 return NULL; 31 } 32 33 string16 recipient_name; 34 if (!dictionary.GetString("postal_address.recipient_name", 35 &recipient_name)) { 36 DLOG(ERROR) << "Response from Google Wallet missing recipient name"; 37 return NULL; 38 } 39 40 string16 postal_code_number; 41 if (!dictionary.GetString("postal_address.postal_code_number", 42 &postal_code_number)) { 43 DLOG(ERROR) << "Response from Google Wallet missing postal code number"; 44 return NULL; 45 } 46 47 string16 phone_number; 48 if (!dictionary.GetString("phone_number", &phone_number)) 49 DVLOG(1) << "Response from Google Wallet missing phone number"; 50 51 string16 address_line_1; 52 string16 address_line_2; 53 const ListValue* address_line_list; 54 if (dictionary.GetList("postal_address.address_line", &address_line_list)) { 55 if (!address_line_list->GetString(0, &address_line_1)) 56 DVLOG(1) << "Response from Google Wallet missing address line 1"; 57 if (!address_line_list->GetString(1, &address_line_2)) 58 DVLOG(1) << "Response from Google Wallet missing address line 2"; 59 } else { 60 DVLOG(1) << "Response from Google Wallet missing address lines"; 61 } 62 63 string16 locality_name; 64 if (!dictionary.GetString("postal_address.locality_name", 65 &locality_name)) { 66 DVLOG(1) << "Response from Google Wallet missing locality name"; 67 } 68 69 string16 administrative_area_name; 70 if (!dictionary.GetString("postal_address.administrative_area_name", 71 &administrative_area_name)) { 72 DVLOG(1) << "Response from Google Wallet missing administrative area name"; 73 } 74 75 Address* address = new Address(country_name_code, 76 recipient_name, 77 address_line_1, 78 address_line_2, 79 locality_name, 80 administrative_area_name, 81 postal_code_number, 82 phone_number, 83 object_id); 84 85 bool is_minimal_address = false; 86 if (dictionary.GetBoolean("is_minimal_address", &is_minimal_address)) 87 address->set_is_complete_address(!is_minimal_address); 88 else 89 DVLOG(1) << "Response from Google Wallet missing is_minimal_address bit"; 90 91 return address; 92 } 93 94 } // namespace 95 96 Address::Address() {} 97 98 Address::Address(const AutofillProfile& profile) 99 : country_name_code_( 100 UTF16ToASCII(profile.GetRawInfo(ADDRESS_HOME_COUNTRY))), 101 recipient_name_(profile.GetRawInfo(NAME_FULL)), 102 address_line_1_(profile.GetRawInfo(ADDRESS_HOME_LINE1)), 103 address_line_2_(profile.GetRawInfo(ADDRESS_HOME_LINE2)), 104 locality_name_(profile.GetRawInfo(ADDRESS_HOME_CITY)), 105 postal_code_number_(profile.GetRawInfo(ADDRESS_HOME_ZIP)), 106 phone_number_(profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER)), 107 is_complete_address_(true) { 108 state_names::GetNameAndAbbreviation(profile.GetRawInfo(ADDRESS_HOME_STATE), 109 NULL, 110 &administrative_area_name_); 111 StringToUpperASCII(&administrative_area_name_); 112 } 113 114 Address::Address(const std::string& country_name_code, 115 const string16& recipient_name, 116 const string16& address_line_1, 117 const string16& address_line_2, 118 const string16& locality_name, 119 const string16& administrative_area_name, 120 const string16& postal_code_number, 121 const string16& phone_number, 122 const std::string& object_id) 123 : country_name_code_(country_name_code), 124 recipient_name_(recipient_name), 125 address_line_1_(address_line_1), 126 address_line_2_(address_line_2), 127 locality_name_(locality_name), 128 administrative_area_name_(administrative_area_name), 129 postal_code_number_(postal_code_number), 130 phone_number_(phone_number), 131 object_id_(object_id), 132 is_complete_address_(true) { 133 } 134 135 Address::~Address() {} 136 137 // static 138 scoped_ptr<Address> Address::CreateAddressWithID( 139 const base::DictionaryValue& dictionary) { 140 std::string object_id; 141 if (!dictionary.GetString("id", &object_id)) { 142 DLOG(ERROR) << "Response from Google Wallet missing object id"; 143 return scoped_ptr<Address>(); 144 } 145 return scoped_ptr<Address>(CreateAddressInternal(dictionary, object_id)); 146 } 147 148 // static 149 scoped_ptr<Address> Address::CreateAddress( 150 const base::DictionaryValue& dictionary) { 151 std::string object_id; 152 dictionary.GetString("id", &object_id); 153 return scoped_ptr<Address>(CreateAddressInternal(dictionary, object_id)); 154 } 155 156 // static 157 scoped_ptr<Address> Address::CreateDisplayAddress( 158 const base::DictionaryValue& dictionary) { 159 std::string country_code; 160 if (!dictionary.GetString("country_code", &country_code)) { 161 DLOG(ERROR) << "Reponse from Google Wallet missing country code"; 162 return scoped_ptr<Address>(); 163 } 164 165 string16 name; 166 if (!dictionary.GetString("name", &name)) { 167 DLOG(ERROR) << "Reponse from Google Wallet missing name"; 168 return scoped_ptr<Address>(); 169 } 170 171 string16 postal_code; 172 if (!dictionary.GetString("postal_code", &postal_code)) { 173 DLOG(ERROR) << "Reponse from Google Wallet missing postal code"; 174 return scoped_ptr<Address>(); 175 } 176 177 string16 address1; 178 if (!dictionary.GetString("address1", &address1)) 179 DVLOG(1) << "Reponse from Google Wallet missing address1"; 180 181 string16 address2; 182 if (!dictionary.GetString("address2", &address2)) 183 DVLOG(1) << "Reponse from Google Wallet missing address2"; 184 185 string16 city; 186 if (!dictionary.GetString("city", &city)) 187 DVLOG(1) << "Reponse from Google Wallet missing city"; 188 189 string16 state; 190 if (!dictionary.GetString("state", &state)) 191 DVLOG(1) << "Reponse from Google Wallet missing state"; 192 193 string16 phone_number; 194 if (!dictionary.GetString("phone_number", &phone_number)) 195 DVLOG(1) << "Reponse from Google Wallet missing phone number"; 196 197 std::string address_state; 198 if (!dictionary.GetString("type", &address_state)) 199 DVLOG(1) << "Response from Google Wallet missing type/state of address"; 200 201 scoped_ptr<Address> address( 202 new Address(country_code, 203 name, 204 address1, 205 address2, 206 city, 207 state, 208 postal_code, 209 phone_number, 210 std::string())); 211 address->set_is_complete_address(address_state == kFullAddress); 212 213 return address.Pass(); 214 } 215 216 scoped_ptr<base::DictionaryValue> Address::ToDictionaryWithID() const { 217 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); 218 219 if (!object_id_.empty()) 220 dict->SetString("id", object_id_); 221 dict->SetString("phone_number", phone_number_); 222 dict->Set("postal_address", ToDictionaryWithoutID().release()); 223 224 return dict.Pass(); 225 } 226 227 scoped_ptr<base::DictionaryValue> Address::ToDictionaryWithoutID() const { 228 scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); 229 230 scoped_ptr<base::ListValue> address_lines(new base::ListValue()); 231 address_lines->AppendString(address_line_1_); 232 if (!address_line_2_.empty()) 233 address_lines->AppendString(address_line_2_); 234 dict->Set("address_line", address_lines.release()); 235 236 dict->SetString("country_name_code", country_name_code_); 237 dict->SetString("recipient_name", recipient_name_); 238 dict->SetString("locality_name", locality_name_); 239 dict->SetString("administrative_area_name", 240 administrative_area_name_); 241 dict->SetString("postal_code_number", postal_code_number_); 242 243 return dict.Pass(); 244 } 245 246 string16 Address::DisplayName() const { 247 #if defined(OS_ANDROID) 248 // TODO(aruslan): improve this stub implementation. 249 return recipient_name(); 250 #else 251 // TODO(estade): improve this stub implementation + l10n. 252 return recipient_name() + ASCIIToUTF16(", ") + address_line_1(); 253 #endif 254 } 255 256 string16 Address::DisplayNameDetail() const { 257 #if defined(OS_ANDROID) 258 // TODO(aruslan): improve this stub implementation. 259 return address_line_1(); 260 #else 261 return string16(); 262 #endif 263 } 264 265 string16 Address::GetInfo(const AutofillType& type, 266 const std::string& app_locale) const { 267 if (type.html_type() == HTML_TYPE_COUNTRY_CODE) { 268 DCHECK(IsStringASCII(country_name_code())); 269 return ASCIIToUTF16(country_name_code()); 270 } else if (type.html_type() == HTML_TYPE_STREET_ADDRESS) { 271 base::string16 address = address_line_1(); 272 if (!address_line_2().empty()) 273 address += ASCIIToUTF16(", ") + address_line_2(); 274 return address; 275 } 276 277 switch (type.GetStorableType()) { 278 case NAME_FULL: 279 return recipient_name(); 280 281 case ADDRESS_HOME_LINE1: 282 return address_line_1(); 283 284 case ADDRESS_HOME_LINE2: 285 return address_line_2(); 286 287 case ADDRESS_HOME_CITY: 288 return locality_name(); 289 290 case ADDRESS_HOME_STATE: 291 return administrative_area_name(); 292 293 case ADDRESS_HOME_ZIP: 294 return postal_code_number(); 295 296 case ADDRESS_HOME_COUNTRY: { 297 AutofillCountry country(country_name_code(), app_locale); 298 return country.name(); 299 } 300 301 case PHONE_HOME_WHOLE_NUMBER: 302 return phone_number(); 303 304 // TODO(estade): implement more. 305 default: 306 NOTREACHED(); 307 return string16(); 308 } 309 } 310 311 bool Address::EqualsIgnoreID(const Address& other) const { 312 return country_name_code_ == other.country_name_code_ && 313 recipient_name_ == other.recipient_name_ && 314 address_line_1_ == other.address_line_1_ && 315 address_line_2_ == other.address_line_2_ && 316 locality_name_ == other.locality_name_ && 317 administrative_area_name_ == other.administrative_area_name_ && 318 postal_code_number_ == other.postal_code_number_ && 319 phone_number_ == other.phone_number_ && 320 is_complete_address_ == other.is_complete_address_; 321 } 322 323 bool Address::operator==(const Address& other) const { 324 return object_id_ == other.object_id_ && EqualsIgnoreID(other); 325 } 326 327 bool Address::operator!=(const Address& other) const { 328 return !(*this == other); 329 } 330 331 } // namespace wallet 332 } // namespace autofill 333