diff options
author | aruslan@chromium.org <aruslan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-18 15:27:40 +0000 |
---|---|---|
committer | aruslan@chromium.org <aruslan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-18 15:27:40 +0000 |
commit | ae2f3ec7c82ad74e036813824e8da5af9e6a2a67 (patch) | |
tree | a5813d17d212ef6dd59a68e70cb21e2b0295607b | |
parent | 20fd79eeb79b9a0f8770a708ddcbf7f66564b57f (diff) | |
download | chromium_src-ae2f3ec7c82ad74e036813824e8da5af9e6a2a67.zip chromium_src-ae2f3ec7c82ad74e036813824e8da5af9e6a2a67.tar.gz chromium_src-ae2f3ec7c82ad74e036813824e8da5af9e6a2a67.tar.bz2 |
Multi-account AccountChooser for interactive autocomplete.
BUG=223923, 226855, 230227
TBR=sky@chromium.org
NOTRY=True
Review URL: https://chromiumcodereview.appspot.com/13331007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@194928 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/ui/autofill/account_chooser_model.cc | 153 | ||||
-rw-r--r-- | chrome/browser/ui/autofill/account_chooser_model.h | 135 | ||||
-rw-r--r-- | chrome/browser/ui/autofill/account_chooser_model_unittest.cc | 158 | ||||
-rw-r--r-- | chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc | 120 | ||||
-rw-r--r-- | chrome/browser/ui/autofill/autofill_dialog_controller_impl.h | 21 | ||||
-rw-r--r-- | chrome/browser/ui/autofill/autofill_dialog_controller_unittest.cc | 40 | ||||
-rw-r--r-- | chrome/browser/ui/autofill/autofill_dialog_models.cc | 85 | ||||
-rw-r--r-- | chrome/browser/ui/autofill/autofill_dialog_models.h | 68 | ||||
-rw-r--r-- | chrome/browser/ui/autofill/autofill_dialog_models_unittest.cc | 111 | ||||
-rw-r--r-- | chrome/chrome_browser_ui.gypi | 2 | ||||
-rw-r--r-- | chrome/chrome_tests_unit.gypi | 1 |
11 files changed, 573 insertions, 321 deletions
diff --git a/chrome/browser/ui/autofill/account_chooser_model.cc b/chrome/browser/ui/autofill/account_chooser_model.cc new file mode 100644 index 0000000..221d441 --- /dev/null +++ b/chrome/browser/ui/autofill/account_chooser_model.cc @@ -0,0 +1,153 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/autofill/account_chooser_model.h" + +#include "base/bind.h" +#include "base/prefs/pref_service.h" +#include "base/stringprintf.h" +#include "base/strings/string_number_conversions.h" +#include "base/time.h" +#include "base/utf_string_conversions.h" +#include "chrome/common/pref_names.h" +#include "components/autofill/browser/autofill_metrics.h" +#include "grit/generated_resources.h" +#include "grit/theme_resources.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/resource/resource_bundle.h" + +namespace autofill { + +const int AccountChooserModel::kActiveWalletItemId = 0; +const int AccountChooserModel::kAutofillItemId = 1; + +AccountChooserModelDelegate::~AccountChooserModelDelegate() {} + +AccountChooserModel::AccountChooserModel( + AccountChooserModelDelegate* delegate, + PrefService* prefs, + const AutofillMetrics& metric_logger, + DialogType dialog_type) + : ALLOW_THIS_IN_INITIALIZER_LIST(ui::SimpleMenuModel(this)), + delegate_(delegate), + checked_item_( + prefs->GetBoolean(::prefs::kAutofillDialogPayWithoutWallet) ? + kAutofillItemId : kActiveWalletItemId), + had_wallet_error_(false), + metric_logger_(metric_logger), + dialog_type_(dialog_type) { + ReconstructMenuItems(); +} + +AccountChooserModel::~AccountChooserModel() { +} + +void AccountChooserModel::SelectActiveWalletAccount() { + ExecuteCommand(kActiveWalletItemId, 0); +} + +void AccountChooserModel::SelectUseAutofill() { + ExecuteCommand(kAutofillItemId, 0); +} + +bool AccountChooserModel::HasAccountsToChoose() const { + return !active_wallet_account_name_.empty(); +} + +void AccountChooserModel::SetActiveWalletAccountName( + const string16& account) { + active_wallet_account_name_ = account; + ReconstructMenuItems(); + delegate_->UpdateAccountChooserView(); +} + +void AccountChooserModel::ClearActiveWalletAccountName() { + active_wallet_account_name_.clear(); + ReconstructMenuItems(); + delegate_->UpdateAccountChooserView(); +} + +bool AccountChooserModel::IsCommandIdChecked(int command_id) const { + return command_id == checked_item_; +} + +bool AccountChooserModel::IsCommandIdEnabled(int command_id) const { + // Currently, _any_ (non-sign-in) error disables _all_ Wallet accounts. + if (command_id != kAutofillItemId && had_wallet_error_) + return false; + + return true; +} + +bool AccountChooserModel::GetAcceleratorForCommandId( + int command_id, + ui::Accelerator* accelerator) { + return false; +} + +void AccountChooserModel::ExecuteCommand(int command_id, int event_flags) { + if (checked_item_ == command_id) + return; + + // Log metrics. + AutofillMetrics::DialogUiEvent chooser_event; + if (command_id == kAutofillItemId) { + chooser_event = + AutofillMetrics::DIALOG_UI_ACCOUNT_CHOOSER_SWITCHED_TO_AUTOFILL; + } else if (checked_item_ == kAutofillItemId) { + chooser_event = + AutofillMetrics::DIALOG_UI_ACCOUNT_CHOOSER_SWITCHED_TO_WALLET; + } else { + chooser_event = + AutofillMetrics::DIALOG_UI_ACCOUNT_CHOOSER_SWITCHED_WALLET_ACCOUNT; + } + metric_logger_.LogDialogUiEvent(dialog_type_, chooser_event); + + checked_item_ = command_id; + ReconstructMenuItems(); + delegate_->AccountChoiceChanged(); +} + +void AccountChooserModel::SetHadWalletError() { + // Any non-sign-in error disables all Wallet accounts. + had_wallet_error_ = true; + ClearActiveWalletAccountName(); + ExecuteCommand(kAutofillItemId, 0); +} + +void AccountChooserModel::SetHadWalletSigninError() { + ClearActiveWalletAccountName(); + ExecuteCommand(kAutofillItemId, 0); +} + +bool AccountChooserModel::WalletIsSelected() const { + return checked_item_ != kAutofillItemId; +} + +bool AccountChooserModel::IsActiveWalletAccountSelected() const { + return checked_item_ == kActiveWalletItemId; +} + +void AccountChooserModel::ReconstructMenuItems() { + Clear(); + const gfx::Image& wallet_icon = + ui::ResourceBundle::GetSharedInstance().GetImageNamed(IDR_WALLET_ICON); + + if (!active_wallet_account_name_.empty()) { + AddCheckItem(kActiveWalletItemId, active_wallet_account_name_); + SetIcon(GetIndexOfCommandId(kActiveWalletItemId), wallet_icon); + } else if (checked_item_ == kActiveWalletItemId) { + // A selected active Wallet account with an empty account name means + // that the sign-in attempt is in progress. + // TODO(aruslan): http://crbug.com/230932 + // A throbber should be shown until the Wallet account name is set. + AddCheckItem(kActiveWalletItemId, + l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_GOOGLE_WALLET)); + } + + AddCheckItemWithStringId(kAutofillItemId, + IDS_AUTOFILL_DIALOG_PAY_WITHOUT_WALLET); +} + +} // namespace autofill diff --git a/chrome/browser/ui/autofill/account_chooser_model.h b/chrome/browser/ui/autofill/account_chooser_model.h new file mode 100644 index 0000000..05b5ee5 --- /dev/null +++ b/chrome/browser/ui/autofill/account_chooser_model.h @@ -0,0 +1,135 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_AUTOFILL_ACCOUNT_CHOOSER_MODEL_H_ +#define CHROME_BROWSER_UI_AUTOFILL_ACCOUNT_CHOOSER_MODEL_H_ + +#include <vector> + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "base/string16.h" +#include "components/autofill/browser/autofill_manager_delegate.h" +#include "ui/base/models/simple_menu_model.h" + +class AutofillMetrics; +class PrefService; + +namespace autofill { + +// A delegate interface to allow the AccountChooserModel to inform its owner +// of changes. +class AccountChooserModelDelegate { + public: + virtual ~AccountChooserModelDelegate(); + + // Called when the active account has changed. + virtual void AccountChoiceChanged() = 0; + + // Called when the account chooser UI needs to be updated. + virtual void UpdateAccountChooserView() = 0; +}; + +// A menu model for the account chooser. This allows users to switch between +// Online Wallet accounts and local Autofill data. +// Terminology: +// - "Active Wallet account": the account used for communications with the +// Online Wallet service. There may be multiple signed-in accounts, but at any +// point of time at most one of is active. +class AccountChooserModel : public ui::SimpleMenuModel, + public ui::SimpleMenuModel::Delegate { + public: + AccountChooserModel(AccountChooserModelDelegate* delegate, + PrefService* prefs, + const AutofillMetrics& metric_logger, + DialogType dialog_type); + virtual ~AccountChooserModel(); + + // ui::SimpleMenuModel::Delegate implementation. + virtual bool IsCommandIdChecked(int command_id) const OVERRIDE; + virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE; + virtual bool GetAcceleratorForCommandId( + int command_id, + ui::Accelerator* accelerator) OVERRIDE; + virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE; + + // Sets the selection to the currently active Online Wallet account. + // Should be called if the user attempts to sign into the Online Wallet + // (e.g. when the user clicks the "Sign-in" link). + void SelectActiveWalletAccount(); + + // Sets the selection to the local Autofill data. + void SelectUseAutofill(); + + // Returns true if there are any accounts for the user to choose from. + bool HasAccountsToChoose() const; + + // Sets the name of the account used to communicate with the Online Wallet. + void SetActiveWalletAccountName(const string16& account); + + // Clears the name of the account used to communicate with the Online Wallet. + // Any Wallet error automatically clears the currently active account name. + void ClearActiveWalletAccountName(); + + // Returns the name of the currently active account, or an empty string. + const string16& active_wallet_account_name() const { + return active_wallet_account_name_; + } + + // Disables all Wallet accounts and switches to the local Autofill data. + // Should be called when the Wallet server returns an error. + void SetHadWalletError(); + + // Switches the dialog to the local Autofill data. + // Should be called when the Online Wallet sign-in attempt has failed. + void SetHadWalletSigninError(); + + bool had_wallet_error() const { return had_wallet_error_; } + + // Returns true if the selected account is an Online Wallet account. + bool WalletIsSelected() const; + + // Returns true if the current selection matches the currently active + // Wallet account. + bool IsActiveWalletAccountSelected() const; + + // Returns the command id of the current selection. + int checked_item() const { return checked_item_; } + + protected: + // Command IDs of the items in this menu; protected for the tests. + // kActiveWalletItemId is the currently active account. + // kAutofillItemId is "Pay without the Wallet" (local autofill data). + // In the future, kFirstAdditionalItemId will be added as the first id + // for additional accounts. + static const int kActiveWalletItemId; + static const int kAutofillItemId; + + private: + // Reconstructs the set of menu items. + void ReconstructMenuItems(); + + AccountChooserModelDelegate* delegate_; + + // The command id of the currently selected item. + int checked_item_; + + // Whether there has been a Wallet error while the owning dialog has been + // open. + bool had_wallet_error_; + + // For logging UMA metrics. + const AutofillMetrics& metric_logger_; + const DialogType dialog_type_; + + // The name (email) of the account currently used in communications with the + // Online Wallet service. + string16 active_wallet_account_name_; + + DISALLOW_COPY_AND_ASSIGN(AccountChooserModel); +}; + +} // namespace autofill + +#endif // CHROME_BROWSER_UI_AUTOFILL_ACCOUNT_CHOOSER_MODEL_H_ diff --git a/chrome/browser/ui/autofill/account_chooser_model_unittest.cc b/chrome/browser/ui/autofill/account_chooser_model_unittest.cc new file mode 100644 index 0000000..4bf62be --- /dev/null +++ b/chrome/browser/ui/autofill/account_chooser_model_unittest.cc @@ -0,0 +1,158 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/prefs/pref_service.h" +#include "base/utf_string_conversions.h" +#include "chrome/browser/ui/autofill/account_chooser_model.h" +#include "chrome/common/pref_names.h" +#include "chrome/test/base/testing_profile.h" +#include "components/autofill/browser/autofill_metrics.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace autofill { + +namespace { + +class TestAccountChooserModel : public AccountChooserModel { + public: + TestAccountChooserModel(AccountChooserModelDelegate* delegate, + PrefService* prefs, + const AutofillMetrics& metric_logger) + : AccountChooserModel(delegate, prefs, metric_logger, + DIALOG_TYPE_REQUEST_AUTOCOMPLETE) {} + virtual ~TestAccountChooserModel() {} + + using AccountChooserModel::kActiveWalletItemId; + using AccountChooserModel::kAutofillItemId; + + private: + DISALLOW_COPY_AND_ASSIGN(TestAccountChooserModel); +}; + +class MockAccountChooserModelDelegate : public AccountChooserModelDelegate { + public: + MockAccountChooserModelDelegate() {} + virtual ~MockAccountChooserModelDelegate() {} + + MOCK_METHOD0(AccountChoiceChanged, void()); + MOCK_METHOD0(UpdateAccountChooserView, void()); +}; + +class AccountChooserModelTest : public testing::Test { + public: + AccountChooserModelTest() + : model_(&delegate_, profile_.GetPrefs(), metric_logger_) {} + virtual ~AccountChooserModelTest() {} + + Profile* profile() { return &profile_; } + MockAccountChooserModelDelegate* delegate() { return &delegate_; } + TestAccountChooserModel* model() { return &model_; } + const AutofillMetrics& metric_logger() { return metric_logger_; } + + private: + TestingProfile profile_; + MockAccountChooserModelDelegate delegate_; + TestAccountChooserModel model_; + AutofillMetrics metric_logger_; +}; + +} // namespace + +TEST_F(AccountChooserModelTest, ObeysPref) { + // When "Pay without wallet" is false, use Wallet by default. + { + profile()->GetPrefs()->SetBoolean( + ::prefs::kAutofillDialogPayWithoutWallet, false); + TestAccountChooserModel model(delegate(), profile()->GetPrefs(), + metric_logger()); + EXPECT_TRUE(model.WalletIsSelected()); + } + // When the user chose to "Pay without wallet", use Autofill. + { + profile()->GetPrefs()->SetBoolean( + ::prefs::kAutofillDialogPayWithoutWallet, true); + TestAccountChooserModel model(delegate(), profile()->GetPrefs(), + metric_logger()); + EXPECT_FALSE(model.WalletIsSelected()); + } +} + +TEST_F(AccountChooserModelTest, IgnoresPrefChanges) { + ASSERT_FALSE(profile()->GetPrefs()->GetBoolean( + ::prefs::kAutofillDialogPayWithoutWallet)); + EXPECT_TRUE(model()->WalletIsSelected()); + + // Check that nothing changes while this dialog is running if a pref changes + // (this could cause subtle bugs or annoyances if a user closes another + // running dialog). + profile()->GetPrefs()->SetBoolean( + ::prefs::kAutofillDialogPayWithoutWallet, true); + EXPECT_TRUE(model()->WalletIsSelected()); +} + +TEST_F(AccountChooserModelTest, HandlesError) { + EXPECT_CALL(*delegate(), AccountChoiceChanged()).Times(1); + EXPECT_CALL(*delegate(), UpdateAccountChooserView()).Times(1); + + ASSERT_TRUE(model()->WalletIsSelected()); + ASSERT_TRUE(model()->IsCommandIdEnabled( + TestAccountChooserModel::kActiveWalletItemId)); + + model()->SetHadWalletError(); + EXPECT_FALSE(model()->WalletIsSelected()); + EXPECT_FALSE(model()->IsCommandIdEnabled( + TestAccountChooserModel::kActiveWalletItemId)); +} + +TEST_F(AccountChooserModelTest, HandlesSigninError) { + EXPECT_CALL(*delegate(), AccountChoiceChanged()).Times(1); + EXPECT_CALL(*delegate(), UpdateAccountChooserView()).Times(2); + + // 0. "Unknown" wallet account, we don't know if the user is signed-in yet. + ASSERT_TRUE(model()->WalletIsSelected()); + ASSERT_TRUE(model()->IsCommandIdEnabled( + TestAccountChooserModel::kActiveWalletItemId)); + ASSERT_TRUE(model()->IsActiveWalletAccountSelected()); + ASSERT_FALSE(model()->HasAccountsToChoose()); + ASSERT_EQ(2, model()->GetItemCount()); + EXPECT_EQ(string16(), model()->active_wallet_account_name()); + + // 1. "Known" wallet account (e.g. after active/passive/automatic sign-in). + // Calls UpdateAccountChooserView. + const string16 kAccount1 = ASCIIToUTF16("john.doe@gmail.com"); + model()->SetActiveWalletAccountName(kAccount1); + ASSERT_TRUE(model()->WalletIsSelected()); + ASSERT_TRUE(model()->IsCommandIdEnabled( + TestAccountChooserModel::kActiveWalletItemId)); + ASSERT_TRUE(model()->IsActiveWalletAccountSelected()); + ASSERT_TRUE(model()->HasAccountsToChoose()); + EXPECT_EQ(2, model()->GetItemCount()); + EXPECT_EQ(kAccount1, model()->active_wallet_account_name()); + + // 2. Sign-in failure. + // Autofill data should be selected and be the only valid choice. + // Calls UpdateAccountChooserView. + // Calls AccountChoiceChanged. + model()->SetHadWalletSigninError(); + EXPECT_FALSE(model()->WalletIsSelected()); + EXPECT_TRUE(model()->IsCommandIdEnabled( + TestAccountChooserModel::kActiveWalletItemId)); + EXPECT_FALSE(model()->IsActiveWalletAccountSelected()); + EXPECT_FALSE(model()->HasAccountsToChoose()); + EXPECT_EQ(1, model()->GetItemCount()); + EXPECT_EQ(string16(), model()->active_wallet_account_name()); +} + +TEST_F(AccountChooserModelTest, RespectsUserChoice) { + EXPECT_CALL(*delegate(), AccountChoiceChanged()).Times(2); + + model()->ExecuteCommand(TestAccountChooserModel::kAutofillItemId, 0); + EXPECT_FALSE(model()->WalletIsSelected()); + + model()->ExecuteCommand(TestAccountChooserModel::kActiveWalletItemId, 0); + EXPECT_TRUE(model()->WalletIsSelected()); +} + +} // namespace autofill diff --git a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc index 5c81a4216..27e9128 100644 --- a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc +++ b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc @@ -192,7 +192,7 @@ void GetBillingInfoFromOutputs(const DetailOutputMap& output, } } -// Returns the containing window for the given |web_contents|. The containing +// Returns the containing window for the given |web_contents|. The containing // window might be a browser window for a Chrome tab, or it might be a shell // window for a platform app. BaseWindow* GetBaseWindowForWebContents( @@ -466,11 +466,12 @@ bool AutofillDialogControllerImpl::ShouldShowSpinner() const { } string16 AutofillDialogControllerImpl::AccountChooserText() const { + // TODO(aruslan): this should be l10n "Not using Google Wallet". if (!account_chooser_model_.WalletIsSelected()) return l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_PAY_WITHOUT_WALLET); if (SignedInState() == SIGNED_IN) - return UTF8ToUTF16(current_username_); + return account_chooser_model_.active_wallet_account_name(); // In this case, the account chooser should be showing the signin link. return string16(); @@ -535,11 +536,14 @@ void AutofillDialogControllerImpl::GetWalletItems() { GetWalletClient()->GetWalletItems(source_url_); } -void AutofillDialogControllerImpl::OnWalletOrSigninUpdate() { +void AutofillDialogControllerImpl::SignedInStateUpdated() { + if (!account_chooser_model_.WalletIsSelected()) + return; + switch (SignedInState()) { case SIGNED_IN: // Start fetching the user name if we don't know it yet. - if (current_username_.empty()) { + if (account_chooser_model_.active_wallet_account_name().empty()) { signin_helper_.reset(new wallet::WalletSigninHelper( this, profile_->GetRequestContext())); signin_helper_->StartUserNameFetch(); @@ -547,24 +551,29 @@ void AutofillDialogControllerImpl::OnWalletOrSigninUpdate() { break; case REQUIRES_SIGN_IN: - // TODO(aruslan): automatic sign-in? + // Switch to the local account and refresh the dialog. + OnWalletSigninError(); break; case REQUIRES_PASSIVE_SIGN_IN: // Attempt to passively sign in the user. - current_username_.clear(); + DCHECK(!signin_helper_); + account_chooser_model_.ClearActiveWalletAccountName(); signin_helper_.reset(new wallet::WalletSigninHelper( - this, profile_->GetRequestContext())); + this, + profile_->GetRequestContext())); signin_helper_->StartPassiveSignin(); break; case REQUIRES_RESPONSE: break; } +} +void AutofillDialogControllerImpl::OnWalletOrSigninUpdate() { + SignedInStateUpdated(); SuggestionsUpdated(); - view_->UpdateAccountChooser(); - view_->UpdateNotificationArea(); + UpdateAccountChooserView(); // On the first successful response, compute the initial user state metric. if (initial_user_state_ == AutofillMetrics::DIALOG_USER_STATE_UNKNOWN) @@ -573,7 +582,6 @@ void AutofillDialogControllerImpl::OnWalletOrSigninUpdate() { void AutofillDialogControllerImpl::OnWalletSigninError() { signin_helper_.reset(); - current_username_.clear(); account_chooser_model_.SetHadWalletSigninError(); GetWalletClient()->CancelRequests(); } @@ -669,12 +677,15 @@ ui::MenuModel* AutofillDialogControllerImpl::MenuModelForSection( } ui::MenuModel* AutofillDialogControllerImpl::MenuModelForAccountChooser() { - // When paying with wallet, but not signed in, there is no menu, just a - // sign in link. - if (account_chooser_model_.WalletIsSelected() && SignedInState() != SIGNED_IN) - return NULL; + // If there were unrecoverable Wallet errors, or if there are choices other + // than "Pay without the wallet", show the full menu. + if (account_chooser_model_.had_wallet_error() || + account_chooser_model_.HasAccountsToChoose()) { + return &account_chooser_model_; + } - return &account_chooser_model_; + // Otherwise, there is no menu, just a sign in link. + return NULL; } gfx::Image AutofillDialogControllerImpl::AccountChooserImage() { @@ -684,8 +695,10 @@ gfx::Image AutofillDialogControllerImpl::AccountChooserImage() { } gfx::Image icon; - account_chooser_model_.GetIconAt(account_chooser_model_.checked_item(), - &icon); + account_chooser_model_.GetIconAt( + account_chooser_model_.GetIndexOfCommandId( + account_chooser_model_.checked_item()), + &icon); return icon; } @@ -797,9 +810,14 @@ scoped_ptr<DataModelWrapper> AutofillDialogControllerImpl::CreateWrapper( return scoped_ptr<DataModelWrapper>( new WalletInstrumentWrapper(wallet_items_->instruments()[index])); } + + if (section == SECTION_SHIPPING) { + return scoped_ptr<DataModelWrapper>( + new WalletAddressWrapper(wallet_items_->addresses()[index])); + } + // TODO(dbeam): should SECTION_EMAIL get here? http://crbug.com/223923 - return scoped_ptr<DataModelWrapper>( - new WalletAddressWrapper(wallet_items_->addresses()[index])); + return scoped_ptr<DataModelWrapper>(); } if (section == SECTION_CC) { @@ -1166,6 +1184,7 @@ std::vector<DialogNotification> } void AutofillDialogControllerImpl::StartSignInFlow() { + DCHECK(!IsPayingWithWallet()); DCHECK(registrar_.IsEmpty()); content::Source<content::NavigationController> source(view_->ShowSignIn()); @@ -1184,9 +1203,10 @@ void AutofillDialogControllerImpl::EndSignInFlow() { void AutofillDialogControllerImpl::NotificationCheckboxStateChanged( DialogNotification::Type type, bool checked) { if (type == DialogNotification::WALLET_USAGE_CONFIRMATION) { - int command = checked ? AccountChooserModel::kWalletItemId : - AccountChooserModel::kAutofillItemId; - account_chooser_model_.ExecuteCommand(command, 0); + if (checked) + account_chooser_model_.SelectActiveWalletAccount(); + else + account_chooser_model_.SelectUseAutofill(); } } @@ -1321,8 +1341,14 @@ void AutofillDialogControllerImpl::Observe( content::Details<content::LoadCommittedDetails>(details).ptr(); if (wallet::IsSignInContinueUrl(load_details->entry->GetVirtualURL())) { EndSignInFlow(); - if (account_chooser_model_.WalletIsSelected()) + + if (account_chooser_model_.WalletIsSelected()) { GetWalletItems(); + } else { + // The sign-in flow means that the user implicitly switched the account + // to the Wallet. This will trigger AccountChoiceChanged. + account_chooser_model_.SelectActiveWalletAccount(); + } } } @@ -1386,28 +1412,29 @@ void AutofillDialogControllerImpl::OnDidGetFullWallet( void AutofillDialogControllerImpl::OnPassiveSigninSuccess( const std::string& username) { - current_username_ = username; + const string16 username16 = UTF8ToUTF16(username); signin_helper_.reset(); + account_chooser_model_.SetActiveWalletAccountName(username16); GetWalletItems(); } void AutofillDialogControllerImpl::OnUserNameFetchSuccess( const std::string& username) { - current_username_ = username; + const string16 username16 = UTF8ToUTF16(username); signin_helper_.reset(); + account_chooser_model_.SetActiveWalletAccountName(username16); OnWalletOrSigninUpdate(); } void AutofillDialogControllerImpl::OnAutomaticSigninSuccess( const std::string& username) { - // TODO(aruslan): automatic sign-in. NOTIMPLEMENTED(); } void AutofillDialogControllerImpl::OnPassiveSigninFailure( const GoogleServiceAuthError& error) { // TODO(aruslan): report an error. - LOG(ERROR) << "failed to passively sign-in: " << error.ToString(); + LOG(ERROR) << "failed to passively sign in: " << error.ToString(); OnWalletSigninError(); } @@ -1420,14 +1447,14 @@ void AutofillDialogControllerImpl::OnUserNameFetchFailure( void AutofillDialogControllerImpl::OnAutomaticSigninFailure( const GoogleServiceAuthError& error) { - // TODO(aruslan): automatic sign-in failure. - NOTIMPLEMENTED(); + // TODO(aruslan): report an error. + LOG(ERROR) << "failed to automatically sign in: " << error.ToString(); + OnWalletSigninError(); } void AutofillDialogControllerImpl::OnDidGetWalletItems( scoped_ptr<wallet::WalletItems> wallet_items) { DCHECK(account_chooser_model_.WalletIsSelected()); - legal_documents_text_.clear(); legal_document_link_ranges_.clear(); @@ -1504,6 +1531,9 @@ void AutofillDialogControllerImpl::OnPersonalDataChanged() { SuggestionsUpdated(); } +//////////////////////////////////////////////////////////////////////////////// +// AccountChooserModelDelegate implementation. + void AutofillDialogControllerImpl::AccountChoiceChanged() { // Whenever the user changes the account, all manual inputs should be reset. ResetManualInputForSection(SECTION_EMAIL); @@ -1517,11 +1547,28 @@ void AutofillDialogControllerImpl::AccountChoiceChanged() { SetIsSubmitting(false); - if (account_chooser_model_.WalletIsSelected() && !wallet_items_) - GetWalletItems(); + if (!signin_helper_ && account_chooser_model_.WalletIsSelected()) { + if (account_chooser_model_.IsActiveWalletAccountSelected()) { + // If the user has chosen an already active Wallet account, and we don't + // have the Wallet items, an attempt to fetch the Wallet data is made to + // see if the user is still signed in. This will trigger a passive sign-in + // if required. + if (!wallet_items_) + GetWalletItems(); + else + SignedInStateUpdated(); + } else { + // TODO(aruslan): trigger the automatic sign-in process. + LOG(ERROR) << "failed to initiate an automatic sign-in"; + OnWalletSigninError(); + } + } SuggestionsUpdated(); + UpdateAccountChooserView(); +} +void AutofillDialogControllerImpl::UpdateAccountChooserView() { if (view_) { view_->UpdateAccountChooser(); view_->UpdateNotificationArea(); @@ -1615,7 +1662,6 @@ bool AutofillDialogControllerImpl::IsFirstRun() const { void AutofillDialogControllerImpl::DisableWallet() { signin_helper_.reset(); - current_username_.clear(); account_chooser_model_.SetHadWalletError(); GetWalletClient()->CancelRequests(); wallet_items_.reset(); @@ -1632,7 +1678,11 @@ void AutofillDialogControllerImpl::SuggestionsUpdated() { HidePopup(); if (IsPayingWithWallet()) { - // TODO(estade): fill in the email address. + if (!account_chooser_model_.active_wallet_account_name().empty()) { + suggested_email_.AddKeyedItem( + base::IntToString(0), + account_chooser_model_.active_wallet_account_name()); + } const std::vector<wallet::Address*>& addresses = wallet_items_->addresses(); @@ -2166,7 +2216,7 @@ void AutofillDialogControllerImpl::LogSuggestionItemSelectedMetric( AutofillMetrics::DialogInitialUserStateMetric AutofillDialogControllerImpl::GetInitialUserState() const { // Consider a user to be an Autofill user if the user has any credit cards - // or addresses saved. Check that the item count is greater than 1 because + // or addresses saved. Check that the item count is greater than 1 because // an "empty" menu still has the "add new" menu item. const bool has_autofill_profiles = suggested_cc_.GetItemCount() > 1 || diff --git a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.h b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.h index adfaccb..f99ee66 100644 --- a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.h +++ b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.h @@ -13,6 +13,7 @@ #include "base/memory/weak_ptr.h" #include "base/string16.h" #include "base/time.h" +#include "chrome/browser/ui/autofill/account_chooser_model.h" #include "chrome/browser/ui/autofill/autofill_dialog_controller.h" #include "chrome/browser/ui/autofill/autofill_dialog_models.h" #include "chrome/browser/ui/autofill/autofill_dialog_types.h" @@ -204,18 +205,16 @@ class AutofillDialogControllerImpl : public AutofillDialogController, // AccountChooserModelDelegate implementation. virtual void AccountChoiceChanged() OVERRIDE; + virtual void UpdateAccountChooserView() OVERRIDE; // wallet::WalletSigninHelperDelegate implementation. - virtual void OnPassiveSigninSuccess( - const std::string& auth_username) OVERRIDE; + virtual void OnPassiveSigninSuccess(const std::string& username) OVERRIDE; virtual void OnPassiveSigninFailure( const GoogleServiceAuthError& error) OVERRIDE; - virtual void OnAutomaticSigninSuccess( - const std::string& auth_username) OVERRIDE; + virtual void OnAutomaticSigninSuccess(const std::string& username) OVERRIDE; virtual void OnAutomaticSigninFailure( const GoogleServiceAuthError& error) OVERRIDE; - virtual void OnUserNameFetchSuccess( - const std::string& auth_username) OVERRIDE; + virtual void OnUserNameFetchSuccess(const std::string& username) OVERRIDE; virtual void OnUserNameFetchFailure( const GoogleServiceAuthError& error) OVERRIDE; @@ -274,6 +273,10 @@ class AutofillDialogControllerImpl : public AutofillDialogController, // Starts fetching the wallet items from Online Wallet. void GetWalletItems(); + // Handles the SignedInState() on Wallet or sign-in state update. + // Triggers the user name fetch and the passive/automatic sign-in. + void SignedInStateUpdated(); + // Refreshes the model on Wallet or sign-in state update. void OnWalletOrSigninUpdate(); @@ -450,12 +453,6 @@ class AutofillDialogControllerImpl : public AutofillDialogController, // The helper is set only during fetch/sign-in, and NULL otherwise. scoped_ptr<wallet::WalletSigninHelper> signin_helper_; - // The user account name (email). - // Valid only if PayingWithWallet() and SigninState() == SIGNED_IN. - // Set whenever the sign-in helper fetches the user info. - // TODO(aruslan): this should be removed (AccountChooser should deal with it). - std::string current_username_; - // A client to talk to the Online Wallet API. wallet::WalletClient wallet_client_; diff --git a/chrome/browser/ui/autofill/autofill_dialog_controller_unittest.cc b/chrome/browser/ui/autofill/autofill_dialog_controller_unittest.cc index ad0d930..9e43443 100644 --- a/chrome/browser/ui/autofill/autofill_dialog_controller_unittest.cc +++ b/chrome/browser/ui/autofill/autofill_dialog_controller_unittest.cc @@ -142,6 +142,23 @@ class TestWalletClient : public wallet::WalletClient { DISALLOW_COPY_AND_ASSIGN(TestWalletClient); }; +// Bring over command-ids from AccountChooserModel. +class TestAccountChooserModel : public AccountChooserModel { + public: + TestAccountChooserModel(AccountChooserModelDelegate* delegate, + PrefService* prefs, + const AutofillMetrics& metric_logger) + : AccountChooserModel(delegate, prefs, metric_logger, + DIALOG_TYPE_REQUEST_AUTOCOMPLETE) {} + virtual ~TestAccountChooserModel() {} + + using AccountChooserModel::kActiveWalletItemId; + using AccountChooserModel::kAutofillItemId; + + private: + DISALLOW_COPY_AND_ASSIGN(TestAccountChooserModel); +}; + class TestAutofillDialogController : public AutofillDialogControllerImpl { public: TestAutofillDialogController( @@ -280,9 +297,10 @@ class AutofillDialogControllerTest : public testing::Test { } void SetUpWallet() { - controller()->MenuModelForAccountChooser()->ActivatedAt( - AccountChooserModel::kWalletItemId); controller()->OnUserNameFetchSuccess("user@example.com"); + ui::MenuModel* account_model = controller()->MenuModelForAccountChooser(); + ASSERT_TRUE(account_model); + account_model->ActivatedAt(TestAccountChooserModel::kActiveWalletItemId); } TestAutofillDialogController* controller() { return controller_; } @@ -629,8 +647,8 @@ TEST_F(AutofillDialogControllerTest, ChangeAccountDuringSubmit) { ui::MenuModel* account_menu = controller()->MenuModelForAccountChooser(); ASSERT_TRUE(account_menu); ASSERT_GE(2, account_menu->GetItemCount()); - account_menu->ActivatedAt(AccountChooserModel::kWalletItemId); - account_menu->ActivatedAt(AccountChooserModel::kAutofillItemId); + account_menu->ActivatedAt(TestAccountChooserModel::kActiveWalletItemId); + account_menu->ActivatedAt(TestAccountChooserModel::kAutofillItemId); EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK)); EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL)); @@ -678,8 +696,8 @@ TEST_F(AutofillDialogControllerTest, ChangeAccountDuringVerifyCvv) { ui::MenuModel* account_menu = controller()->MenuModelForAccountChooser(); ASSERT_TRUE(account_menu); ASSERT_GE(2, account_menu->GetItemCount()); - account_menu->ActivatedAt(AccountChooserModel::kWalletItemId); - account_menu->ActivatedAt(AccountChooserModel::kAutofillItemId); + account_menu->ActivatedAt(TestAccountChooserModel::kActiveWalletItemId); + account_menu->ActivatedAt(TestAccountChooserModel::kAutofillItemId); EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK)); EXPECT_TRUE(controller()->IsDialogButtonEnabled(ui::DIALOG_BUTTON_CANCEL)); @@ -725,12 +743,13 @@ TEST_F(AutofillDialogControllerTest, WalletDetailsExplanation) { // Switch to using Autofill, no explanatory message should show. ui::MenuModel* account_menu = controller()->MenuModelForAccountChooser(); - account_menu->ActivatedAt(AccountChooserModel::kAutofillItemId); + ASSERT_TRUE(account_menu); + account_menu->ActivatedAt(TestAccountChooserModel::kAutofillItemId); EXPECT_TRUE(NotificationsOfType( DialogNotification::EXPLANATORY_MESSAGE).empty()); // Switch to Wallet, pretend this isn't first run. No message should show. - account_menu->ActivatedAt(AccountChooserModel::kWalletItemId); + account_menu->ActivatedAt(TestAccountChooserModel::kActiveWalletItemId); controller()->set_is_first_run(false); EXPECT_TRUE(NotificationsOfType( DialogNotification::EXPLANATORY_MESSAGE).empty()); @@ -761,7 +780,8 @@ TEST_F(AutofillDialogControllerTest, SaveDetailsInWallet) { // Using Autofill on second run, show an interactive, unchecked checkbox. ui::MenuModel* account_model = controller()->MenuModelForAccountChooser(); - account_model->ActivatedAt(AccountChooserModel::kAutofillItemId); + ASSERT_TRUE(account_model); + account_model->ActivatedAt(TestAccountChooserModel::kAutofillItemId); controller()->set_is_first_run(false); notifications = @@ -771,7 +791,7 @@ TEST_F(AutofillDialogControllerTest, SaveDetailsInWallet) { EXPECT_TRUE(notifications.front().interactive()); // Notifications shouldn't be interactive while submitting. - account_model->ActivatedAt(AccountChooserModel::kWalletItemId); + account_model->ActivatedAt(TestAccountChooserModel::kActiveWalletItemId); controller()->OnAccept(); EXPECT_FALSE(NotificationsOfType( DialogNotification::WALLET_USAGE_CONFIRMATION).front().interactive()); diff --git a/chrome/browser/ui/autofill/autofill_dialog_models.cc b/chrome/browser/ui/autofill/autofill_dialog_models.cc index 229fea3..b5419de 100644 --- a/chrome/browser/ui/autofill/autofill_dialog_models.cc +++ b/chrome/browser/ui/autofill/autofill_dialog_models.cc @@ -12,7 +12,6 @@ #include "base/utf_string_conversions.h" #include "chrome/common/pref_names.h" #include "components/autofill/browser/autofill_country.h" -#include "components/autofill/browser/autofill_metrics.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" #include "ui/base/l10n/l10n_util.h" @@ -97,90 +96,6 @@ void SuggestionsMenuModel::ExecuteCommand(int command_id, int event_flags) { delegate_->SuggestionItemSelected(*this); } -// AccountChooserModel --------------------------------------------------------- - -const int AccountChooserModel::kWalletItemId = 0; -const int AccountChooserModel::kAutofillItemId = 1; - -AccountChooserModelDelegate::~AccountChooserModelDelegate() {} - -AccountChooserModel::AccountChooserModel( - AccountChooserModelDelegate* delegate, - PrefService* prefs, - const AutofillMetrics& metric_logger, - DialogType dialog_type) - : ALLOW_THIS_IN_INITIALIZER_LIST(ui::SimpleMenuModel(this)), - account_delegate_(delegate), - checked_item_( - prefs->GetBoolean(::prefs::kAutofillDialogPayWithoutWallet) ? - kAutofillItemId : kWalletItemId), - had_wallet_error_(false), - metric_logger_(metric_logger), - dialog_type_(dialog_type) { - AddCheckItem(kWalletItemId, - l10n_util::GetStringUTF16(IDS_AUTOFILL_DIALOG_GOOGLE_WALLET)); - SetIcon( - kWalletItemId, - ui::ResourceBundle::GetSharedInstance().GetImageNamed(IDR_WALLET_ICON)); - AddCheckItemWithStringId(kAutofillItemId, - IDS_AUTOFILL_DIALOG_PAY_WITHOUT_WALLET); -} - -AccountChooserModel::~AccountChooserModel() { -} - -bool AccountChooserModel::IsCommandIdChecked(int command_id) const { - return command_id == checked_item_; -} - -bool AccountChooserModel::IsCommandIdEnabled(int command_id) const { - if (command_id == kWalletItemId && had_wallet_error_) - return false; - - return true; -} - -bool AccountChooserModel::GetAcceleratorForCommandId( - int command_id, - ui::Accelerator* accelerator) { - return false; -} - -void AccountChooserModel::ExecuteCommand(int command_id, int event_flags) { - if (checked_item_ == command_id) - return; - - // Log metrics. - AutofillMetrics::DialogUiEvent chooser_event; - if (command_id == kAutofillItemId) { - chooser_event = - AutofillMetrics::DIALOG_UI_ACCOUNT_CHOOSER_SWITCHED_TO_AUTOFILL; - } else if (checked_item_ == kAutofillItemId) { - chooser_event = - AutofillMetrics::DIALOG_UI_ACCOUNT_CHOOSER_SWITCHED_TO_WALLET; - } else { - chooser_event = - AutofillMetrics::DIALOG_UI_ACCOUNT_CHOOSER_SWITCHED_WALLET_ACCOUNT; - } - metric_logger_.LogDialogUiEvent(dialog_type_, chooser_event); - - checked_item_ = command_id; - account_delegate_->AccountChoiceChanged(); -} - -void AccountChooserModel::SetHadWalletError() { - had_wallet_error_ = true; - ExecuteCommand(kAutofillItemId, 0); -} - -void AccountChooserModel::SetHadWalletSigninError() { - ExecuteCommand(kAutofillItemId, 0); -} - -bool AccountChooserModel::WalletIsSelected() const { - return checked_item_ == kWalletItemId; -} - // MonthComboboxModel ---------------------------------------------------------- MonthComboboxModel::MonthComboboxModel() {} diff --git a/chrome/browser/ui/autofill/autofill_dialog_models.h b/chrome/browser/ui/autofill/autofill_dialog_models.h index 44ff005..0b36b2a 100644 --- a/chrome/browser/ui/autofill/autofill_dialog_models.h +++ b/chrome/browser/ui/autofill/autofill_dialog_models.h @@ -11,13 +11,9 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/string16.h" -#include "components/autofill/browser/autofill_manager_delegate.h" #include "ui/base/models/combobox_model.h" #include "ui/base/models/simple_menu_model.h" -class AutofillMetrics; -class PrefService; - namespace autofill { class SuggestionsMenuModel; @@ -95,70 +91,6 @@ class SuggestionsMenuModel : public ui::SimpleMenuModel, DISALLOW_COPY_AND_ASSIGN(SuggestionsMenuModel); }; -// A delegate interface to allow the AccountChooserModel to inform its owner -// of changes. -class AccountChooserModelDelegate { - public: - virtual ~AccountChooserModelDelegate(); - - // Called when the active account has changed. - virtual void AccountChoiceChanged() = 0; -}; - -// A menu model for the account chooser. This allows users to switch between -// using Wallet and local Autofill. TODO(estade): this should support multiple -// Wallet accounts. -class AccountChooserModel : public ui::SimpleMenuModel, - public ui::SimpleMenuModel::Delegate { - public: - AccountChooserModel(AccountChooserModelDelegate* delegate, - PrefService* prefs, - const AutofillMetrics& metric_logger, - DialogType dialog_type); - virtual ~AccountChooserModel(); - - // ui::SimpleMenuModel::Delegate implementation. - virtual bool IsCommandIdChecked(int command_id) const OVERRIDE; - virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE; - virtual bool GetAcceleratorForCommandId( - int command_id, - ui::Accelerator* accelerator) OVERRIDE; - virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE; - - // Should be called when the Wallet server returns an error. - void SetHadWalletError(); - - // Should be called when the Online Wallet sign-in attempt has failed. - void SetHadWalletSigninError(); - - bool had_wallet_error() const { return had_wallet_error_; } - - bool WalletIsSelected() const; - - int checked_item() const { return checked_item_; } - - // Command IDs of the items in this menu. For now, we only support a single - // account, so there's only one wallet item. - static const int kWalletItemId; - static const int kAutofillItemId; - - private: - AccountChooserModelDelegate* account_delegate_; - - // The command id of the currently active item. - int checked_item_; - - // Whether there has been a Wallet error while the owning dialog has been - // open. - bool had_wallet_error_; - - // For logging UMA metrics. - const AutofillMetrics& metric_logger_; - const DialogType dialog_type_; - - DISALLOW_COPY_AND_ASSIGN(AccountChooserModel); -}; - // A model for possible months in the Gregorian calendar. class MonthComboboxModel : public ui::ComboboxModel { public: diff --git a/chrome/browser/ui/autofill/autofill_dialog_models_unittest.cc b/chrome/browser/ui/autofill/autofill_dialog_models_unittest.cc index cd03020..b9a90de 100644 --- a/chrome/browser/ui/autofill/autofill_dialog_models_unittest.cc +++ b/chrome/browser/ui/autofill/autofill_dialog_models_unittest.cc @@ -2,121 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/prefs/pref_service.h" #include "chrome/browser/ui/autofill/autofill_dialog_models.h" -#include "chrome/common/pref_names.h" -#include "chrome/test/base/testing_profile.h" -#include "components/autofill/browser/autofill_metrics.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" namespace autofill { -namespace { - -class TestAccountChooserModel : public AccountChooserModel { - public: - TestAccountChooserModel(AccountChooserModelDelegate* delegate, - PrefService* prefs, - const AutofillMetrics& metric_logger) - : AccountChooserModel(delegate, prefs, metric_logger, - DIALOG_TYPE_REQUEST_AUTOCOMPLETE) {} - virtual ~TestAccountChooserModel() {} - - private: - DISALLOW_COPY_AND_ASSIGN(TestAccountChooserModel); -}; - -class MockAccountChooserModelDelegate : public AccountChooserModelDelegate { - public: - MockAccountChooserModelDelegate() {} - virtual ~MockAccountChooserModelDelegate() {} - - MOCK_METHOD0(AccountChoiceChanged, void()); -}; - -class AccountChooserModelTest : public testing::Test { - public: - AccountChooserModelTest() - : model_(&delegate_, profile_.GetPrefs(), metric_logger_) {} - virtual ~AccountChooserModelTest() {} - - Profile* profile() { return &profile_; } - MockAccountChooserModelDelegate* delegate() { return &delegate_; } - TestAccountChooserModel* model() { return &model_; } - const AutofillMetrics& metric_logger() { return metric_logger_; } - - private: - TestingProfile profile_; - MockAccountChooserModelDelegate delegate_; - TestAccountChooserModel model_; - AutofillMetrics metric_logger_; -}; - -} // namespace - -TEST_F(AccountChooserModelTest, ObeysPref) { - // When "Pay without wallet" is false, use Wallet by default. - { - profile()->GetPrefs()->SetBoolean( - ::prefs::kAutofillDialogPayWithoutWallet, false); - TestAccountChooserModel model(delegate(), profile()->GetPrefs(), - metric_logger()); - EXPECT_TRUE(model.WalletIsSelected()); - } - // When the user chose to "Pay without wallet", use Autofill. - { - profile()->GetPrefs()->SetBoolean( - ::prefs::kAutofillDialogPayWithoutWallet, true); - TestAccountChooserModel model(delegate(), profile()->GetPrefs(), - metric_logger()); - EXPECT_FALSE(model.WalletIsSelected()); - } -} - -TEST_F(AccountChooserModelTest, IgnoresPrefChanges) { - ASSERT_FALSE(profile()->GetPrefs()->GetBoolean( - ::prefs::kAutofillDialogPayWithoutWallet)); - EXPECT_TRUE(model()->WalletIsSelected()); - - // Check that nothing changes while this dialog is running if a pref changes - // (this could cause subtle bugs or annoyances if a user closes another - // running dialog). - profile()->GetPrefs()->SetBoolean( - ::prefs::kAutofillDialogPayWithoutWallet, true); - EXPECT_TRUE(model()->WalletIsSelected()); -} - -TEST_F(AccountChooserModelTest, HandlesError) { - EXPECT_CALL(*delegate(), AccountChoiceChanged()).Times(1); - - ASSERT_TRUE(model()->WalletIsSelected()); - ASSERT_TRUE(model()->IsCommandIdEnabled(AccountChooserModel::kWalletItemId)); - - model()->SetHadWalletError(); - EXPECT_FALSE(model()->WalletIsSelected()); - EXPECT_FALSE(model()->IsCommandIdEnabled(AccountChooserModel::kWalletItemId)); -} - -TEST_F(AccountChooserModelTest, HandlesSigninError) { - EXPECT_CALL(*delegate(), AccountChoiceChanged()).Times(1); - - ASSERT_TRUE(model()->WalletIsSelected()); - ASSERT_TRUE(model()->IsCommandIdEnabled(AccountChooserModel::kWalletItemId)); - - model()->SetHadWalletSigninError(); - EXPECT_FALSE(model()->WalletIsSelected()); - EXPECT_TRUE(model()->IsCommandIdEnabled(AccountChooserModel::kWalletItemId)); -} - -TEST_F(AccountChooserModelTest, RespectsUserChoice) { - EXPECT_CALL(*delegate(), AccountChoiceChanged()).Times(2); - - model()->ExecuteCommand(AccountChooserModel::kAutofillItemId, 0); - EXPECT_FALSE(model()->WalletIsSelected()); - - model()->ExecuteCommand(AccountChooserModel::kWalletItemId, 0); - EXPECT_TRUE(model()->WalletIsSelected()); -} - } // namespace autofill diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index d8ba5d3..0da8783 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi @@ -223,6 +223,8 @@ 'browser/ui/aura/tab_contents/web_drag_bookmark_handler_aura.cc', 'browser/ui/aura/tab_contents/web_drag_bookmark_handler_aura.h', 'browser/ui/aura/tabs/dock_info_aurax11.cc', + 'browser/ui/autofill/account_chooser_model.cc', + 'browser/ui/autofill/account_chooser_model.h', 'browser/ui/autofill/autocheckout_bubble.h', 'browser/ui/autofill/autocheckout_bubble.cc', 'browser/ui/autofill/autocheckout_bubble_controller.cc', diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index 34b5cd8..fb9723a 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi @@ -1212,6 +1212,7 @@ 'browser/ui/ash/launcher/launcher_context_menu_unittest.cc', 'browser/ui/ash/screenshot_taker_unittest.cc', 'browser/ui/ash/window_positioner_unittest.cc', + 'browser/ui/autofill/account_chooser_model_unittest.cc', 'browser/ui/autofill/autocheckout_bubble_controller_unittest.cc', 'browser/ui/autofill/autofill_dialog_controller_unittest.cc', 'browser/ui/autofill/autofill_dialog_models_unittest.cc', |