data_model_wrapper.cc revision 58537e28ecd584eab876aee8be7156509866d23a
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 23namespace autofill { 24 25DataModelWrapper::~DataModelWrapper() {} 26 27gfx::Image DataModelWrapper::GetIcon() { 28 return gfx::Image(); 29} 30 31void 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 37bool 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 48bool 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 66DataModelWrapper::DataModelWrapper() {} 67 68void DataModelWrapper::FillFormField(AutofillField* field) const { 69 field->value = GetInfo(field->Type()); 70} 71 72base::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 base::string16 email = GetInfo(AutofillType(EMAIL_ADDRESS)); 88 if (!email.empty()) 89 address += newline + email; 90 address += newline + GetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER)); 91 92 return address; 93} 94 95// EmptyDataModelWrapper 96 97EmptyDataModelWrapper::EmptyDataModelWrapper() {} 98EmptyDataModelWrapper::~EmptyDataModelWrapper() {} 99 100base::string16 EmptyDataModelWrapper::GetInfo(const AutofillType& type) const { 101 return base::string16(); 102} 103 104void EmptyDataModelWrapper::FillFormField(AutofillField* field) const {} 105 106// AutofillDataModelWrapper 107 108AutofillDataModelWrapper::AutofillDataModelWrapper( 109 const AutofillDataModel* data_model, 110 size_t variant) 111 : data_model_(data_model), 112 variant_(variant) {} 113 114AutofillDataModelWrapper::~AutofillDataModelWrapper() {} 115 116base::string16 AutofillDataModelWrapper::GetInfo(const AutofillType& type) 117 const { 118 return data_model_->GetInfo(type, g_browser_process->GetApplicationLocale()); 119} 120 121void AutofillDataModelWrapper::FillFormField(AutofillField* field) const { 122 data_model_->FillFormField( 123 *field, variant_, g_browser_process->GetApplicationLocale(), field); 124} 125 126// AutofillProfileWrapper 127 128AutofillProfileWrapper::AutofillProfileWrapper( 129 const AutofillProfile* profile, size_t variant) 130 : AutofillDataModelWrapper(profile, variant), 131 profile_(profile) {} 132 133AutofillProfileWrapper::~AutofillProfileWrapper() {} 134 135void AutofillProfileWrapper::FillInputs(DetailInputs* inputs) { 136 const std::string app_locale = g_browser_process->GetApplicationLocale(); 137 for (size_t j = 0; j < inputs->size(); ++j) { 138 std::vector<base::string16> values; 139 profile_->GetMultiInfo( 140 AutofillType((*inputs)[j].type), app_locale, &values); 141 (*inputs)[j].initial_value = values[variant()]; 142 } 143} 144 145void AutofillProfileWrapper::FillFormField(AutofillField* field) const { 146 if (field->Type().GetStorableType() == CREDIT_CARD_NAME) { 147 // Cache the field's true type. 148 HtmlFieldType original_type = field->html_type(); 149 150 // Requests for the user's credit card are filled from the billing address, 151 // but the AutofillProfile class doesn't know how to fill credit card 152 // fields. So, temporarily set the type to the corresponding profile type. 153 field->SetHtmlType(HTML_TYPE_NAME, field->html_mode()); 154 AutofillDataModelWrapper::FillFormField(field); 155 156 // Restore the field's true type. 157 field->SetHtmlType(original_type, field->html_mode()); 158 } else { 159 AutofillDataModelWrapper::FillFormField(field); 160 } 161} 162 163AutofillShippingAddressWrapper::AutofillShippingAddressWrapper( 164 const AutofillProfile* profile, size_t variant) 165 : AutofillProfileWrapper(profile, variant) {} 166 167AutofillShippingAddressWrapper::~AutofillShippingAddressWrapper() {} 168 169base::string16 AutofillShippingAddressWrapper::GetInfo( 170 const AutofillType& type) const { 171 // Shipping addresses don't have email addresses associated with them. 172 if (type.GetStorableType() == EMAIL_ADDRESS) 173 return base::string16(); 174 175 return AutofillProfileWrapper::GetInfo(type); 176} 177 178// AutofillCreditCardWrapper 179 180AutofillCreditCardWrapper::AutofillCreditCardWrapper(const CreditCard* card) 181 : AutofillDataModelWrapper(card, 0), 182 card_(card) {} 183 184AutofillCreditCardWrapper::~AutofillCreditCardWrapper() {} 185 186base::string16 AutofillCreditCardWrapper::GetInfo(const AutofillType& type) 187 const { 188 if (type.group() != CREDIT_CARD) 189 return base::string16(); 190 191 if (type.GetStorableType() == CREDIT_CARD_EXP_MONTH) 192 return MonthComboboxModel::FormatMonth(card_->expiration_month()); 193 194 return AutofillDataModelWrapper::GetInfo(type); 195} 196 197gfx::Image AutofillCreditCardWrapper::GetIcon() { 198 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 199 return rb.GetImageNamed(CreditCard::IconResourceId(card_->type())); 200} 201 202bool AutofillCreditCardWrapper::GetDisplayText( 203 base::string16* vertically_compact, 204 base::string16* horizontally_compact) { 205 if (!card_->IsValid()) 206 return false; 207 208 *vertically_compact = *horizontally_compact = card_->TypeAndLastFourDigits(); 209 return true; 210} 211 212// WalletAddressWrapper 213 214WalletAddressWrapper::WalletAddressWrapper( 215 const wallet::Address* address) : address_(address) {} 216 217WalletAddressWrapper::~WalletAddressWrapper() {} 218 219base::string16 WalletAddressWrapper::GetInfo(const AutofillType& type) const { 220 // Reachable from DataModelWrapper::GetDisplayText(). 221 if (type.GetStorableType() == EMAIL_ADDRESS) 222 return base::string16(); 223 224 return address_->GetInfo(type, g_browser_process->GetApplicationLocale()); 225} 226 227bool WalletAddressWrapper::GetDisplayText( 228 base::string16* vertically_compact, 229 base::string16* horizontally_compact) { 230 if (!address_->is_complete_address() || 231 GetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER)).empty()) { 232 return false; 233 } 234 235 return DataModelWrapper::GetDisplayText(vertically_compact, 236 horizontally_compact); 237} 238 239// WalletInstrumentWrapper 240 241WalletInstrumentWrapper::WalletInstrumentWrapper( 242 const wallet::WalletItems::MaskedInstrument* instrument) 243 : instrument_(instrument) {} 244 245WalletInstrumentWrapper::~WalletInstrumentWrapper() {} 246 247base::string16 WalletInstrumentWrapper::GetInfo(const AutofillType& type) 248 const { 249 // Reachable from DataModelWrapper::GetDisplayText(). 250 if (type.GetStorableType() == EMAIL_ADDRESS) 251 return base::string16(); 252 253 if (type.GetStorableType() == CREDIT_CARD_EXP_MONTH) 254 return MonthComboboxModel::FormatMonth(instrument_->expiration_month()); 255 256 return instrument_->GetInfo(type, g_browser_process->GetApplicationLocale()); 257} 258 259gfx::Image WalletInstrumentWrapper::GetIcon() { 260 return instrument_->CardIcon(); 261} 262 263bool WalletInstrumentWrapper::GetDisplayText( 264 base::string16* vertically_compact, 265 base::string16* horizontally_compact) { 266 // TODO(dbeam): handle other instrument statuses? http://crbug.com/233048 267 if (instrument_->status() == wallet::WalletItems::MaskedInstrument::EXPIRED || 268 !instrument_->address().is_complete_address() || 269 GetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER)).empty()) { 270 return false; 271 } 272 273 DataModelWrapper::GetDisplayText(vertically_compact, horizontally_compact); 274 // TODO(estade): descriptive_name() is user-provided. Should we use it or 275 // just type + last 4 digits? 276 base::string16 line1 = instrument_->descriptive_name() + ASCIIToUTF16("\n"); 277 *vertically_compact = line1 + *vertically_compact; 278 *horizontally_compact = line1 + *horizontally_compact; 279 return true; 280} 281 282// FullWalletBillingWrapper 283 284FullWalletBillingWrapper::FullWalletBillingWrapper( 285 wallet::FullWallet* full_wallet) 286 : full_wallet_(full_wallet) { 287 DCHECK(full_wallet_); 288} 289 290FullWalletBillingWrapper::~FullWalletBillingWrapper() {} 291 292base::string16 FullWalletBillingWrapper::GetInfo(const AutofillType& type) 293 const { 294 if (type.GetStorableType() == CREDIT_CARD_EXP_MONTH) 295 return MonthComboboxModel::FormatMonth(full_wallet_->expiration_month()); 296 297 if (type.group() == CREDIT_CARD) 298 return full_wallet_->GetInfo(type); 299 300 return full_wallet_->billing_address()->GetInfo( 301 type, g_browser_process->GetApplicationLocale()); 302} 303 304bool FullWalletBillingWrapper::GetDisplayText( 305 base::string16* vertically_compact, 306 base::string16* horizontally_compact) { 307 // TODO(dbeam): handle other required actions? http://crbug.com/163508 308 if (full_wallet_->HasRequiredAction(wallet::UPDATE_EXPIRATION_DATE)) 309 return false; 310 311 return DataModelWrapper::GetDisplayText(vertically_compact, 312 horizontally_compact); 313} 314 315// FullWalletShippingWrapper 316 317FullWalletShippingWrapper::FullWalletShippingWrapper( 318 wallet::FullWallet* full_wallet) 319 : full_wallet_(full_wallet) { 320 DCHECK(full_wallet_); 321} 322 323FullWalletShippingWrapper::~FullWalletShippingWrapper() {} 324 325base::string16 FullWalletShippingWrapper::GetInfo( 326 const AutofillType& type) const { 327 return full_wallet_->shipping_address()->GetInfo( 328 type, g_browser_process->GetApplicationLocale()); 329} 330 331DetailOutputWrapper::DetailOutputWrapper(const DetailOutputMap& outputs) 332 : outputs_(outputs) {} 333 334DetailOutputWrapper::~DetailOutputWrapper() {} 335 336base::string16 DetailOutputWrapper::GetInfo(const AutofillType& type) const { 337 ServerFieldType storable_type = type.GetStorableType(); 338 for (DetailOutputMap::const_iterator it = outputs_.begin(); 339 it != outputs_.end(); ++it) { 340 if (storable_type == AutofillType(it->first->type).GetStorableType()) 341 return it->second; 342 } 343 return base::string16(); 344} 345 346} // namespace autofill 347