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 3 // found in the LICENSE file. 4 5 #include "chrome/browser/ui/autofill/account_chooser_model.h" 6 7 #include "base/bind.h" 8 #include "base/prefs/pref_service.h" 9 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/stringprintf.h" 11 #include "base/strings/utf_string_conversions.h" 12 #include "base/time/time.h" 13 #include "chrome/browser/profiles/profile.h" 14 #include "chrome/common/pref_names.h" 15 #include "chrome/grit/generated_resources.h" 16 #include "components/autofill/core/browser/autofill_metrics.h" 17 #include "ui/base/l10n/l10n_util.h" 18 19 namespace autofill { 20 21 const int AccountChooserModel::kWalletAddAccountId = 0; 22 const int AccountChooserModel::kAutofillItemId = 1; 23 const int AccountChooserModel::kWalletAccountsStartId = 2; 24 25 AccountChooserModelDelegate::~AccountChooserModelDelegate() {} 26 27 AccountChooserModel::AccountChooserModel( 28 AccountChooserModelDelegate* delegate, 29 Profile* profile, 30 bool disable_wallet, 31 const AutofillMetrics& metric_logger) 32 : ui::SimpleMenuModel(this), 33 delegate_(delegate), 34 checked_item_(kWalletAccountsStartId), 35 had_wallet_error_(false), 36 metric_logger_(metric_logger) { 37 if (profile->GetPrefs()->GetBoolean( 38 ::prefs::kAutofillDialogPayWithoutWallet) || 39 profile->IsOffTheRecord() || 40 disable_wallet) { 41 checked_item_ = kAutofillItemId; 42 } 43 44 ReconstructMenuItems(); 45 } 46 47 AccountChooserModel::~AccountChooserModel() {} 48 49 void AccountChooserModel::SelectWalletAccount(size_t user_index) { 50 DCHECK(user_index == 0U || user_index < wallet_accounts_.size()); 51 checked_item_ = kWalletAccountsStartId + user_index; 52 } 53 54 void AccountChooserModel::SelectUseAutofill() { 55 checked_item_ = kAutofillItemId; 56 } 57 58 bool AccountChooserModel::HasAccountsToChoose() const { 59 return !wallet_accounts_.empty(); 60 } 61 62 void AccountChooserModel::SetWalletAccounts( 63 const std::vector<std::string>& accounts, 64 size_t active_index) { 65 wallet_accounts_ = accounts; 66 SelectWalletAccount(active_index); 67 68 ReconstructMenuItems(); 69 delegate_->UpdateAccountChooserView(); 70 } 71 72 void AccountChooserModel::ClearWalletAccounts() { 73 wallet_accounts_.clear(); 74 if (WalletIsSelected()) 75 checked_item_ = kWalletAccountsStartId; 76 77 ReconstructMenuItems(); 78 delegate_->UpdateAccountChooserView(); 79 } 80 81 base::string16 AccountChooserModel::GetActiveWalletAccountName() const { 82 if (wallet_accounts_.empty()) 83 return base::string16(); 84 85 return base::UTF8ToUTF16(wallet_accounts_[GetActiveWalletAccountIndex()]); 86 } 87 88 size_t AccountChooserModel::GetActiveWalletAccountIndex() const { 89 if (!WalletIsSelected()) 90 return 0; 91 92 return checked_item_ - kWalletAccountsStartId; 93 } 94 95 bool AccountChooserModel::IsCommandIdChecked(int command_id) const { 96 return command_id == checked_item_; 97 } 98 99 bool AccountChooserModel::IsCommandIdEnabled(int command_id) const { 100 // Currently, _any_ (non-sign-in) error disables _all_ Wallet accounts. 101 if (command_id != kAutofillItemId && had_wallet_error_) 102 return false; 103 104 return true; 105 } 106 107 bool AccountChooserModel::GetAcceleratorForCommandId( 108 int command_id, 109 ui::Accelerator* accelerator) { 110 return false; 111 } 112 113 void AccountChooserModel::ExecuteCommand(int command_id, int event_flags) { 114 if (checked_item_ == command_id) 115 return; 116 117 // Log metrics. 118 AutofillMetrics::DialogUiEvent chooser_event; 119 if (command_id == kAutofillItemId) { 120 chooser_event = 121 AutofillMetrics::DIALOG_UI_ACCOUNT_CHOOSER_SWITCHED_TO_AUTOFILL; 122 } else if (command_id == kWalletAddAccountId) { 123 chooser_event = 124 AutofillMetrics::DIALOG_UI_ACCOUNT_CHOOSER_TRIED_TO_ADD_ACCOUNT; 125 } else if (checked_item_ == kAutofillItemId) { 126 chooser_event = 127 AutofillMetrics::DIALOG_UI_ACCOUNT_CHOOSER_SWITCHED_TO_WALLET; 128 } else { 129 chooser_event = 130 AutofillMetrics::DIALOG_UI_ACCOUNT_CHOOSER_SWITCHED_WALLET_ACCOUNT; 131 } 132 metric_logger_.LogDialogUiEvent(chooser_event); 133 134 DoAccountSwitch(command_id); 135 } 136 137 void AccountChooserModel::SetHadWalletError() { 138 // Any non-sign-in error disables all Wallet accounts. 139 had_wallet_error_ = true; 140 ClearWalletAccounts(); 141 DoAccountSwitch(kAutofillItemId); 142 } 143 144 void AccountChooserModel::SetHadWalletSigninError() { 145 ClearWalletAccounts(); 146 DoAccountSwitch(kAutofillItemId); 147 } 148 149 bool AccountChooserModel::WalletIsSelected() const { 150 return checked_item_ != kAutofillItemId; 151 } 152 153 void AccountChooserModel::ReconstructMenuItems() { 154 Clear(); 155 156 if (!wallet_accounts_.empty()) { 157 for (size_t i = 0; i < wallet_accounts_.size(); ++i) { 158 int item_id = kWalletAccountsStartId + i; 159 AddCheckItem(item_id, base::UTF8ToUTF16(wallet_accounts_[i])); 160 } 161 } else if (checked_item_ == kWalletAccountsStartId) { 162 // A selected active Wallet account without account names means 163 // that the sign-in attempt is in progress. 164 AddCheckItem(kWalletAccountsStartId, 165 l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_GOOGLE_WALLET)); 166 } 167 168 AddCheckItemWithStringId(kWalletAddAccountId, 169 IDS_AUTOFILL_DIALOG_ADD_ACCOUNT); 170 AddCheckItemWithStringId(kAutofillItemId, 171 IDS_AUTOFILL_DIALOG_PAY_WITHOUT_WALLET); 172 } 173 174 void AccountChooserModel::DoAccountSwitch(int command_id) { 175 if (checked_item_ == command_id) 176 return; 177 178 if (command_id == kWalletAddAccountId) { 179 delegate_->AddAccount(); 180 return; 181 } 182 183 checked_item_ = command_id; 184 ReconstructMenuItems(); 185 delegate_->AccountChoiceChanged(); 186 } 187 188 } // namespace autofill 189