Home | History | Annotate | Download | only in autofill
      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