1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "components/autofill/core/browser/credit_card.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stddef.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include <algorithm>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <ostream>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/guid.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h"
19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "components/autofill/core/browser/autofill_field.h"
23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "components/autofill/core/browser/autofill_regexes.h"
24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "components/autofill/core/browser/autofill_type.h"
25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "components/autofill/core/browser/validation.h"
267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "components/autofill/core/common/form_field_data.h"
277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "grit/component_strings.h"
28ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "third_party/icu/source/common/unicode/uloc.h"
29ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "third_party/icu/source/i18n/unicode/dtfmtsym.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)// TODO(blundell): Eliminate the need for this conditional include.
33d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)// crbug.com/328150
34d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)#if !defined(OS_IOS)
35d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)#include "grit/webkit_resources.h"
36d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)#endif
37d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace autofill {
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char16 kCreditCardObfuscationSymbol = '*';
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This is the maximum obfuscated symbols displayed.
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// It is introduced to avoid rare cases where the credit card number is
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// too large and fills the screen.
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const size_t kMaxObfuscationSize = 20;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ConvertYear(const base::string16& year, int* num) {
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the |year| is empty, clear the stored value.
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (year.empty()) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *num = 0;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Try parsing the |year| as a number.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (base::StringToInt(year, num))
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *num = 0;
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool ConvertMonth(const base::string16& month,
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  const std::string& app_locale,
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  int* num) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the |month| is empty, clear the stored value.
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (month.empty()) {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *num = 0;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Try parsing the |month| as a number.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (base::StringToInt(month, num))
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If the locale is unknown, give up.
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (app_locale.empty())
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return false;
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Otherwise, try parsing the |month| as a named month, e.g. "January" or
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // "Jan".
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::string16 lowercased_month = StringToLowerASCII(month);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UErrorCode status = U_ZERO_ERROR;
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  icu::Locale locale(app_locale.c_str());
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  icu::DateFormatSymbols date_format_symbols(locale, status);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(status == U_ZERO_ERROR || status == U_USING_FALLBACK_WARNING ||
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         status == U_USING_DEFAULT_WARNING);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32_t num_months;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const icu::UnicodeString* months = date_format_symbols.getMonths(num_months);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int32_t i = 0; i < num_months; ++i) {
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::string16 icu_month = base::string16(months[i].getBuffer(),
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        months[i].length());
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (lowercased_month == StringToLowerASCII(icu_month)) {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *num = i + 1;  // Adjust from 0-indexed to 1-indexed.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  months = date_format_symbols.getShortMonths(num_months);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int32_t i = 0; i < num_months; ++i) {
104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const base::string16 icu_month = base::string16(months[i].getBuffer(),
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        months[i].length());
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (lowercased_month == StringToLowerASCII(icu_month)) {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *num = i + 1;  // Adjust from 0-indexed to 1-indexed.
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *num = 0;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)CreditCard::CreditCard(const std::string& guid, const std::string& origin)
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : AutofillDataModel(guid, origin),
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      type_(kGenericCard),
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expiration_month_(0),
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      expiration_year_(0) {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CreditCard::CreditCard()
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : AutofillDataModel(base::GenerateGUID(), std::string()),
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      type_(kGenericCard),
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expiration_month_(0),
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      expiration_year_(0) {
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)CreditCard::CreditCard(const CreditCard& credit_card)
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : AutofillDataModel(std::string(), std::string()) {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  operator=(credit_card);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CreditCard::~CreditCard() {}
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 CreditCard::StripSeparators(const base::string16& number) {
141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const base::char16 kSeparators[] = {'-', ' ', '\0'};
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::string16 stripped;
143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::RemoveChars(number, kSeparators, &stripped);
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return stripped;
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
148c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)base::string16 CreditCard::TypeForDisplay(const std::string& type) {
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (type == kAmericanExpressCard)
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_AMEX);
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (type == kDinersCard)
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_DINERS);
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (type == kDiscoverCard)
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_DISCOVER);
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (type == kJCBCard)
156c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_JCB);
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (type == kMasterCard)
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_MASTERCARD);
1597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (type == kUnionPay)
1607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_UNION_PAY);
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (type == kVisaCard)
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_VISA);
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // If you hit this DCHECK, the above list of cases needs to be updated to
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // include a new card.
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK_EQ(kGenericCard, type);
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return base::string16();
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
170a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)// static
1717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)int CreditCard::IconResourceId(const std::string& type) {
172d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  // TODO(blundell): Either move these resources out of webkit_resources or
173d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  // this function into //components/autofill/content/browser to eliminate the
174d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  // need for this ifdef-ing. crbug.com/328150
175d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)#if defined(OS_IOS)
176d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  return 0;
177d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)#else
1787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (type == kAmericanExpressCard)
1797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return IDR_AUTOFILL_CC_AMEX;
1807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (type == kDinersCard)
1817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return IDR_AUTOFILL_CC_DINERS;
1827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (type == kDiscoverCard)
1837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return IDR_AUTOFILL_CC_DISCOVER;
1847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (type == kJCBCard)
1857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return IDR_AUTOFILL_CC_JCB;
1867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (type == kMasterCard)
1877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return IDR_AUTOFILL_CC_MASTERCARD;
1887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (type == kUnionPay)
1897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return IDR_AUTOFILL_CC_GENERIC;  // Needs resource: http://crbug.com/259211
1907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (type == kVisaCard)
1917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return IDR_AUTOFILL_CC_VISA;
1927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // If you hit this DCHECK, the above list of cases needs to be updated to
1947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // include a new card.
1957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK_EQ(kGenericCard, type);
1967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return IDR_AUTOFILL_CC_GENERIC;
197d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)#endif  // defined(OS_IOS)
1987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
2007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// static
201a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)std::string CreditCard::GetCreditCardType(const base::string16& number) {
202a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Credit card number specifications taken from:
203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // http://en.wikipedia.org/wiki/Credit_card_numbers,
2047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // http://en.wikipedia.org/wiki/List_of_Issuer_Identification_Numbers,
205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // http://www.discovernetwork.com/merchants/images/Merchant_Marketing_PDF.pdf,
2067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // http://www.regular-expressions.info/creditcard.html,
2077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // http://developer.ean.com/general_info/Valid_Credit_Card_Types,
2087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // http://www.bincodes.com/,
2097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // http://www.fraudpractice.com/FL-binCC.html, and
210a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // http://www.beachnet.com/~hstiles/cardtype.html
211eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //
212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // The last site is currently unavailable, but a cached version remains at
213eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // http://web.archive.org/web/20120923111349/http://www.beachnet.com/~hstiles/cardtype.html
214eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //
215a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Card Type              Prefix(es)                      Length
216a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // ---------------------------------------------------------------
217a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // Visa                   4                               13,16
218a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // American Express       34,37                           15
219eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Diners Club            300-305,3095,36,38-39           14
220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Discover Card          6011,644-649,65                 16
221eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // JCB                    3528-3589                       16
222a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  // MasterCard             51-55                           16
2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // UnionPay               62                              16-19
224a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Check for prefixes of length 1.
226eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (number.empty())
227a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return kGenericCard;
228a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
229eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (number[0] == '4')
230eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return kVisaCard;
231eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
232eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Check for prefixes of length 2.
233eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (number.size() < 2)
234a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    return kGenericCard;
235a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
236eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int first_two_digits = 0;
237eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!base::StringToInt(number.substr(0, 2), &first_two_digits))
238eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return kGenericCard;
239a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
240eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (first_two_digits == 34 || first_two_digits == 37)
241eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return kAmericanExpressCard;
242a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
243eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (first_two_digits == 36 ||
244eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      first_two_digits == 38 ||
245eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      first_two_digits == 39)
246eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return kDinersCard;
247a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
248eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (first_two_digits >= 51 && first_two_digits <= 55)
249eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return kMasterCard;
250a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
2517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (first_two_digits == 62)
2527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return kUnionPay;
2537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
254eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (first_two_digits == 65)
255eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return kDiscoverCard;
256a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
257eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Check for prefixes of length 3.
258eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (number.size() < 3)
259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return kGenericCard;
260a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
261eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int first_three_digits = 0;
262eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!base::StringToInt(number.substr(0, 3), &first_three_digits))
263eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return kGenericCard;
264a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
265eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (first_three_digits >= 300 && first_three_digits <= 305)
266eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return kDinersCard;
267a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
268eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (first_three_digits >= 644 && first_three_digits <= 649)
269eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return kDiscoverCard;
270a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
271eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Check for prefixes of length 4.
272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (number.size() < 4)
273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return kGenericCard;
274a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  int first_four_digits = 0;
276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!base::StringToInt(number.substr(0, 4), &first_four_digits))
277eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return kGenericCard;
278a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (first_four_digits == 3095)
280eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return kDinersCard;
281a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
282eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (first_four_digits >= 3528 && first_four_digits <= 3589)
283eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return kJCBCard;
284a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
285eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (first_four_digits == 6011)
286eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return kDiscoverCard;
287a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
288a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  return kGenericCard;
289a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)}
290a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)
2913240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochbase::string16 CreditCard::GetRawInfo(ServerFieldType type) const {
292424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK_EQ(CREDIT_CARD, AutofillType(type).group());
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (type) {
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case CREDIT_CARD_NAME:
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return name_on_card_;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case CREDIT_CARD_EXP_MONTH:
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return ExpirationMonthAsString();
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case CREDIT_CARD_EXP_2_DIGIT_YEAR:
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return Expiration2DigitYearAsString();
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case CREDIT_CARD_EXP_4_DIGIT_YEAR:
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return Expiration4DigitYearAsString();
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR: {
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::string16 month = ExpirationMonthAsString();
308c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::string16 year = Expiration2DigitYearAsString();
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!month.empty() && !year.empty())
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return month + ASCIIToUTF16("/") + year;
311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return base::string16();
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR: {
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::string16 month = ExpirationMonthAsString();
316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      base::string16 year = Expiration4DigitYearAsString();
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!month.empty() && !year.empty())
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return month + ASCIIToUTF16("/") + year;
319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return base::string16();
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case CREDIT_CARD_TYPE:
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return TypeForDisplay();
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case CREDIT_CARD_NUMBER:
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return number_;
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case CREDIT_CARD_VERIFICATION_CODE:
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Chrome doesn't store credit card verification codes.
330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return base::string16();
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // ComputeDataPresentForArray will hit this repeatedly.
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return base::string16();
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3383240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid CreditCard::SetRawInfo(ServerFieldType type,
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                            const base::string16& value) {
340424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK_EQ(CREDIT_CARD, AutofillType(type).group());
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (type) {
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case CREDIT_CARD_NAME:
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      name_on_card_ = value;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case CREDIT_CARD_EXP_MONTH:
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SetExpirationMonthFromString(value, std::string());
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case CREDIT_CARD_EXP_2_DIGIT_YEAR:
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // This is a read-only attribute.
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case CREDIT_CARD_EXP_4_DIGIT_YEAR:
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SetExpirationYearFromString(value);
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR:
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // This is a read-only attribute.
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR:
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // This is a read-only attribute.
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case CREDIT_CARD_TYPE:
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // This is a read-only attribute, determined by the credit card number.
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case CREDIT_CARD_NUMBER: {
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Don't change the real value if the input is an obfuscated string.
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (value.size() > 0 && value[0] != kCreditCardObfuscationSymbol)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SetNumber(value);
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case CREDIT_CARD_VERIFICATION_CODE:
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Chrome doesn't store the credit card verification code.
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED() << "Attempting to set unknown info-type " << type;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3873240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochbase::string16 CreditCard::GetInfo(const AutofillType& type,
388868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                   const std::string& app_locale) const {
389bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  ServerFieldType storable_type = type.GetStorableType();
390bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (storable_type == CREDIT_CARD_NUMBER)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return StripSeparators(number_);
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
393bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return GetRawInfo(storable_type);
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3963240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochbool CreditCard::SetInfo(const AutofillType& type,
397c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         const base::string16& value,
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         const std::string& app_locale) {
399bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  ServerFieldType storable_type = type.GetStorableType();
400bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  if (storable_type == CREDIT_CARD_NUMBER)
401bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    SetRawInfo(storable_type, StripSeparators(value));
402bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  else if (storable_type == CREDIT_CARD_EXP_MONTH)
4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SetExpirationMonthFromString(value, app_locale);
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
405bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch    SetRawInfo(storable_type, value);
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void CreditCard::GetMatchingTypes(const base::string16& text,
4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  const std::string& app_locale,
4123240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                                  ServerFieldTypeSet* matching_types) const {
4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FormGroup::GetMatchingTypes(text, app_locale, matching_types);
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  base::string16 card_number =
4163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      GetInfo(AutofillType(CREDIT_CARD_NUMBER), app_locale);
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!card_number.empty() && StripSeparators(text) == card_number)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    matching_types->insert(CREDIT_CARD_NUMBER);
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int month;
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (ConvertMonth(text, app_locale, &month) && month != 0 &&
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      month == expiration_month_) {
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    matching_types->insert(CREDIT_CARD_EXP_MONTH);
4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const base::string16 CreditCard::Label() const {
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::string16 label;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (number().empty())
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return name_on_card_;  // No CC number, return name only.
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
432c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::string16 obfuscated_cc_number = ObfuscatedNumber();
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!expiration_month_ || !expiration_year_)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return obfuscated_cc_number;  // No expiration date set.
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(georgey): Internationalize date.
437c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::string16 formatted_date(ExpirationMonthAsString());
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  formatted_date.append(ASCIIToUTF16("/"));
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  formatted_date.append(Expiration4DigitYearAsString());
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  label = l10n_util::GetStringFUTF16(IDS_CREDIT_CARD_NUMBER_PREVIEW_FORMAT,
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     obfuscated_cc_number,
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     formatted_date);
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return label;
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
447c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void CreditCard::SetInfoForMonthInputType(const base::string16& value) {
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check if |text| is "yyyy-mm" format first, and check normal month format.
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!autofill::MatchesPattern(value, UTF8ToUTF16("^[0-9]{4}-[0-9]{1,2}$")))
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
452c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  std::vector<base::string16> year_month;
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::SplitString(value, L'-', &year_month);
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ((int)year_month.size(), 2);
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num = 0;
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool converted = false;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converted = base::StringToInt(year_month[0], &num);
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(converted);
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetExpirationYear(num);
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converted = base::StringToInt(year_month[1], &num);
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(converted);
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetExpirationMonth(num);
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)base::string16 CreditCard::ObfuscatedNumber() const {
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the number is shorter than four digits, there's no need to obfuscate it.
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (number_.size() < 4)
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return number_;
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
470c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::string16 number = StripSeparators(number_);
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Avoid making very long obfuscated numbers.
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  size_t obfuscated_digits = std::min(kMaxObfuscationSize, number.size() - 4);
474c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::string16 result(obfuscated_digits, kCreditCardObfuscationSymbol);
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return result.append(LastFourDigits());
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)base::string16 CreditCard::LastFourDigits() const {
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const size_t kNumLastDigits = 4;
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::string16 number = StripSeparators(number_);
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (number.size() < kNumLastDigits)
483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return base::string16();
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return number.substr(number.size() - kNumLastDigits, kNumLastDigits);
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
488c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)base::string16 CreditCard::TypeForDisplay() const {
489c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return CreditCard::TypeForDisplay(type_);
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
492c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)base::string16 CreditCard::TypeAndLastFourDigits() const {
493c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::string16 type = TypeForDisplay();
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(estade): type may be empty, we probably want to return
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // "Card - 1234" or something in that case.
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
497c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::string16 digits = LastFourDigits();
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (digits.empty())
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return type;
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(estade): i18n.
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return type + ASCIIToUTF16(" - ") + digits;
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreditCard::operator=(const CreditCard& credit_card) {
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (this == &credit_card)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  number_ = credit_card.number_;
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  name_on_card_ = credit_card.name_on_card_;
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  type_ = credit_card.type_;
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expiration_month_ = credit_card.expiration_month_;
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expiration_year_ = credit_card.expiration_year_;
514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
515c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  set_guid(credit_card.guid());
516c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  set_origin(credit_card.origin());
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool CreditCard::UpdateFromImportedCard(const CreditCard& imported_card,
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        const std::string& app_locale) {
5213240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  if (this->GetInfo(AutofillType(CREDIT_CARD_NUMBER), app_locale) !=
5223240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch          imported_card.GetInfo(AutofillType(CREDIT_CARD_NUMBER), app_locale)) {
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Heuristically aggregated data should never overwrite verified data.
5277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Instead, discard any heuristically aggregated credit cards that disagree
5287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // with explicitly entered data, so that the UI is not cluttered with
5297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // duplicate cards.
5307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (this->IsVerified() && !imported_card.IsVerified())
531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return true;
532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  set_origin(imported_card.origin());
5347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that the card number is intentionally not updated, so as to preserve
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // any formatting (i.e. separator characters).  Since the card number is not
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // updated, there is no reason to update the card type, either.
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!imported_card.name_on_card_.empty())
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    name_on_card_ = imported_card.name_on_card_;
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The expiration date for |imported_card| should always be set.
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(imported_card.expiration_month_ && imported_card.expiration_year_);
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expiration_month_ = imported_card.expiration_month_;
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expiration_year_ = imported_card.expiration_year_;
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int CreditCard::Compare(const CreditCard& credit_card) const {
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The following CreditCard field types are the only types we store in the
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // WebDB so far, so we're only concerned with matching these types in the
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // credit card.
5533240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  const ServerFieldType types[] = { CREDIT_CARD_NAME,
5543240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                                    CREDIT_CARD_NUMBER,
5553240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                                    CREDIT_CARD_EXP_MONTH,
5563240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                                    CREDIT_CARD_EXP_4_DIGIT_YEAR };
5573240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  for (size_t i = 0; i < arraysize(types); ++i) {
5583240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    int comparison =
5593240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        GetRawInfo(types[i]).compare(credit_card.GetRawInfo(types[i]));
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (comparison != 0)
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return comparison;
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CreditCard::operator==(const CreditCard& credit_card) const {
568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return guid() == credit_card.guid() &&
569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         origin() == credit_card.origin() &&
570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)         Compare(credit_card) == 0;
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CreditCard::operator!=(const CreditCard& credit_card) const {
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return !operator==(credit_card);
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool CreditCard::IsEmpty(const std::string& app_locale) const {
5783240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  ServerFieldTypeSet types;
579c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  GetNonEmptyTypes(app_locale, &types);
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return types.empty();
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CreditCard::IsComplete() const {
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      autofill::IsValidCreditCardNumber(number_) &&
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expiration_month_ != 0 &&
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expiration_year_ != 0;
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
590eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool CreditCard::IsValid() const {
591eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return autofill::IsValidCreditCardNumber(number_) &&
592eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch         autofill::IsValidCreditCardExpirationDate(
593eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch             expiration_year_, expiration_month_, base::Time::Now());
594eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
595eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
5963240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdochvoid CreditCard::GetSupportedTypes(ServerFieldTypeSet* supported_types) const {
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  supported_types->insert(CREDIT_CARD_NAME);
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  supported_types->insert(CREDIT_CARD_NUMBER);
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  supported_types->insert(CREDIT_CARD_TYPE);
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  supported_types->insert(CREDIT_CARD_EXP_MONTH);
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  supported_types->insert(CREDIT_CARD_EXP_2_DIGIT_YEAR);
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  supported_types->insert(CREDIT_CARD_EXP_4_DIGIT_YEAR);
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  supported_types->insert(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR);
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  supported_types->insert(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR);
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
607c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)base::string16 CreditCard::ExpirationMonthAsString() const {
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (expiration_month_ == 0)
609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return base::string16();
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
611c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::string16 month = base::IntToString16(expiration_month_);
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (expiration_month_ >= 10)
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return month;
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::string16 zero = ASCIIToUTF16("0");
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zero.append(month);
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return zero;
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
620c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)base::string16 CreditCard::Expiration4DigitYearAsString() const {
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (expiration_year_ == 0)
622c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return base::string16();
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base::IntToString16(Expiration4DigitYear());
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)base::string16 CreditCard::Expiration2DigitYearAsString() const {
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (expiration_year_ == 0)
629c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return base::string16();
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base::IntToString16(Expiration2DigitYear());
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void CreditCard::SetExpirationMonthFromString(const base::string16& text,
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              const std::string& app_locale) {
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int month;
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!ConvertMonth(text, app_locale, &month))
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetExpirationMonth(month);
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void CreditCard::SetExpirationYearFromString(const base::string16& text) {
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int year;
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ConvertYear(text, &year))
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetExpirationYear(year);
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
651c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void CreditCard::SetNumber(const base::string16& number) {
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  number_ = number;
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  type_ = GetCreditCardType(StripSeparators(number_));
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreditCard::SetExpirationMonth(int expiration_month) {
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (expiration_month < 0 || expiration_month > 12)
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expiration_month_ = expiration_month;
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreditCard::SetExpirationYear(int expiration_year) {
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (expiration_year != 0 &&
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (expiration_year < 2006 || expiration_year > 10000)) {
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expiration_year_ = expiration_year;
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// So we can compare CreditCards with EXPECT_EQ().
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::ostream& operator<<(std::ostream& os, const CreditCard& credit_card) {
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return os
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << UTF16ToUTF8(credit_card.Label())
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << " "
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << credit_card.guid()
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << " "
679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      << credit_card.origin()
680c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      << " "
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_NAME))
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << " "
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_TYPE))
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << " "
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_NUMBER))
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << " "
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_EXP_MONTH))
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << " "
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR));
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// These values must match the values in WebKitPlatformSupportImpl in
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// webkit/glue. We send these strings to WebKit, which then asks
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WebKitPlatformSupportImpl to load the image data.
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kAmericanExpressCard = "americanExpressCC";
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kDinersCard = "dinersCC";
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kDiscoverCard = "discoverCC";
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kGenericCard = "genericCC";
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kJCBCard = "jcbCC";
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kMasterCard = "masterCardCC";
7017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst char* const kUnionPay = "unionPayCC";
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kVisaCard = "visaCC";
703c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace autofill
705