Home | History | Annotate | Download | only in autofill
      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/bind.h"
      8 #include "base/callback.h"
      9 #include "base/strings/string_util.h"
     10 #include "base/strings/utf_string_conversions.h"
     11 #include "chrome/browser/browser_process.h"
     12 #include "chrome/browser/ui/autofill/autofill_dialog_i18n_input.h"
     13 #include "chrome/browser/ui/autofill/autofill_dialog_models.h"
     14 #include "components/autofill/content/browser/wallet/full_wallet.h"
     15 #include "components/autofill/content/browser/wallet/wallet_address.h"
     16 #include "components/autofill/content/browser/wallet/wallet_items.h"
     17 #include "components/autofill/core/browser/address_i18n.h"
     18 #include "components/autofill/core/browser/autofill_country.h"
     19 #include "components/autofill/core/browser/autofill_data_model.h"
     20 #include "components/autofill/core/browser/autofill_field.h"
     21 #include "components/autofill/core/browser/autofill_profile.h"
     22 #include "components/autofill/core/browser/autofill_type.h"
     23 #include "components/autofill/core/browser/credit_card.h"
     24 #include "components/autofill/core/browser/form_structure.h"
     25 #include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_data.h"
     26 #include "third_party/libaddressinput/chromium/cpp/include/libaddressinput/address_ui.h"
     27 #include "ui/base/resource/resource_bundle.h"
     28 #include "ui/gfx/image/image.h"
     29 
     30 namespace autofill {
     31 
     32 DataModelWrapper::~DataModelWrapper() {}
     33 
     34 void DataModelWrapper::FillInputs(DetailInputs* inputs) {
     35   for (size_t i = 0; i < inputs->size(); ++i) {
     36     (*inputs)[i].initial_value =
     37         GetInfoForDisplay(AutofillType((*inputs)[i].type));
     38   }
     39 }
     40 
     41 base::string16 DataModelWrapper::GetInfoForDisplay(const AutofillType& type)
     42     const {
     43   return GetInfo(type);
     44 }
     45 
     46 gfx::Image DataModelWrapper::GetIcon() {
     47   return gfx::Image();
     48 }
     49 
     50 bool DataModelWrapper::GetDisplayText(
     51     base::string16* vertically_compact,
     52     base::string16* horizontally_compact) {
     53   base::string16 phone =
     54       GetInfoForDisplay(AutofillType(PHONE_HOME_WHOLE_NUMBER));
     55   if (phone.empty())
     56     return false;
     57 
     58   // Format the address.
     59   scoped_ptr< ::i18n::addressinput::AddressData> address_data =
     60       i18n::CreateAddressData(
     61           base::Bind(&DataModelWrapper::GetInfo, base::Unretained(this)));
     62   address_data->language_code = GetLanguageCode();
     63   std::vector<std::string> lines;
     64   address_data->FormatForDisplay(&lines);
     65 
     66   // Email and phone number aren't part of address formatting.
     67   base::string16 non_address_info;
     68   base::string16 email = GetInfoForDisplay(AutofillType(EMAIL_ADDRESS));
     69   if (!email.empty())
     70     non_address_info += base::ASCIIToUTF16("\n") + email;
     71 
     72   non_address_info += base::ASCIIToUTF16("\n") + phone;
     73 
     74   // The separator is locale-specific.
     75   std::string compact_separator =
     76       ::i18n::addressinput::GetCompactAddressLinesSeparator(GetLanguageCode());
     77   *vertically_compact =
     78       base::UTF8ToUTF16(JoinString(lines, compact_separator)) +
     79           non_address_info;
     80   *horizontally_compact = base::UTF8ToUTF16(JoinString(lines, "\n")) +
     81       non_address_info;
     82 
     83   return true;
     84 }
     85 
     86 bool DataModelWrapper::FillFormStructure(
     87     const std::vector<ServerFieldType>& types,
     88     const FormStructure::InputFieldComparator& compare,
     89     FormStructure* form_structure) const {
     90   return form_structure->FillFields(
     91       types,
     92       compare,
     93       base::Bind(&DataModelWrapper::GetInfo, base::Unretained(this)),
     94       g_browser_process->GetApplicationLocale());
     95 }
     96 
     97 DataModelWrapper::DataModelWrapper() {}
     98 
     99 // AutofillProfileWrapper
    100 
    101 AutofillProfileWrapper::AutofillProfileWrapper(const AutofillProfile* profile)
    102     : profile_(profile),
    103       variant_group_(NO_GROUP),
    104       variant_(0) {}
    105 
    106 AutofillProfileWrapper::AutofillProfileWrapper(
    107     const AutofillProfile* profile,
    108     const AutofillType& type,
    109     size_t variant)
    110     : profile_(profile),
    111       variant_group_(type.group()),
    112       variant_(variant) {}
    113 
    114 AutofillProfileWrapper::~AutofillProfileWrapper() {}
    115 
    116 base::string16 AutofillProfileWrapper::GetInfo(const AutofillType& type) const {
    117   // Requests for the user's credit card are filled from the billing address,
    118   // but the AutofillProfile class doesn't know how to fill credit card
    119   // fields. So, request for the corresponding profile type instead.
    120   AutofillType effective_type = type;
    121   if (type.GetStorableType() == CREDIT_CARD_NAME)
    122     effective_type = AutofillType(NAME_BILLING_FULL);
    123 
    124   size_t variant = GetVariantForType(effective_type);
    125   const std::string& app_locale = g_browser_process->GetApplicationLocale();
    126   return profile_->GetInfoForVariant(effective_type, variant, app_locale);
    127 }
    128 
    129 base::string16 AutofillProfileWrapper::GetInfoForDisplay(
    130     const AutofillType& type) const {
    131   // We display the "raw" phone number which contains user-defined formatting.
    132   if (type.GetStorableType() == PHONE_HOME_WHOLE_NUMBER) {
    133     std::vector<base::string16> values;
    134     profile_->GetRawMultiInfo(type.GetStorableType(), &values);
    135     const base::string16& phone_number = values[GetVariantForType(type)];
    136 
    137     // If there is no user-defined formatting at all, add some standard
    138     // formatting.
    139     if (base::ContainsOnlyChars(phone_number,
    140                                 base::ASCIIToUTF16("0123456789"))) {
    141       std::string region = base::UTF16ToASCII(
    142           GetInfo(AutofillType(HTML_TYPE_COUNTRY_CODE, HTML_MODE_NONE)));
    143       i18n::PhoneObject phone(phone_number, region);
    144       base::string16 formatted_number = phone.GetFormattedNumber();
    145       // Formatting may fail.
    146       if (!formatted_number.empty())
    147         return formatted_number;
    148     }
    149 
    150     return phone_number;
    151   }
    152 
    153   return DataModelWrapper::GetInfoForDisplay(type);
    154 }
    155 
    156 const std::string& AutofillProfileWrapper::GetLanguageCode() const {
    157   return profile_->language_code();
    158 }
    159 
    160 size_t AutofillProfileWrapper::GetVariantForType(const AutofillType& type)
    161     const {
    162   if (type.group() == variant_group_)
    163     return variant_;
    164 
    165   return 0;
    166 }
    167 
    168 // AutofillShippingAddressWrapper
    169 
    170 AutofillShippingAddressWrapper::AutofillShippingAddressWrapper(
    171     const AutofillProfile* profile)
    172     : AutofillProfileWrapper(profile) {}
    173 
    174 AutofillShippingAddressWrapper::~AutofillShippingAddressWrapper() {}
    175 
    176 base::string16 AutofillShippingAddressWrapper::GetInfo(
    177     const AutofillType& type) const {
    178   // Shipping addresses don't have email addresses associated with them.
    179   if (type.GetStorableType() == EMAIL_ADDRESS)
    180     return base::string16();
    181 
    182   return AutofillProfileWrapper::GetInfo(type);
    183 }
    184 
    185 // AutofillCreditCardWrapper
    186 
    187 AutofillCreditCardWrapper::AutofillCreditCardWrapper(const CreditCard* card)
    188     : card_(card) {}
    189 
    190 AutofillCreditCardWrapper::~AutofillCreditCardWrapper() {}
    191 
    192 base::string16 AutofillCreditCardWrapper::GetInfo(const AutofillType& type)
    193     const {
    194   if (type.group() != CREDIT_CARD)
    195     return base::string16();
    196 
    197   if (type.GetStorableType() == CREDIT_CARD_EXP_MONTH)
    198     return MonthComboboxModel::FormatMonth(card_->expiration_month());
    199 
    200   return card_->GetInfo(type, g_browser_process->GetApplicationLocale());
    201 }
    202 
    203 gfx::Image AutofillCreditCardWrapper::GetIcon() {
    204   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
    205   return rb.GetImageNamed(CreditCard::IconResourceId(card_->type()));
    206 }
    207 
    208 bool AutofillCreditCardWrapper::GetDisplayText(
    209     base::string16* vertically_compact,
    210     base::string16* horizontally_compact) {
    211   if (!card_->IsValid())
    212     return false;
    213 
    214   *vertically_compact = *horizontally_compact = card_->TypeAndLastFourDigits();
    215   return true;
    216 }
    217 
    218 const std::string& AutofillCreditCardWrapper::GetLanguageCode() const {
    219   // Formatting a credit card for display does not depend on language code.
    220   return base::EmptyString();
    221 }
    222 
    223 // WalletAddressWrapper
    224 
    225 WalletAddressWrapper::WalletAddressWrapper(
    226     const wallet::Address* address) : address_(address) {}
    227 
    228 WalletAddressWrapper::~WalletAddressWrapper() {}
    229 
    230 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 
    238 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 
    246 bool WalletAddressWrapper::GetDisplayText(
    247     base::string16* vertically_compact,
    248     base::string16* horizontally_compact) {
    249   if (!address_->is_complete_address())
    250     return false;
    251 
    252   return DataModelWrapper::GetDisplayText(vertically_compact,
    253                                           horizontally_compact);
    254 }
    255 
    256 const std::string& WalletAddressWrapper::GetLanguageCode() const {
    257   return address_->language_code();
    258 }
    259 
    260 // WalletInstrumentWrapper
    261 
    262 WalletInstrumentWrapper::WalletInstrumentWrapper(
    263     const wallet::WalletItems::MaskedInstrument* instrument)
    264     : instrument_(instrument) {}
    265 
    266 WalletInstrumentWrapper::~WalletInstrumentWrapper() {}
    267 
    268 base::string16 WalletInstrumentWrapper::GetInfo(const AutofillType& type)
    269     const {
    270   // Reachable from DataModelWrapper::GetDisplayText().
    271   if (type.GetStorableType() == EMAIL_ADDRESS)
    272     return base::string16();
    273 
    274   if (type.GetStorableType() == CREDIT_CARD_EXP_MONTH)
    275     return MonthComboboxModel::FormatMonth(instrument_->expiration_month());
    276 
    277   return instrument_->GetInfo(type, g_browser_process->GetApplicationLocale());
    278 }
    279 
    280 base::string16 WalletInstrumentWrapper::GetInfoForDisplay(
    281     const AutofillType& type) const {
    282   if (type.GetStorableType() == PHONE_HOME_WHOLE_NUMBER)
    283     return instrument_->address().DisplayPhoneNumber();
    284 
    285   return DataModelWrapper::GetInfoForDisplay(type);
    286 }
    287 
    288 gfx::Image WalletInstrumentWrapper::GetIcon() {
    289   return instrument_->CardIcon();
    290 }
    291 
    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     return false;
    299   }
    300 
    301   if (!DataModelWrapper::GetDisplayText(vertically_compact,
    302                                         horizontally_compact)) {
    303     return false;
    304   }
    305 
    306   // TODO(estade): descriptive_name() is user-provided. Should we use it or
    307   // just type + last 4 digits?
    308   base::string16 line1 =
    309       instrument_->descriptive_name() + base::ASCIIToUTF16("\n");
    310   *vertically_compact = line1 + *vertically_compact;
    311   *horizontally_compact = line1 + *horizontally_compact;
    312   return true;
    313 }
    314 
    315 const std::string& WalletInstrumentWrapper::GetLanguageCode() const {
    316   return instrument_->address().language_code();
    317 }
    318 
    319 // FullWalletBillingWrapper
    320 
    321 FullWalletBillingWrapper::FullWalletBillingWrapper(
    322     wallet::FullWallet* full_wallet)
    323     : full_wallet_(full_wallet) {
    324   DCHECK(full_wallet_);
    325 }
    326 
    327 FullWalletBillingWrapper::~FullWalletBillingWrapper() {}
    328 
    329 base::string16 FullWalletBillingWrapper::GetInfo(const AutofillType& type)
    330     const {
    331   return full_wallet_->GetInfo(g_browser_process->GetApplicationLocale(), type);
    332 }
    333 
    334 bool FullWalletBillingWrapper::GetDisplayText(
    335     base::string16* vertically_compact,
    336     base::string16* horizontally_compact) {
    337   // TODO(dbeam): handle other required actions? http://crbug.com/163508
    338   if (full_wallet_->HasRequiredAction(wallet::UPDATE_EXPIRATION_DATE))
    339     return false;
    340 
    341   return DataModelWrapper::GetDisplayText(vertically_compact,
    342                                           horizontally_compact);
    343 }
    344 
    345 const std::string& FullWalletBillingWrapper::GetLanguageCode() const {
    346   // Can be NULL if there are required actions.
    347   return full_wallet_->billing_address() ?
    348       full_wallet_->billing_address()->language_code() : base::EmptyString();
    349 }
    350 
    351 // FullWalletShippingWrapper
    352 
    353 FullWalletShippingWrapper::FullWalletShippingWrapper(
    354     wallet::FullWallet* full_wallet)
    355     : full_wallet_(full_wallet) {
    356   DCHECK(full_wallet_);
    357 }
    358 
    359 FullWalletShippingWrapper::~FullWalletShippingWrapper() {}
    360 
    361 base::string16 FullWalletShippingWrapper::GetInfo(
    362     const AutofillType& type) const {
    363   return full_wallet_->shipping_address()->GetInfo(
    364       type, g_browser_process->GetApplicationLocale());
    365 }
    366 
    367 const std::string& FullWalletShippingWrapper::GetLanguageCode() const {
    368   // Can be NULL if there are required actions or shipping address is not
    369   // required.
    370   return full_wallet_->shipping_address() ?
    371       full_wallet_->shipping_address()->language_code() : base::EmptyString();
    372 }
    373 
    374 // I18nAddressDataWrapper
    375 
    376 I18nAddressDataWrapper::I18nAddressDataWrapper(
    377     const ::i18n::addressinput::AddressData* address)
    378     : address_(address) {}
    379 
    380 I18nAddressDataWrapper::~I18nAddressDataWrapper() {}
    381 
    382 base::string16 I18nAddressDataWrapper::GetInfo(const AutofillType& type) const {
    383   ::i18n::addressinput::AddressField field;
    384   if (!i18ninput::FieldForType(type.GetStorableType(), &field))
    385     return base::string16();
    386 
    387   if (field == ::i18n::addressinput::STREET_ADDRESS)
    388     return base::string16();
    389 
    390   if (field == ::i18n::addressinput::COUNTRY) {
    391     return AutofillCountry(address_->country_code,
    392                            g_browser_process->GetApplicationLocale()).name();
    393   }
    394 
    395   return base::UTF8ToUTF16(address_->GetFieldValue(field));
    396 }
    397 
    398 const std::string& I18nAddressDataWrapper::GetLanguageCode() const {
    399   return address_->language_code;
    400 }
    401 
    402 }  // namespace autofill
    403