Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(49)

Side by Side Diff: chrome/browser/autofill/credit_card.cc

Issue 12434004: Move remaining Autofill code to //components/autofill. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix long lines Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/autofill/credit_card.h ('k') | chrome/browser/autofill/credit_card_field.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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/autofill/credit_card.h"
6
7 #include <stddef.h>
8
9 #include <ostream>
10 #include <string>
11
12 #include "base/basictypes.h"
13 #include "base/guid.h"
14 #include "base/logging.h"
15 #include "base/string16.h"
16 #include "base/string_util.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/string_split.h"
19 #include "base/utf_string_conversions.h"
20 #include "chrome/browser/autofill/autofill_country.h"
21 #include "chrome/browser/autofill/autofill_field.h"
22 #include "chrome/browser/autofill/autofill_regexes.h"
23 #include "chrome/browser/autofill/autofill_type.h"
24 #include "chrome/browser/autofill/field_types.h"
25 #include "chrome/browser/autofill/validation.h"
26 #include "components/autofill/common/form_field_data.h"
27 #include "grit/generated_resources.h"
28 #include "grit/webkit_resources.h"
29 #include "third_party/icu/public/common/unicode/uloc.h"
30 #include "third_party/icu/public/i18n/unicode/dtfmtsym.h"
31 #include "ui/base/l10n/l10n_util.h"
32
33 namespace {
34
35 const char16 kCreditCardObfuscationSymbol = '*';
36
37 // This is the maximum obfuscated symbols displayed.
38 // It is introduced to avoid rare cases where the credit card number is
39 // too large and fills the screen.
40 const size_t kMaxObfuscationSize = 20;
41
42 std::string GetCreditCardType(const string16& number) {
43 // Don't check for a specific type if this is not a credit card number.
44 if (!autofill::IsValidCreditCardNumber(number))
45 return kGenericCard;
46
47 // Credit card number specifications taken from:
48 // http://en.wikipedia.org/wiki/Credit_card_numbers and
49 // http://www.beachnet.com/~hstiles/cardtype.html
50 // Card Type Prefix(es) Length
51 // ---------------------------------------------------------------
52 // Visa 4 13,16
53 // American Express 34,37 15
54 // Diners Club 300-305,2014,2149,36, 14,15
55 // Discover Card 6011,65 16
56 // JCB 3 16
57 // JCB 2131,1800 15
58 // MasterCard 51-55 16
59 // Solo (debit card) 6334,6767 16,18,19
60
61 // We need at least 4 digits to work with.
62 if (number.length() < 4)
63 return kGenericCard;
64
65 int first_four_digits = 0;
66 if (!base::StringToInt(number.substr(0, 4), &first_four_digits))
67 return kGenericCard;
68
69 int first_three_digits = first_four_digits / 10;
70 int first_two_digits = first_three_digits / 10;
71 int first_digit = first_two_digits / 10;
72
73 switch (number.length()) {
74 case 13:
75 if (first_digit == 4)
76 return kVisaCard;
77
78 break;
79 case 14:
80 if (first_three_digits >= 300 && first_three_digits <= 305)
81 return kDinersCard;
82
83 if (first_digit == 36)
84 return kDinersCard;
85
86 break;
87 case 15:
88 if (first_two_digits == 34 || first_two_digits == 37)
89 return kAmericanExpressCard;
90
91 if (first_four_digits == 2131 || first_four_digits == 1800)
92 return kJCBCard;
93
94 if (first_four_digits == 2014 || first_four_digits == 2149)
95 return kDinersCard;
96
97 break;
98 case 16:
99 if (first_four_digits == 6011 || first_two_digits == 65)
100 return kDiscoverCard;
101
102 if (first_four_digits == 6334 || first_four_digits == 6767)
103 return kSoloCard;
104
105 if (first_two_digits >= 51 && first_two_digits <= 55)
106 return kMasterCard;
107
108 if (first_digit == 3)
109 return kJCBCard;
110
111 if (first_digit == 4)
112 return kVisaCard;
113
114 break;
115 case 18:
116 case 19:
117 if (first_four_digits == 6334 || first_four_digits == 6767)
118 return kSoloCard;
119
120 break;
121 }
122
123 return kGenericCard;
124 }
125
126 bool ConvertYear(const string16& year, int* num) {
127 // If the |year| is empty, clear the stored value.
128 if (year.empty()) {
129 *num = 0;
130 return true;
131 }
132
133 // Try parsing the |year| as a number.
134 if (base::StringToInt(year, num))
135 return true;
136
137 *num = 0;
138 return false;
139 }
140
141 bool ConvertMonth(const string16& month,
142 const std::string& app_locale,
143 int* num) {
144 // If the |month| is empty, clear the stored value.
145 if (month.empty()) {
146 *num = 0;
147 return true;
148 }
149
150 // Try parsing the |month| as a number.
151 if (base::StringToInt(month, num))
152 return true;
153
154 // If the locale is unknown, give up.
155 if (app_locale.empty())
156 return false;
157
158 // Otherwise, try parsing the |month| as a named month, e.g. "January" or
159 // "Jan".
160 string16 lowercased_month = StringToLowerASCII(month);
161
162 UErrorCode status = U_ZERO_ERROR;
163 icu::Locale locale(app_locale.c_str());
164 icu::DateFormatSymbols date_format_symbols(locale, status);
165 DCHECK(status == U_ZERO_ERROR || status == U_USING_FALLBACK_WARNING ||
166 status == U_USING_DEFAULT_WARNING);
167
168 int32_t num_months;
169 const icu::UnicodeString* months = date_format_symbols.getMonths(num_months);
170 for (int32_t i = 0; i < num_months; ++i) {
171 const string16 icu_month = string16(months[i].getBuffer(),
172 months[i].length());
173 if (lowercased_month == StringToLowerASCII(icu_month)) {
174 *num = i + 1; // Adjust from 0-indexed to 1-indexed.
175 return true;
176 }
177 }
178
179 months = date_format_symbols.getShortMonths(num_months);
180 for (int32_t i = 0; i < num_months; ++i) {
181 const string16 icu_month = string16(months[i].getBuffer(),
182 months[i].length());
183 if (lowercased_month == StringToLowerASCII(icu_month)) {
184 *num = i + 1; // Adjust from 0-indexed to 1-indexed.
185 return true;
186 }
187 }
188
189 *num = 0;
190 return false;
191 }
192
193 } // namespace
194
195 CreditCard::CreditCard(const std::string& guid)
196 : type_(kGenericCard),
197 expiration_month_(0),
198 expiration_year_(0),
199 guid_(guid) {
200 }
201
202 CreditCard::CreditCard()
203 : type_(kGenericCard),
204 expiration_month_(0),
205 expiration_year_(0),
206 guid_(base::GenerateGUID()) {
207 }
208
209 CreditCard::CreditCard(const CreditCard& credit_card) : FormGroup() {
210 operator=(credit_card);
211 }
212
213 CreditCard::~CreditCard() {}
214
215 // static
216 const string16 CreditCard::StripSeparators(const string16& number) {
217 const char16 kSeparators[] = {'-', ' ', '\0'};
218 string16 stripped;
219 RemoveChars(number, kSeparators, &stripped);
220 return stripped;
221 }
222
223 std::string CreditCard::GetGUID() const {
224 return guid();
225 }
226
227 string16 CreditCard::GetRawInfo(AutofillFieldType type) const {
228 switch (type) {
229 case CREDIT_CARD_NAME:
230 return name_on_card_;
231
232 case CREDIT_CARD_EXP_MONTH:
233 return ExpirationMonthAsString();
234
235 case CREDIT_CARD_EXP_2_DIGIT_YEAR:
236 return Expiration2DigitYearAsString();
237
238 case CREDIT_CARD_EXP_4_DIGIT_YEAR:
239 return Expiration4DigitYearAsString();
240
241 case CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR: {
242 string16 month = ExpirationMonthAsString();
243 string16 year = Expiration2DigitYearAsString();
244 if (!month.empty() && !year.empty())
245 return month + ASCIIToUTF16("/") + year;
246 return string16();
247 }
248
249 case CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR: {
250 string16 month = ExpirationMonthAsString();
251 string16 year = Expiration4DigitYearAsString();
252 if (!month.empty() && !year.empty())
253 return month + ASCIIToUTF16("/") + year;
254 return string16();
255 }
256
257 case CREDIT_CARD_TYPE:
258 return TypeForDisplay();
259
260 case CREDIT_CARD_NUMBER:
261 return number_;
262
263 case CREDIT_CARD_VERIFICATION_CODE:
264 // Chrome doesn't store credit card verification codes.
265 return string16();
266
267 default:
268 // ComputeDataPresentForArray will hit this repeatedly.
269 return string16();
270 }
271 }
272
273 void CreditCard::SetRawInfo(AutofillFieldType type, const string16& value) {
274 switch (type) {
275 case CREDIT_CARD_NAME:
276 name_on_card_ = value;
277 break;
278
279 case CREDIT_CARD_EXP_MONTH:
280 SetExpirationMonthFromString(value, std::string());
281 break;
282
283 case CREDIT_CARD_EXP_2_DIGIT_YEAR:
284 // This is a read-only attribute.
285 break;
286
287 case CREDIT_CARD_EXP_4_DIGIT_YEAR:
288 SetExpirationYearFromString(value);
289 break;
290
291 case CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR:
292 // This is a read-only attribute.
293 break;
294
295 case CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR:
296 // This is a read-only attribute.
297 break;
298
299 case CREDIT_CARD_TYPE:
300 // This is a read-only attribute, determined by the credit card number.
301 break;
302
303 case CREDIT_CARD_NUMBER: {
304 // Don't change the real value if the input is an obfuscated string.
305 if (value.size() > 0 && value[0] != kCreditCardObfuscationSymbol)
306 SetNumber(value);
307 break;
308 }
309
310 case CREDIT_CARD_VERIFICATION_CODE:
311 // Chrome doesn't store the credit card verification code.
312 break;
313
314 default:
315 NOTREACHED() << "Attempting to set unknown info-type " << type;
316 break;
317 }
318 }
319
320 string16 CreditCard::GetInfo(AutofillFieldType type,
321 const std::string& app_locale) const {
322 if (type == CREDIT_CARD_NUMBER)
323 return StripSeparators(number_);
324
325 return GetRawInfo(type);
326 }
327
328 bool CreditCard::SetInfo(AutofillFieldType type,
329 const string16& value,
330 const std::string& app_locale) {
331 if (type == CREDIT_CARD_NUMBER)
332 SetRawInfo(type, StripSeparators(value));
333 else if (type == CREDIT_CARD_EXP_MONTH)
334 SetExpirationMonthFromString(value, app_locale);
335 else
336 SetRawInfo(type, value);
337
338 return true;
339 }
340
341 void CreditCard::GetMatchingTypes(const string16& text,
342 const std::string& app_locale,
343 FieldTypeSet* matching_types) const {
344 FormGroup::GetMatchingTypes(text, app_locale, matching_types);
345
346 string16 card_number = GetInfo(CREDIT_CARD_NUMBER, app_locale);
347 if (!card_number.empty() && StripSeparators(text) == card_number)
348 matching_types->insert(CREDIT_CARD_NUMBER);
349
350 int month;
351 if (ConvertMonth(text, app_locale, &month) && month != 0 &&
352 month == expiration_month_) {
353 matching_types->insert(CREDIT_CARD_EXP_MONTH);
354 }
355 }
356
357 const string16 CreditCard::Label() const {
358 string16 label;
359 if (number().empty())
360 return name_on_card_; // No CC number, return name only.
361
362 string16 obfuscated_cc_number = ObfuscatedNumber();
363 if (!expiration_month_ || !expiration_year_)
364 return obfuscated_cc_number; // No expiration date set.
365
366 // TODO(georgey): Internationalize date.
367 string16 formatted_date(ExpirationMonthAsString());
368 formatted_date.append(ASCIIToUTF16("/"));
369 formatted_date.append(Expiration4DigitYearAsString());
370
371 label = l10n_util::GetStringFUTF16(IDS_CREDIT_CARD_NUMBER_PREVIEW_FORMAT,
372 obfuscated_cc_number,
373 formatted_date);
374 return label;
375 }
376
377 void CreditCard::SetInfoForMonthInputType(const string16& value) {
378 // Check if |text| is "yyyy-mm" format first, and check normal month format.
379 if (!autofill::MatchesPattern(value, UTF8ToUTF16("^[0-9]{4}-[0-9]{1,2}$")))
380 return;
381
382 std::vector<string16> year_month;
383 base::SplitString(value, L'-', &year_month);
384 DCHECK_EQ((int)year_month.size(), 2);
385 int num = 0;
386 bool converted = false;
387 converted = base::StringToInt(year_month[0], &num);
388 DCHECK(converted);
389 SetExpirationYear(num);
390 converted = base::StringToInt(year_month[1], &num);
391 DCHECK(converted);
392 SetExpirationMonth(num);
393 }
394
395 string16 CreditCard::ObfuscatedNumber() const {
396 // If the number is shorter than four digits, there's no need to obfuscate it.
397 if (number_.size() < 4)
398 return number_;
399
400 string16 number = StripSeparators(number_);
401
402 // Avoid making very long obfuscated numbers.
403 size_t obfuscated_digits = std::min(kMaxObfuscationSize, number.size() - 4);
404 string16 result(obfuscated_digits, kCreditCardObfuscationSymbol);
405 return result.append(LastFourDigits());
406 }
407
408 string16 CreditCard::LastFourDigits() const {
409 static const size_t kNumLastDigits = 4;
410
411 string16 number = StripSeparators(number_);
412 if (number.size() < kNumLastDigits)
413 return string16();
414
415 return number.substr(number.size() - kNumLastDigits, kNumLastDigits);
416 }
417
418 string16 CreditCard::TypeForDisplay() const {
419 if (type_ == kAmericanExpressCard)
420 return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_AMEX);
421 if (type_ == kDinersCard)
422 return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_DINERS);
423 if (type_ == kDiscoverCard)
424 return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_DISCOVER);
425 if (type_ == kJCBCard)
426 return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_JCB);
427 if (type_ == kMasterCard)
428 return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_MASTERCARD);
429 if (type_ == kSoloCard)
430 return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_SOLO);
431 if (type_ == kVisaCard)
432 return l10n_util::GetStringUTF16(IDS_AUTOFILL_CC_VISA);
433
434 // If you hit this DCHECK, the above list of cases needs to be updated to
435 // include a new card.
436 DCHECK_EQ(kGenericCard, type_);
437 return string16();
438 }
439
440 string16 CreditCard::TypeAndLastFourDigits() const {
441 string16 type = TypeForDisplay();
442 // TODO(estade): type may be empty, we probably want to return
443 // "Card - 1234" or something in that case.
444
445 string16 digits = LastFourDigits();
446 if (digits.empty())
447 return type;
448
449 // TODO(estade): i18n.
450 return type + ASCIIToUTF16(" - ") + digits;
451 }
452
453 int CreditCard::IconResourceId() const {
454 if (type_ == kAmericanExpressCard)
455 return IDR_AUTOFILL_CC_AMEX;
456 if (type_ == kDinersCard)
457 return IDR_AUTOFILL_CC_DINERS;
458 if (type_ == kDiscoverCard)
459 return IDR_AUTOFILL_CC_DISCOVER;
460 if (type_ == kJCBCard)
461 return IDR_AUTOFILL_CC_JCB;
462 if (type_ == kMasterCard)
463 return IDR_AUTOFILL_CC_MASTERCARD;
464 if (type_ == kSoloCard)
465 return IDR_AUTOFILL_CC_SOLO;
466 if (type_ == kVisaCard)
467 return IDR_AUTOFILL_CC_VISA;
468
469 // If you hit this DCHECK, the above list of cases needs to be updated to
470 // include a new card.
471 DCHECK_EQ(kGenericCard, type_);
472 return IDR_AUTOFILL_CC_GENERIC;
473 }
474
475 void CreditCard::operator=(const CreditCard& credit_card) {
476 if (this == &credit_card)
477 return;
478
479 number_ = credit_card.number_;
480 name_on_card_ = credit_card.name_on_card_;
481 type_ = credit_card.type_;
482 expiration_month_ = credit_card.expiration_month_;
483 expiration_year_ = credit_card.expiration_year_;
484 guid_ = credit_card.guid_;
485 }
486
487 bool CreditCard::UpdateFromImportedCard(const CreditCard& imported_card,
488 const std::string& app_locale) {
489 if (this->GetInfo(CREDIT_CARD_NUMBER, app_locale) !=
490 imported_card.GetInfo(CREDIT_CARD_NUMBER, app_locale)) {
491 return false;
492 }
493
494 // Note that the card number is intentionally not updated, so as to preserve
495 // any formatting (i.e. separator characters). Since the card number is not
496 // updated, there is no reason to update the card type, either.
497 if (!imported_card.name_on_card_.empty())
498 name_on_card_ = imported_card.name_on_card_;
499
500 // The expiration date for |imported_card| should always be set.
501 DCHECK(imported_card.expiration_month_ && imported_card.expiration_year_);
502 expiration_month_ = imported_card.expiration_month_;
503 expiration_year_ = imported_card.expiration_year_;
504
505 return true;
506 }
507
508 void CreditCard::FillFormField(const AutofillField& field,
509 size_t /*variant*/,
510 FormFieldData* field_data) const {
511 DCHECK_EQ(AutofillType::CREDIT_CARD, AutofillType(field.type()).group());
512 DCHECK(field_data);
513
514 const std::string app_locale = AutofillCountry::ApplicationLocale();
515
516 if (field_data->form_control_type == "select-one") {
517 FillSelectControl(field.type(), field_data);
518 } else if (field_data->form_control_type == "month") {
519 // HTML5 input="month" consists of year-month.
520 string16 year = GetInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, app_locale);
521 string16 month = GetInfo(CREDIT_CARD_EXP_MONTH, app_locale);
522 if (!year.empty() && !month.empty()) {
523 // Fill the value only if |this| includes both year and month
524 // information.
525 field_data->value = year + ASCIIToUTF16("-") + month;
526 }
527 } else {
528 field_data->value = GetInfo(field.type(), app_locale);
529 }
530 }
531
532 int CreditCard::Compare(const CreditCard& credit_card) const {
533 // The following CreditCard field types are the only types we store in the
534 // WebDB so far, so we're only concerned with matching these types in the
535 // credit card.
536 const AutofillFieldType types[] = { CREDIT_CARD_NAME,
537 CREDIT_CARD_NUMBER,
538 CREDIT_CARD_EXP_MONTH,
539 CREDIT_CARD_EXP_4_DIGIT_YEAR };
540 for (size_t index = 0; index < arraysize(types); ++index) {
541 int comparison = GetRawInfo(types[index]).compare(
542 credit_card.GetRawInfo(types[index]));
543 if (comparison != 0)
544 return comparison;
545 }
546
547 return 0;
548 }
549
550 bool CreditCard::operator==(const CreditCard& credit_card) const {
551 if (guid_ != credit_card.guid_)
552 return false;
553
554 return Compare(credit_card) == 0;
555 }
556
557 bool CreditCard::operator!=(const CreditCard& credit_card) const {
558 return !operator==(credit_card);
559 }
560
561 bool CreditCard::IsEmpty() const {
562 FieldTypeSet types;
563 GetNonEmptyTypes(AutofillCountry::ApplicationLocale(), &types);
564 return types.empty();
565 }
566
567 bool CreditCard::IsComplete() const {
568 return
569 autofill::IsValidCreditCardNumber(number_) &&
570 expiration_month_ != 0 &&
571 expiration_year_ != 0;
572 }
573
574 void CreditCard::GetSupportedTypes(FieldTypeSet* supported_types) const {
575 supported_types->insert(CREDIT_CARD_NAME);
576 supported_types->insert(CREDIT_CARD_NUMBER);
577 supported_types->insert(CREDIT_CARD_TYPE);
578 supported_types->insert(CREDIT_CARD_EXP_MONTH);
579 supported_types->insert(CREDIT_CARD_EXP_2_DIGIT_YEAR);
580 supported_types->insert(CREDIT_CARD_EXP_4_DIGIT_YEAR);
581 supported_types->insert(CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR);
582 supported_types->insert(CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR);
583 }
584
585 string16 CreditCard::ExpirationMonthAsString() const {
586 if (expiration_month_ == 0)
587 return string16();
588
589 string16 month = base::IntToString16(expiration_month_);
590 if (expiration_month_ >= 10)
591 return month;
592
593 string16 zero = ASCIIToUTF16("0");
594 zero.append(month);
595 return zero;
596 }
597
598 string16 CreditCard::Expiration4DigitYearAsString() const {
599 if (expiration_year_ == 0)
600 return string16();
601
602 return base::IntToString16(Expiration4DigitYear());
603 }
604
605 string16 CreditCard::Expiration2DigitYearAsString() const {
606 if (expiration_year_ == 0)
607 return string16();
608
609 return base::IntToString16(Expiration2DigitYear());
610 }
611
612 void CreditCard::SetExpirationMonthFromString(const string16& text,
613 const std::string& app_locale) {
614 int month;
615 if (!ConvertMonth(text, app_locale, &month))
616 return;
617
618 SetExpirationMonth(month);
619 }
620
621 void CreditCard::SetExpirationYearFromString(const string16& text) {
622 int year;
623 if (!ConvertYear(text, &year))
624 return;
625
626 SetExpirationYear(year);
627 }
628
629 void CreditCard::SetNumber(const string16& number) {
630 number_ = number;
631 type_ = GetCreditCardType(StripSeparators(number_));
632 }
633
634 void CreditCard::SetExpirationMonth(int expiration_month) {
635 if (expiration_month < 0 || expiration_month > 12)
636 return;
637
638 expiration_month_ = expiration_month;
639 }
640
641 void CreditCard::SetExpirationYear(int expiration_year) {
642 if (expiration_year != 0 &&
643 (expiration_year < 2006 || expiration_year > 10000)) {
644 return;
645 }
646
647 expiration_year_ = expiration_year;
648 }
649
650 // So we can compare CreditCards with EXPECT_EQ().
651 std::ostream& operator<<(std::ostream& os, const CreditCard& credit_card) {
652 return os
653 << UTF16ToUTF8(credit_card.Label())
654 << " "
655 << credit_card.guid()
656 << " "
657 << UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_NAME))
658 << " "
659 << UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_TYPE))
660 << " "
661 << UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_NUMBER))
662 << " "
663 << UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_EXP_MONTH))
664 << " "
665 << UTF16ToUTF8(credit_card.GetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR));
666 }
667
668 // These values must match the values in WebKitPlatformSupportImpl in
669 // webkit/glue. We send these strings to WebKit, which then asks
670 // WebKitPlatformSupportImpl to load the image data.
671 const char* const kAmericanExpressCard = "americanExpressCC";
672 const char* const kDinersCard = "dinersCC";
673 const char* const kDiscoverCard = "discoverCC";
674 const char* const kGenericCard = "genericCC";
675 const char* const kJCBCard = "jcbCC";
676 const char* const kMasterCard = "masterCardCC";
677 const char* const kSoloCard = "soloCC";
678 const char* const kVisaCard = "visaCC";
OLDNEW
« no previous file with comments | « chrome/browser/autofill/credit_card.h ('k') | chrome/browser/autofill/credit_card_field.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698