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

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 356 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 arraysize(kCCInputs), 367 arraysize(kCCInputs),
368 &requested_cc_billing_fields_); 368 &requested_cc_billing_fields_);
369 BuildInputs(kBillingInputs, 369 BuildInputs(kBillingInputs,
370 arraysize(kBillingInputs), 370 arraysize(kBillingInputs),
371 &requested_cc_billing_fields_); 371 &requested_cc_billing_fields_);
372 372
373 BuildInputs(kShippingInputs, 373 BuildInputs(kShippingInputs,
374 arraysize(kShippingInputs), 374 arraysize(kShippingInputs),
375 &requested_shipping_fields_); 375 &requested_shipping_fields_);
376 376
377 SuggestionsUpdated();
378
379 // TODO(estade): don't show the dialog if the site didn't specify the right 377 // TODO(estade): don't show the dialog if the site didn't specify the right
380 // fields. First we must figure out what the "right" fields are. 378 // fields. First we must figure out what the "right" fields are.
381 view_.reset(CreateView()); 379 view_.reset(CreateView());
382 view_->Show(); 380 view_->Show();
383 GetManager()->AddObserver(this); 381 GetManager()->AddObserver(this);
384 382
383 // This should be done while |view_| is non-NULL.
Evan Stade 2013/04/30 19:03:10 dislike. The controller should not need to update
Dan Beam 2013/05/01 00:43:09 Reverted.
384 SuggestionsUpdated();
385
385 // Try to see if the user is already signed-in. 386 // Try to see if the user is already signed-in.
386 // If signed-in, fetch the user's Wallet data. 387 // If signed-in, fetch the user's Wallet data.
387 // Otherwise, see if the user could be signed in passively. 388 // Otherwise, see if the user could be signed in passively.
388 // TODO(aruslan): UMA metrics for sign-in. 389 // TODO(aruslan): UMA metrics for sign-in.
389 if (account_chooser_model_.WalletIsSelected()) 390 if (account_chooser_model_.WalletIsSelected())
390 GetWalletItems(); 391 GetWalletItems();
391 else 392 else
392 LogDialogLatencyToShow(); 393 LogDialogLatencyToShow();
393 } 394 }
394 395
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
634 635
635 legal_document_link_ranges_.clear(); 636 legal_document_link_ranges_.clear();
636 for (size_t i = 0; i < documents.size(); ++i) { 637 for (size_t i = 0; i < documents.size(); ++i) {
637 size_t link_start = text.find(documents[i]->display_name()); 638 size_t link_start = text.find(documents[i]->display_name());
638 legal_document_link_ranges_.push_back(ui::Range( 639 legal_document_link_ranges_.push_back(ui::Range(
639 link_start, link_start + documents[i]->display_name().size())); 640 link_start, link_start + documents[i]->display_name().size()));
640 } 641 }
641 legal_documents_text_ = text; 642 legal_documents_text_ = text;
642 } 643 }
643 644
645 void AutofillDialogControllerImpl::ShowEditingMode(DialogSection section) {
646 scoped_ptr<DataModelWrapper> wrapper = CreateWrapper(section);
647 wrapper->FillInputs(MutableRequestedFieldsForSection(section));
648 section_editing_state_[section] = true;
649 view_->UpdateSection(section);
650 }
651
644 void AutofillDialogControllerImpl::ResetManualInputForSection( 652 void AutofillDialogControllerImpl::ResetManualInputForSection(
645 DialogSection section) { 653 DialogSection section) {
646 DetailInputs* inputs = MutableRequestedFieldsForSection(section); 654 DetailInputs* inputs = MutableRequestedFieldsForSection(section);
647 for (size_t i = 0; i < inputs->size(); ++i) 655 for (size_t i = 0; i < inputs->size(); ++i)
648 (*inputs)[i].initial_value.clear(); 656 (*inputs)[i].initial_value.clear();
657 // TODO(dbeam): why is this here rather than in EditCancelledForSection()?
649 section_editing_state_[section] = false; 658 section_editing_state_[section] = false;
650 } 659 }
651 660
652 const DetailInputs& AutofillDialogControllerImpl::RequestedFieldsForSection( 661 const DetailInputs& AutofillDialogControllerImpl::RequestedFieldsForSection(
653 DialogSection section) const { 662 DialogSection section) const {
654 switch (section) { 663 switch (section) {
655 case SECTION_EMAIL: 664 case SECTION_EMAIL:
656 return requested_email_fields_; 665 return requested_email_fields_;
657 case SECTION_CC: 666 case SECTION_CC:
658 return requested_cc_fields_; 667 return requested_cc_fields_;
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 ExtraSuggestionIconForSection(section), 753 ExtraSuggestionIconForSection(section),
745 EditEnabledForSection(section)); 754 EditEnabledForSection(section));
746 } 755 }
747 756
748 string16 AutofillDialogControllerImpl::SuggestionTextForSection( 757 string16 AutofillDialogControllerImpl::SuggestionTextForSection(
749 DialogSection section) { 758 DialogSection section) {
750 string16 action_text = RequiredActionTextForSection(section); 759 string16 action_text = RequiredActionTextForSection(section);
751 if (!action_text.empty()) 760 if (!action_text.empty())
752 return action_text; 761 return action_text;
753 762
754 // When the user has clicked 'edit', don't show a suggestion (even though 763 // When the user has clicked 'edit' or a suggestion is somehow invalid (e.g. a
755 // there is a profile selected in the model). 764 // user selects a credit card that has expired), don't show a suggestion (even
765 // though there is a profile selected in the model).
756 if (section_editing_state_[section]) 766 if (section_editing_state_[section])
757 return string16(); 767 return string16();
758 768
759 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); 769 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section);
760 std::string item_key = model->GetItemKeyForCheckedItem(); 770 std::string item_key = model->GetItemKeyForCheckedItem();
761 if (item_key == kSameAsBillingKey) { 771 if (item_key == kSameAsBillingKey) {
762 return l10n_util::GetStringUTF16( 772 return l10n_util::GetStringUTF16(
763 IDS_AUTOFILL_DIALOG_USING_BILLING_FOR_SHIPPING); 773 IDS_AUTOFILL_DIALOG_USING_BILLING_FOR_SHIPPING);
764 } 774 }
765 775
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
895 } 905 }
896 906
897 if (section == SECTION_CC_BILLING && IsSubmitPausedOn(wallet::VERIFY_CVV)) 907 if (section == SECTION_CC_BILLING && IsSubmitPausedOn(wallet::VERIFY_CVV))
898 return false; 908 return false;
899 909
900 return true; 910 return true;
901 } 911 }
902 912
903 void AutofillDialogControllerImpl::EditClickedForSection( 913 void AutofillDialogControllerImpl::EditClickedForSection(
904 DialogSection section) { 914 DialogSection section) {
905 DetailInputs* inputs = MutableRequestedFieldsForSection(section); 915 ShowEditingMode(section);
906 scoped_ptr<DataModelWrapper> model = CreateWrapper(section);
907 model->FillInputs(inputs);
908 section_editing_state_[section] = true;
909 view_->UpdateSection(section);
910
911 GetMetricLogger().LogDialogUiEvent( 916 GetMetricLogger().LogDialogUiEvent(
912 dialog_type_, DialogSectionToUiEditEvent(section)); 917 dialog_type_, DialogSectionToUiEditEvent(section));
913 } 918 }
914 919
915 void AutofillDialogControllerImpl::EditCancelledForSection( 920 void AutofillDialogControllerImpl::EditCancelledForSection(
916 DialogSection section) { 921 DialogSection section) {
917 ResetManualInputForSection(section); 922 ResetManualInputForSection(section);
918 view_->UpdateSection(section); 923 view_->UpdateSection(section);
919 } 924 }
920 925
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after
1388 chrome::kAutofillSubPage)); 1393 chrome::kAutofillSubPage));
1389 } else { 1394 } else {
1390 // TODO(estade): show a wallet URL. 1395 // TODO(estade): show a wallet URL.
1391 NOTIMPLEMENTED(); 1396 NOTIMPLEMENTED();
1392 } 1397 }
1393 1398
1394 return; 1399 return;
1395 } 1400 }
1396 1401
1397 model->SetCheckedIndex(index); 1402 model->SetCheckedIndex(index);
1398 EditCancelledForSection(SectionForSuggestionsMenuModel(*model)); 1403 const DialogSection section = SectionForSuggestionsMenuModel(*model);
1404 EditCancelledForSection(section);
1405
1406 // If a user chooses a real suggestion (not Add/Edit) and the suggestion text
1407 // is empty, it's invalid. Show the editing UI and highlight invalid fields.
1408 if (IsASuggestionItemKey(model->GetItemKeyForCheckedItem()) &&
1409 SuggestionTextForSection(section).empty()) {
1410 ShowEditingMode(section);
1411 }
1399 1412
1400 LogSuggestionItemSelectedMetric(*model); 1413 LogSuggestionItemSelectedMetric(*model);
1401 } 1414 }
1402 1415
1403 //////////////////////////////////////////////////////////////////////////////// 1416 ////////////////////////////////////////////////////////////////////////////////
1404 // wallet::WalletClientDelegate implementation. 1417 // wallet::WalletClientDelegate implementation.
1405 1418
1406 const AutofillMetrics& AutofillDialogControllerImpl::GetMetricLogger() const { 1419 const AutofillMetrics& AutofillDialogControllerImpl::GetMetricLogger() const {
1407 return metric_logger_; 1420 return metric_logger_;
1408 } 1421 }
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
1566 1579
1567 void AutofillDialogControllerImpl::OnPersonalDataChanged() { 1580 void AutofillDialogControllerImpl::OnPersonalDataChanged() {
1568 SuggestionsUpdated(); 1581 SuggestionsUpdated();
1569 } 1582 }
1570 1583
1571 //////////////////////////////////////////////////////////////////////////////// 1584 ////////////////////////////////////////////////////////////////////////////////
1572 // AccountChooserModelDelegate implementation. 1585 // AccountChooserModelDelegate implementation.
1573 1586
1574 void AutofillDialogControllerImpl::AccountChoiceChanged() { 1587 void AutofillDialogControllerImpl::AccountChoiceChanged() {
1575 // Whenever the user changes the account, all manual inputs should be reset. 1588 // Whenever the user changes the account, all manual inputs should be reset.
1576 ResetManualInputForSection(SECTION_EMAIL); 1589 for (size_t section = SECTION_MIN; section <= SECTION_MAX; ++section) {
1577 ResetManualInputForSection(SECTION_CC); 1590 ResetManualInputForSection(static_cast<DialogSection>(section));
1578 ResetManualInputForSection(SECTION_BILLING); 1591 }
1579 ResetManualInputForSection(SECTION_CC_BILLING);
1580 ResetManualInputForSection(SECTION_SHIPPING);
1581 1592
1582 if (is_submitting_) 1593 if (is_submitting_)
1583 GetWalletClient()->CancelRequests(); 1594 GetWalletClient()->CancelRequests();
1584 1595
1585 SetIsSubmitting(false); 1596 SetIsSubmitting(false);
1586 1597
1587 if (!signin_helper_ && account_chooser_model_.WalletIsSelected()) { 1598 if (!signin_helper_ && account_chooser_model_.WalletIsSelected()) {
1588 if (account_chooser_model_.IsActiveWalletAccountSelected()) { 1599 if (account_chooser_model_.IsActiveWalletAccountSelected()) {
1589 // If the user has chosen an already active Wallet account, and we don't 1600 // 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 1601 // have the Wallet items, an attempt to fetch the Wallet data is made to
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
1727 } 1738 }
1728 1739
1729 const std::vector<wallet::Address*>& addresses = 1740 const std::vector<wallet::Address*>& addresses =
1730 wallet_items_->addresses(); 1741 wallet_items_->addresses();
1731 for (size_t i = 0; i < addresses.size(); ++i) { 1742 for (size_t i = 0; i < addresses.size(); ++i) {
1732 // TODO(dbeam): respect the default instrument ID. http://crbug.com/232954 1743 // TODO(dbeam): respect the default instrument ID. http://crbug.com/232954
1733 suggested_shipping_.AddKeyedItemWithSublabel( 1744 suggested_shipping_.AddKeyedItemWithSublabel(
1734 base::IntToString(i), 1745 base::IntToString(i),
1735 addresses[i]->DisplayName(), 1746 addresses[i]->DisplayName(),
1736 addresses[i]->DisplayNameDetail()); 1747 addresses[i]->DisplayNameDetail());
1737
1738 } 1748 }
1739 1749
1740 if (!IsSubmitPausedOn(wallet::VERIFY_CVV)) { 1750 if (!IsSubmitPausedOn(wallet::VERIFY_CVV)) {
1741 const std::vector<wallet::WalletItems::MaskedInstrument*>& instruments = 1751 const std::vector<wallet::WalletItems::MaskedInstrument*>& instruments =
1742 wallet_items_->instruments(); 1752 wallet_items_->instruments();
1743 for (size_t i = 0; i < instruments.size(); ++i) { 1753 for (size_t i = 0; i < instruments.size(); ++i) {
1744 // TODO(dbeam): respect the default address ID. http://crbug.com/232954 1754 // TODO(dbeam): respect the default address ID. http://crbug.com/232954
1745 suggested_cc_billing_.AddKeyedItemWithSublabelAndIcon( 1755 suggested_cc_billing_.AddKeyedItemWithSublabelAndIcon(
1746 base::IntToString(i), 1756 base::IntToString(i),
1747 instruments[i]->DisplayName(), 1757 instruments[i]->DisplayName(),
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1815 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_MANAGE_EMAIL_ADDRESS)); 1825 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_MANAGE_EMAIL_ADDRESS));
1816 } 1826 }
1817 1827
1818 suggested_shipping_.AddKeyedItem( 1828 suggested_shipping_.AddKeyedItem(
1819 kAddNewItemKey, 1829 kAddNewItemKey,
1820 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADD_SHIPPING_ADDRESS)); 1830 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADD_SHIPPING_ADDRESS));
1821 suggested_shipping_.AddKeyedItem( 1831 suggested_shipping_.AddKeyedItem(
1822 kManageItemsKey, 1832 kManageItemsKey,
1823 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_MANAGE_SHIPPING_ADDRESS)); 1833 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_MANAGE_SHIPPING_ADDRESS));
1824 1834
1825 // Default shipping address is the first suggestion, if one exists. Otherwise 1835 for (size_t i = SECTION_MIN; i <= SECTION_MAX; ++i) {
1826 // it's the "Use shipping for billing" item. 1836 DialogSection section = static_cast<DialogSection>(i);
1827 const std::string& first_real_suggestion_item_key = 1837 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section);
1828 suggested_shipping_.GetItemKeyAt(1); 1838
1829 if (IsASuggestionItemKey(first_real_suggestion_item_key)) 1839 if (model->GetItemCount() == 0)
1830 suggested_shipping_.SetCheckedItem(first_real_suggestion_item_key); 1840 continue;
1841
1842 size_t default_suggestion_index = 0;
1843
1844 if (section == SECTION_SHIPPING) {
1845 // Default shipping address is the first suggestion, if one exists.
1846 // Otherwise it's the "Use shipping for billing" item.
1847 const size_t kFirstRealSuggestionIndex = 1;
Evan Stade 2013/04/30 19:03:10 I don't see the benefit to the way you rewrote thi
Dan Beam 2013/05/01 00:43:09 Reverted.
1848 if (IsASuggestionItemKey(model->GetItemKeyAt(kFirstRealSuggestionIndex)))
1849 default_suggestion_index = kFirstRealSuggestionIndex;
1850 }
1851
1852 SuggestionItemSelected(model, default_suggestion_index);
Evan Stade 2013/04/30 19:03:10 this feels wrong to me. For one thing, it screws w
Dan Beam 2013/05/01 00:43:09 Done.
1853 }
1831 1854
1832 if (view_) 1855 if (view_)
1833 view_->ModelChanged(); 1856 view_->ModelChanged();
1834 } 1857 }
1835 1858
1836 bool AutofillDialogControllerImpl::IsCompleteProfile( 1859 bool AutofillDialogControllerImpl::IsCompleteProfile(
1837 const AutofillProfile& profile) { 1860 const AutofillProfile& profile) {
1838 const std::string app_locale = g_browser_process->GetApplicationLocale(); 1861 const std::string app_locale = g_browser_process->GetApplicationLocale();
1839 for (size_t i = 0; i < requested_shipping_fields_.size(); ++i) { 1862 for (size_t i = 0; i < requested_shipping_fields_.size(); ++i) {
1840 AutofillFieldType type = requested_shipping_fields_[i].type; 1863 AutofillFieldType type = requested_shipping_fields_[i].type;
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after
2308 void AutofillDialogControllerImpl::LogSuggestionItemSelectedMetric( 2331 void AutofillDialogControllerImpl::LogSuggestionItemSelectedMetric(
2309 const SuggestionsMenuModel& model) { 2332 const SuggestionsMenuModel& model) {
2310 DialogSection section = SectionForSuggestionsMenuModel(model); 2333 DialogSection section = SectionForSuggestionsMenuModel(model);
2311 2334
2312 AutofillMetrics::DialogUiEvent dialog_ui_event; 2335 AutofillMetrics::DialogUiEvent dialog_ui_event;
2313 if (model.GetItemKeyForCheckedItem() == kAddNewItemKey) { 2336 if (model.GetItemKeyForCheckedItem() == kAddNewItemKey) {
2314 // Selected to add a new item. 2337 // Selected to add a new item.
2315 dialog_ui_event = DialogSectionToUiItemAddedEvent(section); 2338 dialog_ui_event = DialogSectionToUiItemAddedEvent(section);
2316 } else if (IsASuggestionItemKey(model.GetItemKeyForCheckedItem())) { 2339 } else if (IsASuggestionItemKey(model.GetItemKeyForCheckedItem())) {
2317 // Selected an existing item. 2340 // Selected an existing item.
2318 DCHECK(!section_editing_state_[section]);
2319 dialog_ui_event = DialogSectionToUiSelectionChangedEvent(section); 2341 dialog_ui_event = DialogSectionToUiSelectionChangedEvent(section);
2320 } else { 2342 } else {
2321 // TODO(estade): add logging for "Manage items" or "Use billing for 2343 // TODO(estade): add logging for "Manage items" or "Use billing for
2322 // shipping"? 2344 // shipping"?
2323 return; 2345 return;
2324 } 2346 }
2325 2347
2326 GetMetricLogger().LogDialogUiEvent(dialog_type_, dialog_ui_event); 2348 GetMetricLogger().LogDialogUiEvent(dialog_type_, dialog_ui_event);
2327 } 2349 }
2328 2350
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2373 url, 2395 url,
2374 content::PAGE_TRANSITION_AUTO_BOOKMARK); 2396 content::PAGE_TRANSITION_AUTO_BOOKMARK);
2375 params.disposition = NEW_FOREGROUND_TAB; 2397 params.disposition = NEW_FOREGROUND_TAB;
2376 chrome::Navigate(&params); 2398 chrome::Navigate(&params);
2377 #else 2399 #else
2378 // TODO(estade): use TabModelList? 2400 // TODO(estade): use TabModelList?
2379 #endif 2401 #endif
2380 } 2402 }
2381 2403
2382 } // namespace autofill 2404 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698