1 // Copyright (c) 2012 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/data_model_wrapper.h"
6
7 #include "base/callback.h"
8 #include "base/strings/string_util.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/ui/autofill/autofill_dialog_common.h"
12 #include "chrome/browser/ui/autofill/autofill_dialog_models.h"
13 #include "components/autofill/content/browser/wallet/full_wallet.h"
14 #include "components/autofill/content/browser/wallet/wallet_address.h"
15 #include "components/autofill/content/browser/wallet/wallet_items.h"
16 #include "components/autofill/core/browser/autofill_data_model.h"
17 #include "components/autofill/core/browser/autofill_field.h"
18 #include "components/autofill/core/browser/autofill_profile.h"
19 #include "components/autofill/core/browser/autofill_type.h"
20 #include "components/autofill/core/browser/credit_card.h"
21 #include "components/autofill/core/browser/form_structure.h"
22 #include "ui/base/resource/resource_bundle.h"
23 #include "ui/gfx/image/image.h"
24
25 namespace autofill {
26
~DataModelWrapper()27 DataModelWrapper::~DataModelWrapper() {}
28
FillInputs(DetailInputs * inputs)29 void DataModelWrapper::FillInputs(DetailInputs* inputs) {
30 for (size_t i = 0; i < inputs->size(); ++i) {
31 DetailInput* input = &(*inputs)[i];
32 input->initial_value = common::GetHardcodedValueForType(input->type);
33 if (input->initial_value.empty())
34 input->initial_value = GetInfo(AutofillType(input->type));
35 }
36 }
37
GetInfoForDisplay(const AutofillType & type) const38 base::string16 DataModelWrapper::GetInfoForDisplay(const AutofillType& type)
39 const {
40 return GetInfo(type);
41 }
42
GetIcon()43 gfx::Image DataModelWrapper::GetIcon() {
44 return gfx::Image();
45 }
46
GetDisplayText(base::string16 * vertically_compact,base::string16 * horizontally_compact)47 bool DataModelWrapper::GetDisplayText(
48 base::string16* vertically_compact,
49 base::string16* horizontally_compact) {
50 base::string16 comma = ASCIIToUTF16(", ");
51 base::string16 newline = ASCIIToUTF16("\n");
52
53 *vertically_compact = GetAddressDisplayText(comma);
54 *horizontally_compact = GetAddressDisplayText(newline);
55 return true;
56 }
57
FillFormStructure(const DetailInputs & inputs,const InputFieldComparator & compare,FormStructure * form_structure) const58 bool DataModelWrapper::FillFormStructure(
59 const DetailInputs& inputs,
60 const InputFieldComparator& compare,
61 FormStructure* form_structure) const {
62 bool filled_something = false;
63 for (size_t i = 0; i < form_structure->field_count(); ++i) {
64 AutofillField* field = form_structure->field(i);
65 for (size_t j = 0; j < inputs.size(); ++j) {
66 if (compare.Run(inputs[j], *field)) {
67 AutofillField::FillFormField(*field, GetInfo(field->Type()),
68 g_browser_process->GetApplicationLocale(),
69 field);
70 filled_something = true;
71 break;
72 }
73 }
74 }
75 return filled_something;
76 }
77
DataModelWrapper()78 DataModelWrapper::DataModelWrapper() {}
79
GetAddressDisplayText(const base::string16 & separator)80 base::string16 DataModelWrapper::GetAddressDisplayText(
81 const base::string16& separator) {
82 base::string16 address = GetInfoForDisplay(AutofillType(NAME_FULL)) +
83 separator + GetInfoForDisplay(AutofillType(ADDRESS_HOME_LINE1));
84 base::string16 address2 = GetInfoForDisplay(AutofillType(ADDRESS_HOME_LINE2));
85 if (!address2.empty())
86 address += separator + address2;
87
88 base::string16 comma = ASCIIToUTF16(", ");
89 base::string16 newline = ASCIIToUTF16("\n");
90 address += separator +
91 GetInfoForDisplay(AutofillType(ADDRESS_HOME_CITY)) + comma +
92 GetInfoForDisplay(AutofillType(ADDRESS_HOME_STATE)) + ASCIIToUTF16(" ") +
93 GetInfoForDisplay(AutofillType(ADDRESS_HOME_ZIP));
94
95 base::string16 email = GetInfoForDisplay(AutofillType(EMAIL_ADDRESS));
96 if (!email.empty())
97 address += newline + email;
98 address += newline + GetInfoForDisplay(AutofillType(PHONE_HOME_WHOLE_NUMBER));
99
100 return address;
101 }
102
103 // EmptyDataModelWrapper
104
EmptyDataModelWrapper()105 EmptyDataModelWrapper::EmptyDataModelWrapper() {}
~EmptyDataModelWrapper()106 EmptyDataModelWrapper::~EmptyDataModelWrapper() {}
107
GetInfo(const AutofillType & type) const108 base::string16 EmptyDataModelWrapper::GetInfo(const AutofillType& type) const {
109 return base::string16();
110 }
111
112 // AutofillProfileWrapper
113
AutofillProfileWrapper(const AutofillProfile * profile)114 AutofillProfileWrapper::AutofillProfileWrapper(const AutofillProfile* profile)
115 : profile_(profile),
116 variant_group_(NO_GROUP),
117 variant_(0) {}
118
AutofillProfileWrapper(const AutofillProfile * profile,const AutofillType & type,size_t variant)119 AutofillProfileWrapper::AutofillProfileWrapper(
120 const AutofillProfile* profile,
121 const AutofillType& type,
122 size_t variant)
123 : profile_(profile),
124 variant_group_(type.group()),
125 variant_(variant) {}
126
~AutofillProfileWrapper()127 AutofillProfileWrapper::~AutofillProfileWrapper() {}
128
GetInfo(const AutofillType & type) const129 base::string16 AutofillProfileWrapper::GetInfo(const AutofillType& type) const {
130 // Requests for the user's credit card are filled from the billing address,
131 // but the AutofillProfile class doesn't know how to fill credit card
132 // fields. So, request for the corresponding profile type instead.
133 AutofillType effective_type = type;
134 if (type.GetStorableType() == CREDIT_CARD_NAME)
135 effective_type = AutofillType(NAME_BILLING_FULL);
136
137 size_t variant = GetVariantForType(effective_type);
138 const std::string& app_locale = g_browser_process->GetApplicationLocale();
139 return profile_->GetInfoForVariant(effective_type, variant, app_locale);
140 }
141
GetInfoForDisplay(const AutofillType & type) const142 base::string16 AutofillProfileWrapper::GetInfoForDisplay(
143 const AutofillType& type) const {
144 // We display the "raw" phone number which contains user-defined formatting.
145 if (type.GetStorableType() == PHONE_HOME_WHOLE_NUMBER) {
146 std::vector<base::string16> values;
147 profile_->GetRawMultiInfo(type.GetStorableType(), &values);
148 const base::string16& phone_number = values[GetVariantForType(type)];
149
150 // If there is no user-defined formatting at all, add some standard
151 // formatting.
152 if (ContainsOnlyChars(phone_number, ASCIIToUTF16("0123456789"))) {
153 std::string region = UTF16ToASCII(
154 GetInfo(AutofillType(HTML_TYPE_COUNTRY_CODE, HTML_MODE_NONE)));
155 i18n::PhoneObject phone(phone_number, region);
156 return phone.GetFormattedNumber();
157 }
158
159 return phone_number;
160 }
161
162 return DataModelWrapper::GetInfoForDisplay(type);
163 }
164
GetVariantForType(const AutofillType & type) const165 size_t AutofillProfileWrapper::GetVariantForType(const AutofillType& type)
166 const {
167 if (type.group() == variant_group_)
168 return variant_;
169
170 return 0;
171 }
172
173 // AutofillShippingAddressWrapper
174
AutofillShippingAddressWrapper(const AutofillProfile * profile)175 AutofillShippingAddressWrapper::AutofillShippingAddressWrapper(
176 const AutofillProfile* profile)
177 : AutofillProfileWrapper(profile) {}
178
~AutofillShippingAddressWrapper()179 AutofillShippingAddressWrapper::~AutofillShippingAddressWrapper() {}
180
GetInfo(const AutofillType & type) const181 base::string16 AutofillShippingAddressWrapper::GetInfo(
182 const AutofillType& type) const {
183 // Shipping addresses don't have email addresses associated with them.
184 if (type.GetStorableType() == EMAIL_ADDRESS)
185 return base::string16();
186
187 return AutofillProfileWrapper::GetInfo(type);
188 }
189
190 // AutofillCreditCardWrapper
191
AutofillCreditCardWrapper(const CreditCard * card)192 AutofillCreditCardWrapper::AutofillCreditCardWrapper(const CreditCard* card)
193 : card_(card) {}
194
~AutofillCreditCardWrapper()195 AutofillCreditCardWrapper::~AutofillCreditCardWrapper() {}
196
GetInfo(const AutofillType & type) const197 base::string16 AutofillCreditCardWrapper::GetInfo(const AutofillType& type)
198 const {
199 if (type.group() != CREDIT_CARD)
200 return base::string16();
201
202 if (type.GetStorableType() == CREDIT_CARD_EXP_MONTH)
203 return MonthComboboxModel::FormatMonth(card_->expiration_month());
204
205 return card_->GetInfo(type, g_browser_process->GetApplicationLocale());
206 }
207
GetIcon()208 gfx::Image AutofillCreditCardWrapper::GetIcon() {
209 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
210 return rb.GetImageNamed(CreditCard::IconResourceId(card_->type()));
211 }
212
GetDisplayText(base::string16 * vertically_compact,base::string16 * horizontally_compact)213 bool AutofillCreditCardWrapper::GetDisplayText(
214 base::string16* vertically_compact,
215 base::string16* horizontally_compact) {
216 if (!card_->IsValid())
217 return false;
218
219 *vertically_compact = *horizontally_compact = card_->TypeAndLastFourDigits();
220 return true;
221 }
222
223 // WalletAddressWrapper
224
WalletAddressWrapper(const wallet::Address * address)225 WalletAddressWrapper::WalletAddressWrapper(
226 const wallet::Address* address) : address_(address) {}
227
~WalletAddressWrapper()228 WalletAddressWrapper::~WalletAddressWrapper() {}
229
GetInfo(const AutofillType & type) const230 base::string16 WalletAddressWrapper::GetInfo(const AutofillType& type) const {
231 // Reachable from DataModelWrapper::GetDisplayText().
232 if (type.GetStorableType() == EMAIL_ADDRESS)
233 return base::string16();
234
235 return address_->GetInfo(type, g_browser_process->GetApplicationLocale());
236 }
237
GetInfoForDisplay(const AutofillType & type) const238 base::string16 WalletAddressWrapper::GetInfoForDisplay(const AutofillType& type)
239 const {
240 if (type.GetStorableType() == PHONE_HOME_WHOLE_NUMBER)
241 return address_->DisplayPhoneNumber();
242
243 return DataModelWrapper::GetInfoForDisplay(type);
244 }
245
GetDisplayText(base::string16 * vertically_compact,base::string16 * horizontally_compact)246 bool WalletAddressWrapper::GetDisplayText(
247 base::string16* vertically_compact,
248 base::string16* horizontally_compact) {
249 if (!address_->is_complete_address() ||
250 GetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER)).empty()) {
251 return false;
252 }
253
254 return DataModelWrapper::GetDisplayText(vertically_compact,
255 horizontally_compact);
256 }
257
258 // WalletInstrumentWrapper
259
WalletInstrumentWrapper(const wallet::WalletItems::MaskedInstrument * instrument)260 WalletInstrumentWrapper::WalletInstrumentWrapper(
261 const wallet::WalletItems::MaskedInstrument* instrument)
262 : instrument_(instrument) {}
263
~WalletInstrumentWrapper()264 WalletInstrumentWrapper::~WalletInstrumentWrapper() {}
265
GetInfo(const AutofillType & type) const266 base::string16 WalletInstrumentWrapper::GetInfo(const AutofillType& type)
267 const {
268 // Reachable from DataModelWrapper::GetDisplayText().
269 if (type.GetStorableType() == EMAIL_ADDRESS)
270 return base::string16();
271
272 if (type.GetStorableType() == CREDIT_CARD_EXP_MONTH)
273 return MonthComboboxModel::FormatMonth(instrument_->expiration_month());
274
275 return instrument_->GetInfo(type, g_browser_process->GetApplicationLocale());
276 }
277
GetInfoForDisplay(const AutofillType & type) const278 base::string16 WalletInstrumentWrapper::GetInfoForDisplay(
279 const AutofillType& type) const {
280 if (type.GetStorableType() == PHONE_HOME_WHOLE_NUMBER)
281 return instrument_->address().DisplayPhoneNumber();
282
283 return DataModelWrapper::GetInfoForDisplay(type);
284 }
285
GetIcon()286 gfx::Image WalletInstrumentWrapper::GetIcon() {
287 return instrument_->CardIcon();
288 }
289
GetDisplayText(base::string16 * vertically_compact,base::string16 * horizontally_compact)290 bool WalletInstrumentWrapper::GetDisplayText(
291 base::string16* vertically_compact,
292 base::string16* horizontally_compact) {
293 // TODO(dbeam): handle other instrument statuses? http://crbug.com/233048
294 if (instrument_->status() == wallet::WalletItems::MaskedInstrument::EXPIRED ||
295 !instrument_->address().is_complete_address() ||
296 GetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER)).empty()) {
297 return false;
298 }
299
300 DataModelWrapper::GetDisplayText(vertically_compact, horizontally_compact);
301 // TODO(estade): descriptive_name() is user-provided. Should we use it or
302 // just type + last 4 digits?
303 base::string16 line1 = instrument_->descriptive_name() + ASCIIToUTF16("\n");
304 *vertically_compact = line1 + *vertically_compact;
305 *horizontally_compact = line1 + *horizontally_compact;
306 return true;
307 }
308
309 // FullWalletBillingWrapper
310
FullWalletBillingWrapper(wallet::FullWallet * full_wallet)311 FullWalletBillingWrapper::FullWalletBillingWrapper(
312 wallet::FullWallet* full_wallet)
313 : full_wallet_(full_wallet) {
314 DCHECK(full_wallet_);
315 }
316
~FullWalletBillingWrapper()317 FullWalletBillingWrapper::~FullWalletBillingWrapper() {}
318
GetInfo(const AutofillType & type) const319 base::string16 FullWalletBillingWrapper::GetInfo(const AutofillType& type)
320 const {
321 if (type.GetStorableType() == CREDIT_CARD_EXP_MONTH)
322 return MonthComboboxModel::FormatMonth(full_wallet_->expiration_month());
323
324 if (type.group() == CREDIT_CARD)
325 return full_wallet_->GetInfo(type);
326
327 return full_wallet_->billing_address()->GetInfo(
328 type, g_browser_process->GetApplicationLocale());
329 }
330
GetDisplayText(base::string16 * vertically_compact,base::string16 * horizontally_compact)331 bool FullWalletBillingWrapper::GetDisplayText(
332 base::string16* vertically_compact,
333 base::string16* horizontally_compact) {
334 // TODO(dbeam): handle other required actions? http://crbug.com/163508
335 if (full_wallet_->HasRequiredAction(wallet::UPDATE_EXPIRATION_DATE))
336 return false;
337
338 return DataModelWrapper::GetDisplayText(vertically_compact,
339 horizontally_compact);
340 }
341
342 // FullWalletShippingWrapper
343
FullWalletShippingWrapper(wallet::FullWallet * full_wallet)344 FullWalletShippingWrapper::FullWalletShippingWrapper(
345 wallet::FullWallet* full_wallet)
346 : full_wallet_(full_wallet) {
347 DCHECK(full_wallet_);
348 }
349
~FullWalletShippingWrapper()350 FullWalletShippingWrapper::~FullWalletShippingWrapper() {}
351
GetInfo(const AutofillType & type) const352 base::string16 FullWalletShippingWrapper::GetInfo(
353 const AutofillType& type) const {
354 return full_wallet_->shipping_address()->GetInfo(
355 type, g_browser_process->GetApplicationLocale());
356 }
357
FieldMapWrapper(const FieldValueMap & field_map)358 FieldMapWrapper::FieldMapWrapper(const FieldValueMap& field_map)
359 : field_map_(field_map) {}
360
~FieldMapWrapper()361 FieldMapWrapper::~FieldMapWrapper() {}
362
GetInfo(const AutofillType & type) const363 base::string16 FieldMapWrapper::GetInfo(const AutofillType& type) const {
364 FieldValueMap::const_iterator it = field_map_.find(type.server_type());
365 return it != field_map_.end() ? it->second : base::string16();
366 }
367
368 } // namespace autofill
369