| 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 |