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 "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::SelectWalletAccount(size_t user_index) {
     52   DCHECK(user_index == 0U || user_index < wallet_accounts_.size());
     53   checked_item_ = kWalletAccountsStartId + user_index;
     54 }
     55 
     56 void AccountChooserModel::SelectUseAutofill() {
     57   checked_item_ = kAutofillItemId;
     58 }
     59 
     60 bool AccountChooserModel::HasAccountsToChoose() const {
     61   return !wallet_accounts_.empty();
     62 }
     63 
     64 void AccountChooserModel::SetWalletAccounts(
     65     const std::vector<std::string>& accounts,
     66     size_t active_index) {
     67   wallet_accounts_ = accounts;
     68   SelectWalletAccount(active_index);
     69 
     70   ReconstructMenuItems();
     71   delegate_->UpdateAccountChooserView();
     72 }
     73 
     74 void AccountChooserModel::ClearWalletAccounts() {
     75   wallet_accounts_.clear();
     76   if (WalletIsSelected())
     77     checked_item_ = kWalletAccountsStartId;
     78 
     79   ReconstructMenuItems();
     80   delegate_->UpdateAccountChooserView();
     81 }
     82 
     83 base::string16 AccountChooserModel::GetActiveWalletAccountName() const {
     84   if (wallet_accounts_.empty())
     85     return base::string16();
     86 
     87   return base::UTF8ToUTF16(wallet_accounts_[GetActiveWalletAccountIndex()]);
     88 }
     89 
     90 size_t AccountChooserModel::GetActiveWalletAccountIndex() const {
     91   if (!WalletIsSelected())
     92     return 0;
     93 
     94   return checked_item_ - kWalletAccountsStartId;
     95 }
     96 
     97 bool AccountChooserModel::IsCommandIdChecked(int command_id) const {
     98   return command_id == checked_item_;
     99 }
    100 
    101 bool AccountChooserModel::IsCommandIdEnabled(int command_id) const {
    102   // Currently, _any_ (non-sign-in) error disables _all_ Wallet accounts.
    103   if (command_id != kAutofillItemId && had_wallet_error_)
    104     return false;
    105 
    106   return true;
    107 }
    108 
    109 bool AccountChooserModel::GetAcceleratorForCommandId(
    110     int command_id,
    111     ui::Accelerator* accelerator) {
    112   return false;
    113 }
    114 
    115 void AccountChooserModel::ExecuteCommand(int command_id, int event_flags) {
    116   if (checked_item_ == command_id)
    117     return;
    118 
    119   // Log metrics.
    120   AutofillMetrics::DialogUiEvent chooser_event;
    121   if (command_id == kAutofillItemId) {
    122     chooser_event =
    123         AutofillMetrics::DIALOG_UI_ACCOUNT_CHOOSER_SWITCHED_TO_AUTOFILL;
    124   } else if (command_id == kWalletAddAccountId) {
    125     chooser_event =
    126         AutofillMetrics::DIALOG_UI_ACCOUNT_CHOOSER_TRIED_TO_ADD_ACCOUNT;
    127   } else if (checked_item_ == kAutofillItemId) {
    128     chooser_event =
    129         AutofillMetrics::DIALOG_UI_ACCOUNT_CHOOSER_SWITCHED_TO_WALLET;
    130   } else {
    131     chooser_event =
    132         AutofillMetrics::DIALOG_UI_ACCOUNT_CHOOSER_SWITCHED_WALLET_ACCOUNT;
    133   }
    134   metric_logger_.LogDialogUiEvent(chooser_event);
    135 
    136   DoAccountSwitch(command_id);
    137 }
    138 
    139 void AccountChooserModel::SetHadWalletError() {
    140   // Any non-sign-in error disables all Wallet accounts.
    141   had_wallet_error_ = true;
    142   ClearWalletAccounts();
    143   DoAccountSwitch(kAutofillItemId);
    144 }
    145 
    146 void AccountChooserModel::SetHadWalletSigninError() {
    147   ClearWalletAccounts();
    148   DoAccountSwitch(kAutofillItemId);
    149 }
    150 
    151 bool AccountChooserModel::WalletIsSelected() const {
    152   return checked_item_ != kAutofillItemId;
    153 }
    154 
    155 void AccountChooserModel::ReconstructMenuItems() {
    156   Clear();
    157 
    158   if (!wallet_accounts_.empty()) {
    159     for (size_t i = 0; i < wallet_accounts_.size(); ++i) {
    160       int item_id = kWalletAccountsStartId + i;
    161       AddCheckItem(item_id, base::UTF8ToUTF16(wallet_accounts_[i]));
    162     }
    163   } else if (checked_item_ == kWalletAccountsStartId) {
    164     // A selected active Wallet account without account names means
    165     // that the sign-in attempt is in progress.
    166     AddCheckItem(kWalletAccountsStartId,
    167                  l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_GOOGLE_WALLET));
    168   }
    169 
    170   AddCheckItemWithStringId(kWalletAddAccountId,
    171                            IDS_AUTOFILL_DIALOG_ADD_ACCOUNT);
    172   AddCheckItemWithStringId(kAutofillItemId,
    173                            IDS_AUTOFILL_DIALOG_PAY_WITHOUT_WALLET);
    174 }
    175 
    176 void AccountChooserModel::DoAccountSwitch(int command_id) {
    177   if (checked_item_ == command_id)
    178     return;
    179 
    180   if (command_id == kWalletAddAccountId) {
    181     delegate_->AddAccount();
    182     return;
    183   }
    184 
    185   checked_item_ = command_id;
    186   ReconstructMenuItems();
    187   delegate_->AccountChoiceChanged();
    188 }
    189 
    190 }  // namespace autofill
    191