OLD | NEW |
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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 | 72 |
73 // This is a pseudo-scientifically chosen maximum amount we want a fronting | 73 // This is a pseudo-scientifically chosen maximum amount we want a fronting |
74 // (proxy) card to be able to charge. The current actual max is $2000. Using | 74 // (proxy) card to be able to charge. The current actual max is $2000. Using |
75 // only $1850 leaves some room for tax and shipping, etc. TODO(dbeam): send a | 75 // only $1850 leaves some room for tax and shipping, etc. TODO(dbeam): send a |
76 // special value to the server to just ask for the maximum so we don't need to | 76 // special value to the server to just ask for the maximum so we don't need to |
77 // hardcode it here (http://crbug.com/180731). TODO(dbeam): also maybe allow | 77 // hardcode it here (http://crbug.com/180731). TODO(dbeam): also maybe allow |
78 // users to give us this number via an <input> (http://crbug.com/180733). | 78 // users to give us this number via an <input> (http://crbug.com/180733). |
79 const int kCartMax = 1850; | 79 const int kCartMax = 1850; |
80 const char kCartCurrency[] = "USD"; | 80 const char kCartCurrency[] = "USD"; |
81 | 81 |
| 82 const char kAddNewItemKey[] = "add-new-item"; |
| 83 const char kManageItemsKey[] = "manage-items"; |
| 84 const char kSameAsBillingKey[] = "same-as-billing"; |
| 85 |
82 // Returns true if |input| should be shown when |field| has been requested. | 86 // Returns true if |input| should be shown when |field| has been requested. |
83 bool InputTypeMatchesFieldType(const DetailInput& input, | 87 bool InputTypeMatchesFieldType(const DetailInput& input, |
84 const AutofillField& field) { | 88 const AutofillField& field) { |
85 // If any credit card expiration info is asked for, show both month and year | 89 // If any credit card expiration info is asked for, show both month and year |
86 // inputs. | 90 // inputs. |
87 if (field.type() == CREDIT_CARD_EXP_4_DIGIT_YEAR || | 91 if (field.type() == CREDIT_CARD_EXP_4_DIGIT_YEAR || |
88 field.type() == CREDIT_CARD_EXP_2_DIGIT_YEAR || | 92 field.type() == CREDIT_CARD_EXP_2_DIGIT_YEAR || |
89 field.type() == CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR || | 93 field.type() == CREDIT_CARD_EXP_DATE_4_DIGIT_YEAR || |
90 field.type() == CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR || | 94 field.type() == CREDIT_CARD_EXP_DATE_2_DIGIT_YEAR || |
91 field.type() == CREDIT_CARD_EXP_MONTH) { | 95 field.type() == CREDIT_CARD_EXP_MONTH) { |
(...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
404 // AutofillDialogController implementation. | 408 // AutofillDialogController implementation. |
405 | 409 |
406 string16 AutofillDialogControllerImpl::DialogTitle() const { | 410 string16 AutofillDialogControllerImpl::DialogTitle() const { |
407 return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_TITLE); | 411 return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_TITLE); |
408 } | 412 } |
409 | 413 |
410 string16 AutofillDialogControllerImpl::EditSuggestionText() const { | 414 string16 AutofillDialogControllerImpl::EditSuggestionText() const { |
411 return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_EDIT); | 415 return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_EDIT); |
412 } | 416 } |
413 | 417 |
414 string16 AutofillDialogControllerImpl::UseBillingForShippingText() const { | |
415 return l10n_util::GetStringUTF16( | |
416 IDS_AUTOFILL_DIALOG_USE_BILLING_FOR_SHIPPING); | |
417 } | |
418 | |
419 string16 AutofillDialogControllerImpl::CancelButtonText() const { | 418 string16 AutofillDialogControllerImpl::CancelButtonText() const { |
420 return l10n_util::GetStringUTF16(IDS_CANCEL); | 419 return l10n_util::GetStringUTF16(IDS_CANCEL); |
421 } | 420 } |
422 | 421 |
423 string16 AutofillDialogControllerImpl::ConfirmButtonText() const { | 422 string16 AutofillDialogControllerImpl::ConfirmButtonText() const { |
424 return l10n_util::GetStringUTF16(IsSubmitPausedOn(wallet::VERIFY_CVV) ? | 423 return l10n_util::GetStringUTF16(IsSubmitPausedOn(wallet::VERIFY_CVV) ? |
425 IDS_AUTOFILL_DIALOG_VERIFY_BUTTON : IDS_AUTOFILL_DIALOG_SUBMIT_BUTTON); | 424 IDS_AUTOFILL_DIALOG_VERIFY_BUTTON : IDS_AUTOFILL_DIALOG_SUBMIT_BUTTON); |
426 } | 425 } |
427 | 426 |
428 string16 AutofillDialogControllerImpl::CancelSignInText() const { | 427 string16 AutofillDialogControllerImpl::CancelSignInText() const { |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
717 return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_SECTION_SHIPPING); | 716 return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_SECTION_SHIPPING); |
718 default: | 717 default: |
719 NOTREACHED(); | 718 NOTREACHED(); |
720 return string16(); | 719 return string16(); |
721 } | 720 } |
722 } | 721 } |
723 | 722 |
724 SuggestionState AutofillDialogControllerImpl::SuggestionStateForSection( | 723 SuggestionState AutofillDialogControllerImpl::SuggestionStateForSection( |
725 DialogSection section) { | 724 DialogSection section) { |
726 return SuggestionState(SuggestionTextForSection(section), | 725 return SuggestionState(SuggestionTextForSection(section), |
| 726 SuggestionTextStyleForSection(section), |
727 SuggestionIconForSection(section), | 727 SuggestionIconForSection(section), |
728 ExtraSuggestionTextForSection(section), | 728 ExtraSuggestionTextForSection(section), |
729 ExtraSuggestionIconForSection(section), | 729 ExtraSuggestionIconForSection(section), |
730 EditEnabledForSection(section)); | 730 EditEnabledForSection(section)); |
731 } | 731 } |
732 | 732 |
733 string16 AutofillDialogControllerImpl::SuggestionTextForSection( | 733 string16 AutofillDialogControllerImpl::SuggestionTextForSection( |
734 DialogSection section) { | 734 DialogSection section) { |
735 string16 action_text = RequiredActionTextForSection(section); | 735 string16 action_text = RequiredActionTextForSection(section); |
736 if (!action_text.empty()) | 736 if (!action_text.empty()) |
737 return action_text; | 737 return action_text; |
738 | 738 |
739 // When the user has clicked 'edit', don't show a suggestion (even though | 739 // When the user has clicked 'edit', don't show a suggestion (even though |
740 // there is a profile selected in the model). | 740 // there is a profile selected in the model). |
741 if (section_editing_state_[section]) | 741 if (section_editing_state_[section]) |
742 return string16(); | 742 return string16(); |
743 | 743 |
744 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); | 744 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); |
745 std::string item_key = model->GetItemKeyForCheckedItem(); | 745 std::string item_key = model->GetItemKeyForCheckedItem(); |
746 if (item_key.empty()) | 746 if (item_key == kSameAsBillingKey) { |
| 747 return l10n_util::GetStringUTF16( |
| 748 IDS_AUTOFILL_DIALOG_USING_BILLING_FOR_SHIPPING); |
| 749 } |
| 750 |
| 751 if (!IsASuggestionItemKey(item_key)) |
747 return string16(); | 752 return string16(); |
748 | 753 |
749 if (section == SECTION_EMAIL) | 754 if (section == SECTION_EMAIL) |
750 return model->GetLabelAt(model->checked_item()); | 755 return model->GetLabelAt(model->checked_item()); |
751 | 756 |
752 scoped_ptr<DataModelWrapper> wrapper = CreateWrapper(section); | 757 scoped_ptr<DataModelWrapper> wrapper = CreateWrapper(section); |
753 return wrapper->GetDisplayText(); | 758 return wrapper->GetDisplayText(); |
754 } | 759 } |
755 | 760 |
| 761 gfx::Font::FontStyle |
| 762 AutofillDialogControllerImpl::SuggestionTextStyleForSection( |
| 763 DialogSection section) const { |
| 764 const SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); |
| 765 if (model->GetItemKeyForCheckedItem() == kSameAsBillingKey) |
| 766 return gfx::Font::ITALIC; |
| 767 |
| 768 return gfx::Font::NORMAL; |
| 769 } |
| 770 |
756 string16 AutofillDialogControllerImpl::RequiredActionTextForSection( | 771 string16 AutofillDialogControllerImpl::RequiredActionTextForSection( |
757 DialogSection section) const { | 772 DialogSection section) const { |
758 if (section == SECTION_CC_BILLING && IsSubmitPausedOn(wallet::VERIFY_CVV)) { | 773 if (section == SECTION_CC_BILLING && IsSubmitPausedOn(wallet::VERIFY_CVV)) { |
759 const wallet::WalletItems::MaskedInstrument* current_instrument = | 774 const wallet::WalletItems::MaskedInstrument* current_instrument = |
760 wallet_items_->GetInstrumentById(active_instrument_id_); | 775 wallet_items_->GetInstrumentById(active_instrument_id_); |
761 if (current_instrument) | 776 if (current_instrument) |
762 return current_instrument->TypeAndLastFourDigits(); | 777 return current_instrument->TypeAndLastFourDigits(); |
763 | 778 |
764 DetailOutputMap output; | 779 DetailOutputMap output; |
765 view_->GetUserInput(section, &output); | 780 view_->GetUserInput(section, &output); |
(...skipping 22 matching lines...) Expand all Loading... |
788 if (section == SECTION_CC_BILLING) { | 803 if (section == SECTION_CC_BILLING) { |
789 return scoped_ptr<DataModelWrapper>( | 804 return scoped_ptr<DataModelWrapper>( |
790 new FullWalletBillingWrapper(full_wallet_.get())); | 805 new FullWalletBillingWrapper(full_wallet_.get())); |
791 } | 806 } |
792 if (section == SECTION_SHIPPING) { | 807 if (section == SECTION_SHIPPING) { |
793 return scoped_ptr<DataModelWrapper>( | 808 return scoped_ptr<DataModelWrapper>( |
794 new FullWalletShippingWrapper(full_wallet_.get())); | 809 new FullWalletShippingWrapper(full_wallet_.get())); |
795 } | 810 } |
796 } | 811 } |
797 | 812 |
798 if (IsManuallyEditingSection(section)) | |
799 return scoped_ptr<DataModelWrapper>(); | |
800 | |
801 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); | 813 SuggestionsMenuModel* model = SuggestionsMenuModelForSection(section); |
802 std::string item_key = model->GetItemKeyForCheckedItem(); | 814 std::string item_key = model->GetItemKeyForCheckedItem(); |
| 815 if (!IsASuggestionItemKey(item_key) || IsManuallyEditingSection(section)) |
| 816 return scoped_ptr<DataModelWrapper>(); |
803 | 817 |
804 if (IsPayingWithWallet()) { | 818 if (IsPayingWithWallet()) { |
805 int index; | 819 int index; |
806 bool success = base::StringToInt(item_key, &index); | 820 bool success = base::StringToInt(item_key, &index); |
807 DCHECK(success); | 821 DCHECK(success); |
808 | 822 |
809 if (section == SECTION_CC_BILLING) { | 823 if (section == SECTION_CC_BILLING) { |
810 return scoped_ptr<DataModelWrapper>( | 824 return scoped_ptr<DataModelWrapper>( |
811 new WalletInstrumentWrapper(wallet_items_->instruments()[index])); | 825 new WalletInstrumentWrapper(wallet_items_->instruments()[index])); |
812 } | 826 } |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
854 gfx::Image AutofillDialogControllerImpl::ExtraSuggestionIconForSection( | 868 gfx::Image AutofillDialogControllerImpl::ExtraSuggestionIconForSection( |
855 DialogSection section) const { | 869 DialogSection section) const { |
856 if (section == SECTION_CC || section == SECTION_CC_BILLING) | 870 if (section == SECTION_CC || section == SECTION_CC_BILLING) |
857 return IconForField(CREDIT_CARD_VERIFICATION_CODE, string16()); | 871 return IconForField(CREDIT_CARD_VERIFICATION_CODE, string16()); |
858 | 872 |
859 return gfx::Image(); | 873 return gfx::Image(); |
860 } | 874 } |
861 | 875 |
862 bool AutofillDialogControllerImpl::EditEnabledForSection( | 876 bool AutofillDialogControllerImpl::EditEnabledForSection( |
863 DialogSection section) const { | 877 DialogSection section) const { |
864 return section != SECTION_CC_BILLING || !IsSubmitPausedOn(wallet::VERIFY_CVV); | 878 if (SuggestionsMenuModelForSection(section)->GetItemKeyForCheckedItem() == |
| 879 kSameAsBillingKey) { |
| 880 return false; |
| 881 } |
| 882 |
| 883 if (section == SECTION_CC_BILLING && IsSubmitPausedOn(wallet::VERIFY_CVV)) |
| 884 return false; |
| 885 |
| 886 return true; |
865 } | 887 } |
866 | 888 |
867 void AutofillDialogControllerImpl::EditClickedForSection( | 889 void AutofillDialogControllerImpl::EditClickedForSection( |
868 DialogSection section) { | 890 DialogSection section) { |
869 DetailInputs* inputs = MutableRequestedFieldsForSection(section); | 891 DetailInputs* inputs = MutableRequestedFieldsForSection(section); |
870 scoped_ptr<DataModelWrapper> model = CreateWrapper(section); | 892 scoped_ptr<DataModelWrapper> model = CreateWrapper(section); |
871 model->FillInputs(inputs); | 893 model->FillInputs(inputs); |
872 section_editing_state_[section] = true; | 894 section_editing_state_[section] = true; |
873 view_->UpdateSection(section, CLEAR_USER_INPUT); | 895 view_->UpdateSection(section, CLEAR_USER_INPUT); |
874 | 896 |
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1349 // to the Wallet. This will trigger AccountChoiceChanged. | 1371 // to the Wallet. This will trigger AccountChoiceChanged. |
1350 account_chooser_model_.SelectActiveWalletAccount(); | 1372 account_chooser_model_.SelectActiveWalletAccount(); |
1351 } | 1373 } |
1352 } | 1374 } |
1353 } | 1375 } |
1354 | 1376 |
1355 //////////////////////////////////////////////////////////////////////////////// | 1377 //////////////////////////////////////////////////////////////////////////////// |
1356 // SuggestionsMenuModelDelegate implementation. | 1378 // SuggestionsMenuModelDelegate implementation. |
1357 | 1379 |
1358 void AutofillDialogControllerImpl::SuggestionItemSelected( | 1380 void AutofillDialogControllerImpl::SuggestionItemSelected( |
1359 const SuggestionsMenuModel& model) { | 1381 SuggestionsMenuModel* model, |
1360 const DialogSection section = SectionForSuggestionsMenuModel(model); | 1382 size_t index) { |
1361 EditCancelledForSection(section); | 1383 if (model->GetItemKeyAt(index) == kManageItemsKey) { |
| 1384 // TODO(estade): show chrome://settings or a wallet URL. |
| 1385 return; |
| 1386 } |
1362 | 1387 |
1363 LogSuggestionItemSelectedMetric(model); | 1388 model->SetCheckedIndex(index); |
| 1389 EditCancelledForSection(SectionForSuggestionsMenuModel(*model)); |
| 1390 |
| 1391 LogSuggestionItemSelectedMetric(*model); |
1364 } | 1392 } |
1365 | 1393 |
1366 //////////////////////////////////////////////////////////////////////////////// | 1394 //////////////////////////////////////////////////////////////////////////////// |
1367 // wallet::WalletClientDelegate implementation. | 1395 // wallet::WalletClientDelegate implementation. |
1368 | 1396 |
1369 const AutofillMetrics& AutofillDialogControllerImpl::GetMetricLogger() const { | 1397 const AutofillMetrics& AutofillDialogControllerImpl::GetMetricLogger() const { |
1370 return metric_logger_; | 1398 return metric_logger_; |
1371 } | 1399 } |
1372 | 1400 |
1373 DialogType AutofillDialogControllerImpl::GetDialogType() const { | 1401 DialogType AutofillDialogControllerImpl::GetDialogType() const { |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1670 } | 1698 } |
1671 | 1699 |
1672 void AutofillDialogControllerImpl::SuggestionsUpdated() { | 1700 void AutofillDialogControllerImpl::SuggestionsUpdated() { |
1673 suggested_email_.Reset(); | 1701 suggested_email_.Reset(); |
1674 suggested_cc_.Reset(); | 1702 suggested_cc_.Reset(); |
1675 suggested_billing_.Reset(); | 1703 suggested_billing_.Reset(); |
1676 suggested_cc_billing_.Reset(); | 1704 suggested_cc_billing_.Reset(); |
1677 suggested_shipping_.Reset(); | 1705 suggested_shipping_.Reset(); |
1678 HidePopup(); | 1706 HidePopup(); |
1679 | 1707 |
| 1708 suggested_shipping_.AddKeyedItem( |
| 1709 kSameAsBillingKey, |
| 1710 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_USE_BILLING_FOR_SHIPPING)); |
| 1711 |
1680 if (IsPayingWithWallet()) { | 1712 if (IsPayingWithWallet()) { |
1681 if (!account_chooser_model_.active_wallet_account_name().empty()) { | 1713 if (!account_chooser_model_.active_wallet_account_name().empty()) { |
1682 suggested_email_.AddKeyedItem( | 1714 suggested_email_.AddKeyedItem( |
1683 base::IntToString(0), | 1715 base::IntToString(0), |
1684 account_chooser_model_.active_wallet_account_name()); | 1716 account_chooser_model_.active_wallet_account_name()); |
1685 } | 1717 } |
1686 | 1718 |
1687 const std::vector<wallet::Address*>& addresses = | 1719 const std::vector<wallet::Address*>& addresses = |
1688 wallet_items_->addresses(); | 1720 wallet_items_->addresses(); |
1689 for (size_t i = 0; i < addresses.size(); ++i) { | 1721 for (size_t i = 0; i < addresses.size(); ++i) { |
1690 // TODO(dbeam): respect the default instrument ID. http://crbug.com/232954 | 1722 // TODO(dbeam): respect the default instrument ID. http://crbug.com/232954 |
1691 suggested_shipping_.AddKeyedItemWithSublabel( | 1723 suggested_shipping_.AddKeyedItemWithSublabel( |
1692 base::IntToString(i), | 1724 base::IntToString(i), |
1693 addresses[i]->DisplayName(), | 1725 addresses[i]->DisplayName(), |
1694 addresses[i]->DisplayNameDetail()); | 1726 addresses[i]->DisplayNameDetail()); |
| 1727 |
1695 } | 1728 } |
1696 | 1729 |
1697 if (!IsSubmitPausedOn(wallet::VERIFY_CVV)) { | 1730 if (!IsSubmitPausedOn(wallet::VERIFY_CVV)) { |
1698 const std::vector<wallet::WalletItems::MaskedInstrument*>& instruments = | 1731 const std::vector<wallet::WalletItems::MaskedInstrument*>& instruments = |
1699 wallet_items_->instruments(); | 1732 wallet_items_->instruments(); |
1700 for (size_t i = 0; i < instruments.size(); ++i) { | 1733 for (size_t i = 0; i < instruments.size(); ++i) { |
1701 // TODO(dbeam): respect the default address ID. http://crbug.com/232954 | 1734 // TODO(dbeam): respect the default address ID. http://crbug.com/232954 |
1702 suggested_cc_billing_.AddKeyedItemWithSublabelAndIcon( | 1735 suggested_cc_billing_.AddKeyedItemWithSublabelAndIcon( |
1703 base::IntToString(i), | 1736 base::IntToString(i), |
1704 instruments[i]->DisplayName(), | 1737 instruments[i]->DisplayName(), |
1705 instruments[i]->DisplayNameDetail(), | 1738 instruments[i]->DisplayNameDetail(), |
1706 instruments[i]->CardIcon()); | 1739 instruments[i]->CardIcon()); |
1707 } | 1740 } |
1708 | 1741 |
| 1742 // TODO(estade): this should have a URL sublabel. |
1709 suggested_cc_billing_.AddKeyedItem( | 1743 suggested_cc_billing_.AddKeyedItem( |
1710 std::string(), | 1744 kAddNewItemKey, |
1711 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADD_BILLING_DETAILS)); | 1745 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADD_BILLING_DETAILS)); |
| 1746 suggested_cc_billing_.AddKeyedItem( |
| 1747 kManageItemsKey, |
| 1748 l10n_util::GetStringUTF16( |
| 1749 IDS_AUTOFILL_DIALOG_MANAGE_BILLING_DETAILS)); |
1712 } | 1750 } |
1713 } else { | 1751 } else { |
1714 PersonalDataManager* manager = GetManager(); | 1752 PersonalDataManager* manager = GetManager(); |
1715 const std::vector<CreditCard*>& cards = manager->credit_cards(); | 1753 const std::vector<CreditCard*>& cards = manager->credit_cards(); |
1716 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 1754 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
1717 for (size_t i = 0; i < cards.size(); ++i) { | 1755 for (size_t i = 0; i < cards.size(); ++i) { |
1718 suggested_cc_.AddKeyedItemWithIcon( | 1756 suggested_cc_.AddKeyedItemWithIcon( |
1719 cards[i]->guid(), | 1757 cards[i]->guid(), |
1720 cards[i]->Label(), | 1758 cards[i]->Label(), |
1721 rb.GetImageNamed(cards[i]->IconResourceId())); | 1759 rb.GetImageNamed(cards[i]->IconResourceId())); |
(...skipping 16 matching lines...) Expand all Loading... |
1738 // Don't add variants for addresses: the email variants are handled above, | 1776 // Don't add variants for addresses: the email variants are handled above, |
1739 // name is part of credit card and we'll just ignore phone number | 1777 // name is part of credit card and we'll just ignore phone number |
1740 // variants. | 1778 // variants. |
1741 suggested_billing_.AddKeyedItem(profiles[i]->guid(), | 1779 suggested_billing_.AddKeyedItem(profiles[i]->guid(), |
1742 profiles[i]->Label()); | 1780 profiles[i]->Label()); |
1743 suggested_shipping_.AddKeyedItem(profiles[i]->guid(), | 1781 suggested_shipping_.AddKeyedItem(profiles[i]->guid(), |
1744 profiles[i]->Label()); | 1782 profiles[i]->Label()); |
1745 } | 1783 } |
1746 | 1784 |
1747 suggested_cc_.AddKeyedItem( | 1785 suggested_cc_.AddKeyedItem( |
1748 std::string(), | 1786 kAddNewItemKey, |
1749 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADD_CREDIT_CARD)); | 1787 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADD_CREDIT_CARD)); |
| 1788 suggested_cc_.AddKeyedItem( |
| 1789 kManageItemsKey, |
| 1790 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_MANAGE_CREDIT_CARD)); |
1750 suggested_billing_.AddKeyedItem( | 1791 suggested_billing_.AddKeyedItem( |
1751 std::string(), | 1792 kAddNewItemKey, |
1752 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADD_BILLING_ADDRESS)); | 1793 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADD_BILLING_ADDRESS)); |
| 1794 suggested_billing_.AddKeyedItem( |
| 1795 kManageItemsKey, |
| 1796 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_MANAGE_BILLING_ADDRESS)); |
1753 } | 1797 } |
1754 | 1798 |
1755 suggested_email_.AddKeyedItem( | 1799 suggested_email_.AddKeyedItem( |
1756 std::string(), | 1800 kAddNewItemKey, |
1757 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADD_EMAIL_ADDRESS)); | 1801 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADD_EMAIL_ADDRESS)); |
| 1802 if (!IsPayingWithWallet()) { |
| 1803 suggested_email_.AddKeyedItem( |
| 1804 kManageItemsKey, |
| 1805 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_MANAGE_EMAIL_ADDRESS)); |
| 1806 } |
| 1807 |
1758 suggested_shipping_.AddKeyedItem( | 1808 suggested_shipping_.AddKeyedItem( |
1759 std::string(), | 1809 kAddNewItemKey, |
1760 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADD_SHIPPING_ADDRESS)); | 1810 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_ADD_SHIPPING_ADDRESS)); |
| 1811 suggested_shipping_.AddKeyedItem( |
| 1812 kManageItemsKey, |
| 1813 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_MANAGE_SHIPPING_ADDRESS)); |
| 1814 |
| 1815 // Default shipping address is the first suggestion, if one exists. Otherwise |
| 1816 // it's the "Use shipping for billing" item. |
| 1817 const std::string& first_real_suggestion_item_key = |
| 1818 suggested_shipping_.GetItemKeyAt(1); |
| 1819 if (IsASuggestionItemKey(first_real_suggestion_item_key)) |
| 1820 suggested_shipping_.SetCheckedItem(first_real_suggestion_item_key); |
1761 | 1821 |
1762 if (view_) | 1822 if (view_) |
1763 view_->ModelChanged(); | 1823 view_->ModelChanged(); |
1764 } | 1824 } |
1765 | 1825 |
1766 bool AutofillDialogControllerImpl::IsCompleteProfile( | 1826 bool AutofillDialogControllerImpl::IsCompleteProfile( |
1767 const AutofillProfile& profile) { | 1827 const AutofillProfile& profile) { |
1768 const std::string app_locale = g_browser_process->GetApplicationLocale(); | 1828 const std::string app_locale = g_browser_process->GetApplicationLocale(); |
1769 for (size_t i = 0; i < requested_shipping_fields_.size(); ++i) { | 1829 for (size_t i = 0; i < requested_shipping_fields_.size(); ++i) { |
1770 AutofillFieldType type = requested_shipping_fields_[i].type; | 1830 AutofillFieldType type = requested_shipping_fields_[i].type; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1852 AutofillField* field = form_structure_.field(i); | 1912 AutofillField* field = form_structure_.field(i); |
1853 if (field->type() == CREDIT_CARD_VERIFICATION_CODE) { | 1913 if (field->type() == CREDIT_CARD_VERIFICATION_CODE) { |
1854 field->value = cvc; | 1914 field->value = cvc; |
1855 break; | 1915 break; |
1856 } | 1916 } |
1857 } | 1917 } |
1858 } | 1918 } |
1859 | 1919 |
1860 SuggestionsMenuModel* AutofillDialogControllerImpl:: | 1920 SuggestionsMenuModel* AutofillDialogControllerImpl:: |
1861 SuggestionsMenuModelForSection(DialogSection section) { | 1921 SuggestionsMenuModelForSection(DialogSection section) { |
1862 const AutofillDialogControllerImpl* const_this = | |
1863 static_cast<const AutofillDialogControllerImpl*>(this); | |
1864 return const_cast<SuggestionsMenuModel*>( | |
1865 const_this->SuggestionsMenuModelForSection(section)); | |
1866 } | |
1867 | |
1868 const SuggestionsMenuModel* AutofillDialogControllerImpl:: | |
1869 SuggestionsMenuModelForSection(DialogSection section) const { | |
1870 switch (section) { | 1922 switch (section) { |
1871 case SECTION_EMAIL: | 1923 case SECTION_EMAIL: |
1872 return &suggested_email_; | 1924 return &suggested_email_; |
1873 case SECTION_CC: | 1925 case SECTION_CC: |
1874 return &suggested_cc_; | 1926 return &suggested_cc_; |
1875 case SECTION_BILLING: | 1927 case SECTION_BILLING: |
1876 return &suggested_billing_; | 1928 return &suggested_billing_; |
1877 case SECTION_SHIPPING: | 1929 case SECTION_SHIPPING: |
1878 return &suggested_shipping_; | 1930 return &suggested_shipping_; |
1879 case SECTION_CC_BILLING: | 1931 case SECTION_CC_BILLING: |
1880 return &suggested_cc_billing_; | 1932 return &suggested_cc_billing_; |
1881 } | 1933 } |
1882 | 1934 |
1883 NOTREACHED(); | 1935 NOTREACHED(); |
1884 return NULL; | 1936 return NULL; |
1885 } | 1937 } |
1886 | 1938 |
| 1939 const SuggestionsMenuModel* AutofillDialogControllerImpl:: |
| 1940 SuggestionsMenuModelForSection(DialogSection section) const { |
| 1941 return const_cast<AutofillDialogControllerImpl*>(this)-> |
| 1942 SuggestionsMenuModelForSection(section); |
| 1943 } |
| 1944 |
1887 DialogSection AutofillDialogControllerImpl::SectionForSuggestionsMenuModel( | 1945 DialogSection AutofillDialogControllerImpl::SectionForSuggestionsMenuModel( |
1888 const SuggestionsMenuModel& model) { | 1946 const SuggestionsMenuModel& model) { |
1889 if (&model == &suggested_email_) | 1947 if (&model == &suggested_email_) |
1890 return SECTION_EMAIL; | 1948 return SECTION_EMAIL; |
1891 | 1949 |
1892 if (&model == &suggested_cc_) | 1950 if (&model == &suggested_cc_) |
1893 return SECTION_CC; | 1951 return SECTION_CC; |
1894 | 1952 |
1895 if (&model == &suggested_billing_) | 1953 if (&model == &suggested_billing_) |
1896 return SECTION_BILLING; | 1954 return SECTION_BILLING; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1946 scoped_ptr<risk::Fingerprint> fingerprint) { | 2004 scoped_ptr<risk::Fingerprint> fingerprint) { |
1947 NOTIMPLEMENTED(); | 2005 NOTIMPLEMENTED(); |
1948 } | 2006 } |
1949 | 2007 |
1950 bool AutofillDialogControllerImpl::IsManuallyEditingSection( | 2008 bool AutofillDialogControllerImpl::IsManuallyEditingSection( |
1951 DialogSection section) const { | 2009 DialogSection section) const { |
1952 std::map<DialogSection, bool>::const_iterator it = | 2010 std::map<DialogSection, bool>::const_iterator it = |
1953 section_editing_state_.find(section); | 2011 section_editing_state_.find(section); |
1954 return (it != section_editing_state_.end() && it->second) || | 2012 return (it != section_editing_state_.end() && it->second) || |
1955 SuggestionsMenuModelForSection(section)-> | 2013 SuggestionsMenuModelForSection(section)-> |
1956 GetItemKeyForCheckedItem().empty(); | 2014 GetItemKeyForCheckedItem() == kAddNewItemKey; |
| 2015 } |
| 2016 |
| 2017 bool AutofillDialogControllerImpl::IsASuggestionItemKey( |
| 2018 const std::string& key) { |
| 2019 return !key.empty() && |
| 2020 key != kAddNewItemKey && |
| 2021 key != kManageItemsKey && |
| 2022 key != kSameAsBillingKey; |
1957 } | 2023 } |
1958 | 2024 |
1959 bool AutofillDialogControllerImpl::IsManuallyEditingAnySection() const { | 2025 bool AutofillDialogControllerImpl::IsManuallyEditingAnySection() const { |
1960 for (size_t section = SECTION_MIN; section <= SECTION_MAX; ++section) { | 2026 for (size_t section = SECTION_MIN; section <= SECTION_MAX; ++section) { |
1961 if (IsManuallyEditingSection(static_cast<DialogSection>(section))) | 2027 if (IsManuallyEditingSection(static_cast<DialogSection>(section))) |
1962 return true; | 2028 return true; |
1963 } | 2029 } |
1964 return false; | 2030 return false; |
1965 } | 2031 } |
1966 | 2032 |
1967 bool AutofillDialogControllerImpl::AllSectionsAreValid() const { | 2033 bool AutofillDialogControllerImpl::AllSectionsAreValid() const { |
1968 for (size_t section = SECTION_MIN; section <= SECTION_MAX; ++section) { | 2034 for (size_t section = SECTION_MIN; section <= SECTION_MAX; ++section) { |
1969 if (!SectionIsValid(static_cast<DialogSection>(section))) | 2035 if (!SectionIsValid(static_cast<DialogSection>(section))) |
1970 return false; | 2036 return false; |
1971 } | 2037 } |
1972 return true; | 2038 return true; |
1973 } | 2039 } |
1974 | 2040 |
1975 bool AutofillDialogControllerImpl::SectionIsValid( | 2041 bool AutofillDialogControllerImpl::SectionIsValid( |
1976 DialogSection section) const { | 2042 DialogSection section) const { |
1977 if (!IsManuallyEditingSection(section)) | 2043 if (!IsManuallyEditingSection(section)) |
1978 return true; | 2044 return true; |
1979 | 2045 |
1980 DetailOutputMap detail_outputs; | 2046 DetailOutputMap detail_outputs; |
1981 view_->GetUserInput(SECTION_EMAIL, &detail_outputs); | 2047 view_->GetUserInput(SECTION_EMAIL, &detail_outputs); |
1982 return InputsAreValid(detail_outputs, VALIDATE_EDIT).empty(); | 2048 return InputsAreValid(detail_outputs, VALIDATE_EDIT).empty(); |
1983 } | 2049 } |
1984 | 2050 |
1985 bool AutofillDialogControllerImpl::ShouldUseBillingForShipping() { | 2051 bool AutofillDialogControllerImpl::ShouldUseBillingForShipping() { |
1986 // If the user is editing or inputting data, ask the view. | 2052 return suggested_shipping_.GetItemKeyForCheckedItem() == kSameAsBillingKey; |
1987 if (IsManuallyEditingSection(SECTION_SHIPPING)) | |
1988 return view_->UseBillingForShipping(); | |
1989 | |
1990 // Otherwise, the checkbox should be hidden so its state is irrelevant. | |
1991 // Always use the shipping suggestion model. | |
1992 return false; | |
1993 } | 2053 } |
1994 | 2054 |
1995 bool AutofillDialogControllerImpl::ShouldSaveDetailsLocally() { | 2055 bool AutofillDialogControllerImpl::ShouldSaveDetailsLocally() { |
1996 // It's possible that the user checked [X] Save details locally before | 2056 // It's possible that the user checked [X] Save details locally before |
1997 // switching payment methods, so only ask the view whether to save details | 2057 // switching payment methods, so only ask the view whether to save details |
1998 // locally if that checkbox is showing (currently if not paying with wallet). | 2058 // locally if that checkbox is showing (currently if not paying with wallet). |
1999 // Also, if the user isn't editing any sections, there's no data to save | 2059 // Also, if the user isn't editing any sections, there's no data to save |
2000 // locally. | 2060 // locally. |
2001 return ShouldOfferToSaveInChrome() && view_->SaveDetailsLocally(); | 2061 return ShouldOfferToSaveInChrome() && view_->SaveDetailsLocally(); |
2002 } | 2062 } |
(...skipping 14 matching lines...) Expand all Loading... |
2017 // TODO(dbeam): disallow interacting with the dialog while submitting. | 2077 // TODO(dbeam): disallow interacting with the dialog while submitting. |
2018 // http://crbug.com/230932 | 2078 // http://crbug.com/230932 |
2019 | 2079 |
2020 active_instrument_id_.clear(); | 2080 active_instrument_id_.clear(); |
2021 active_address_id_.clear(); | 2081 active_address_id_.clear(); |
2022 full_wallet_.reset(); | 2082 full_wallet_.reset(); |
2023 | 2083 |
2024 if (!section_editing_state_[SECTION_CC_BILLING]) { | 2084 if (!section_editing_state_[SECTION_CC_BILLING]) { |
2025 SuggestionsMenuModel* billing = | 2085 SuggestionsMenuModel* billing = |
2026 SuggestionsMenuModelForSection(SECTION_CC_BILLING); | 2086 SuggestionsMenuModelForSection(SECTION_CC_BILLING); |
2027 if (!billing->GetItemKeyForCheckedItem().empty() && | 2087 if (IsASuggestionItemKey(billing->GetItemKeyForCheckedItem()) && |
2028 billing->checked_item() < | 2088 billing->checked_item() < |
2029 static_cast<int>(wallet_items_->instruments().size())) { | 2089 static_cast<int>(wallet_items_->instruments().size())) { |
2030 const wallet::WalletItems::MaskedInstrument* active_instrument = | 2090 const wallet::WalletItems::MaskedInstrument* active_instrument = |
2031 wallet_items_->instruments()[billing->checked_item()]; | 2091 wallet_items_->instruments()[billing->checked_item()]; |
2032 active_instrument_id_ = active_instrument->object_id(); | 2092 active_instrument_id_ = active_instrument->object_id(); |
2033 | 2093 |
2034 // TODO(dbeam): save this as a shipping address. http://crbug.com/225442 | 2094 // TODO(dbeam): save this as a shipping address. http://crbug.com/225442 |
2035 if (ShouldUseBillingForShipping()) | 2095 if (ShouldUseBillingForShipping()) |
2036 active_address_id_ = active_instrument->address().object_id(); | 2096 active_address_id_ = active_instrument->address().object_id(); |
2037 } | 2097 } |
2038 } | 2098 } |
2039 | 2099 |
2040 if (!section_editing_state_[SECTION_SHIPPING] && active_address_id_.empty()) { | 2100 if (!section_editing_state_[SECTION_SHIPPING] && active_address_id_.empty()) { |
2041 SuggestionsMenuModel* shipping = | 2101 SuggestionsMenuModel* shipping = |
2042 SuggestionsMenuModelForSection(SECTION_SHIPPING); | 2102 SuggestionsMenuModelForSection(SECTION_SHIPPING); |
2043 if (!shipping->GetItemKeyForCheckedItem().empty() && | 2103 if (IsASuggestionItemKey(shipping->GetItemKeyForCheckedItem()) && |
2044 shipping->checked_item() < | 2104 shipping->checked_item() - 1 < |
2045 static_cast<int>(wallet_items_->addresses().size())) { | 2105 static_cast<int>(wallet_items_->addresses().size())) { |
2046 active_address_id_ = | 2106 active_address_id_ = |
2047 wallet_items_->addresses()[shipping->checked_item()]->object_id(); | 2107 wallet_items_->addresses()[shipping->checked_item() - 1]->object_id(); |
2048 } | 2108 } |
2049 } | 2109 } |
2050 | 2110 |
2051 GetWalletClient()->AcceptLegalDocuments( | 2111 GetWalletClient()->AcceptLegalDocuments( |
2052 wallet_items_->legal_documents(), | 2112 wallet_items_->legal_documents(), |
2053 wallet_items_->google_transaction_id(), | 2113 wallet_items_->google_transaction_id(), |
2054 source_url_); | 2114 source_url_); |
2055 | 2115 |
2056 scoped_ptr<wallet::Instrument> new_instrument; | 2116 scoped_ptr<wallet::Instrument> new_instrument; |
2057 if (active_instrument_id_.empty()) { | 2117 if (active_instrument_id_.empty()) { |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2194 base::Time::Now() - dialog_shown_timestamp_, | 2254 base::Time::Now() - dialog_shown_timestamp_, |
2195 dialog_type_, | 2255 dialog_type_, |
2196 AutofillMetrics::DIALOG_CANCELED); | 2256 AutofillMetrics::DIALOG_CANCELED); |
2197 } | 2257 } |
2198 | 2258 |
2199 void AutofillDialogControllerImpl::LogSuggestionItemSelectedMetric( | 2259 void AutofillDialogControllerImpl::LogSuggestionItemSelectedMetric( |
2200 const SuggestionsMenuModel& model) { | 2260 const SuggestionsMenuModel& model) { |
2201 DialogSection section = SectionForSuggestionsMenuModel(model); | 2261 DialogSection section = SectionForSuggestionsMenuModel(model); |
2202 | 2262 |
2203 AutofillMetrics::DialogUiEvent dialog_ui_event; | 2263 AutofillMetrics::DialogUiEvent dialog_ui_event; |
2204 if (model.GetItemKeyForCheckedItem().empty()) { | 2264 if (model.GetItemKeyForCheckedItem() == kAddNewItemKey) { |
2205 // Selected to add a new item. | 2265 // Selected to add a new item. |
2206 dialog_ui_event = DialogSectionToUiItemAddedEvent(section); | 2266 dialog_ui_event = DialogSectionToUiItemAddedEvent(section); |
2207 } else { | 2267 } else if (IsASuggestionItemKey(model.GetItemKeyForCheckedItem())) { |
2208 // Selected an existing item. | 2268 // Selected an existing item. |
2209 DCHECK(!section_editing_state_[section]); | 2269 DCHECK(!section_editing_state_[section]); |
2210 dialog_ui_event = DialogSectionToUiSelectionChangedEvent(section); | 2270 dialog_ui_event = DialogSectionToUiSelectionChangedEvent(section); |
| 2271 } else { |
| 2272 // TODO(estade): add logging for "Manage items" or "Use billing for |
| 2273 // shipping"? |
| 2274 return; |
2211 } | 2275 } |
2212 | 2276 |
2213 GetMetricLogger().LogDialogUiEvent(dialog_type_, dialog_ui_event); | 2277 GetMetricLogger().LogDialogUiEvent(dialog_type_, dialog_ui_event); |
2214 } | 2278 } |
2215 | 2279 |
2216 AutofillMetrics::DialogInitialUserStateMetric | 2280 AutofillMetrics::DialogInitialUserStateMetric |
2217 AutofillDialogControllerImpl::GetInitialUserState() const { | 2281 AutofillDialogControllerImpl::GetInitialUserState() const { |
2218 // Consider a user to be an Autofill user if the user has any credit cards | 2282 // Consider a user to be an Autofill user if the user has any credit cards |
2219 // or addresses saved. Check that the item count is greater than 1 because | 2283 // or addresses saved. Check that the item count is greater than 2 because |
2220 // an "empty" menu still has the "add new" menu item. | 2284 // an "empty" menu still has the "add new" menu item and "manage" menu item. |
2221 const bool has_autofill_profiles = | 2285 const bool has_autofill_profiles = |
2222 suggested_cc_.GetItemCount() > 1 || | 2286 suggested_cc_.GetItemCount() > 2 || |
2223 suggested_billing_.GetItemCount() > 1; | 2287 suggested_billing_.GetItemCount() > 2; |
2224 | 2288 |
2225 if (SignedInState() != SIGNED_IN) { | 2289 if (SignedInState() != SIGNED_IN) { |
2226 // Not signed in. | 2290 // Not signed in. |
2227 return has_autofill_profiles ? | 2291 return has_autofill_profiles ? |
2228 AutofillMetrics::DIALOG_USER_NOT_SIGNED_IN_HAS_AUTOFILL : | 2292 AutofillMetrics::DIALOG_USER_NOT_SIGNED_IN_HAS_AUTOFILL : |
2229 AutofillMetrics::DIALOG_USER_NOT_SIGNED_IN_NO_AUTOFILL; | 2293 AutofillMetrics::DIALOG_USER_NOT_SIGNED_IN_NO_AUTOFILL; |
2230 } | 2294 } |
2231 | 2295 |
2232 // Signed in. | 2296 // Signed in. |
2233 if (wallet_items_->instruments().empty()) { | 2297 if (wallet_items_->instruments().empty()) { |
2234 // No Wallet items. | 2298 // No Wallet items. |
2235 return has_autofill_profiles ? | 2299 return has_autofill_profiles ? |
2236 AutofillMetrics::DIALOG_USER_SIGNED_IN_NO_WALLET_HAS_AUTOFILL : | 2300 AutofillMetrics::DIALOG_USER_SIGNED_IN_NO_WALLET_HAS_AUTOFILL : |
2237 AutofillMetrics::DIALOG_USER_SIGNED_IN_NO_WALLET_NO_AUTOFILL; | 2301 AutofillMetrics::DIALOG_USER_SIGNED_IN_NO_WALLET_NO_AUTOFILL; |
2238 } | 2302 } |
2239 | 2303 |
2240 // Has Wallet items. | 2304 // Has Wallet items. |
2241 return has_autofill_profiles ? | 2305 return has_autofill_profiles ? |
2242 AutofillMetrics::DIALOG_USER_SIGNED_IN_HAS_WALLET_HAS_AUTOFILL : | 2306 AutofillMetrics::DIALOG_USER_SIGNED_IN_HAS_WALLET_HAS_AUTOFILL : |
2243 AutofillMetrics::DIALOG_USER_SIGNED_IN_HAS_WALLET_NO_AUTOFILL; | 2307 AutofillMetrics::DIALOG_USER_SIGNED_IN_HAS_WALLET_NO_AUTOFILL; |
2244 } | 2308 } |
2245 | 2309 |
2246 } // namespace autofill | 2310 } // namespace autofill |
OLD | NEW |