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