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