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