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