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 |