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

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

Issue 14425010: Handle expired Autofill credit cards in autofill dialog (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 years, 7 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 <string> 8 #include <string>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 634
635 legal_document_link_ranges_.clear(); 635 legal_document_link_ranges_.clear();
636 for (size_t i = 0; i < documents.size(); ++i) { 636 for (size_t i = 0; i < documents.size(); ++i) {
637 size_t link_start = text.find(documents[i]->display_name()); 637 size_t link_start = text.find(documents[i]->display_name());
638 legal_document_link_ranges_.push_back(ui::Range( 638 legal_document_link_ranges_.push_back(ui::Range(
639 link_start, link_start + documents[i]->display_name().size())); 639 link_start, link_start + documents[i]->display_name().size()));
640 } 640 }
641 legal_documents_text_ = text; 641 legal_documents_text_ = text;
642 } 642 }
643 643
644 void AutofillDialogControllerImpl::ResetManualInputForSection( 644 void AutofillDialogControllerImpl::PrepareDetailInputsForSection(
645 DialogSection section) { 645 DialogSection section) {
646 // Reset all previously entered data and stop editing |section|.
646 DetailInputs* inputs = MutableRequestedFieldsForSection(section); 647 DetailInputs* inputs = MutableRequestedFieldsForSection(section);
647 for (size_t i = 0; i < inputs->size(); ++i) 648 for (size_t i = 0; i < inputs->size(); ++i) {
648 (*inputs)[i].initial_value.clear(); 649 (*inputs)[i].initial_value.clear();
650 }
649 section_editing_state_[section] = false; 651 section_editing_state_[section] = false;
652
653 // If the chosen item in |model| yields an empty suggestion text, it is
654 // invalid. In this case, show the editing UI with invalid fields highlighted.
655 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section);
656 if (IsASuggestionItemKey(model->GetItemKeyForCheckedItem()) &&
657 SuggestionTextForSection(section).empty()) {
658 scoped_ptr<DataModelWrapper> wrapper = CreateWrapper(section);
659 wrapper->FillInputs(MutableRequestedFieldsForSection(section));
660 section_editing_state_[section] = true;
661 }
662
663 if (view_)
664 view_->UpdateSection(section);
650 } 665 }
651 666
652 const DetailInputs& AutofillDialogControllerImpl::RequestedFieldsForSection( 667 const DetailInputs& AutofillDialogControllerImpl::RequestedFieldsForSection(
653 DialogSection section) const { 668 DialogSection section) const {
654 switch (section) { 669 switch (section) {
655 case SECTION_EMAIL: 670 case SECTION_EMAIL:
656 return requested_email_fields_; 671 return requested_email_fields_;
657 case SECTION_CC: 672 case SECTION_CC:
658 return requested_cc_fields_; 673 return requested_cc_fields_;
659 case SECTION_BILLING: 674 case SECTION_BILLING:
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 ExtraSuggestionIconForSection(section), 759 ExtraSuggestionIconForSection(section),
745 EditEnabledForSection(section)); 760 EditEnabledForSection(section));
746 } 761 }
747 762
748 string16 AutofillDialogControllerImpl::SuggestionTextForSection( 763 string16 AutofillDialogControllerImpl::SuggestionTextForSection(
749 DialogSection section) { 764 DialogSection section) {
750 string16 action_text = RequiredActionTextForSection(section); 765 string16 action_text = RequiredActionTextForSection(section);
751 if (!action_text.empty()) 766 if (!action_text.empty())
752 return action_text; 767 return action_text;
753 768
754 // When the user has clicked 'edit', don't show a suggestion (even though 769 // When the user has clicked 'edit' or a suggestion is somehow invalid (e.g. a
755 // there is a profile selected in the model). 770 // user selects a credit card that has expired), don't show a suggestion (even
771 // though there is a profile selected in the model).
756 if (section_editing_state_[section]) 772 if (section_editing_state_[section])
757 return string16(); 773 return string16();
758 774
759 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); 775 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section);
760 std::string item_key = model->GetItemKeyForCheckedItem(); 776 std::string item_key = model->GetItemKeyForCheckedItem();
761 if (item_key == kSameAsBillingKey) { 777 if (item_key == kSameAsBillingKey) {
762 return l10n_util::GetStringUTF16( 778 return l10n_util::GetStringUTF16(
763 IDS_AUTOFILL_DIALOG_USING_BILLING_FOR_SHIPPING); 779 IDS_AUTOFILL_DIALOG_USING_BILLING_FOR_SHIPPING);
764 } 780 }
765 781
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
895 } 911 }
896 912
897 if (section == SECTION_CC_BILLING && IsSubmitPausedOn(wallet::VERIFY_CVV)) 913 if (section == SECTION_CC_BILLING && IsSubmitPausedOn(wallet::VERIFY_CVV))
898 return false; 914 return false;
899 915
900 return true; 916 return true;
901 } 917 }
902 918
903 void AutofillDialogControllerImpl::EditClickedForSection( 919 void AutofillDialogControllerImpl::EditClickedForSection(
904 DialogSection section) { 920 DialogSection section) {
905 DetailInputs* inputs = MutableRequestedFieldsForSection(section); 921 scoped_ptr<DataModelWrapper> wrapper = CreateWrapper(section);
906 scoped_ptr<DataModelWrapper> model = CreateWrapper(section); 922 wrapper->FillInputs(MutableRequestedFieldsForSection(section));
907 model->FillInputs(inputs);
908 section_editing_state_[section] = true; 923 section_editing_state_[section] = true;
909 view_->UpdateSection(section); 924 view_->UpdateSection(section);
910 925
911 GetMetricLogger().LogDialogUiEvent( 926 GetMetricLogger().LogDialogUiEvent(
912 dialog_type_, DialogSectionToUiEditEvent(section)); 927 dialog_type_, DialogSectionToUiEditEvent(section));
913 } 928 }
914 929
915 void AutofillDialogControllerImpl::EditCancelledForSection( 930 void AutofillDialogControllerImpl::EditCancelledForSection(
916 DialogSection section) { 931 DialogSection section) {
917 ResetManualInputForSection(section); 932 PrepareDetailInputsForSection(section);
918 view_->UpdateSection(section);
919 } 933 }
920 934
921 gfx::Image AutofillDialogControllerImpl::IconForField( 935 gfx::Image AutofillDialogControllerImpl::IconForField(
922 AutofillFieldType type, const string16& user_input) const { 936 AutofillFieldType type, const string16& user_input) const {
923 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 937 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
924 if (type == CREDIT_CARD_VERIFICATION_CODE) 938 if (type == CREDIT_CARD_VERIFICATION_CODE)
925 return rb.GetImageNamed(IDR_CREDIT_CARD_CVC_HINT); 939 return rb.GetImageNamed(IDR_CREDIT_CARD_CVC_HINT);
926 940
927 // For the credit card, we show a few grayscale images, and possibly one 941 // For the credit card, we show a few grayscale images, and possibly one
928 // color image if |user_input| is a valid card number. 942 // color image if |user_input| is a valid card number.
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after
1388 chrome::kAutofillSubPage)); 1402 chrome::kAutofillSubPage));
1389 } else { 1403 } else {
1390 // TODO(estade): show a wallet URL. 1404 // TODO(estade): show a wallet URL.
1391 NOTIMPLEMENTED(); 1405 NOTIMPLEMENTED();
1392 } 1406 }
1393 1407
1394 return; 1408 return;
1395 } 1409 }
1396 1410
1397 model->SetCheckedIndex(index); 1411 model->SetCheckedIndex(index);
1398 EditCancelledForSection(SectionForSuggestionsMenuModel(*model)); 1412
1413 const DialogSection section = SectionForSuggestionsMenuModel(*model);
1414 PrepareDetailInputsForSection(section);
1399 1415
1400 LogSuggestionItemSelectedMetric(*model); 1416 LogSuggestionItemSelectedMetric(*model);
1401 } 1417 }
1402 1418
1403 //////////////////////////////////////////////////////////////////////////////// 1419 ////////////////////////////////////////////////////////////////////////////////
1404 // wallet::WalletClientDelegate implementation. 1420 // wallet::WalletClientDelegate implementation.
1405 1421
1406 const AutofillMetrics& AutofillDialogControllerImpl::GetMetricLogger() const { 1422 const AutofillMetrics& AutofillDialogControllerImpl::GetMetricLogger() const {
1407 return metric_logger_; 1423 return metric_logger_;
1408 } 1424 }
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
1565 // PersonalDataManagerObserver implementation. 1581 // PersonalDataManagerObserver implementation.
1566 1582
1567 void AutofillDialogControllerImpl::OnPersonalDataChanged() { 1583 void AutofillDialogControllerImpl::OnPersonalDataChanged() {
1568 SuggestionsUpdated(); 1584 SuggestionsUpdated();
1569 } 1585 }
1570 1586
1571 //////////////////////////////////////////////////////////////////////////////// 1587 ////////////////////////////////////////////////////////////////////////////////
1572 // AccountChooserModelDelegate implementation. 1588 // AccountChooserModelDelegate implementation.
1573 1589
1574 void AutofillDialogControllerImpl::AccountChoiceChanged() { 1590 void AutofillDialogControllerImpl::AccountChoiceChanged() {
1575 // Whenever the user changes the account, all manual inputs should be reset.
1576 ResetManualInputForSection(SECTION_EMAIL);
1577 ResetManualInputForSection(SECTION_CC);
1578 ResetManualInputForSection(SECTION_BILLING);
1579 ResetManualInputForSection(SECTION_CC_BILLING);
1580 ResetManualInputForSection(SECTION_SHIPPING);
Dan Beam 2013/05/01 00:46:22 these weren't necessary
1581
1582 if (is_submitting_) 1591 if (is_submitting_)
1583 GetWalletClient()->CancelRequests(); 1592 GetWalletClient()->CancelRequests();
1584 1593
1585 SetIsSubmitting(false); 1594 SetIsSubmitting(false);
1586 1595
1587 if (!signin_helper_ && account_chooser_model_.WalletIsSelected()) { 1596 if (!signin_helper_ && account_chooser_model_.WalletIsSelected()) {
1588 if (account_chooser_model_.IsActiveWalletAccountSelected()) { 1597 if (account_chooser_model_.IsActiveWalletAccountSelected()) {
1589 // If the user has chosen an already active Wallet account, and we don't 1598 // If the user has chosen an already active Wallet account, and we don't
1590 // have the Wallet items, an attempt to fetch the Wallet data is made to 1599 // have the Wallet items, an attempt to fetch the Wallet data is made to
1591 // see if the user is still signed in. This will trigger a passive sign-in 1600 // see if the user is still signed in. This will trigger a passive sign-in
1592 // if required. 1601 // if required.
1593 if (!wallet_items_) 1602 if (!wallet_items_)
1594 GetWalletItems(); 1603 GetWalletItems();
1595 else 1604 else
1596 SignedInStateUpdated(); 1605 SignedInStateUpdated();
1597 } else { 1606 } else {
1598 // TODO(aruslan): trigger the automatic sign-in process. 1607 // TODO(aruslan): trigger the automatic sign-in process.
1599 LOG(ERROR) << "failed to initiate an automatic sign-in"; 1608 LOG(ERROR) << "failed to initiate an automatic sign-in";
1600 OnWalletSigninError(); 1609 OnWalletSigninError();
1601 } 1610 }
1602 } 1611 }
1603 1612
1604 SuggestionsUpdated(); 1613 SuggestionsUpdated();
Dan Beam 2013/05/01 00:46:22 as this calls PrepareDetailInputsForSection() on a
1605 UpdateAccountChooserView(); 1614 UpdateAccountChooserView();
1606 } 1615 }
1607 1616
1608 void AutofillDialogControllerImpl::UpdateAccountChooserView() { 1617 void AutofillDialogControllerImpl::UpdateAccountChooserView() {
1609 if (view_) { 1618 if (view_) {
1610 view_->UpdateAccountChooser(); 1619 view_->UpdateAccountChooser();
1611 view_->UpdateNotificationArea(); 1620 view_->UpdateNotificationArea();
1612 } 1621 }
1613 } 1622 }
1614 1623
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1727 } 1736 }
1728 1737
1729 const std::vector<wallet::Address*>& addresses = 1738 const std::vector<wallet::Address*>& addresses =
1730 wallet_items_->addresses(); 1739 wallet_items_->addresses();
1731 for (size_t i = 0; i < addresses.size(); ++i) { 1740 for (size_t i = 0; i < addresses.size(); ++i) {
1732 // TODO(dbeam): respect the default instrument ID. http://crbug.com/232954 1741 // TODO(dbeam): respect the default instrument ID. http://crbug.com/232954
1733 suggested_shipping_.AddKeyedItemWithSublabel( 1742 suggested_shipping_.AddKeyedItemWithSublabel(
1734 base::IntToString(i), 1743 base::IntToString(i),
1735 addresses[i]->DisplayName(), 1744 addresses[i]->DisplayName(),
1736 addresses[i]->DisplayNameDetail()); 1745 addresses[i]->DisplayNameDetail());
1737
1738 } 1746 }
1739 1747
1740 if (!IsSubmitPausedOn(wallet::VERIFY_CVV)) { 1748 if (!IsSubmitPausedOn(wallet::VERIFY_CVV)) {
1741 const std::vector<wallet::WalletItems::MaskedInstrument*>& instruments = 1749 const std::vector<wallet::WalletItems::MaskedInstrument*>& instruments =
1742 wallet_items_->instruments(); 1750 wallet_items_->instruments();
1743 for (size_t i = 0; i < instruments.size(); ++i) { 1751 for (size_t i = 0; i < instruments.size(); ++i) {
1744 // TODO(dbeam): respect the default address ID. http://crbug.com/232954 1752 // TODO(dbeam): respect the default address ID. http://crbug.com/232954
1745 suggested_cc_billing_.AddKeyedItemWithSublabelAndIcon( 1753 suggested_cc_billing_.AddKeyedItemWithSublabelAndIcon(
1746 base::IntToString(i), 1754 base::IntToString(i),
1747 instruments[i]->DisplayName(), 1755 instruments[i]->DisplayName(),
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1820 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADD_SHIPPING_ADDRESS)); 1828 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADD_SHIPPING_ADDRESS));
1821 suggested_shipping_.AddKeyedItem( 1829 suggested_shipping_.AddKeyedItem(
1822 kManageItemsKey, 1830 kManageItemsKey,
1823 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_MANAGE_SHIPPING_ADDRESS)); 1831 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_MANAGE_SHIPPING_ADDRESS));
1824 1832
1825 // Default shipping address is the first suggestion, if one exists. Otherwise 1833 // Default shipping address is the first suggestion, if one exists. Otherwise
1826 // it's the "Use shipping for billing" item. 1834 // it's the "Use shipping for billing" item.
1827 const std::string& first_real_suggestion_item_key = 1835 const std::string& first_real_suggestion_item_key =
1828 suggested_shipping_.GetItemKeyAt(1); 1836 suggested_shipping_.GetItemKeyAt(1);
1829 if (IsASuggestionItemKey(first_real_suggestion_item_key)) 1837 if (IsASuggestionItemKey(first_real_suggestion_item_key))
1830 suggested_shipping_.SetCheckedItem(first_real_suggestion_item_key); 1838 suggested_shipping_.SetCheckedItem(first_real_suggestion_item_key);
1831 1839
1832 if (view_) 1840 if (view_)
1833 view_->ModelChanged(); 1841 view_->ModelChanged();
1842
1843 for (size_t section = SECTION_MIN; section <= SECTION_MAX; ++section) {
1844 PrepareDetailInputsForSection(static_cast<DialogSection>(section));
1845 }
1834 } 1846 }
1835 1847
1848
1836 bool AutofillDialogControllerImpl::IsCompleteProfile( 1849 bool AutofillDialogControllerImpl::IsCompleteProfile(
1837 const AutofillProfile& profile) { 1850 const AutofillProfile& profile) {
1838 const std::string app_locale = g_browser_process->GetApplicationLocale(); 1851 const std::string app_locale = g_browser_process->GetApplicationLocale();
1839 for (size_t i = 0; i < requested_shipping_fields_.size(); ++i) { 1852 for (size_t i = 0; i < requested_shipping_fields_.size(); ++i) {
1840 AutofillFieldType type = requested_shipping_fields_[i].type; 1853 AutofillFieldType type = requested_shipping_fields_[i].type;
1841 if (type != ADDRESS_HOME_LINE2 && 1854 if (type != ADDRESS_HOME_LINE2 &&
1842 profile.GetInfo(type, app_locale).empty()) { 1855 profile.GetInfo(type, app_locale).empty()) {
1843 return false; 1856 return false;
1844 } 1857 }
1845 } 1858 }
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after
2308 void AutofillDialogControllerImpl::LogSuggestionItemSelectedMetric( 2321 void AutofillDialogControllerImpl::LogSuggestionItemSelectedMetric(
2309 const SuggestionsMenuModel& model) { 2322 const SuggestionsMenuModel& model) {
2310 DialogSection section = SectionForSuggestionsMenuModel(model); 2323 DialogSection section = SectionForSuggestionsMenuModel(model);
2311 2324
2312 AutofillMetrics::DialogUiEvent dialog_ui_event; 2325 AutofillMetrics::DialogUiEvent dialog_ui_event;
2313 if (model.GetItemKeyForCheckedItem() == kAddNewItemKey) { 2326 if (model.GetItemKeyForCheckedItem() == kAddNewItemKey) {
2314 // Selected to add a new item. 2327 // Selected to add a new item.
2315 dialog_ui_event = DialogSectionToUiItemAddedEvent(section); 2328 dialog_ui_event = DialogSectionToUiItemAddedEvent(section);
2316 } else if (IsASuggestionItemKey(model.GetItemKeyForCheckedItem())) { 2329 } else if (IsASuggestionItemKey(model.GetItemKeyForCheckedItem())) {
2317 // Selected an existing item. 2330 // Selected an existing item.
2318 DCHECK(!section_editing_state_[section]);
2319 dialog_ui_event = DialogSectionToUiSelectionChangedEvent(section); 2331 dialog_ui_event = DialogSectionToUiSelectionChangedEvent(section);
2320 } else { 2332 } else {
2321 // TODO(estade): add logging for "Manage items" or "Use billing for 2333 // TODO(estade): add logging for "Manage items" or "Use billing for
2322 // shipping"? 2334 // shipping"?
2323 return; 2335 return;
2324 } 2336 }
2325 2337
2326 GetMetricLogger().LogDialogUiEvent(dialog_type_, dialog_ui_event); 2338 GetMetricLogger().LogDialogUiEvent(dialog_type_, dialog_ui_event);
2327 } 2339 }
2328 2340
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2373 url, 2385 url,
2374 content::PAGE_TRANSITION_AUTO_BOOKMARK); 2386 content::PAGE_TRANSITION_AUTO_BOOKMARK);
2375 params.disposition = NEW_FOREGROUND_TAB; 2387 params.disposition = NEW_FOREGROUND_TAB;
2376 chrome::Navigate(&params); 2388 chrome::Navigate(&params);
2377 #else 2389 #else
2378 // TODO(estade): use TabModelList? 2390 // TODO(estade): use TabModelList?
2379 #endif 2391 #endif
2380 } 2392 }
2381 2393
2382 } // namespace autofill 2394 } // namespace autofill
OLDNEW
« no previous file with comments | « chrome/browser/ui/autofill/autofill_dialog_controller_impl.h ('k') | chrome/browser/ui/autofill/data_model_wrapper.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698