blob: 9595c3c5ea7136aa10418830a82caaad87087481 [file] [log] [blame]
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +01001// 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"
Ben Murdocheb525c52013-07-10 11:40:50 +010011#include "components/autofill/core/browser/autofill_country.h"
12#include "components/autofill/core/browser/autofill_profile.h"
Ben Murdoch32409262013-08-07 11:04:47 +010013#include "components/autofill/core/browser/autofill_type.h"
Ben Murdocheb525c52013-07-10 11:40:50 +010014#include "components/autofill/core/browser/state_names.h"
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010015
16namespace autofill {
17namespace wallet {
18
19// Server specified type for address with complete details.
20const char kFullAddress[] = "FULL";
21
22namespace {
23
24Address* 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
96Address::Address() {}
97
98Address::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)),
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100105 postal_code_number_(profile.GetRawInfo(ADDRESS_HOME_ZIP)),
106 phone_number_(profile.GetRawInfo(PHONE_HOME_WHOLE_NUMBER)),
Torne (Richard Coles)5e3f23d2013-06-11 16:24:11 +0100107 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}
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100113
114Address::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),
Torne (Richard Coles)5e3f23d2013-06-11 16:24:11 +0100132 is_complete_address_(true) {
133}
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100134
135Address::~Address() {}
136
137// static
138scoped_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
149scoped_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
157scoped_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
216scoped_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
227scoped_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
246string16 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
256string16 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
Ben Murdoch32409262013-08-07 11:04:47 +0100265string16 Address::GetInfo(const AutofillType& type,
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100266 const std::string& app_locale) const {
Ben Murdochbb1529c2013-08-08 10:24:53 +0100267 switch (type.GetStorableType()) {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100268 case NAME_FULL:
269 return recipient_name();
270
271 case ADDRESS_HOME_LINE1:
272 return address_line_1();
273
274 case ADDRESS_HOME_LINE2:
275 return address_line_2();
276
277 case ADDRESS_HOME_CITY:
278 return locality_name();
279
280 case ADDRESS_HOME_STATE:
281 return administrative_area_name();
282
283 case ADDRESS_HOME_ZIP:
284 return postal_code_number();
285
286 case ADDRESS_HOME_COUNTRY: {
287 AutofillCountry country(country_name_code(), app_locale);
288 return country.name();
289 }
290
291 case PHONE_HOME_WHOLE_NUMBER:
292 return phone_number();
293
294 // TODO(estade): implement more.
295 default:
296 NOTREACHED();
297 return string16();
298 }
299}
300
301bool Address::EqualsIgnoreID(const Address& other) const {
302 return country_name_code_ == other.country_name_code_ &&
303 recipient_name_ == other.recipient_name_ &&
304 address_line_1_ == other.address_line_1_ &&
305 address_line_2_ == other.address_line_2_ &&
306 locality_name_ == other.locality_name_ &&
307 administrative_area_name_ == other.administrative_area_name_ &&
308 postal_code_number_ == other.postal_code_number_ &&
309 phone_number_ == other.phone_number_ &&
310 is_complete_address_ == other.is_complete_address_;
311}
312
313bool Address::operator==(const Address& other) const {
314 return object_id_ == other.object_id_ && EqualsIgnoreID(other);
315}
316
317bool Address::operator!=(const Address& other) const {
318 return !(*this == other);
319}
320
321} // namespace wallet
322} // namespace autofill