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

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 981 matching lines...) Expand 10 before | Expand all | Expand 10 after
992 string16 AutofillDialogControllerImpl::ExtraSuggestionTextForSection( 992 string16 AutofillDialogControllerImpl::ExtraSuggestionTextForSection(
993 DialogSection section) const { 993 DialogSection section) const {
994 if (section == SECTION_CC || 994 if (section == SECTION_CC ||
995 (section == SECTION_CC_BILLING && IsSubmitPausedOn(wallet::VERIFY_CVV))) { 995 (section == SECTION_CC_BILLING && IsSubmitPausedOn(wallet::VERIFY_CVV))) {
996 return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC); 996 return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PLACEHOLDER_CVC);
997 } 997 }
998 998
999 return string16(); 999 return string16();
1000 } 1000 }
1001 1001
1002 const wallet::WalletItems::MaskedInstrument* AutofillDialogControllerImpl::
1003 ActiveInstrument() const {
1004 if (!IsPayingWithWallet())
1005 return NULL;
1006
1007 const SuggestionsMenuModel* model =
1008 SuggestionsMenuModelForSection(SECTION_CC_BILLING);
1009 const std::string item_key = model->GetItemKeyForCheckedItem();
1010 if (!IsASuggestionItemKey(item_key))
1011 return NULL;
1012
1013 int index;
1014 if (!base::StringToInt(item_key, &index) || index < 0 ||
1015 static_cast<size_t>(index) >= wallet_items_->instruments().size()) {
1016 NOTREACHED();
1017 return NULL;
1018 }
1019
1020 return wallet_items_->instruments()[index];
1021 }
1022
1023 const wallet::Address* AutofillDialogControllerImpl::
1024 ActiveShippingAddress() const {
1025 if (!IsPayingWithWallet())
1026 return NULL;
1027
1028 const SuggestionsMenuModel* model =
1029 SuggestionsMenuModelForSection(SECTION_SHIPPING);
1030 const std::string item_key = model->GetItemKeyForCheckedItem();
1031 if (!IsASuggestionItemKey(item_key))
1032 return NULL;
1033
1034 int index;
1035 if (!base::StringToInt(item_key, &index) || index < 0 ||
1036 static_cast<size_t>(index) >= wallet_items_->addresses().size()) {
1037 NOTREACHED();
1038 return NULL;
1039 }
1040
1041 return wallet_items_->addresses()[index];
1042 }
1043
1002 scoped_ptr<DataModelWrapper> AutofillDialogControllerImpl::CreateWrapper( 1044 scoped_ptr<DataModelWrapper> AutofillDialogControllerImpl::CreateWrapper(
1003 DialogSection section) { 1045 DialogSection section) {
1004 if (IsPayingWithWallet() && full_wallet_ && 1046 if (IsPayingWithWallet() && full_wallet_ &&
1005 full_wallet_->required_actions().empty()) { 1047 full_wallet_->required_actions().empty()) {
1006 if (section == SECTION_CC_BILLING) { 1048 if (section == SECTION_CC_BILLING) {
1007 return scoped_ptr<DataModelWrapper>( 1049 return scoped_ptr<DataModelWrapper>(
1008 new FullWalletBillingWrapper(full_wallet_.get())); 1050 new FullWalletBillingWrapper(full_wallet_.get()));
1009 } 1051 }
1010 if (section == SECTION_SHIPPING) { 1052 if (section == SECTION_SHIPPING) {
1011 return scoped_ptr<DataModelWrapper>( 1053 return scoped_ptr<DataModelWrapper>(
1012 new FullWalletShippingWrapper(full_wallet_.get())); 1054 new FullWalletShippingWrapper(full_wallet_.get()));
1013 } 1055 }
1014 } 1056 }
1015 1057
1016 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); 1058 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section);
1017 std::string item_key = model->GetItemKeyForCheckedItem(); 1059 std::string item_key = model->GetItemKeyForCheckedItem();
1018 if (!IsASuggestionItemKey(item_key) || IsManuallyEditingSection(section)) 1060 if (!IsASuggestionItemKey(item_key) || IsManuallyEditingSection(section))
1019 return scoped_ptr<DataModelWrapper>(); 1061 return scoped_ptr<DataModelWrapper>();
1020 1062
1021 if (IsPayingWithWallet()) { 1063 if (IsPayingWithWallet()) {
1022 int index;
1023 bool success = base::StringToInt(item_key, &index);
1024 DCHECK(success);
1025
1026 if (section == SECTION_CC_BILLING) { 1064 if (section == SECTION_CC_BILLING) {
1027 return scoped_ptr<DataModelWrapper>( 1065 return scoped_ptr<DataModelWrapper>(
1028 new WalletInstrumentWrapper(wallet_items_->instruments()[index])); 1066 new WalletInstrumentWrapper(ActiveInstrument()));
1029 } 1067 }
1030 1068
1031 if (section == SECTION_SHIPPING) { 1069 if (section == SECTION_SHIPPING) {
1032 return scoped_ptr<DataModelWrapper>( 1070 return scoped_ptr<DataModelWrapper>(
1033 new WalletAddressWrapper(wallet_items_->addresses()[index])); 1071 new WalletAddressWrapper(ActiveShippingAddress()));
1034 } 1072 }
1035 1073
1036 return scoped_ptr<DataModelWrapper>(); 1074 return scoped_ptr<DataModelWrapper>();
1037 } 1075 }
1038 1076
1039 if (section == SECTION_CC) { 1077 if (section == SECTION_CC) {
1040 CreditCard* card = GetManager()->GetCreditCardByGUID(item_key); 1078 CreditCard* card = GetManager()->GetCreditCardByGUID(item_key);
1041 DCHECK(card); 1079 DCHECK(card);
1042 return scoped_ptr<DataModelWrapper>(new AutofillCreditCardWrapper(card)); 1080 return scoped_ptr<DataModelWrapper>(new AutofillCreditCardWrapper(card));
1043 } 1081 }
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
1225 const AutofillFieldType type = iter->first->type; 1263 const AutofillFieldType type = iter->first->type;
1226 string16 message = InputValidityMessage(type, iter->second); 1264 string16 message = InputValidityMessage(type, iter->second);
1227 if (!message.empty()) 1265 if (!message.empty())
1228 invalid_messages[type] = message; 1266 invalid_messages[type] = message;
1229 else 1267 else
1230 field_values[type] = iter->second; 1268 field_values[type] = iter->second;
1231 } 1269 }
1232 1270
1233 // Validate the date formed by month and year field. (Autofill dialog is 1271 // Validate the date formed by month and year field. (Autofill dialog is
1234 // never supposed to have 2-digit years, so not checked). 1272 // never supposed to have 2-digit years, so not checked).
1235 if (field_values.count(CREDIT_CARD_EXP_MONTH) && 1273 if (field_values.count(CREDIT_CARD_EXP_4_DIGIT_YEAR) &&
1236 field_values.count(CREDIT_CARD_EXP_4_DIGIT_YEAR)) { 1274 field_values.count(CREDIT_CARD_EXP_MONTH) &&
1237 if (!autofill::IsValidCreditCardExpirationDate( 1275 !IsCreditCardExpirationValid(field_values[CREDIT_CARD_EXP_4_DIGIT_YEAR],
1238 field_values[CREDIT_CARD_EXP_4_DIGIT_YEAR], 1276 field_values[CREDIT_CARD_EXP_MONTH])) {
1239 field_values[CREDIT_CARD_EXP_MONTH], 1277 invalid_messages[CREDIT_CARD_EXP_4_DIGIT_YEAR] =
1240 base::Time::Now())) { 1278 ASCIIToUTF16("more complicated message");
1241 invalid_messages[CREDIT_CARD_EXP_MONTH] = 1279 invalid_messages[CREDIT_CARD_EXP_MONTH] =
1242 ASCIIToUTF16("more complicated message"); 1280 ASCIIToUTF16("more complicated message");
1243 invalid_messages[CREDIT_CARD_EXP_4_DIGIT_YEAR] =
1244 ASCIIToUTF16("more complicated message");
1245 }
1246 } 1281 }
1247 1282
1248 // If there is a credit card number and a CVC, validate them together. 1283 // If there is a credit card number and a CVC, validate them together.
1249 if (field_values.count(CREDIT_CARD_NUMBER) && 1284 if (field_values.count(CREDIT_CARD_NUMBER) &&
1250 field_values.count(CREDIT_CARD_VERIFICATION_CODE) && 1285 field_values.count(CREDIT_CARD_VERIFICATION_CODE) &&
1251 InputValidityMessage(CREDIT_CARD_NUMBER, 1286 InputValidityMessage(CREDIT_CARD_NUMBER,
1252 field_values[CREDIT_CARD_NUMBER]).empty()) { 1287 field_values[CREDIT_CARD_NUMBER]).empty() &&
1253 if (!autofill::IsValidCreditCardSecurityCode( 1288 !autofill::IsValidCreditCardSecurityCode(
1254 field_values[CREDIT_CARD_VERIFICATION_CODE], 1289 field_values[CREDIT_CARD_VERIFICATION_CODE],
1255 field_values[CREDIT_CARD_NUMBER])) { 1290 field_values[CREDIT_CARD_NUMBER])) {
1256 invalid_messages[CREDIT_CARD_VERIFICATION_CODE] = 1291 invalid_messages[CREDIT_CARD_VERIFICATION_CODE] =
1257 ASCIIToUTF16("CVC doesn't match card type!"); 1292 ASCIIToUTF16("CVC doesn't match card type!");
1258 }
1259 } 1293 }
1260 1294
1261 // Validate the phone number against the country code of the address. 1295 // Validate the phone number against the country code of the address.
1262 if (field_values.count(ADDRESS_HOME_COUNTRY) && 1296 if (field_values.count(ADDRESS_HOME_COUNTRY) &&
1263 field_values.count(PHONE_HOME_WHOLE_NUMBER)) { 1297 field_values.count(PHONE_HOME_WHOLE_NUMBER)) {
1264 i18n::PhoneObject phone_object( 1298 i18n::PhoneObject phone_object(
1265 field_values[PHONE_HOME_WHOLE_NUMBER], 1299 field_values[PHONE_HOME_WHOLE_NUMBER],
1266 AutofillCountry::GetCountryCode( 1300 AutofillCountry::GetCountryCode(
1267 field_values[ADDRESS_HOME_COUNTRY], 1301 field_values[ADDRESS_HOME_COUNTRY],
1268 g_browser_process->GetApplicationLocale())); 1302 g_browser_process->GetApplicationLocale()));
(...skipping 1117 matching lines...) Expand 10 before | Expand all | Expand 10 after
2386 } 2420 }
2387 2421
2388 bool AutofillDialogControllerImpl::IsManuallyEditingSection( 2422 bool AutofillDialogControllerImpl::IsManuallyEditingSection(
2389 DialogSection section) const { 2423 DialogSection section) const {
2390 return IsEditingExistingData(section) || 2424 return IsEditingExistingData(section) ||
2391 SuggestionsMenuModelForSection(section)-> 2425 SuggestionsMenuModelForSection(section)->
2392 GetItemKeyForCheckedItem() == kAddNewItemKey; 2426 GetItemKeyForCheckedItem() == kAddNewItemKey;
2393 } 2427 }
2394 2428
2395 bool AutofillDialogControllerImpl::IsASuggestionItemKey( 2429 bool AutofillDialogControllerImpl::IsASuggestionItemKey(
2396 const std::string& key) { 2430 const std::string& key) const {
2397 return !key.empty() && 2431 return !key.empty() &&
2398 key != kAddNewItemKey && 2432 key != kAddNewItemKey &&
2399 key != kManageItemsKey && 2433 key != kManageItemsKey &&
2400 key != kSameAsBillingKey; 2434 key != kSameAsBillingKey;
2401 } 2435 }
2402 2436
2403 bool AutofillDialogControllerImpl::IsManuallyEditingAnySection() const { 2437 bool AutofillDialogControllerImpl::IsManuallyEditingAnySection() const {
2404 for (size_t section = SECTION_MIN; section <= SECTION_MAX; ++section) { 2438 for (size_t section = SECTION_MIN; section <= SECTION_MAX; ++section) {
2405 if (IsManuallyEditingSection(static_cast<DialogSection>(section))) 2439 if (IsManuallyEditingSection(static_cast<DialogSection>(section)))
2406 return true; 2440 return true;
(...skipping 24 matching lines...) Expand all
2431 bool AutofillDialogControllerImpl::SectionIsValid( 2465 bool AutofillDialogControllerImpl::SectionIsValid(
2432 DialogSection section) const { 2466 DialogSection section) const {
2433 if (!IsManuallyEditingSection(section)) 2467 if (!IsManuallyEditingSection(section))
2434 return true; 2468 return true;
2435 2469
2436 DetailOutputMap detail_outputs; 2470 DetailOutputMap detail_outputs;
2437 view_->GetUserInput(section, &detail_outputs); 2471 view_->GetUserInput(section, &detail_outputs);
2438 return InputsAreValid(detail_outputs, VALIDATE_EDIT).empty(); 2472 return InputsAreValid(detail_outputs, VALIDATE_EDIT).empty();
2439 } 2473 }
2440 2474
2475 bool AutofillDialogControllerImpl::IsCreditCardExpirationValid(
2476 const base::string16& year,
2477 const base::string16& month) const {
2478 // If the expiration is in the past as per the local clock, it's invalid.
2479 base::Time now = base::Time::Now();
2480 if (!autofill::IsValidCreditCardExpirationDate(year, month, now))
2481 return false;
2482
2483 if (IsPayingWithWallet() && IsEditingExistingData(SECTION_CC_BILLING)) {
2484 const wallet::WalletItems::MaskedInstrument* instrument =
2485 ActiveInstrument();
2486 const std::string& locale = g_browser_process->GetApplicationLocale();
2487 int month_int;
2488 if (base::StringToInt(month, &month_int) &&
2489 instrument->status() ==
2490 wallet::WalletItems::MaskedInstrument::EXPIRED &&
2491 year == instrument->GetInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR, locale) &&
2492 month_int == instrument->expiration_month()) {
2493 // Otherwise, if the user is editing an instrument that's deemed expired
2494 // by the Online Wallet server, mark it invalid on selection.
2495 return false;
2496 }
2497 }
2498
2499 return true;
2500 }
2501
2441 bool AutofillDialogControllerImpl::ShouldUseBillingForShipping() { 2502 bool AutofillDialogControllerImpl::ShouldUseBillingForShipping() {
2442 return SectionIsActive(SECTION_SHIPPING) && 2503 return SectionIsActive(SECTION_SHIPPING) &&
2443 suggested_shipping_.GetItemKeyForCheckedItem() == kSameAsBillingKey; 2504 suggested_shipping_.GetItemKeyForCheckedItem() == kSameAsBillingKey;
2444 } 2505 }
2445 2506
2446 bool AutofillDialogControllerImpl::ShouldSaveDetailsLocally() { 2507 bool AutofillDialogControllerImpl::ShouldSaveDetailsLocally() {
2447 // It's possible that the user checked [X] Save details locally before 2508 // It's possible that the user checked [X] Save details locally before
2448 // switching payment methods, so only ask the view whether to save details 2509 // switching payment methods, so only ask the view whether to save details
2449 // locally if that checkbox is showing (currently if not paying with wallet). 2510 // locally if that checkbox is showing (currently if not paying with wallet).
2450 // Also, if the user isn't editing any sections, there's no data to save 2511 // 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
2482 base::Bind(&UserDidOptIntoLocationServices)); 2543 base::Bind(&UserDidOptIntoLocationServices));
2483 2544
2484 GetWalletClient()->AcceptLegalDocuments( 2545 GetWalletClient()->AcceptLegalDocuments(
2485 wallet_items_->legal_documents(), 2546 wallet_items_->legal_documents(),
2486 wallet_items_->google_transaction_id(), 2547 wallet_items_->google_transaction_id(),
2487 source_url_); 2548 source_url_);
2488 2549
2489 if (AreLegalDocumentsCurrent()) 2550 if (AreLegalDocumentsCurrent())
2490 LoadRiskFingerprintData(); 2551 LoadRiskFingerprintData();
2491 2552
2492 SuggestionsMenuModel* billing = 2553 const wallet::WalletItems::MaskedInstrument* active_instrument =
2493 SuggestionsMenuModelForSection(SECTION_CC_BILLING); 2554 ActiveInstrument();
2494 int instrument_index = -1;
2495 base::StringToInt(billing->GetItemKeyForCheckedItem(), &instrument_index);
2496
2497 if (!IsManuallyEditingSection(SECTION_CC_BILLING)) { 2555 if (!IsManuallyEditingSection(SECTION_CC_BILLING)) {
2498 active_instrument_id_ = 2556 active_instrument_id_ = active_instrument->object_id();
2499 wallet_items_->instruments()[instrument_index]->object_id();
2500 DCHECK(!active_instrument_id_.empty()); 2557 DCHECK(!active_instrument_id_.empty());
2501 } 2558 }
2502 2559
2503 SuggestionsMenuModel* shipping = 2560 const wallet::Address* active_address = ActiveShippingAddress();
2504 SuggestionsMenuModelForSection(SECTION_SHIPPING);
2505 int address_index = -1;
2506 base::StringToInt(shipping->GetItemKeyForCheckedItem(), &address_index);
2507
2508 if (!IsManuallyEditingSection(SECTION_SHIPPING) && 2561 if (!IsManuallyEditingSection(SECTION_SHIPPING) &&
2509 !ShouldUseBillingForShipping()) { 2562 !ShouldUseBillingForShipping()) {
2510 active_address_id_ = 2563 active_address_id_ = active_address->object_id();
2511 wallet_items_->addresses()[address_index]->object_id();
2512 DCHECK(!active_address_id_.empty()); 2564 DCHECK(!active_address_id_.empty());
2513 } 2565 }
2514 2566
2515 scoped_ptr<wallet::Instrument> inputted_instrument = 2567 scoped_ptr<wallet::Instrument> inputted_instrument =
2516 CreateTransientInstrument(); 2568 CreateTransientInstrument();
2517 scoped_ptr<wallet::WalletClient::UpdateInstrumentRequest> update_request = 2569 scoped_ptr<wallet::WalletClient::UpdateInstrumentRequest> update_request =
2518 CreateUpdateInstrumentRequest( 2570 CreateUpdateInstrumentRequest(
2519 inputted_instrument.get(), 2571 inputted_instrument.get(),
2520 !IsEditingExistingData(SECTION_CC_BILLING) ? std::string() : 2572 !IsEditingExistingData(SECTION_CC_BILLING) ? std::string() :
2521 wallet_items_->instruments()[instrument_index]->object_id()); 2573 active_instrument->object_id());
2522 2574
2523 scoped_ptr<wallet::Address> inputted_address; 2575 scoped_ptr<wallet::Address> inputted_address;
2524 if (active_address_id_.empty()) { 2576 if (active_address_id_.empty()) {
2525 if (ShouldUseBillingForShipping()) { 2577 if (ShouldUseBillingForShipping()) {
2526 const wallet::Address& address = inputted_instrument ? 2578 const wallet::Address& address = inputted_instrument ?
2527 inputted_instrument->address() : 2579 inputted_instrument->address() : active_instrument->address();
2528 wallet_items_->instruments()[instrument_index]->address();
2529 // Try to find an exact matched shipping address and use it for shipping, 2580 // Try to find an exact matched shipping address and use it for shipping,
2530 // otherwise save it as a new shipping address. http://crbug.com/225442 2581 // otherwise save it as a new shipping address. http://crbug.com/225442
2531 const wallet::Address* duplicated_address = 2582 const wallet::Address* duplicated_address =
2532 FindDuplicateAddress(wallet_items_->addresses(), address); 2583 FindDuplicateAddress(wallet_items_->addresses(), address);
2533 if (duplicated_address) { 2584 if (duplicated_address) {
2534 active_address_id_ = duplicated_address->object_id(); 2585 active_address_id_ = duplicated_address->object_id();
2535 DCHECK(!active_address_id_.empty()); 2586 DCHECK(!active_address_id_.empty());
2536 } else { 2587 } else {
2537 inputted_address.reset(new wallet::Address(address)); 2588 inputted_address.reset(new wallet::Address(address));
2538 DCHECK(inputted_address->object_id().empty()); 2589 DCHECK(inputted_address->object_id().empty());
2539 } 2590 }
2540 } else { 2591 } else {
2541 inputted_address = CreateTransientAddress(); 2592 inputted_address = CreateTransientAddress();
2542 if (IsEditingExistingData(SECTION_SHIPPING)) { 2593 if (IsEditingExistingData(SECTION_SHIPPING)) {
2543 inputted_address->set_object_id( 2594 inputted_address->set_object_id(active_address->object_id());
2544 wallet_items_->addresses()[address_index]->object_id());
2545 DCHECK(!inputted_address->object_id().empty()); 2595 DCHECK(!inputted_address->object_id().empty());
2546 } 2596 }
2547 } 2597 }
2548 } 2598 }
2549 2599
2550 // If there's neither an address nor instrument to save, |GetFullWallet()| 2600 // If there's neither an address nor instrument to save, |GetFullWallet()|
2551 // is called when the risk fingerprint is loaded. 2601 // is called when the risk fingerprint is loaded.
2552 if (!active_instrument_id_.empty() && !active_address_id_.empty()) 2602 if (!active_instrument_id_.empty() && !active_address_id_.empty())
2553 return; 2603 return;
2554 2604
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
2909 AutofillMetrics::DIALOG_USER_SIGNED_IN_NO_WALLET_NO_AUTOFILL; 2959 AutofillMetrics::DIALOG_USER_SIGNED_IN_NO_WALLET_NO_AUTOFILL;
2910 } 2960 }
2911 2961
2912 // Has Wallet items. 2962 // Has Wallet items.
2913 return has_autofill_profiles ? 2963 return has_autofill_profiles ?
2914 AutofillMetrics::DIALOG_USER_SIGNED_IN_HAS_WALLET_HAS_AUTOFILL : 2964 AutofillMetrics::DIALOG_USER_SIGNED_IN_HAS_WALLET_HAS_AUTOFILL :
2915 AutofillMetrics::DIALOG_USER_SIGNED_IN_HAS_WALLET_NO_AUTOFILL; 2965 AutofillMetrics::DIALOG_USER_SIGNED_IN_HAS_WALLET_NO_AUTOFILL;
2916 } 2966 }
2917 2967
2918 } // namespace autofill 2968 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698