data_model_wrapper.cc revision f2477e01787aa58f445919b809d89e252beef54f
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/string_util.h"
9#include "base/strings/utf_string_conversions.h"
10#include "chrome/browser/browser_process.h"
11#include "chrome/browser/ui/autofill/autofill_dialog_common.h"
12#include "chrome/browser/ui/autofill/autofill_dialog_models.h"
13#include "components/autofill/content/browser/wallet/full_wallet.h"
14#include "components/autofill/content/browser/wallet/wallet_address.h"
15#include "components/autofill/content/browser/wallet/wallet_items.h"
16#include "components/autofill/core/browser/autofill_data_model.h"
17#include "components/autofill/core/browser/autofill_field.h"
18#include "components/autofill/core/browser/autofill_profile.h"
19#include "components/autofill/core/browser/autofill_type.h"
20#include "components/autofill/core/browser/credit_card.h"
21#include "components/autofill/core/browser/form_structure.h"
22#include "ui/base/resource/resource_bundle.h"
23#include "ui/gfx/image/image.h"
24
25namespace autofill {
26
27DataModelWrapper::~DataModelWrapper() {}
28
29void DataModelWrapper::FillInputs(DetailInputs* inputs) {
30  for (size_t i = 0; i < inputs->size(); ++i) {
31    DetailInput* input = &(*inputs)[i];
32    input->initial_value = common::GetHardcodedValueForType(input->type);
33    if (input->initial_value.empty())
34      input->initial_value = GetInfo(AutofillType(input->type));
35  }
36}
37
38base::string16 DataModelWrapper::GetInfoForDisplay(const AutofillType& type)
39    const {
40  return GetInfo(type);
41}
42
43gfx::Image DataModelWrapper::GetIcon() {
44  return gfx::Image();
45}
46
47bool DataModelWrapper::GetDisplayText(
48    base::string16* vertically_compact,
49    base::string16* horizontally_compact) {
50  base::string16 comma = ASCIIToUTF16(", ");
51  base::string16 newline = ASCIIToUTF16("\n");
52
53  *vertically_compact = GetAddressDisplayText(comma);
54  *horizontally_compact = GetAddressDisplayText(newline);
55  return true;
56}
57
58bool DataModelWrapper::FillFormStructure(
59    const DetailInputs& inputs,
60    const InputFieldComparator& compare,
61    FormStructure* form_structure) const {
62  bool filled_something = false;
63  for (size_t i = 0; i < form_structure->field_count(); ++i) {
64    AutofillField* field = form_structure->field(i);
65    for (size_t j = 0; j < inputs.size(); ++j) {
66      if (compare.Run(inputs[j], *field)) {
67        AutofillField::FillFormField(*field, GetInfo(field->Type()),
68                                     g_browser_process->GetApplicationLocale(),
69                                     field);
70        filled_something = true;
71        break;
72      }
73    }
74  }
75  return filled_something;
76}
77
78DataModelWrapper::DataModelWrapper() {}
79
80base::string16 DataModelWrapper::GetAddressDisplayText(
81    const base::string16& separator) {
82  base::string16 address = GetInfoForDisplay(AutofillType(NAME_FULL)) +
83      separator + GetInfoForDisplay(AutofillType(ADDRESS_HOME_LINE1));
84  base::string16 address2 = GetInfoForDisplay(AutofillType(ADDRESS_HOME_LINE2));
85  if (!address2.empty())
86    address += separator + address2;
87
88  base::string16 comma = ASCIIToUTF16(", ");
89  base::string16 newline = ASCIIToUTF16("\n");
90  address += separator +
91      GetInfoForDisplay(AutofillType(ADDRESS_HOME_CITY)) + comma +
92      GetInfoForDisplay(AutofillType(ADDRESS_HOME_STATE)) + ASCIIToUTF16(" ") +
93      GetInfoForDisplay(AutofillType(ADDRESS_HOME_ZIP));
94
95  base::string16 email = GetInfoForDisplay(AutofillType(EMAIL_ADDRESS));
96  if (!email.empty())
97    address += newline + email;
98  address += newline + GetInfoForDisplay(AutofillType(PHONE_HOME_WHOLE_NUMBER));
99
100  return address;
101}
102
103// EmptyDataModelWrapper
104
105EmptyDataModelWrapper::EmptyDataModelWrapper() {}
106EmptyDataModelWrapper::~EmptyDataModelWrapper() {}
107
108base::string16 EmptyDataModelWrapper::GetInfo(const AutofillType& type) const {
109  return base::string16();
110}
111
112// AutofillProfileWrapper
113
114AutofillProfileWrapper::AutofillProfileWrapper(const AutofillProfile* profile)
115    : profile_(profile),
116      variant_group_(NO_GROUP),
117      variant_(0) {}
118
119AutofillProfileWrapper::AutofillProfileWrapper(
120    const AutofillProfile* profile,
121    const AutofillType& type,
122    size_t variant)
123    : profile_(profile),
124      variant_group_(type.group()),
125      variant_(variant) {}
126
127AutofillProfileWrapper::~AutofillProfileWrapper() {}
128
129base::string16 AutofillProfileWrapper::GetInfo(const AutofillType& type) const {
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, request for the corresponding profile type instead.
133  AutofillType effective_type = type;
134  if (type.GetStorableType() == CREDIT_CARD_NAME)
135    effective_type = AutofillType(NAME_BILLING_FULL);
136
137  size_t variant = GetVariantForType(effective_type);
138  const std::string& app_locale = g_browser_process->GetApplicationLocale();
139  return profile_->GetInfoForVariant(effective_type, variant, app_locale);
140}
141
142base::string16 AutofillProfileWrapper::GetInfoForDisplay(
143    const AutofillType& type) const {
144  // We display the "raw" phone number which contains user-defined formatting.
145  if (type.GetStorableType() == PHONE_HOME_WHOLE_NUMBER) {
146    std::vector<base::string16> values;
147    profile_->GetRawMultiInfo(type.GetStorableType(), &values);
148    const base::string16& phone_number = values[GetVariantForType(type)];
149
150    // If there is no user-defined formatting at all, add some standard
151    // formatting.
152    if (ContainsOnlyChars(phone_number, ASCIIToUTF16("0123456789"))) {
153      std::string region = UTF16ToASCII(
154          GetInfo(AutofillType(HTML_TYPE_COUNTRY_CODE, HTML_MODE_NONE)));
155      i18n::PhoneObject phone(phone_number, region);
156      return phone.GetFormattedNumber();
157    }
158
159    return phone_number;
160  }
161
162  return DataModelWrapper::GetInfoForDisplay(type);
163}
164
165size_t AutofillProfileWrapper::GetVariantForType(const AutofillType& type)
166    const {
167  if (type.group() == variant_group_)
168    return variant_;
169
170  return 0;
171}
172
173// AutofillShippingAddressWrapper
174
175AutofillShippingAddressWrapper::AutofillShippingAddressWrapper(
176    const AutofillProfile* profile)
177    : AutofillProfileWrapper(profile) {}
178
179AutofillShippingAddressWrapper::~AutofillShippingAddressWrapper() {}
180
181base::string16 AutofillShippingAddressWrapper::GetInfo(
182    const AutofillType& type) const {
183  // Shipping addresses don't have email addresses associated with them.
184  if (type.GetStorableType() == EMAIL_ADDRESS)
185    return base::string16();
186
187  return AutofillProfileWrapper::GetInfo(type);
188}
189
190// AutofillCreditCardWrapper
191
192AutofillCreditCardWrapper::AutofillCreditCardWrapper(const CreditCard* card)
193    : card_(card) {}
194
195AutofillCreditCardWrapper::~AutofillCreditCardWrapper() {}
196
197base::string16 AutofillCreditCardWrapper::GetInfo(const AutofillType& type)
198    const {
199  if (type.group() != CREDIT_CARD)
200    return base::string16();
201
202  if (type.GetStorableType() == CREDIT_CARD_EXP_MONTH)
203    return MonthComboboxModel::FormatMonth(card_->expiration_month());
204
205  return card_->GetInfo(type, g_browser_process->GetApplicationLocale());
206}
207
208gfx::Image AutofillCreditCardWrapper::GetIcon() {
209  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
210  return rb.GetImageNamed(CreditCard::IconResourceId(card_->type()));
211}
212
213bool AutofillCreditCardWrapper::GetDisplayText(
214    base::string16* vertically_compact,
215    base::string16* horizontally_compact) {
216  if (!card_->IsValid())
217    return false;
218
219  *vertically_compact = *horizontally_compact = card_->TypeAndLastFourDigits();
220  return true;
221}
222
223// WalletAddressWrapper
224
225WalletAddressWrapper::WalletAddressWrapper(
226    const wallet::Address* address) : address_(address) {}
227
228WalletAddressWrapper::~WalletAddressWrapper() {}
229
230base::string16 WalletAddressWrapper::GetInfo(const AutofillType& type) const {
231  // Reachable from DataModelWrapper::GetDisplayText().
232  if (type.GetStorableType() == EMAIL_ADDRESS)
233    return base::string16();
234
235  return address_->GetInfo(type, g_browser_process->GetApplicationLocale());
236}
237
238base::string16 WalletAddressWrapper::GetInfoForDisplay(const AutofillType& type)
239    const {
240  if (type.GetStorableType() == PHONE_HOME_WHOLE_NUMBER)
241    return address_->DisplayPhoneNumber();
242
243  return DataModelWrapper::GetInfoForDisplay(type);
244}
245
246bool WalletAddressWrapper::GetDisplayText(
247    base::string16* vertically_compact,
248    base::string16* horizontally_compact) {
249  if (!address_->is_complete_address() ||
250      GetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER)).empty()) {
251    return false;
252  }
253
254  return DataModelWrapper::GetDisplayText(vertically_compact,
255                                          horizontally_compact);
256}
257
258// WalletInstrumentWrapper
259
260WalletInstrumentWrapper::WalletInstrumentWrapper(
261    const wallet::WalletItems::MaskedInstrument* instrument)
262    : instrument_(instrument) {}
263
264WalletInstrumentWrapper::~WalletInstrumentWrapper() {}
265
266base::string16 WalletInstrumentWrapper::GetInfo(const AutofillType& type)
267    const {
268  // Reachable from DataModelWrapper::GetDisplayText().
269  if (type.GetStorableType() == EMAIL_ADDRESS)
270    return base::string16();
271
272  if (type.GetStorableType() == CREDIT_CARD_EXP_MONTH)
273    return MonthComboboxModel::FormatMonth(instrument_->expiration_month());
274
275  return instrument_->GetInfo(type, g_browser_process->GetApplicationLocale());
276}
277
278base::string16 WalletInstrumentWrapper::GetInfoForDisplay(
279    const AutofillType& type) const {
280  if (type.GetStorableType() == PHONE_HOME_WHOLE_NUMBER)
281    return instrument_->address().DisplayPhoneNumber();
282
283  return DataModelWrapper::GetInfoForDisplay(type);
284}
285
286gfx::Image WalletInstrumentWrapper::GetIcon() {
287  return instrument_->CardIcon();
288}
289
290bool WalletInstrumentWrapper::GetDisplayText(
291    base::string16* vertically_compact,
292    base::string16* horizontally_compact) {
293  // TODO(dbeam): handle other instrument statuses? http://crbug.com/233048
294  if (instrument_->status() == wallet::WalletItems::MaskedInstrument::EXPIRED ||
295      !instrument_->address().is_complete_address() ||
296      GetInfo(AutofillType(PHONE_HOME_WHOLE_NUMBER)).empty()) {
297    return false;
298  }
299
300  DataModelWrapper::GetDisplayText(vertically_compact, horizontally_compact);
301  // TODO(estade): descriptive_name() is user-provided. Should we use it or
302  // just type + last 4 digits?
303  base::string16 line1 = instrument_->descriptive_name() + ASCIIToUTF16("\n");
304  *vertically_compact = line1 + *vertically_compact;
305  *horizontally_compact = line1 + *horizontally_compact;
306  return true;
307}
308
309// FullWalletBillingWrapper
310
311FullWalletBillingWrapper::FullWalletBillingWrapper(
312    wallet::FullWallet* full_wallet)
313    : full_wallet_(full_wallet) {
314  DCHECK(full_wallet_);
315}
316
317FullWalletBillingWrapper::~FullWalletBillingWrapper() {}
318
319base::string16 FullWalletBillingWrapper::GetInfo(const AutofillType& type)
320    const {
321  if (type.GetStorableType() == CREDIT_CARD_EXP_MONTH)
322    return MonthComboboxModel::FormatMonth(full_wallet_->expiration_month());
323
324  if (type.group() == CREDIT_CARD)
325    return full_wallet_->GetInfo(type);
326
327  return full_wallet_->billing_address()->GetInfo(
328      type, g_browser_process->GetApplicationLocale());
329}
330
331bool FullWalletBillingWrapper::GetDisplayText(
332    base::string16* vertically_compact,
333    base::string16* horizontally_compact) {
334  // TODO(dbeam): handle other required actions? http://crbug.com/163508
335  if (full_wallet_->HasRequiredAction(wallet::UPDATE_EXPIRATION_DATE))
336    return false;
337
338  return DataModelWrapper::GetDisplayText(vertically_compact,
339                                          horizontally_compact);
340}
341
342// FullWalletShippingWrapper
343
344FullWalletShippingWrapper::FullWalletShippingWrapper(
345    wallet::FullWallet* full_wallet)
346    : full_wallet_(full_wallet) {
347  DCHECK(full_wallet_);
348}
349
350FullWalletShippingWrapper::~FullWalletShippingWrapper() {}
351
352base::string16 FullWalletShippingWrapper::GetInfo(
353    const AutofillType& type) const {
354  return full_wallet_->shipping_address()->GetInfo(
355      type, g_browser_process->GetApplicationLocale());
356}
357
358FieldMapWrapper::FieldMapWrapper(const FieldValueMap& field_map)
359    : field_map_(field_map) {}
360
361FieldMapWrapper::~FieldMapWrapper() {}
362
363base::string16 FieldMapWrapper::GetInfo(const AutofillType& type) const {
364  FieldValueMap::const_iterator it = field_map_.find(type.server_type());
365  return it != field_map_.end() ? it->second : base::string16();
366}
367
368}  // namespace autofill
369