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.
5 #include "chrome/browser/ui/autofill/data_model_wrapper.h"
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"
25 using base::ASCIIToUTF16
;
29 DataModelWrapper::~DataModelWrapper() {}
31 void DataModelWrapper::FillInputs(DetailInputs
* inputs
) {
32 for (size_t i
= 0; i
< inputs
->size(); ++i
) {
33 DetailInput
* input
= &(*inputs
)[i
];
34 input
->initial_value
= common::GetHardcodedValueForType(input
->type
);
35 if (input
->initial_value
.empty())
36 input
->initial_value
= GetInfo(AutofillType(input
->type
));
40 base::string16
DataModelWrapper::GetInfoForDisplay(const AutofillType
& type
)
45 gfx::Image
DataModelWrapper::GetIcon() {
49 bool DataModelWrapper::GetDisplayText(
50 base::string16
* vertically_compact
,
51 base::string16
* horizontally_compact
) {
52 base::string16 comma
= ASCIIToUTF16(", ");
53 base::string16 newline
= ASCIIToUTF16("\n");
55 *vertically_compact
= GetAddressDisplayText(comma
);
56 *horizontally_compact
= GetAddressDisplayText(newline
);
60 bool DataModelWrapper::FillFormStructure(
61 const DetailInputs
& inputs
,
62 const InputFieldComparator
& compare
,
63 FormStructure
* form_structure
) const {
64 bool filled_something
= false;
65 for (size_t i
= 0; i
< form_structure
->field_count(); ++i
) {
66 AutofillField
* field
= form_structure
->field(i
);
67 for (size_t j
= 0; j
< inputs
.size(); ++j
) {
68 if (compare
.Run(inputs
[j
], *field
)) {
69 AutofillField::FillFormField(*field
, GetInfo(field
->Type()),
70 g_browser_process
->GetApplicationLocale(),
72 filled_something
= true;
77 return filled_something
;
80 DataModelWrapper::DataModelWrapper() {}
82 base::string16
DataModelWrapper::GetAddressDisplayText(
83 const base::string16
& separator
) {
84 base::string16 address
= GetInfoForDisplay(AutofillType(NAME_FULL
)) +
85 separator
+ GetInfoForDisplay(AutofillType(ADDRESS_HOME_LINE1
));
86 base::string16 address2
= GetInfoForDisplay(AutofillType(ADDRESS_HOME_LINE2
));
87 if (!address2
.empty())
88 address
+= separator
+ address2
;
90 base::string16 comma
= ASCIIToUTF16(", ");
91 base::string16 newline
= ASCIIToUTF16("\n");
92 address
+= separator
+
93 GetInfoForDisplay(AutofillType(ADDRESS_HOME_CITY
)) + comma
+
94 GetInfoForDisplay(AutofillType(ADDRESS_HOME_STATE
)) + ASCIIToUTF16(" ") +
95 GetInfoForDisplay(AutofillType(ADDRESS_HOME_ZIP
));
97 base::string16 email
= GetInfoForDisplay(AutofillType(EMAIL_ADDRESS
));
99 address
+= newline
+ email
;
100 address
+= newline
+ GetInfoForDisplay(AutofillType(PHONE_HOME_WHOLE_NUMBER
));
105 // EmptyDataModelWrapper
107 EmptyDataModelWrapper::EmptyDataModelWrapper() {}
108 EmptyDataModelWrapper::~EmptyDataModelWrapper() {}
110 base::string16
EmptyDataModelWrapper::GetInfo(const AutofillType
& type
) const {
111 return base::string16();
114 // AutofillProfileWrapper
116 AutofillProfileWrapper::AutofillProfileWrapper(const AutofillProfile
* profile
)
118 variant_group_(NO_GROUP
),
121 AutofillProfileWrapper::AutofillProfileWrapper(
122 const AutofillProfile
* profile
,
123 const AutofillType
& type
,
126 variant_group_(type
.group()),
129 AutofillProfileWrapper::~AutofillProfileWrapper() {}
131 base::string16
AutofillProfileWrapper::GetInfo(const AutofillType
& type
) const {
132 // Requests for the user's credit card are filled from the billing address,
133 // but the AutofillProfile class doesn't know how to fill credit card
134 // fields. So, request for the corresponding profile type instead.
135 AutofillType effective_type
= type
;
136 if (type
.GetStorableType() == CREDIT_CARD_NAME
)
137 effective_type
= AutofillType(NAME_BILLING_FULL
);
139 size_t variant
= GetVariantForType(effective_type
);
140 const std::string
& app_locale
= g_browser_process
->GetApplicationLocale();
141 return profile_
->GetInfoForVariant(effective_type
, variant
, app_locale
);
144 base::string16
AutofillProfileWrapper::GetInfoForDisplay(
145 const AutofillType
& type
) const {
146 // We display the "raw" phone number which contains user-defined formatting.
147 if (type
.GetStorableType() == PHONE_HOME_WHOLE_NUMBER
) {
148 std::vector
<base::string16
> values
;
149 profile_
->GetRawMultiInfo(type
.GetStorableType(), &values
);
150 const base::string16
& phone_number
= values
[GetVariantForType(type
)];
152 // If there is no user-defined formatting at all, add some standard
154 if (ContainsOnlyChars(phone_number
, ASCIIToUTF16("0123456789"))) {
155 std::string region
= UTF16ToASCII(
156 GetInfo(AutofillType(HTML_TYPE_COUNTRY_CODE
, HTML_MODE_NONE
)));
157 i18n::PhoneObject
phone(phone_number
, region
);
158 return phone
.GetFormattedNumber();
164 return DataModelWrapper::GetInfoForDisplay(type
);
167 size_t AutofillProfileWrapper::GetVariantForType(const AutofillType
& type
)
169 if (type
.group() == variant_group_
)
175 // AutofillShippingAddressWrapper
177 AutofillShippingAddressWrapper::AutofillShippingAddressWrapper(
178 const AutofillProfile
* profile
)
179 : AutofillProfileWrapper(profile
) {}
181 AutofillShippingAddressWrapper::~AutofillShippingAddressWrapper() {}
183 base::string16
AutofillShippingAddressWrapper::GetInfo(
184 const AutofillType
& type
) const {
185 // Shipping addresses don't have email addresses associated with them.
186 if (type
.GetStorableType() == EMAIL_ADDRESS
)
187 return base::string16();
189 return AutofillProfileWrapper::GetInfo(type
);
192 // AutofillCreditCardWrapper
194 AutofillCreditCardWrapper::AutofillCreditCardWrapper(const CreditCard
* card
)
197 AutofillCreditCardWrapper::~AutofillCreditCardWrapper() {}
199 base::string16
AutofillCreditCardWrapper::GetInfo(const AutofillType
& type
)
201 if (type
.group() != CREDIT_CARD
)
202 return base::string16();
204 if (type
.GetStorableType() == CREDIT_CARD_EXP_MONTH
)
205 return MonthComboboxModel::FormatMonth(card_
->expiration_month());
207 return card_
->GetInfo(type
, g_browser_process
->GetApplicationLocale());
210 gfx::Image
AutofillCreditCardWrapper::GetIcon() {
211 ui::ResourceBundle
& rb
= ui::ResourceBundle::GetSharedInstance();
212 return rb
.GetImageNamed(CreditCard::IconResourceId(card_
->type()));
215 bool AutofillCreditCardWrapper::GetDisplayText(
216 base::string16
* vertically_compact
,
217 base::string16
* horizontally_compact
) {
218 if (!card_
->IsValid())
221 *vertically_compact
= *horizontally_compact
= card_
->TypeAndLastFourDigits();
225 // WalletAddressWrapper
227 WalletAddressWrapper::WalletAddressWrapper(
228 const wallet::Address
* address
) : address_(address
) {}
230 WalletAddressWrapper::~WalletAddressWrapper() {}
232 base::string16
WalletAddressWrapper::GetInfo(const AutofillType
& type
) const {
233 // Reachable from DataModelWrapper::GetDisplayText().
234 if (type
.GetStorableType() == EMAIL_ADDRESS
)
235 return base::string16();
237 return address_
->GetInfo(type
, g_browser_process
->GetApplicationLocale());
240 base::string16
WalletAddressWrapper::GetInfoForDisplay(const AutofillType
& type
)
242 if (type
.GetStorableType() == PHONE_HOME_WHOLE_NUMBER
)
243 return address_
->DisplayPhoneNumber();
245 return DataModelWrapper::GetInfoForDisplay(type
);
248 bool WalletAddressWrapper::GetDisplayText(
249 base::string16
* vertically_compact
,
250 base::string16
* horizontally_compact
) {
251 if (!address_
->is_complete_address() ||
252 GetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER
)).empty()) {
256 return DataModelWrapper::GetDisplayText(vertically_compact
,
257 horizontally_compact
);
260 // WalletInstrumentWrapper
262 WalletInstrumentWrapper::WalletInstrumentWrapper(
263 const wallet::WalletItems::MaskedInstrument
* instrument
)
264 : instrument_(instrument
) {}
266 WalletInstrumentWrapper::~WalletInstrumentWrapper() {}
268 base::string16
WalletInstrumentWrapper::GetInfo(const AutofillType
& type
)
270 // Reachable from DataModelWrapper::GetDisplayText().
271 if (type
.GetStorableType() == EMAIL_ADDRESS
)
272 return base::string16();
274 if (type
.GetStorableType() == CREDIT_CARD_EXP_MONTH
)
275 return MonthComboboxModel::FormatMonth(instrument_
->expiration_month());
277 return instrument_
->GetInfo(type
, g_browser_process
->GetApplicationLocale());
280 base::string16
WalletInstrumentWrapper::GetInfoForDisplay(
281 const AutofillType
& type
) const {
282 if (type
.GetStorableType() == PHONE_HOME_WHOLE_NUMBER
)
283 return instrument_
->address().DisplayPhoneNumber();
285 return DataModelWrapper::GetInfoForDisplay(type
);
288 gfx::Image
WalletInstrumentWrapper::GetIcon() {
289 return instrument_
->CardIcon();
292 bool WalletInstrumentWrapper::GetDisplayText(
293 base::string16
* vertically_compact
,
294 base::string16
* horizontally_compact
) {
295 // TODO(dbeam): handle other instrument statuses? http://crbug.com/233048
296 if (instrument_
->status() == wallet::WalletItems::MaskedInstrument::EXPIRED
||
297 !instrument_
->address().is_complete_address() ||
298 GetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER
)).empty()) {
302 DataModelWrapper::GetDisplayText(vertically_compact
, horizontally_compact
);
303 // TODO(estade): descriptive_name() is user-provided. Should we use it or
304 // just type + last 4 digits?
305 base::string16 line1
= instrument_
->descriptive_name() + ASCIIToUTF16("\n");
306 *vertically_compact
= line1
+ *vertically_compact
;
307 *horizontally_compact
= line1
+ *horizontally_compact
;
311 // FullWalletBillingWrapper
313 FullWalletBillingWrapper::FullWalletBillingWrapper(
314 wallet::FullWallet
* full_wallet
)
315 : full_wallet_(full_wallet
) {
316 DCHECK(full_wallet_
);
319 FullWalletBillingWrapper::~FullWalletBillingWrapper() {}
321 base::string16
FullWalletBillingWrapper::GetInfo(const AutofillType
& type
)
323 if (type
.GetStorableType() == CREDIT_CARD_EXP_MONTH
)
324 return MonthComboboxModel::FormatMonth(full_wallet_
->expiration_month());
326 if (type
.group() == CREDIT_CARD
)
327 return full_wallet_
->GetInfo(type
);
329 return full_wallet_
->billing_address()->GetInfo(
330 type
, g_browser_process
->GetApplicationLocale());
333 bool FullWalletBillingWrapper::GetDisplayText(
334 base::string16
* vertically_compact
,
335 base::string16
* horizontally_compact
) {
336 // TODO(dbeam): handle other required actions? http://crbug.com/163508
337 if (full_wallet_
->HasRequiredAction(wallet::UPDATE_EXPIRATION_DATE
))
340 return DataModelWrapper::GetDisplayText(vertically_compact
,
341 horizontally_compact
);
344 // FullWalletShippingWrapper
346 FullWalletShippingWrapper::FullWalletShippingWrapper(
347 wallet::FullWallet
* full_wallet
)
348 : full_wallet_(full_wallet
) {
349 DCHECK(full_wallet_
);
352 FullWalletShippingWrapper::~FullWalletShippingWrapper() {}
354 base::string16
FullWalletShippingWrapper::GetInfo(
355 const AutofillType
& type
) const {
356 return full_wallet_
->shipping_address()->GetInfo(
357 type
, g_browser_process
->GetApplicationLocale());
360 FieldMapWrapper::FieldMapWrapper(const FieldValueMap
& field_map
)
361 : field_map_(field_map
) {}
363 FieldMapWrapper::~FieldMapWrapper() {}
365 base::string16
FieldMapWrapper::GetInfo(const AutofillType
& type
) const {
366 FieldValueMap::const_iterator it
= field_map_
.find(type
.server_type());
367 return it
!= field_map_
.end() ? it
->second
: base::string16();
370 } // namespace autofill