• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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