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
~AccountChooserModelDelegate()25 AccountChooserModelDelegate::~AccountChooserModelDelegate() {}
26
AccountChooserModel(AccountChooserModelDelegate * delegate,Profile * profile,bool disable_wallet,const AutofillMetrics & metric_logger)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
~AccountChooserModel()47 AccountChooserModel::~AccountChooserModel() {}
48
SelectWalletAccount(size_t user_index)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
SelectUseAutofill()54 void AccountChooserModel::SelectUseAutofill() {
55 checked_item_ = kAutofillItemId;
56 }
57
HasAccountsToChoose() const58 bool AccountChooserModel::HasAccountsToChoose() const {
59 return !wallet_accounts_.empty();
60 }
61
SetWalletAccounts(const std::vector<std::string> & accounts,size_t active_index)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
ClearWalletAccounts()72 void AccountChooserModel::ClearWalletAccounts() {
73 wallet_accounts_.clear();
74 if (WalletIsSelected())
75 checked_item_ = kWalletAccountsStartId;
76
77 ReconstructMenuItems();
78 delegate_->UpdateAccountChooserView();
79 }
80
GetActiveWalletAccountName() const81 base::string16 AccountChooserModel::GetActiveWalletAccountName() const {
82 if (wallet_accounts_.empty())
83 return base::string16();
84
85 return base::UTF8ToUTF16(wallet_accounts_[GetActiveWalletAccountIndex()]);
86 }
87
GetActiveWalletAccountIndex() const88 size_t AccountChooserModel::GetActiveWalletAccountIndex() const {
89 if (!WalletIsSelected())
90 return 0;
91
92 return checked_item_ - kWalletAccountsStartId;
93 }
94
IsCommandIdChecked(int command_id) const95 bool AccountChooserModel::IsCommandIdChecked(int command_id) const {
96 return command_id == checked_item_;
97 }
98
IsCommandIdEnabled(int command_id) const99 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
GetAcceleratorForCommandId(int command_id,ui::Accelerator * accelerator)107 bool AccountChooserModel::GetAcceleratorForCommandId(
108 int command_id,
109 ui::Accelerator* accelerator) {
110 return false;
111 }
112
ExecuteCommand(int command_id,int event_flags)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
SetHadWalletError()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
SetHadWalletSigninError()144 void AccountChooserModel::SetHadWalletSigninError() {
145 ClearWalletAccounts();
146 DoAccountSwitch(kAutofillItemId);
147 }
148
WalletIsSelected() const149 bool AccountChooserModel::WalletIsSelected() const {
150 return checked_item_ != kAutofillItemId;
151 }
152
ReconstructMenuItems()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
DoAccountSwitch(int command_id)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