data_model_wrapper.cc revision 424c4d7b64af9d0d8fd9624f381f469654d5e3d2
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  // TODO(estade): email?
88  address += newline + GetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER));
89
90  return address;
91}
92
93// EmptyDataModelWrapper
94
95EmptyDataModelWrapper::EmptyDataModelWrapper() {}
96EmptyDataModelWrapper::~EmptyDataModelWrapper() {}
97
98base::string16 EmptyDataModelWrapper::GetInfo(const AutofillType& type) const {
99  return base::string16();
100}
101
102void EmptyDataModelWrapper::FillFormField(AutofillField* field) const {}
103
104// AutofillDataModelWrapper
105
106AutofillDataModelWrapper::AutofillDataModelWrapper(
107    const AutofillDataModel* data_model,
108    size_t variant)
109    : data_model_(data_model),
110      variant_(variant) {}
111
112AutofillDataModelWrapper::~AutofillDataModelWrapper() {}
113
114base::string16 AutofillDataModelWrapper::GetInfo(const AutofillType& type)
115    const {
116  return data_model_->GetInfo(type, g_browser_process->GetApplicationLocale());
117}
118
119void AutofillDataModelWrapper::FillFormField(AutofillField* field) const {
120  data_model_->FillFormField(
121      *field, variant_, g_browser_process->GetApplicationLocale(), field);
122}
123
124// AutofillProfileWrapper
125
126AutofillProfileWrapper::AutofillProfileWrapper(
127    const AutofillProfile* profile, size_t variant)
128    : AutofillDataModelWrapper(profile, variant),
129      profile_(profile) {}
130
131AutofillProfileWrapper::~AutofillProfileWrapper() {}
132
133void 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
143void 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
163AutofillCreditCardWrapper::AutofillCreditCardWrapper(const CreditCard* card)
164    : AutofillDataModelWrapper(card, 0),
165      card_(card) {}
166
167AutofillCreditCardWrapper::~AutofillCreditCardWrapper() {}
168
169base::string16 AutofillCreditCardWrapper::GetInfo(const AutofillType& type)
170    const {
171  if (type.group() != CREDIT_CARD)
172    return base::string16();
173
174  if (type.GetStorableType() == CREDIT_CARD_EXP_MONTH)
175    return MonthComboboxModel::FormatMonth(card_->expiration_month());
176
177  return AutofillDataModelWrapper::GetInfo(type);
178}
179
180gfx::Image AutofillCreditCardWrapper::GetIcon() {
181  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
182  return rb.GetImageNamed(CreditCard::IconResourceId(card_->type()));
183}
184
185bool AutofillCreditCardWrapper::GetDisplayText(
186    base::string16* vertically_compact,
187    base::string16* horizontally_compact) {
188  if (!card_->IsValid())
189    return false;
190
191  *vertically_compact = *horizontally_compact = card_->TypeAndLastFourDigits();
192  return true;
193}
194
195// WalletAddressWrapper
196
197WalletAddressWrapper::WalletAddressWrapper(
198    const wallet::Address* address) : address_(address) {}
199
200WalletAddressWrapper::~WalletAddressWrapper() {}
201
202base::string16 WalletAddressWrapper::GetInfo(const AutofillType& type) const {
203  return address_->GetInfo(type, g_browser_process->GetApplicationLocale());
204}
205
206bool WalletAddressWrapper::GetDisplayText(
207    base::string16* vertically_compact,
208    base::string16* horizontally_compact) {
209  if (!address_->is_complete_address() ||
210      GetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER)).empty()) {
211    return false;
212  }
213
214  return DataModelWrapper::GetDisplayText(vertically_compact,
215                                          horizontally_compact);
216}
217
218// WalletInstrumentWrapper
219
220WalletInstrumentWrapper::WalletInstrumentWrapper(
221    const wallet::WalletItems::MaskedInstrument* instrument)
222    : instrument_(instrument) {}
223
224WalletInstrumentWrapper::~WalletInstrumentWrapper() {}
225
226base::string16 WalletInstrumentWrapper::GetInfo(const AutofillType& type)
227    const {
228  if (type.GetStorableType() == CREDIT_CARD_EXP_MONTH)
229    return MonthComboboxModel::FormatMonth(instrument_->expiration_month());
230
231  return instrument_->GetInfo(type, g_browser_process->GetApplicationLocale());
232}
233
234gfx::Image WalletInstrumentWrapper::GetIcon() {
235  return instrument_->CardIcon();
236}
237
238bool WalletInstrumentWrapper::GetDisplayText(
239    base::string16* vertically_compact,
240    base::string16* horizontally_compact) {
241  // TODO(dbeam): handle other instrument statuses? http://crbug.com/233048
242  if (instrument_->status() == wallet::WalletItems::MaskedInstrument::EXPIRED ||
243      !instrument_->address().is_complete_address() ||
244      GetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER)).empty()) {
245    return false;
246  }
247
248  DataModelWrapper::GetDisplayText(vertically_compact, horizontally_compact);
249  // TODO(estade): descriptive_name() is user-provided. Should we use it or
250  // just type + last 4 digits?
251  base::string16 line1 = instrument_->descriptive_name() + ASCIIToUTF16("\n");
252  *vertically_compact = line1 + *vertically_compact;
253  *horizontally_compact = line1 + *horizontally_compact;
254  return true;
255}
256
257// FullWalletBillingWrapper
258
259FullWalletBillingWrapper::FullWalletBillingWrapper(
260    wallet::FullWallet* full_wallet)
261    : full_wallet_(full_wallet) {
262  DCHECK(full_wallet_);
263}
264
265FullWalletBillingWrapper::~FullWalletBillingWrapper() {}
266
267base::string16 FullWalletBillingWrapper::GetInfo(const AutofillType& type)
268    const {
269  if (type.GetStorableType() == CREDIT_CARD_EXP_MONTH)
270    return MonthComboboxModel::FormatMonth(full_wallet_->expiration_month());
271
272  if (type.group() == CREDIT_CARD)
273    return full_wallet_->GetInfo(type);
274
275  return full_wallet_->billing_address()->GetInfo(
276      type, g_browser_process->GetApplicationLocale());
277}
278
279bool FullWalletBillingWrapper::GetDisplayText(
280    base::string16* vertically_compact,
281    base::string16* horizontally_compact) {
282  // TODO(dbeam): handle other required actions? http://crbug.com/163508
283  if (full_wallet_->HasRequiredAction(wallet::UPDATE_EXPIRATION_DATE))
284    return false;
285
286  return DataModelWrapper::GetDisplayText(vertically_compact,
287                                          horizontally_compact);
288}
289
290// FullWalletShippingWrapper
291
292FullWalletShippingWrapper::FullWalletShippingWrapper(
293    wallet::FullWallet* full_wallet)
294    : full_wallet_(full_wallet) {
295  DCHECK(full_wallet_);
296}
297
298FullWalletShippingWrapper::~FullWalletShippingWrapper() {}
299
300base::string16 FullWalletShippingWrapper::GetInfo(
301    const AutofillType& type) const {
302  return full_wallet_->shipping_address()->GetInfo(
303      type, g_browser_process->GetApplicationLocale());
304}
305
306DetailOutputWrapper::DetailOutputWrapper(const DetailOutputMap& outputs)
307    : outputs_(outputs) {}
308
309DetailOutputWrapper::~DetailOutputWrapper() {}
310
311base::string16 DetailOutputWrapper::GetInfo(const AutofillType& type) const {
312  ServerFieldType storable_type = type.GetStorableType();
313  for (DetailOutputMap::const_iterator it = outputs_.begin();
314       it != outputs_.end(); ++it) {
315    if (storable_type == AutofillType(it->first->type).GetStorableType())
316      return it->second;
317  }
318  return base::string16();
319}
320
321}  // namespace autofill
322