| OLD | NEW |
| (Empty) |
| 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_split.h" | |
| 9 #include "base/strings/string_util.h" | |
| 10 #include "base/strings/utf_string_conversions.h" | |
| 11 #include "base/values.h" | |
| 12 #include "build/build_config.h" | |
| 13 #include "components/autofill/core/browser/autofill_country.h" | |
| 14 #include "components/autofill/core/browser/autofill_profile.h" | |
| 15 #include "components/autofill/core/browser/autofill_type.h" | |
| 16 #include "components/autofill/core/browser/phone_number.h" | |
| 17 #include "components/autofill/core/browser/state_names.h" | |
| 18 | |
| 19 namespace autofill { | |
| 20 namespace wallet { | |
| 21 | |
| 22 // Server specified type for address with complete details. | |
| 23 const char kFullAddress[] = "FULL"; | |
| 24 | |
| 25 namespace { | |
| 26 | |
| 27 Address* CreateAddressInternal(const base::DictionaryValue& dictionary, | |
| 28 const std::string& object_id) { | |
| 29 std::string country_name_code; | |
| 30 if (!dictionary.GetString("postal_address.country_name_code", | |
| 31 &country_name_code)) { | |
| 32 DLOG(ERROR) << "Response from Google Payments missing country name"; | |
| 33 return NULL; | |
| 34 } | |
| 35 | |
| 36 base::string16 recipient_name; | |
| 37 if (!dictionary.GetString("postal_address.recipient_name", | |
| 38 &recipient_name)) { | |
| 39 DLOG(ERROR) << "Response from Google Payments missing recipient name"; | |
| 40 return NULL; | |
| 41 } | |
| 42 | |
| 43 base::string16 postal_code_number; | |
| 44 if (!dictionary.GetString("postal_address.postal_code_number", | |
| 45 &postal_code_number)) { | |
| 46 DLOG(ERROR) << "Response from Google Payments missing postal code number"; | |
| 47 return NULL; | |
| 48 } | |
| 49 // TODO(estade): what about postal_code_number_extension? | |
| 50 | |
| 51 base::string16 sorting_code; | |
| 52 if (!dictionary.GetString("postal_address.sorting_code", | |
| 53 &sorting_code)) { | |
| 54 DVLOG(1) << "Response from Google Payments missing sorting code"; | |
| 55 } | |
| 56 | |
| 57 base::string16 phone_number; | |
| 58 if (!dictionary.GetString("phone_number", &phone_number)) | |
| 59 DVLOG(1) << "Response from Google Payments missing phone number"; | |
| 60 | |
| 61 std::vector<base::string16> street_address; | |
| 62 const base::ListValue* address_line_list; | |
| 63 if (dictionary.GetList("postal_address.address_line", &address_line_list)) { | |
| 64 for (size_t i = 0; i < address_line_list->GetSize(); ++i) { | |
| 65 base::string16 line; | |
| 66 address_line_list->GetString(i, &line); | |
| 67 street_address.push_back(line); | |
| 68 } | |
| 69 } else { | |
| 70 DVLOG(1) << "Response from Google Payments missing address lines"; | |
| 71 } | |
| 72 | |
| 73 base::string16 locality_name; | |
| 74 if (!dictionary.GetString("postal_address.locality_name", | |
| 75 &locality_name)) { | |
| 76 DVLOG(1) << "Response from Google Payments missing locality name"; | |
| 77 } | |
| 78 | |
| 79 base::string16 dependent_locality_name; | |
| 80 if (!dictionary.GetString("postal_address.dependent_locality_name", | |
| 81 &dependent_locality_name)) { | |
| 82 DVLOG(1) << "Response from Google Payments missing dependent locality name"; | |
| 83 } | |
| 84 | |
| 85 base::string16 administrative_area_name; | |
| 86 if (!dictionary.GetString("postal_address.administrative_area_name", | |
| 87 &administrative_area_name)) { | |
| 88 DVLOG(1) | |
| 89 << "Response from Google Payments missing administrative area name"; | |
| 90 } | |
| 91 | |
| 92 std::string language_code; | |
| 93 if (!dictionary.GetString("postal_address.language_code", | |
| 94 &language_code)) { | |
| 95 DVLOG(1) << "Response from Google Payments missing language code"; | |
| 96 } | |
| 97 | |
| 98 Address* address = new Address(country_name_code, | |
| 99 recipient_name, | |
| 100 street_address, | |
| 101 locality_name, | |
| 102 dependent_locality_name, | |
| 103 administrative_area_name, | |
| 104 postal_code_number, | |
| 105 sorting_code, | |
| 106 phone_number, | |
| 107 object_id, | |
| 108 language_code); | |
| 109 | |
| 110 bool is_minimal_address = false; | |
| 111 if (dictionary.GetBoolean("is_minimal_address", &is_minimal_address)) | |
| 112 address->set_is_complete_address(!is_minimal_address); | |
| 113 else | |
| 114 DVLOG(1) << "Response from Google Payments missing is_minimal_address bit"; | |
| 115 | |
| 116 return address; | |
| 117 } | |
| 118 | |
| 119 } // namespace | |
| 120 | |
| 121 Address::Address() {} | |
| 122 | |
| 123 Address::Address(const AutofillProfile& profile) | |
| 124 : country_name_code_( | |
| 125 base::UTF16ToASCII(profile.GetRawInfo(ADDRESS_HOME_COUNTRY))), | |
| 126 recipient_name_(profile.GetRawInfo(NAME_FULL)), | |
| 127 locality_name_(profile.GetRawInfo(ADDRESS_HOME_CITY)), | |
| 128 dependent_locality_name_( | |
| 129 profile.GetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY)), | |
| 130 administrative_area_name_(profile.GetRawInfo(ADDRESS_HOME_STATE)), | |
| 131 postal_code_number_(profile.GetRawInfo(ADDRESS_HOME_ZIP)), | |
| 132 sorting_code_(profile.GetRawInfo(ADDRESS_HOME_SORTING_CODE)), | |
| 133 phone_number_(profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER)), | |
| 134 is_complete_address_(true), | |
| 135 language_code_(profile.language_code()) { | |
| 136 street_address_ = base::SplitString( | |
| 137 profile.GetRawInfo(ADDRESS_HOME_STREET_ADDRESS), base::ASCIIToUTF16("\n"), | |
| 138 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); | |
| 139 | |
| 140 if (!country_name_code_.empty()) | |
| 141 phone_object_ = i18n::PhoneObject(phone_number_, country_name_code_); | |
| 142 } | |
| 143 | |
| 144 Address::Address(const std::string& country_name_code, | |
| 145 const base::string16& recipient_name, | |
| 146 const std::vector<base::string16>& street_address, | |
| 147 const base::string16& locality_name, | |
| 148 const base::string16& dependent_locality_name, | |
| 149 const base::string16& administrative_area_name, | |
| 150 const base::string16& postal_code_number, | |
| 151 const base::string16& sorting_code, | |
| 152 const base::string16& phone_number, | |
| 153 const std::string& object_id, | |
| 154 const std::string& language_code) | |
| 155 : country_name_code_(country_name_code), | |
| 156 recipient_name_(recipient_name), | |
| 157 street_address_(street_address), | |
| 158 locality_name_(locality_name), | |
| 159 dependent_locality_name_(dependent_locality_name), | |
| 160 administrative_area_name_(administrative_area_name), | |
| 161 postal_code_number_(postal_code_number), | |
| 162 sorting_code_(sorting_code), | |
| 163 phone_number_(phone_number), | |
| 164 phone_object_(phone_number, country_name_code), | |
| 165 object_id_(object_id), | |
| 166 is_complete_address_(true), | |
| 167 language_code_(language_code) {} | |
| 168 | |
| 169 Address::~Address() {} | |
| 170 | |
| 171 // static | |
| 172 std::unique_ptr<Address> Address::CreateAddressWithID( | |
| 173 const base::DictionaryValue& dictionary) { | |
| 174 std::string object_id; | |
| 175 if (!dictionary.GetString("id", &object_id)) { | |
| 176 DLOG(ERROR) << "Response from Google Payments missing object id"; | |
| 177 return std::unique_ptr<Address>(); | |
| 178 } | |
| 179 return std::unique_ptr<Address>(CreateAddressInternal(dictionary, object_id)); | |
| 180 } | |
| 181 | |
| 182 // static | |
| 183 std::unique_ptr<Address> Address::CreateAddress( | |
| 184 const base::DictionaryValue& dictionary) { | |
| 185 std::string object_id; | |
| 186 dictionary.GetString("id", &object_id); | |
| 187 return std::unique_ptr<Address>(CreateAddressInternal(dictionary, object_id)); | |
| 188 } | |
| 189 | |
| 190 // static | |
| 191 std::unique_ptr<Address> Address::CreateDisplayAddress( | |
| 192 const base::DictionaryValue& dictionary) { | |
| 193 std::string country_code; | |
| 194 if (!dictionary.GetString("country_code", &country_code)) { | |
| 195 DLOG(ERROR) << "Reponse from Google Payments missing country code"; | |
| 196 return std::unique_ptr<Address>(); | |
| 197 } | |
| 198 | |
| 199 base::string16 name; | |
| 200 if (!dictionary.GetString("name", &name)) { | |
| 201 DLOG(ERROR) << "Reponse from Google Payments missing name"; | |
| 202 return std::unique_ptr<Address>(); | |
| 203 } | |
| 204 | |
| 205 base::string16 postal_code; | |
| 206 if (!dictionary.GetString("postal_code", &postal_code)) { | |
| 207 DLOG(ERROR) << "Reponse from Google Payments missing postal code"; | |
| 208 return std::unique_ptr<Address>(); | |
| 209 } | |
| 210 | |
| 211 base::string16 sorting_code; | |
| 212 if (!dictionary.GetString("sorting_code", &sorting_code)) { | |
| 213 DVLOG(1) << "Reponse from Google Payments missing sorting code"; | |
| 214 } | |
| 215 | |
| 216 std::vector<base::string16> street_address; | |
| 217 base::string16 address1; | |
| 218 if (dictionary.GetString("address1", &address1)) | |
| 219 street_address.push_back(address1); | |
| 220 else | |
| 221 DVLOG(1) << "Reponse from Google Payments missing address1"; | |
| 222 | |
| 223 base::string16 address2; | |
| 224 if (dictionary.GetString("address2", &address2) && !address2.empty()) { | |
| 225 street_address.resize(2); | |
| 226 street_address[1] = address2; | |
| 227 } else { | |
| 228 DVLOG(1) << "Reponse from Google Payments missing or empty address2"; | |
| 229 } | |
| 230 | |
| 231 base::string16 city; | |
| 232 if (!dictionary.GetString("city", &city)) | |
| 233 DVLOG(1) << "Reponse from Google Payments missing city"; | |
| 234 | |
| 235 base::string16 dependent_locality_name; | |
| 236 if (!dictionary.GetString("dependent_locality_name", | |
| 237 &dependent_locality_name)) { | |
| 238 DVLOG(1) << "Reponse from Google Payments missing district"; | |
| 239 } | |
| 240 | |
| 241 base::string16 state; | |
| 242 if (!dictionary.GetString("state", &state)) | |
| 243 DVLOG(1) << "Reponse from Google Payments missing state"; | |
| 244 | |
| 245 base::string16 phone_number; | |
| 246 if (!dictionary.GetString("phone_number", &phone_number)) | |
| 247 DVLOG(1) << "Reponse from Google Payments missing phone number"; | |
| 248 | |
| 249 std::string address_state; | |
| 250 if (!dictionary.GetString("type", &address_state)) | |
| 251 DVLOG(1) << "Response from Google Payments missing type/state of address"; | |
| 252 | |
| 253 std::string language_code; | |
| 254 if (!dictionary.GetString("language_code", &language_code)) | |
| 255 DVLOG(1) << "Response from Google Payments missing language code"; | |
| 256 | |
| 257 std::unique_ptr<Address> address(new Address( | |
| 258 country_code, name, street_address, city, dependent_locality_name, state, | |
| 259 postal_code, sorting_code, phone_number, std::string(), language_code)); | |
| 260 address->set_is_complete_address(address_state == kFullAddress); | |
| 261 | |
| 262 return address; | |
| 263 } | |
| 264 | |
| 265 std::unique_ptr<base::DictionaryValue> Address::ToDictionaryWithID() const { | |
| 266 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | |
| 267 | |
| 268 if (!object_id_.empty()) | |
| 269 dict->SetString("id", object_id_); | |
| 270 dict->SetString("phone_number", phone_number_); | |
| 271 dict->Set("postal_address", ToDictionaryWithoutID().release()); | |
| 272 | |
| 273 return dict; | |
| 274 } | |
| 275 | |
| 276 std::unique_ptr<base::DictionaryValue> Address::ToDictionaryWithoutID() const { | |
| 277 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); | |
| 278 | |
| 279 std::unique_ptr<base::ListValue> address_lines(new base::ListValue()); | |
| 280 address_lines->AppendStrings(street_address_); | |
| 281 dict->Set("address_line", address_lines.release()); | |
| 282 | |
| 283 dict->SetString("country_name_code", country_name_code_); | |
| 284 dict->SetString("recipient_name", recipient_name_); | |
| 285 dict->SetString("locality_name", locality_name_); | |
| 286 dict->SetString("dependent_locality_name", dependent_locality_name_); | |
| 287 dict->SetString("administrative_area_name", | |
| 288 administrative_area_name_); | |
| 289 dict->SetString("postal_code_number", postal_code_number_); | |
| 290 dict->SetString("sorting_code", sorting_code_); | |
| 291 dict->SetString("language_code", language_code_); | |
| 292 | |
| 293 return dict; | |
| 294 } | |
| 295 | |
| 296 base::string16 Address::DisplayName() const { | |
| 297 #if defined(OS_ANDROID) | |
| 298 // TODO(aruslan): improve this stub implementation. | |
| 299 return recipient_name(); | |
| 300 #else | |
| 301 // TODO(estade): improve this stub implementation + l10n. | |
| 302 return recipient_name() + base::ASCIIToUTF16(", ") + GetStreetAddressLine(0); | |
| 303 #endif | |
| 304 } | |
| 305 | |
| 306 base::string16 Address::DisplayNameDetail() const { | |
| 307 #if defined(OS_ANDROID) | |
| 308 // TODO(aruslan): improve this stub implementation. | |
| 309 return GetStreetAddressLine(0); | |
| 310 #else | |
| 311 return base::string16(); | |
| 312 #endif | |
| 313 } | |
| 314 | |
| 315 base::string16 Address::DisplayPhoneNumber() const { | |
| 316 // Return a formatted phone number. Wallet doesn't store user formatting, so | |
| 317 // impose our own. phone_number() always includes a country code, so using | |
| 318 // PhoneObject to format it would result in an internationalized format. Since | |
| 319 // Wallet only supports the US right now, stick to national formatting. | |
| 320 return i18n::PhoneObject(phone_number(), country_name_code()). | |
| 321 GetNationallyFormattedNumber(); | |
| 322 } | |
| 323 | |
| 324 base::string16 Address::GetInfo(const AutofillType& type, | |
| 325 const std::string& app_locale) const { | |
| 326 if (type.html_type() == HTML_TYPE_COUNTRY_CODE) { | |
| 327 DCHECK(base::IsStringASCII(country_name_code())); | |
| 328 return base::ASCIIToUTF16(country_name_code()); | |
| 329 } | |
| 330 | |
| 331 switch (type.GetStorableType()) { | |
| 332 case NAME_FULL: | |
| 333 return recipient_name(); | |
| 334 | |
| 335 case ADDRESS_HOME_STREET_ADDRESS: | |
| 336 return base::JoinString(street_address_, base::ASCIIToUTF16("\n")); | |
| 337 | |
| 338 case ADDRESS_HOME_LINE1: | |
| 339 return GetStreetAddressLine(0); | |
| 340 | |
| 341 case ADDRESS_HOME_LINE2: | |
| 342 return GetStreetAddressLine(1); | |
| 343 | |
| 344 case ADDRESS_HOME_CITY: | |
| 345 return locality_name(); | |
| 346 | |
| 347 case ADDRESS_HOME_STATE: | |
| 348 return administrative_area_name(); | |
| 349 | |
| 350 case ADDRESS_HOME_ZIP: | |
| 351 return postal_code_number(); | |
| 352 | |
| 353 case ADDRESS_HOME_COUNTRY: { | |
| 354 AutofillCountry country(country_name_code(), app_locale); | |
| 355 return country.name(); | |
| 356 } | |
| 357 | |
| 358 case PHONE_HOME_WHOLE_NUMBER: | |
| 359 // Wallet doesn't store user phone number formatting, so just strip all | |
| 360 // formatting. | |
| 361 return phone_object_.GetWholeNumber(); | |
| 362 | |
| 363 case ADDRESS_HOME_DEPENDENT_LOCALITY: | |
| 364 return dependent_locality_name_; | |
| 365 | |
| 366 case ADDRESS_HOME_SORTING_CODE: | |
| 367 return sorting_code_; | |
| 368 | |
| 369 case COMPANY_NAME: | |
| 370 // A field that Wallet doesn't support. TODO(dbeam): can it be supported? | |
| 371 return base::string16(); | |
| 372 | |
| 373 default: | |
| 374 NOTREACHED(); | |
| 375 return base::string16(); | |
| 376 } | |
| 377 } | |
| 378 | |
| 379 void Address::SetPhoneNumber(const base::string16& phone_number) { | |
| 380 phone_number_ = phone_number; | |
| 381 phone_object_ = i18n::PhoneObject(phone_number_, country_name_code_); | |
| 382 } | |
| 383 | |
| 384 bool Address::EqualsIgnoreID(const Address& other) const { | |
| 385 return country_name_code_ == other.country_name_code_ && | |
| 386 recipient_name_ == other.recipient_name_ && | |
| 387 street_address_ == other.street_address_ && | |
| 388 locality_name_ == other.locality_name_ && | |
| 389 dependent_locality_name_ == other.dependent_locality_name_ && | |
| 390 administrative_area_name_ == other.administrative_area_name_ && | |
| 391 postal_code_number_ == other.postal_code_number_ && | |
| 392 sorting_code_ == other.sorting_code_ && | |
| 393 phone_number_ == other.phone_number_ && | |
| 394 is_complete_address_ == other.is_complete_address_; | |
| 395 } | |
| 396 | |
| 397 base::string16 Address::GetStreetAddressLine(size_t line) const { | |
| 398 return street_address_.size() > line ? street_address_[line] : | |
| 399 base::string16(); | |
| 400 } | |
| 401 | |
| 402 bool Address::operator==(const Address& other) const { | |
| 403 return object_id_ == other.object_id_ && | |
| 404 language_code_ == other.language_code_ && | |
| 405 EqualsIgnoreID(other); | |
| 406 } | |
| 407 | |
| 408 bool Address::operator!=(const Address& other) const { | |
| 409 return !(*this == other); | |
| 410 } | |
| 411 | |
| 412 } // namespace wallet | |
| 413 } // namespace autofill | |
| OLD | NEW |