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