| Index: chrome/browser/chromeos/login/existing_user_controller.cc
|
| diff --git a/chrome/browser/chromeos/login/existing_user_controller.cc b/chrome/browser/chromeos/login/existing_user_controller.cc
|
| index 1395e1be81b8353fec5bee1cf4640aaff2cda297..e7e3d2e2d74ef134644c9aab970ca4104f287fc5 100644
|
| --- a/chrome/browser/chromeos/login/existing_user_controller.cc
|
| +++ b/chrome/browser/chromeos/login/existing_user_controller.cc
|
| @@ -47,6 +47,10 @@ const size_t kMaxUsers = 6;
|
| // Used to indicate no user has been selected.
|
| const size_t kNotSelected = -1;
|
|
|
| +// Offset of cursor in first position from edit left side. It's used to position
|
| +// info bubble arrow to cursor.
|
| +const int kCursorOffset = 5;
|
| +
|
| // Checks if display names are unique. If there are duplicates, enables
|
| // tooltips with full emails to let users distinguish their accounts.
|
| // Otherwise, disables the tooltips.
|
| @@ -77,6 +81,7 @@ ExistingUserController::ExistingUserController(
|
| background_window_(NULL),
|
| background_view_(NULL),
|
| selected_view_index_(kNotSelected),
|
| + num_login_attempts_(0),
|
| bubble_(NULL) {
|
| if (delete_scheduled_instance_)
|
| delete_scheduled_instance_->Delete();
|
| @@ -189,7 +194,13 @@ void ExistingUserController::Login(UserController* source,
|
| std::vector<UserController*>::const_iterator i =
|
| std::find(controllers_.begin(), controllers_.end(), source);
|
| DCHECK(i != controllers_.end());
|
| - selected_view_index_ = i - controllers_.begin();
|
| +
|
| + if (selected_view_index_ == static_cast<size_t>(i - controllers_.begin())) {
|
| + num_login_attempts_++;
|
| + } else {
|
| + selected_view_index_ = i - controllers_.begin();
|
| + num_login_attempts_ = 0;
|
| + }
|
|
|
| authenticator_ = LoginUtils::Get()->CreateAuthenticator(this);
|
| Profile* profile = g_browser_process->profile_manager()->GetDefaultProfile();
|
| @@ -233,6 +244,7 @@ void ExistingUserController::OnUserSelected(UserController* source) {
|
| selected_view_index_ != kNotSelected) {
|
| controllers_[selected_view_index_]->ClearAndEnableFields();
|
| ClearCaptchaState();
|
| + num_login_attempts_ = 0;
|
| }
|
| selected_view_index_ = new_selected_index;
|
| }
|
| @@ -312,7 +324,10 @@ void ExistingUserController::OnLoginFailure(const LoginFailure& failure) {
|
| ShowError(IDS_LOGIN_ERROR_AUTHENTICATING, error);
|
| }
|
| } else {
|
| - ShowError(IDS_LOGIN_ERROR_AUTHENTICATING, error);
|
| + if (controllers_[selected_view_index_]->is_guest())
|
| + ShowError(IDS_LOGIN_ERROR_AUTHENTICATING_NEW, error);
|
| + else
|
| + ShowError(IDS_LOGIN_ERROR_AUTHENTICATING, error);
|
| }
|
| }
|
|
|
| @@ -345,12 +360,27 @@ void ExistingUserController::ShowError(int error_id,
|
| // low level error info that is not localized and even is not user friendly.
|
| // For now just ignore it because error_text contains all required information
|
| // for end users, developers can see details string in Chrome logs.
|
| +
|
| + gfx::Rect bounds = controllers_[selected_view_index_]->GetScreenBounds();
|
| + BubbleBorder::ArrowLocation arrow;
|
| + if (controllers_[selected_view_index_]->is_guest()) {
|
| + arrow = BubbleBorder::LEFT_TOP;
|
| + } else {
|
| + // Point info bubble arrow to cursor position (approximately).
|
| + bounds.set_width(kCursorOffset * 2);
|
| + arrow = BubbleBorder::BOTTOM_LEFT;
|
| + }
|
| + std::wstring help_link;
|
| + if (num_login_attempts_ > static_cast<size_t>(1))
|
| + help_link = l10n_util::GetString(IDS_CANT_ACCESS_ACCOUNT_BUTTON);
|
| +
|
| bubble_ = MessageBubble::Show(
|
| controllers_[selected_view_index_]->controls_window(),
|
| - controllers_[selected_view_index_]->GetScreenBounds(),
|
| - BubbleBorder::BOTTOM_LEFT,
|
| + bounds,
|
| + arrow,
|
| ResourceBundle::GetSharedInstance().GetBitmapNamed(IDR_WARNING),
|
| error_text,
|
| + help_link,
|
| this);
|
| }
|
|
|
| @@ -402,6 +432,11 @@ void ExistingUserController::OnPasswordChangeDetected(
|
| window->Show();
|
| }
|
|
|
| +void ExistingUserController::OnHelpLinkActivated() {
|
| + AddStartUrl(GetAccountRecoveryHelpUrl());
|
| + LoginOffTheRecord();
|
| +}
|
| +
|
| void ExistingUserController::OnCaptchaEntered(const std::string& captcha) {
|
| login_captcha_ = captcha;
|
| }
|
|
|