172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Use of this source code is governed by a BSD-style license that can be
372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// found in the LICENSE file.
472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/chromeos/login/views_login_display.h"
672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include <algorithm>
872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/stl_util-inl.h"
10dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "base/utf_string_conversions.h"
1172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/chromeos/login/help_app_launcher.h"
1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/chromeos/login/message_bubble.h"
1372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/chromeos/login/wizard_accessibility_helper.h"
1472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/chromeos/view_ids.h"
1572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/chromeos/wm_ipc.h"
1672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/views/window.h"
1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "grit/chromium_strings.h"
1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "grit/generated_resources.h"
19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "grit/theme_resources.h"
2072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h"
2172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/resource/resource_bundle.h"
2272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "views/widget/widget_gtk.h"
2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "views/window/window.h"
2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
2572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsennamespace {
2672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
2772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Max number of users we'll show. The true max is the min of this and the
2872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// number of windows that fit on the screen.
2972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst size_t kMaxUsers = 6;
3072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
3172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Minimum number of users we'll show (including Guest and New User pods).
3272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst size_t kMinUsers = 3;
3372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
3472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Used to indicate no user has been selected.
3572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst size_t kNotSelected = -1;
3672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
3772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Offset of cursor in first position from edit left side. It's used to position
3872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// info bubble arrow to cursor.
3972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenconst int kCursorOffset = 5;
4072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
4172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Checks if display names are unique. If there are duplicates, enables
4272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// tooltips with full emails to let users distinguish their accounts.
4372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Otherwise, disables the tooltips.
4472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid EnableTooltipsIfNeeded(
4572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const std::vector<chromeos::UserController*>& controllers) {
4672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  std::map<std::string, int> visible_display_names;
4772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  for (size_t i = 0; i + 1 < controllers.size(); ++i) {
4872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const std::string& display_name =
4972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        controllers[i]->user().GetDisplayName();
5072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    ++visible_display_names[display_name];
5172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
5272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  for (size_t i = 0; i < controllers.size(); ++i) {
5372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const std::string& display_name =
5472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        controllers[i]->user().GetDisplayName();
5572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    bool show_tooltip = controllers[i]->is_new_user() ||
5672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                        controllers[i]->is_guest() ||
5772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                        visible_display_names[display_name] > 1;
5872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    controllers[i]->EnableNameTooltip(show_tooltip);
5972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
6072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
6172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
6272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}  // namespace
6372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
6472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsennamespace chromeos {
6572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
6672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenViewsLoginDisplay::ViewsLoginDisplay(LoginDisplay::Delegate* delegate,
6772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                     const gfx::Rect& background_bounds)
6872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    : LoginDisplay(delegate, background_bounds),
6972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      bubble_(NULL),
7072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      controller_for_removal_(NULL),
7172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      selected_view_index_(kNotSelected) {
7272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
7372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
7472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenViewsLoginDisplay::~ViewsLoginDisplay() {
7572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ClearErrors();
7672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  STLDeleteElements(&controllers_);
7772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  STLDeleteElements(&invisible_controllers_);
7872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
7972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
8072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen////////////////////////////////////////////////////////////////////////////////
8172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// ViewsLoginDisplay, LoginDisplay implementation:
8272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//
8372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
8472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ViewsLoginDisplay::Init(const std::vector<UserManager::User>& users,
8572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                             bool show_guest,
8672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                             bool show_new_user) {
8772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  size_t max_users = kMaxUsers;
8872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (width() > 0) {
8972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    size_t users_per_screen = (width() - login::kUserImageSize) /
9072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        (UserController::kUnselectedSize + UserController::kPadding);
9172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    max_users = std::max(kMinUsers, std::min(kMaxUsers, users_per_screen));
9272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
9372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  size_t visible_users_count = std::min(users.size(), max_users -
9572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      static_cast<int>(show_guest) - static_cast<int>(show_new_user));
9672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  for (size_t i = 0; i < users.size(); ++i) {
9772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    UserController* user_controller = new UserController(this, users[i]);
9872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (controllers_.size() < visible_users_count) {
9972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      controllers_.push_back(user_controller);
10072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    } else if (user_controller->is_owner()) {
10172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      // Make sure that owner of the device is always visible on login screen.
10272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      invisible_controllers_.insert(invisible_controllers_.begin(),
10372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                    controllers_.back());
10472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      controllers_.back() = user_controller;
10572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    } else {
10672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      invisible_controllers_.push_back(user_controller);
10772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    }
10872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
10972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (show_guest)
11072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    controllers_.push_back(new UserController(this, true));
11172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
11272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (show_new_user)
11372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    controllers_.push_back(new UserController(this, false));
11472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
11572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // If there's only new user pod, show the guest session link on it.
11672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  bool show_guest_link = controllers_.size() == 1;
11772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  for (size_t i = 0; i < controllers_.size(); ++i) {
11872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    (controllers_[i])->Init(static_cast<int>(i),
11972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                            static_cast<int>(controllers_.size()),
12072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                            show_guest_link);
12172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
12272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EnableTooltipsIfNeeded(controllers_);
12372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
12472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
12572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ViewsLoginDisplay::OnBeforeUserRemoved(const std::string& username) {
12672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  controller_for_removal_ = controllers_[selected_view_index_];
12772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  controllers_.erase(controllers_.begin() + selected_view_index_);
12872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EnableTooltipsIfNeeded(controllers_);
12972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
13072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Update user count before unmapping windows, otherwise window manager won't
13172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // be in the right state.
13272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  int new_size = static_cast<int>(controllers_.size());
13372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  for (int i = 0; i < new_size; ++i)
13472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    controllers_[i]->UpdateUserCount(i, new_size);
13572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
13672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
13772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ViewsLoginDisplay::OnUserImageChanged(UserManager::User* user) {
13872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  UserController* controller = GetUserControllerByEmail(user->email());
13972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (controller)
14072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    controller->OnUserImageChanged(user);
14172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
14272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
14372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ViewsLoginDisplay::OnUserRemoved(const std::string& username) {
14472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // We need to unmap entry windows, the windows will be unmapped in destructor.
145dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  MessageLoop::current()->DeleteSoon(FROM_HERE, controller_for_removal_);
14672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  controller_for_removal_ = NULL;
14772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
14872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Nothing to insert.
14972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (invisible_controllers_.empty())
15072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
15172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
15272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Insert just before guest or add new user pods if any.
153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  size_t new_size = controllers_.size();
154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  size_t insert_position = new_size;
15572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  while (insert_position > 0 &&
15672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen         (controllers_[insert_position - 1]->is_new_user() ||
157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          controllers_[insert_position - 1]->is_guest())) {
15872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    --insert_position;
159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
16072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
16172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  controllers_.insert(controllers_.begin() + insert_position,
16272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                      invisible_controllers_[0]);
16372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  invisible_controllers_.erase(invisible_controllers_.begin());
16472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
16572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Update counts for exiting pods.
166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  new_size = controllers_.size();
167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (size_t i = 0; i < new_size; ++i) {
16872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if (i != insert_position)
16972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      controllers_[i]->UpdateUserCount(i, new_size);
17072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
17172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
17272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // And initialize new one that was invisible.
17372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  controllers_[insert_position]->Init(insert_position, new_size, false);
17472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
17572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EnableTooltipsIfNeeded(controllers_);
17672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
17772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
17872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ViewsLoginDisplay::OnFadeOut() {
17972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  controllers_[selected_view_index_]->StopThrobber();
18072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
18172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
18272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ViewsLoginDisplay::SetUIEnabled(bool is_enabled) {
18372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Send message to WM to enable/disable click on windows.
18472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  WmIpc::Message message(WM_IPC_MESSAGE_WM_SET_LOGIN_STATE);
18572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  message.set_param(0, is_enabled);
18672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  WmIpc::instance()->SendMessage(message);
18772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
18872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (is_enabled)
18972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    controllers_[selected_view_index_]->ClearAndEnablePassword();
19072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
19172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
19272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ViewsLoginDisplay::ShowError(int error_msg_id,
19372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                  int login_attempts,
19472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                  HelpAppLauncher::HelpTopic help_topic_id) {
19572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ClearErrors();
19672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  string16 error_text;
19772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  error_msg_id_ = error_msg_id;
19872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  help_topic_id_ = help_topic_id;
19972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
20072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // GetStringF fails on debug build if there's no replacement in the string.
20172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (error_msg_id == IDS_LOGIN_ERROR_AUTHENTICATING_HOSTED) {
20272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    error_text = l10n_util::GetStringFUTF16(
20372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        error_msg_id, l10n_util::GetStringUTF16(IDS_PRODUCT_OS_NAME));
204dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  } else if (error_msg_id == IDS_LOGIN_ERROR_CAPTIVE_PORTAL) {
205dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    error_text = l10n_util::GetStringFUTF16(
206dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        error_msg_id, delegate()->GetConnectedNetworkName());
20772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  } else {
20872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    error_text = l10n_util::GetStringUTF16(error_msg_id);
20972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
21072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
21172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  gfx::Rect bounds =
21272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      controllers_[selected_view_index_]->GetMainInputScreenBounds();
21372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  BubbleBorder::ArrowLocation arrow;
21472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (controllers_[selected_view_index_]->is_new_user()) {
21572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    arrow = BubbleBorder::LEFT_TOP;
21672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  } else {
21772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    // Point info bubble arrow to cursor position (approximately).
21872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    bounds.set_width(kCursorOffset * 2);
21972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    arrow = BubbleBorder::BOTTOM_LEFT;
22072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
22172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
22272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  string16 help_link;
22372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (error_msg_id == IDS_LOGIN_ERROR_CAPTIVE_PORTAL) {
22472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    help_link = l10n_util::GetStringUTF16(IDS_LOGIN_FIX_CAPTIVE_PORTAL);
225dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  } else if (error_msg_id == IDS_LOGIN_ERROR_CAPTIVE_PORTAL_NO_GUEST_MODE) {
226dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    // No help link is needed.
22772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  } else if (error_msg_id == IDS_LOGIN_ERROR_AUTHENTICATING_HOSTED ||
22872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen             login_attempts > 1) {
22972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    help_link = l10n_util::GetStringUTF16(IDS_LEARN_MORE);
23072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
23172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
23272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  bubble_ = MessageBubble::Show(
23372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      controllers_[selected_view_index_]->controls_window(),
23472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      bounds,
23572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      arrow,
23672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      ResourceBundle::GetSharedInstance().GetBitmapNamed(IDR_WARNING),
23772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      UTF16ToWide(error_text),
23872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      UTF16ToWide(help_link),
23972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      this);
24072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  WizardAccessibilityHelper::GetInstance()->MaybeSpeak(
24172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      UTF16ToUTF8(error_text).c_str(), false, false);
24272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
24372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
24472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen////////////////////////////////////////////////////////////////////////////////
24572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// ViewsLoginDisplay, UserController::Delegate implementation:
24672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//
24772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
24872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ViewsLoginDisplay::CreateAccount() {
24972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  delegate()->CreateAccount();
25072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
25172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
25272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ViewsLoginDisplay::Login(UserController* source,
25372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                              const string16& password) {
25472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  delegate()->Login(source->user().email(), UTF16ToUTF8(password));
25572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
25672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
25772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ViewsLoginDisplay::LoginAsGuest() {
25872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  delegate()->LoginAsGuest();
25972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
26072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
26172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ViewsLoginDisplay::ClearErrors() {
26272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // bubble_ will be set to NULL in callback.
26372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (bubble_)
26472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    bubble_->Close();
26572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
26672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
26772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ViewsLoginDisplay::OnUserSelected(UserController* source) {
26872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  std::vector<UserController*>::const_iterator i =
26972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      std::find(controllers_.begin(), controllers_.end(), source);
27072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  DCHECK(i != controllers_.end());
27172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  size_t new_selected_index = i - controllers_.begin();
27272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (new_selected_index != selected_view_index_ &&
27372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      selected_view_index_ != kNotSelected) {
27472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    controllers_[selected_view_index_]->ClearAndEnableFields();
27572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    controllers_[new_selected_index]->ClearAndEnableFields();
27672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    delegate()->OnUserSelected(source->user().email());
27772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
27872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  selected_view_index_ = new_selected_index;
279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  WizardAccessibilityHelper::GetInstance()->MaybeSpeak(
280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      source->GetAccessibleUserLabel().c_str(), false, true);
28172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
28272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
28372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ViewsLoginDisplay::RemoveUser(UserController* source) {
28472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ClearErrors();
285dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  UserManager::Get()->RemoveUser(source->user().email(), this);
28672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
28772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
28872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ViewsLoginDisplay::SelectUser(int index) {
28972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (index >= 0 && index < static_cast<int>(controllers_.size()) &&
29072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      index != static_cast<int>(selected_view_index_)) {
29172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    WmIpc::Message message(WM_IPC_MESSAGE_WM_SELECT_LOGIN_USER);
29272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    message.set_param(0, index);
29372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    WmIpc::instance()->SendMessage(message);
29472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
29572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
29672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
297ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ViewsLoginDisplay::StartEnterpriseEnrollment() {
298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  delegate()->OnStartEnterpriseEnrollment();
299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
30172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen////////////////////////////////////////////////////////////////////////////////
30272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// ViewsLoginDisplay, views::MessageBubbleDelegate implementation:
30372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//
30472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
30572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid ViewsLoginDisplay::OnHelpLinkActivated() {
30672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ClearErrors();
30772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (error_msg_id_ == IDS_LOGIN_ERROR_CAPTIVE_PORTAL) {
30872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    delegate()->FixCaptivePortal();
30972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
31072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
31172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!parent_window())
31272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
31372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!help_app_.get())
31472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    help_app_ = new HelpAppLauncher(parent_window());
31572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  help_app_->ShowHelpTopic(help_topic_id_);
31672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
31772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
31872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen////////////////////////////////////////////////////////////////////////////////
31972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// ViewsLoginDisplay, private:
32072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen//
32172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
32272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenUserController* ViewsLoginDisplay::GetUserControllerByEmail(
32372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    const std::string& email) {
32472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  std::vector<UserController*>::iterator i;
32572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  for (i = controllers_.begin(); i != controllers_.end(); ++i) {
32672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if ((*i)->user().email() == email)
32772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return *i;
32872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
32972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  for (i = invisible_controllers_.begin();
33072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen       i != invisible_controllers_.end(); ++i) {
33172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    if ((*i)->user().email() == email)
33272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      return *i;
33372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
33472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return NULL;
33572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
33672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
33772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}  // namespace chromeos
338