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/callback.h"
      8 #include "base/strings/utf_string_conversions.h"
      9 #include "chrome/browser/browser_process.h"
     10 #include "chrome/browser/ui/autofill/autofill_dialog_models.h"
     11 #include "components/autofill/content/browser/wallet/full_wallet.h"
     12 #include "components/autofill/content/browser/wallet/wallet_address.h"
     13 #include "components/autofill/content/browser/wallet/wallet_items.h"
     14 #include "components/autofill/core/browser/autofill_data_model.h"
     15 #include "components/autofill/core/browser/autofill_profile.h"
     16 #include "components/autofill/core/browser/autofill_type.h"
     17 #include "components/autofill/core/browser/credit_card.h"
     18 #include "components/autofill/core/browser/form_structure.h"
     19 #include "components/autofill/core/browser/validation.h"
     20 #include "ui/base/resource/resource_bundle.h"
     21 #include "ui/gfx/image/image.h"
     22 
     23 namespace autofill {
     24 
     25 DataModelWrapper::~DataModelWrapper() {}
     26 
     27 gfx::Image DataModelWrapper::GetIcon() {
     28   return gfx::Image();
     29 }
     30 
     31 void DataModelWrapper::FillInputs(DetailInputs* inputs) {
     32   for (size_t i = 0; i < inputs->size(); ++i) {
     33     (*inputs)[i].initial_value = GetInfo(AutofillType((*inputs)[i].type));
     34   }
     35 }
     36 
     37 bool DataModelWrapper::GetDisplayText(
     38     base::string16* vertically_compact,
     39     base::string16* horizontally_compact) {
     40   base::string16 comma = ASCIIToUTF16(", ");
     41   base::string16 newline = ASCIIToUTF16("\n");
     42 
     43   *vertically_compact = GetAddressDisplayText(comma);
     44   *horizontally_compact = GetAddressDisplayText(newline);
     45   return true;
     46 }
     47 
     48 bool DataModelWrapper::FillFormStructure(
     49     const DetailInputs& inputs,
     50     const InputFieldComparator& compare,
     51     FormStructure* form_structure) const {
     52   bool filled_something = false;
     53   for (size_t i = 0; i < form_structure->field_count(); ++i) {
     54     AutofillField* field = form_structure->field(i);
     55     for (size_t j = 0; j < inputs.size(); ++j) {
     56       if (compare.Run(inputs[j], *field)) {
     57         FillFormField(field);
     58         filled_something = true;
     59         break;
     60       }
     61     }
     62   }
     63   return filled_something;
     64 }
     65 
     66 DataModelWrapper::DataModelWrapper() {}
     67 
     68 void DataModelWrapper::FillFormField(AutofillField* field) const {
     69   field->value = GetInfo(field->Type());
     70 }
     71 
     72 base::string16 DataModelWrapper::GetAddressDisplayText(
     73     const base::string16& separator) {
     74   base::string16 address = GetInfo(AutofillType(NAME_FULL)) + separator +
     75       GetInfo(AutofillType(ADDRESS_HOME_LINE1));
     76   base::string16 address2 = GetInfo(AutofillType(ADDRESS_HOME_LINE2));
     77   if (!address2.empty())
     78     address += separator + address2;
     79 
     80   base::string16 comma = ASCIIToUTF16(", ");
     81   base::string16 newline = ASCIIToUTF16("\n");
     82   address += separator +
     83       GetInfo(AutofillType(ADDRESS_HOME_CITY)) + comma +
     84       GetInfo(AutofillType(ADDRESS_HOME_STATE)) + ASCIIToUTF16(" ") +
     85       GetInfo(AutofillType(ADDRESS_HOME_ZIP));
     86 
     87   // TODO(estade): email?
     88   address += newline + GetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER));
     89 
     90   return address;
     91 }
     92 
     93 // EmptyDataModelWrapper
     94 
     95 EmptyDataModelWrapper::EmptyDataModelWrapper() {}
     96 EmptyDataModelWrapper::~EmptyDataModelWrapper() {}
     97 
     98 base::string16 EmptyDataModelWrapper::GetInfo(const AutofillType& type) const {
     99   return base::string16();
    100 }
    101 
    102 void EmptyDataModelWrapper::FillFormField(AutofillField* field) const {}
    103 
    104 // AutofillDataModelWrapper
    105 
    106 AutofillDataModelWrapper::AutofillDataModelWrapper(
    107     const AutofillDataModel* data_model,
    108     size_t variant)
    109     : data_model_(data_model),
    110       variant_(variant) {}
    111 
    112 AutofillDataModelWrapper::~AutofillDataModelWrapper() {}
    113 
    114 base::string16 AutofillDataModelWrapper::GetInfo(const AutofillType& type)
    115     const {
    116   return data_model_->GetInfo(type, g_browser_process->GetApplicationLocale());
    117 }
    118 
    119 void AutofillDataModelWrapper::FillFormField(AutofillField* field) const {
    120   data_model_->FillFormField(
    121       *field, variant_, g_browser_process->GetApplicationLocale(), field);
    122 }
    123 
    124 // AutofillProfileWrapper
    125 
    126 AutofillProfileWrapper::AutofillProfileWrapper(
    127     const AutofillProfile* profile, size_t variant)
    128     : AutofillDataModelWrapper(profile, variant),
    129       profile_(profile) {}
    130 
    131 AutofillProfileWrapper::~AutofillProfileWrapper() {}
    132 
    133 void AutofillProfileWrapper::FillInputs(DetailInputs* inputs) {
    134   const std::string app_locale = g_browser_process->GetApplicationLocale();
    135   for (size_t j = 0; j < inputs->size(); ++j) {
    136     std::vector<base::string16> values;
    137     profile_->GetMultiInfo(
    138         AutofillType((*inputs)[j].type), app_locale, &values);
    139     (*inputs)[j].initial_value = values[variant()];
    140   }
    141 }
    142 
    143 void AutofillProfileWrapper::FillFormField(AutofillField* field) const {
    144   if (field->Type().GetStorableType() == CREDIT_CARD_NAME) {
    145     // Cache the field's true type.
    146     HtmlFieldType original_type = field->html_type();
    147 
    148     // Requests for the user's credit card are filled from the billing address,
    149     // but the AutofillProfile class doesn't know how to fill credit card
    150     // fields. So, temporarily set the type to the corresponding profile type.
    151     field->SetHtmlType(HTML_TYPE_NAME, field->html_mode());
    152     AutofillDataModelWrapper::FillFormField(field);
    153 
    154     // Restore the field's true type.
    155     field->SetHtmlType(original_type, field->html_mode());
    156   } else {
    157     AutofillDataModelWrapper::FillFormField(field);
    158   }
    159 }
    160 
    161 // AutofillCreditCardWrapper
    162 
    163 AutofillCreditCardWrapper::AutofillCreditCardWrapper(const CreditCard* card)
    164     : AutofillDataModelWrapper(card, 0),
    165       card_(card) {}
    166 
    167 AutofillCreditCardWrapper::~AutofillCreditCardWrapper() {}
    168 
    169 base::string16 AutofillCreditCardWrapper::GetInfo(const AutofillType& type)
    170     const {
    171   if (type.GetStorableType() == CREDIT_CARD_EXP_MONTH)
    172     return MonthComboboxModel::FormatMonth(card_->expiration_month());
    173 
    174   return AutofillDataModelWrapper::GetInfo(type);
    175 }
    176 
    177 gfx::Image AutofillCreditCardWrapper::GetIcon() {
    178   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
    179   return rb.GetImageNamed(CreditCard::IconResourceId(card_->type()));
    180 }
    181 
    182 bool AutofillCreditCardWrapper::GetDisplayText(
    183     base::string16* vertically_compact,
    184     base::string16* horizontally_compact) {
    185   if (!card_->IsValid())
    186     return false;
    187 
    188   *vertically_compact = *horizontally_compact = card_->TypeAndLastFourDigits();
    189   return true;
    190 }
    191 
    192 // WalletAddressWrapper
    193 
    194 WalletAddressWrapper::WalletAddressWrapper(
    195     const wallet::Address* address) : address_(address) {}
    196 
    197 WalletAddressWrapper::~WalletAddressWrapper() {}
    198 
    199 base::string16 WalletAddressWrapper::GetInfo(const AutofillType& type) const {
    200   return address_->GetInfo(type, g_browser_process->GetApplicationLocale());
    201 }
    202 
    203 bool WalletAddressWrapper::GetDisplayText(
    204     base::string16* vertically_compact,
    205     base::string16* horizontally_compact) {
    206   if (!address_->is_complete_address() ||
    207       GetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER)).empty()) {
    208     return false;
    209   }
    210 
    211   return DataModelWrapper::GetDisplayText(vertically_compact,
    212                                           horizontally_compact);
    213 }
    214 
    215 // WalletInstrumentWrapper
    216 
    217 WalletInstrumentWrapper::WalletInstrumentWrapper(
    218     const wallet::WalletItems::MaskedInstrument* instrument)
    219     : instrument_(instrument) {}
    220 
    221 WalletInstrumentWrapper::~WalletInstrumentWrapper() {}
    222 
    223 base::string16 WalletInstrumentWrapper::GetInfo(const AutofillType& type)
    224     const {
    225   if (type.GetStorableType() == CREDIT_CARD_EXP_MONTH)
    226     return MonthComboboxModel::FormatMonth(instrument_->expiration_month());
    227 
    228   return instrument_->GetInfo(type, g_browser_process->GetApplicationLocale());
    229 }
    230 
    231 gfx::Image WalletInstrumentWrapper::GetIcon() {
    232   return instrument_->CardIcon();
    233 }
    234 
    235 bool WalletInstrumentWrapper::GetDisplayText(
    236     base::string16* vertically_compact,
    237     base::string16* horizontally_compact) {
    238   // TODO(dbeam): handle other instrument statuses? http://crbug.com/233048
    239   if (instrument_->status() == wallet::WalletItems::MaskedInstrument::EXPIRED ||
    240       !instrument_->address().is_complete_address() ||
    241       GetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER)).empty()) {
    242     return false;
    243   }
    244 
    245   DataModelWrapper::GetDisplayText(vertically_compact, horizontally_compact);
    246   // TODO(estade): descriptive_name() is user-provided. Should we use it or
    247   // just type + last 4 digits?
    248   base::string16 line1 = instrument_->descriptive_name() + ASCIIToUTF16("\n");
    249   *vertically_compact = line1 + *vertically_compact;
    250   *horizontally_compact = line1 + *horizontally_compact;
    251   return true;
    252 }
    253 
    254 // FullWalletBillingWrapper
    255 
    256 FullWalletBillingWrapper::FullWalletBillingWrapper(
    257     wallet::FullWallet* full_wallet)
    258     : full_wallet_(full_wallet) {
    259   DCHECK(full_wallet_);
    260 }
    261 
    262 FullWalletBillingWrapper::~FullWalletBillingWrapper() {}
    263 
    264 base::string16 FullWalletBillingWrapper::GetInfo(const AutofillType& type)
    265     const {
    266   if (type.GetStorableType() == CREDIT_CARD_EXP_MONTH)
    267     return MonthComboboxModel::FormatMonth(full_wallet_->expiration_month());
    268 
    269   if (type.group() == CREDIT_CARD)
    270     return full_wallet_->GetInfo(type);
    271 
    272   return full_wallet_->billing_address()->GetInfo(
    273       type, g_browser_process->GetApplicationLocale());
    274 }
    275 
    276 bool FullWalletBillingWrapper::GetDisplayText(
    277     base::string16* vertically_compact,
    278     base::string16* horizontally_compact) {
    279   // TODO(dbeam): handle other required actions? http://crbug.com/163508
    280   if (full_wallet_->HasRequiredAction(wallet::UPDATE_EXPIRATION_DATE))
    281     return false;
    282 
    283   return DataModelWrapper::GetDisplayText(vertically_compact,
    284                                           horizontally_compact);
    285 }
    286 
    287 // FullWalletShippingWrapper
    288 
    289 FullWalletShippingWrapper::FullWalletShippingWrapper(
    290     wallet::FullWallet* full_wallet)
    291     : full_wallet_(full_wallet) {
    292   DCHECK(full_wallet_);
    293 }
    294 
    295 FullWalletShippingWrapper::~FullWalletShippingWrapper() {}
    296 
    297 base::string16 FullWalletShippingWrapper::GetInfo(
    298     const AutofillType& type) const {
    299   return full_wallet_->shipping_address()->GetInfo(
    300       type, g_browser_process->GetApplicationLocale());
    301 }
    302 
    303 DetailOutputWrapper::DetailOutputWrapper(const DetailOutputMap& outputs)
    304     : outputs_(outputs) {}
    305 
    306 DetailOutputWrapper::~DetailOutputWrapper() {}
    307 
    308 base::string16 DetailOutputWrapper::GetInfo(const AutofillType& type) const {
    309   ServerFieldType storable_type = type.GetStorableType();
    310   for (DetailOutputMap::const_iterator it = outputs_.begin();
    311        it != outputs_.end(); ++it) {
    312     if (storable_type == AutofillType(it->first->type).GetStorableType())
    313       return it->second;
    314   }
    315   return base::string16();
    316 }
    317 
    318 }  // namespace autofill
    319