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

Side by Side Diff: chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc

Issue 15961007: Highlight fields we know to be invalid but have no way of locally checking. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 years, 6 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/autofill/autofill_dialog_controller_impl.h" 5 #include "chrome/browser/ui/autofill/autofill_dialog_controller_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 #include <string> 9 #include <string>
10 10
(...skipping 998 matching lines...) Expand 10 before | Expand all | Expand 10 after
1009 string16 AutofillDialogControllerImpl::ExtraSuggestionTextForSection( 1009 string16 AutofillDialogControllerImpl::ExtraSuggestionTextForSection(
1010 DialogSection section) const { 1010 DialogSection section) const {
1011 if (section == SECTION_CC || 1011 if (section == SECTION_CC ||
1012 (section == SECTION_CC_BILLING && IsSubmitPausedOn(wallet::VERIFY_CVV))) { 1012 (section == SECTION_CC_BILLING && IsSubmitPausedOn(wallet::VERIFY_CVV))) {
1013 return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC); 1013 return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC);
1014 } 1014 }
1015 1015
1016 return string16(); 1016 return string16();
1017 } 1017 }
1018 1018
1019 const wallet::WalletItems::MaskedInstrument* AutofillDialogControllerImpl::
1020 ActiveInstrument() const {
Evan Stade 2013/06/03 21:24:46 could you make an ActiveShippingAddress() while yo
Dan Beam 2013/06/03 22:04:19 Done.
1021 if (!IsPayingWithWallet())
1022 return NULL;
1023
1024 const SuggestionsMenuModel* model =
1025 SuggestionsMenuModelForSection(SECTION_CC_BILLING);
1026 const std::string item_key = model->GetItemKeyForCheckedItem();
1027 if (!IsASuggestionItemKey(item_key))
1028 return NULL;
1029
1030 int index;
1031 if (!base::StringToInt(item_key, &index) || index < 0 ||
1032 static_cast<size_t>(index) >= wallet_items_->instruments().size()) {
1033 NOTREACHED();
1034 return NULL;
1035 }
1036
1037 return wallet_items_->instruments()[index];
1038 }
1039
1019 scoped_ptr<DataModelWrapper> AutofillDialogControllerImpl::CreateWrapper( 1040 scoped_ptr<DataModelWrapper> AutofillDialogControllerImpl::CreateWrapper(
1020 DialogSection section) { 1041 DialogSection section) {
1021 if (IsPayingWithWallet() && full_wallet_ && 1042 if (IsPayingWithWallet() && full_wallet_ &&
1022 full_wallet_->required_actions().empty()) { 1043 full_wallet_->required_actions().empty()) {
1023 if (section == SECTION_CC_BILLING) { 1044 if (section == SECTION_CC_BILLING) {
1024 return scoped_ptr<DataModelWrapper>( 1045 return scoped_ptr<DataModelWrapper>(
1025 new FullWalletBillingWrapper(full_wallet_.get())); 1046 new FullWalletBillingWrapper(full_wallet_.get()));
1026 } 1047 }
1027 if (section == SECTION_SHIPPING) { 1048 if (section == SECTION_SHIPPING) {
1028 return scoped_ptr<DataModelWrapper>( 1049 return scoped_ptr<DataModelWrapper>(
1029 new FullWalletShippingWrapper(full_wallet_.get())); 1050 new FullWalletShippingWrapper(full_wallet_.get()));
1030 } 1051 }
1031 } 1052 }
1032 1053
1033 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); 1054 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section);
1034 std::string item_key = model->GetItemKeyForCheckedItem(); 1055 std::string item_key = model->GetItemKeyForCheckedItem();
1035 if (!IsASuggestionItemKey(item_key) || IsManuallyEditingSection(section)) 1056 if (!IsASuggestionItemKey(item_key) || IsManuallyEditingSection(section))
1036 return scoped_ptr<DataModelWrapper>(); 1057 return scoped_ptr<DataModelWrapper>();
1037 1058
1038 if (IsPayingWithWallet()) { 1059 if (IsPayingWithWallet()) {
1060 if (section == SECTION_CC_BILLING) {
1061 return scoped_ptr<DataModelWrapper>(
1062 new WalletInstrumentWrapper(ActiveInstrument()));
1063 }
1064
1065 if (section != SECTION_SHIPPING)
1066 return scoped_ptr<DataModelWrapper>();
1067
1039 int index; 1068 int index;
1040 bool success = base::StringToInt(item_key, &index); 1069 bool success = base::StringToInt(item_key, &index);
1041 DCHECK(success); 1070 DCHECK(success);
1042 1071
1043 if (section == SECTION_CC_BILLING) { 1072 return scoped_ptr<DataModelWrapper>(
1044 return scoped_ptr<DataModelWrapper>( 1073 new WalletAddressWrapper(wallet_items_->addresses()[index]));
1045 new WalletInstrumentWrapper(wallet_items_->instruments()[index]));
1046 }
1047
1048 if (section == SECTION_SHIPPING) {
1049 return scoped_ptr<DataModelWrapper>(
1050 new WalletAddressWrapper(wallet_items_->addresses()[index]));
1051 }
1052
1053 return scoped_ptr<DataModelWrapper>();
1054 } 1074 }
1055 1075
1056 if (section == SECTION_CC) { 1076 if (section == SECTION_CC) {
1057 CreditCard* card = GetManager()->GetCreditCardByGUID(item_key); 1077 CreditCard* card = GetManager()->GetCreditCardByGUID(item_key);
1058 DCHECK(card); 1078 DCHECK(card);
1059 return scoped_ptr<DataModelWrapper>(new AutofillCreditCardWrapper(card)); 1079 return scoped_ptr<DataModelWrapper>(new AutofillCreditCardWrapper(card));
1060 } 1080 }
1061 1081
1062 AutofillProfile* profile = GetManager()->GetProfileByGUID(item_key); 1082 AutofillProfile* profile = GetManager()->GetProfileByGUID(item_key);
1063 DCHECK(profile); 1083 DCHECK(profile);
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1242 const AutofillFieldType type = iter->first->type; 1262 const AutofillFieldType type = iter->first->type;
1243 string16 message = InputValidityMessage(type, iter->second); 1263 string16 message = InputValidityMessage(type, iter->second);
1244 if (!message.empty()) 1264 if (!message.empty())
1245 invalid_messages[type] = message; 1265 invalid_messages[type] = message;
1246 else 1266 else
1247 field_values[type] = iter->second; 1267 field_values[type] = iter->second;
1248 } 1268 }
1249 1269
1250 // Validate the date formed by month and year field. (Autofill dialog is 1270 // Validate the date formed by month and year field. (Autofill dialog is
1251 // never supposed to have 2-digit years, so not checked). 1271 // never supposed to have 2-digit years, so not checked).
1252 if (field_values.count(CREDIT_CARD_EXP_MONTH) && 1272 if (field_values.count(CREDIT_CARD_EXP_4_DIGIT_YEAR) &&
1253 field_values.count(CREDIT_CARD_EXP_4_DIGIT_YEAR)) { 1273 field_values.count(CREDIT_CARD_EXP_MONTH) &&
1254 if (!autofill::IsValidCreditCardExpirationDate( 1274 !IsCreditCardExpirationValid(field_values[CREDIT_CARD_EXP_4_DIGIT_YEAR],
1255 field_values[CREDIT_CARD_EXP_4_DIGIT_YEAR], 1275 field_values[CREDIT_CARD_EXP_MONTH])) {
1256 field_values[CREDIT_CARD_EXP_MONTH], 1276 invalid_messages[CREDIT_CARD_EXP_4_DIGIT_YEAR] =
1257 base::Time::Now())) { 1277 ASCIIToUTF16("more complicated message");
1258 invalid_messages[CREDIT_CARD_EXP_MONTH] = 1278 invalid_messages[CREDIT_CARD_EXP_MONTH] =
1259 ASCIIToUTF16("more complicated message"); 1279 ASCIIToUTF16("more complicated message");
1260 invalid_messages[CREDIT_CARD_EXP_4_DIGIT_YEAR] =
1261 ASCIIToUTF16("more complicated message");
1262 }
1263 } 1280 }
1264 1281
1265 // If there is a credit card number and a CVC, validate them together. 1282 // If there is a credit card number and a CVC, validate them together.
1266 if (field_values.count(CREDIT_CARD_NUMBER) && 1283 if (field_values.count(CREDIT_CARD_NUMBER) &&
1267 field_values.count(CREDIT_CARD_VERIFICATION_CODE) && 1284 field_values.count(CREDIT_CARD_VERIFICATION_CODE) &&
1268 InputValidityMessage(CREDIT_CARD_NUMBER, 1285 InputValidityMessage(CREDIT_CARD_NUMBER,
1269 field_values[CREDIT_CARD_NUMBER]).empty()) { 1286 field_values[CREDIT_CARD_NUMBER]).empty() &&
1270 if (!autofill::IsValidCreditCardSecurityCode( 1287 !autofill::IsValidCreditCardSecurityCode(
1271 field_values[CREDIT_CARD_VERIFICATION_CODE], 1288 field_values[CREDIT_CARD_VERIFICATION_CODE],
1272 field_values[CREDIT_CARD_NUMBER])) { 1289 field_values[CREDIT_CARD_NUMBER])) {
1273 invalid_messages[CREDIT_CARD_VERIFICATION_CODE] = 1290 invalid_messages[CREDIT_CARD_VERIFICATION_CODE] =
1274 ASCIIToUTF16("CVC doesn't match card type!"); 1291 ASCIIToUTF16("CVC doesn't match card type!");
1275 }
1276 } 1292 }
1277 1293
1278 // Validate the phone number against the country code of the address. 1294 // Validate the phone number against the country code of the address.
1279 if (field_values.count(ADDRESS_HOME_COUNTRY) && 1295 if (field_values.count(ADDRESS_HOME_COUNTRY) &&
1280 field_values.count(PHONE_HOME_WHOLE_NUMBER)) { 1296 field_values.count(PHONE_HOME_WHOLE_NUMBER)) {
1281 i18n::PhoneObject phone_object( 1297 i18n::PhoneObject phone_object(
1282 field_values[PHONE_HOME_WHOLE_NUMBER], 1298 field_values[PHONE_HOME_WHOLE_NUMBER],
1283 AutofillCountry::GetCountryCode( 1299 AutofillCountry::GetCountryCode(
1284 field_values[ADDRESS_HOME_COUNTRY], 1300 field_values[ADDRESS_HOME_COUNTRY],
1285 g_browser_process->GetApplicationLocale())); 1301 g_browser_process->GetApplicationLocale()));
(...skipping 1105 matching lines...) Expand 10 before | Expand all | Expand 10 after
2391 } 2407 }
2392 2408
2393 bool AutofillDialogControllerImpl::IsManuallyEditingSection( 2409 bool AutofillDialogControllerImpl::IsManuallyEditingSection(
2394 DialogSection section) const { 2410 DialogSection section) const {
2395 return IsEditingExistingData(section) || 2411 return IsEditingExistingData(section) ||
2396 SuggestionsMenuModelForSection(section)-> 2412 SuggestionsMenuModelForSection(section)->
2397 GetItemKeyForCheckedItem() == kAddNewItemKey; 2413 GetItemKeyForCheckedItem() == kAddNewItemKey;
2398 } 2414 }
2399 2415
2400 bool AutofillDialogControllerImpl::IsASuggestionItemKey( 2416 bool AutofillDialogControllerImpl::IsASuggestionItemKey(
2401 const std::string& key) { 2417 const std::string& key) const {
2402 return !key.empty() && 2418 return !key.empty() &&
2403 key != kAddNewItemKey && 2419 key != kAddNewItemKey &&
2404 key != kManageItemsKey && 2420 key != kManageItemsKey &&
2405 key != kSameAsBillingKey; 2421 key != kSameAsBillingKey;
2406 } 2422 }
2407 2423
2408 bool AutofillDialogControllerImpl::IsManuallyEditingAnySection() const { 2424 bool AutofillDialogControllerImpl::IsManuallyEditingAnySection() const {
2409 for (size_t section = SECTION_MIN; section <= SECTION_MAX; ++section) { 2425 for (size_t section = SECTION_MIN; section <= SECTION_MAX; ++section) {
2410 if (IsManuallyEditingSection(static_cast<DialogSection>(section))) 2426 if (IsManuallyEditingSection(static_cast<DialogSection>(section)))
2411 return true; 2427 return true;
(...skipping 24 matching lines...) Expand all
2436 bool AutofillDialogControllerImpl::SectionIsValid( 2452 bool AutofillDialogControllerImpl::SectionIsValid(
2437 DialogSection section) const { 2453 DialogSection section) const {
2438 if (!IsManuallyEditingSection(section)) 2454 if (!IsManuallyEditingSection(section))
2439 return true; 2455 return true;
2440 2456
2441 DetailOutputMap detail_outputs; 2457 DetailOutputMap detail_outputs;
2442 view_->GetUserInput(section, &detail_outputs); 2458 view_->GetUserInput(section, &detail_outputs);
2443 return InputsAreValid(detail_outputs, VALIDATE_EDIT).empty(); 2459 return InputsAreValid(detail_outputs, VALIDATE_EDIT).empty();
2444 } 2460 }
2445 2461
2462 bool AutofillDialogControllerImpl::IsCreditCardExpirationValid(
2463 const base::string16& year,
2464 const base::string16& month) const {
2465 // If the expiration is in the past as per the local clock, it's invalid.
2466 base::Time now = base::Time::Now();
2467 if (!autofill::IsValidCreditCardExpirationDate(year, month, now))
2468 return false;
2469
2470 if (IsPayingWithWallet() && IsEditingExistingData(SECTION_CC_BILLING)) {
2471 const wallet::WalletItems::MaskedInstrument* instrument =
2472 ActiveInstrument();
2473 const std::string& locale = g_browser_process->GetApplicationLocale();
2474 int month_int;
2475 if (base::StringToInt(month, &month_int) &&
2476 instrument->status() ==
2477 wallet::WalletItems::MaskedInstrument::EXPIRED &&
2478 year == instrument->GetInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, locale) &&
2479 month_int == instrument->expiration_month()) {
2480 // Otherwise, if the user is editing an instrument that's deemed expired
2481 // by the Online Wallet server, mark it invalid on selection.
2482 return false;
2483 }
2484 }
2485
2486 return true;
2487 }
2488
2446 bool AutofillDialogControllerImpl::ShouldUseBillingForShipping() { 2489 bool AutofillDialogControllerImpl::ShouldUseBillingForShipping() {
2447 return SectionIsActive(SECTION_SHIPPING) && 2490 return SectionIsActive(SECTION_SHIPPING) &&
2448 suggested_shipping_.GetItemKeyForCheckedItem() == kSameAsBillingKey; 2491 suggested_shipping_.GetItemKeyForCheckedItem() == kSameAsBillingKey;
2449 } 2492 }
2450 2493
2451 bool AutofillDialogControllerImpl::ShouldSaveDetailsLocally() { 2494 bool AutofillDialogControllerImpl::ShouldSaveDetailsLocally() {
2452 // It's possible that the user checked [X] Save details locally before 2495 // It's possible that the user checked [X] Save details locally before
2453 // switching payment methods, so only ask the view whether to save details 2496 // switching payment methods, so only ask the view whether to save details
2454 // locally if that checkbox is showing (currently if not paying with wallet). 2497 // locally if that checkbox is showing (currently if not paying with wallet).
2455 // Also, if the user isn't editing any sections, there's no data to save 2498 // Also, if the user isn't editing any sections, there's no data to save
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2487 base::Bind(&UserDidOptIntoLocationServices)); 2530 base::Bind(&UserDidOptIntoLocationServices));
2488 2531
2489 GetWalletClient()->AcceptLegalDocuments( 2532 GetWalletClient()->AcceptLegalDocuments(
2490 wallet_items_->legal_documents(), 2533 wallet_items_->legal_documents(),
2491 wallet_items_->google_transaction_id(), 2534 wallet_items_->google_transaction_id(),
2492 source_url_); 2535 source_url_);
2493 2536
2494 if (AreLegalDocumentsCurrent()) 2537 if (AreLegalDocumentsCurrent())
2495 LoadRiskFingerprintData(); 2538 LoadRiskFingerprintData();
2496 2539
2497 SuggestionsMenuModel* billing = 2540 const wallet::WalletItems::MaskedInstrument* active_instrument =
2498 SuggestionsMenuModelForSection(SECTION_CC_BILLING); 2541 ActiveInstrument();
2499 int instrument_index = -1;
2500 base::StringToInt(billing->GetItemKeyForCheckedItem(), &instrument_index);
2501
2502 if (!IsManuallyEditingSection(SECTION_CC_BILLING)) { 2542 if (!IsManuallyEditingSection(SECTION_CC_BILLING)) {
2503 active_instrument_id_ = 2543 active_instrument_id_ = active_instrument->object_id();
2504 wallet_items_->instruments()[instrument_index]->object_id();
2505 DCHECK(!active_instrument_id_.empty()); 2544 DCHECK(!active_instrument_id_.empty());
2506 } 2545 }
2507 2546
2508 SuggestionsMenuModel* shipping = 2547 SuggestionsMenuModel* shipping =
2509 SuggestionsMenuModelForSection(SECTION_SHIPPING); 2548 SuggestionsMenuModelForSection(SECTION_SHIPPING);
2510 int address_index = -1; 2549 int address_index = -1;
2511 base::StringToInt(shipping->GetItemKeyForCheckedItem(), &address_index); 2550 base::StringToInt(shipping->GetItemKeyForCheckedItem(), &address_index);
2512 2551
2513 if (!IsManuallyEditingSection(SECTION_SHIPPING) && 2552 if (!IsManuallyEditingSection(SECTION_SHIPPING) &&
2514 !ShouldUseBillingForShipping()) { 2553 !ShouldUseBillingForShipping()) {
2515 active_address_id_ = 2554 active_address_id_ =
2516 wallet_items_->addresses()[address_index]->object_id(); 2555 wallet_items_->addresses()[address_index]->object_id();
2517 DCHECK(!active_address_id_.empty()); 2556 DCHECK(!active_address_id_.empty());
2518 } 2557 }
2519 2558
2520 scoped_ptr<wallet::Instrument> inputted_instrument = 2559 scoped_ptr<wallet::Instrument> inputted_instrument =
2521 CreateTransientInstrument(); 2560 CreateTransientInstrument();
2522 scoped_ptr<wallet::WalletClient::UpdateInstrumentRequest> update_request = 2561 scoped_ptr<wallet::WalletClient::UpdateInstrumentRequest> update_request =
2523 CreateUpdateInstrumentRequest( 2562 CreateUpdateInstrumentRequest(
2524 inputted_instrument.get(), 2563 inputted_instrument.get(),
2525 !IsEditingExistingData(SECTION_CC_BILLING) ? std::string() : 2564 !IsEditingExistingData(SECTION_CC_BILLING) ? std::string() :
2526 wallet_items_->instruments()[instrument_index]->object_id()); 2565 active_instrument->object_id());
2527 2566
2528 scoped_ptr<wallet::Address> inputted_address; 2567 scoped_ptr<wallet::Address> inputted_address;
2529 if (active_address_id_.empty()) { 2568 if (active_address_id_.empty()) {
2530 if (ShouldUseBillingForShipping()) { 2569 if (ShouldUseBillingForShipping()) {
2531 const wallet::Address& address = inputted_instrument ? 2570 const wallet::Address& address = inputted_instrument ?
2532 inputted_instrument->address() : 2571 inputted_instrument->address() : active_instrument->address();
2533 wallet_items_->instruments()[instrument_index]->address();
2534 // Try to find an exact matched shipping address and use it for shipping, 2572 // Try to find an exact matched shipping address and use it for shipping,
2535 // otherwise save it as a new shipping address. http://crbug.com/225442 2573 // otherwise save it as a new shipping address. http://crbug.com/225442
2536 const wallet::Address* duplicated_address = 2574 const wallet::Address* duplicated_address =
2537 FindDuplicateAddress(wallet_items_->addresses(), address); 2575 FindDuplicateAddress(wallet_items_->addresses(), address);
2538 if (duplicated_address) { 2576 if (duplicated_address) {
2539 active_address_id_ = duplicated_address->object_id(); 2577 active_address_id_ = duplicated_address->object_id();
2540 DCHECK(!active_address_id_.empty()); 2578 DCHECK(!active_address_id_.empty());
2541 } else { 2579 } else {
2542 inputted_address.reset(new wallet::Address(address)); 2580 inputted_address.reset(new wallet::Address(address));
2543 DCHECK(inputted_address->object_id().empty()); 2581 DCHECK(inputted_address->object_id().empty());
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
2912 AutofillMetrics::DIALOG_USER_SIGNED_IN_NO_WALLET_NO_AUTOFILL; 2950 AutofillMetrics::DIALOG_USER_SIGNED_IN_NO_WALLET_NO_AUTOFILL;
2913 } 2951 }
2914 2952
2915 // Has Wallet items. 2953 // Has Wallet items.
2916 return has_autofill_profiles ? 2954 return has_autofill_profiles ?
2917 AutofillMetrics::DIALOG_USER_SIGNED_IN_HAS_WALLET_HAS_AUTOFILL : 2955 AutofillMetrics::DIALOG_USER_SIGNED_IN_HAS_WALLET_HAS_AUTOFILL :
2918 AutofillMetrics::DIALOG_USER_SIGNED_IN_HAS_WALLET_NO_AUTOFILL; 2956 AutofillMetrics::DIALOG_USER_SIGNED_IN_HAS_WALLET_NO_AUTOFILL;
2919 } 2957 }
2920 2958
2921 } // namespace autofill 2959 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698