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