1// Copyright 2014 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/chromeos/login/ui/webui_login_display.h"
6
7#include "ash/shell.h"
8#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
9#include "chrome/browser/chromeos/login/lock/screen_locker.h"
10#include "chrome/browser/chromeos/login/screens/chrome_user_selection_screen.h"
11#include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
12#include "chrome/browser/chromeos/login/ui/user_adding_screen.h"
13#include "chrome/browser/chromeos/login/ui/webui_login_view.h"
14#include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h"
15#include "chrome/browser/profiles/profile_manager.h"
16#include "chrome/browser/ui/browser_window.h"
17#include "chrome/grit/chromium_strings.h"
18#include "chrome/grit/generated_resources.h"
19#include "chromeos/ime/ime_keyboard.h"
20#include "chromeos/ime/input_method_manager.h"
21#include "chromeos/login/user_names.h"
22#include "components/user_manager/user_manager.h"
23#include "grit/components_strings.h"
24#include "ui/base/l10n/l10n_util.h"
25#include "ui/views/widget/widget.h"
26#include "ui/wm/core/user_activity_detector.h"
27
28namespace chromeos {
29
30// WebUILoginDisplay, public: --------------------------------------------------
31
32WebUILoginDisplay::~WebUILoginDisplay() {
33  if (webui_handler_)
34    webui_handler_->ResetSigninScreenHandlerDelegate();
35#if !defined(USE_ATHENA)
36  wm::UserActivityDetector* activity_detector = ash::Shell::GetInstance()->
37    user_activity_detector();
38  if (activity_detector->HasObserver(this))
39    activity_detector->RemoveObserver(this);
40#endif
41}
42
43// LoginDisplay implementation: ------------------------------------------------
44
45WebUILoginDisplay::WebUILoginDisplay(LoginDisplay::Delegate* delegate)
46    : LoginDisplay(delegate, gfx::Rect()),
47      show_guest_(false),
48      show_new_user_(false),
49      webui_handler_(NULL),
50      gaia_screen_(new GaiaScreen()),
51      user_selection_screen_(new ChromeUserSelectionScreen()) {
52}
53
54void WebUILoginDisplay::ClearAndEnablePassword() {
55  if (webui_handler_)
56      webui_handler_->ClearAndEnablePassword();
57}
58
59void WebUILoginDisplay::Init(const user_manager::UserList& users,
60                             bool show_guest,
61                             bool show_users,
62                             bool show_new_user) {
63  // Testing that the delegate has been set.
64  DCHECK(delegate_);
65
66  user_selection_screen_->Init(users, show_guest);
67  show_guest_ = show_guest;
68  show_users_ = show_users;
69  show_new_user_ = show_new_user;
70
71#if !defined(USE_ATHENA)
72  wm::UserActivityDetector* activity_detector = ash::Shell::GetInstance()->
73      user_activity_detector();
74  if (!activity_detector->HasObserver(this))
75    activity_detector->AddObserver(this);
76#endif
77}
78
79// ---- Common methods
80
81// ---- User selection screen methods
82
83void WebUILoginDisplay::OnBeforeUserRemoved(const std::string& username) {
84  user_selection_screen_->OnBeforeUserRemoved(username);
85}
86
87void WebUILoginDisplay::OnUserRemoved(const std::string& username) {
88  user_selection_screen_->OnUserRemoved(username);
89}
90
91void WebUILoginDisplay::OnUserImageChanged(const user_manager::User& user) {
92  user_selection_screen_->OnUserImageChanged(user);
93}
94
95void WebUILoginDisplay::HandleGetUsers() {
96  user_selection_screen_->HandleGetUsers();
97}
98
99const user_manager::UserList& WebUILoginDisplay::GetUsers() const {
100  return user_selection_screen_->GetUsers();
101}
102
103// User selection screen, screen lock API
104
105void WebUILoginDisplay::SetAuthType(
106    const std::string& username,
107    ScreenlockBridge::LockHandler::AuthType auth_type) {
108  user_selection_screen_->SetAuthType(username, auth_type);
109}
110
111ScreenlockBridge::LockHandler::AuthType WebUILoginDisplay::GetAuthType(
112    const std::string& username) const {
113  return user_selection_screen_->GetAuthType(username);
114}
115
116// ---- Gaia screen methods
117
118// ---- Not yet classified methods
119
120void WebUILoginDisplay::OnPreferencesChanged() {
121  if (webui_handler_)
122    webui_handler_->OnPreferencesChanged();
123}
124
125void WebUILoginDisplay::SetUIEnabled(bool is_enabled) {
126  // TODO(nkostylev): Cleanup this condition,
127  // see http://crbug.com/157885 and http://crbug.com/158255.
128  // Allow this call only before user sign in or at lock screen.
129  // If this call is made after new user signs in but login screen is still
130  // around that would trigger a sign in extension refresh.
131  if (is_enabled && (!user_manager::UserManager::Get()->IsUserLoggedIn() ||
132                     ScreenLocker::default_screen_locker())) {
133    ClearAndEnablePassword();
134  }
135
136  if (chromeos::LoginDisplayHost* host =
137          chromeos::LoginDisplayHostImpl::default_host()) {
138    if (chromeos::WebUILoginView* login_view = host->GetWebUILoginView())
139      login_view->SetUIEnabled(is_enabled);
140  }
141}
142
143void WebUILoginDisplay::ShowError(int error_msg_id,
144                                  int login_attempts,
145                                  HelpAppLauncher::HelpTopic help_topic_id) {
146  VLOG(1) << "Show error, error_id: " << error_msg_id
147          << ", attempts:" << login_attempts
148          <<  ", help_topic_id: " << help_topic_id;
149  if (!webui_handler_)
150    return;
151
152  std::string error_text;
153  switch (error_msg_id) {
154    case IDS_LOGIN_ERROR_AUTHENTICATING_HOSTED:
155      error_text = l10n_util::GetStringFUTF8(
156          error_msg_id, l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_OS_NAME));
157      break;
158    case IDS_LOGIN_ERROR_CAPTIVE_PORTAL:
159      error_text = l10n_util::GetStringFUTF8(
160          error_msg_id, delegate()->GetConnectedNetworkName());
161      break;
162    default:
163      error_text = l10n_util::GetStringUTF8(error_msg_id);
164      break;
165  }
166
167  // Only display hints about keyboard layout if the error is authentication-
168  // related.
169  if (error_msg_id != IDS_LOGIN_ERROR_WHITELIST &&
170      error_msg_id != IDS_LOGIN_ERROR_OWNER_KEY_LOST &&
171      error_msg_id != IDS_LOGIN_ERROR_OWNER_REQUIRED) {
172    // Display a warning if Caps Lock is on.
173    input_method::InputMethodManager* ime_manager =
174        input_method::InputMethodManager::Get();
175    if (ime_manager->GetImeKeyboard()->CapsLockIsEnabled()) {
176      // TODO(ivankr): use a format string instead of concatenation.
177      error_text += "\n" +
178          l10n_util::GetStringUTF8(IDS_LOGIN_ERROR_CAPS_LOCK_HINT);
179    }
180
181    // Display a hint to switch keyboards if there are other active input
182    // methods.
183    if (ime_manager->GetActiveIMEState()->GetNumActiveInputMethods() > 1) {
184      error_text += "\n" +
185          l10n_util::GetStringUTF8(IDS_LOGIN_ERROR_KEYBOARD_SWITCH_HINT);
186    }
187  }
188
189  std::string help_link;
190  switch (error_msg_id) {
191    case IDS_LOGIN_ERROR_AUTHENTICATING_HOSTED:
192      help_link = l10n_util::GetStringUTF8(IDS_LEARN_MORE);
193      break;
194    default:
195      if (login_attempts > 1)
196        help_link = l10n_util::GetStringUTF8(IDS_LEARN_MORE);
197      break;
198  }
199
200  webui_handler_->ShowError(login_attempts, error_text, help_link,
201                            help_topic_id);
202}
203
204void WebUILoginDisplay::ShowErrorScreen(LoginDisplay::SigninError error_id) {
205  VLOG(1) << "Show error screen, error_id: " << error_id;
206  if (!webui_handler_)
207    return;
208  webui_handler_->ShowErrorScreen(error_id);
209}
210
211void WebUILoginDisplay::ShowGaiaPasswordChanged(const std::string& username) {
212  if (webui_handler_)
213    webui_handler_->ShowGaiaPasswordChanged(username);
214}
215
216void WebUILoginDisplay::ShowPasswordChangedDialog(bool show_password_error) {
217  if (webui_handler_)
218    webui_handler_->ShowPasswordChangedDialog(show_password_error);
219}
220
221void WebUILoginDisplay::ShowSigninUI(const std::string& email) {
222  if (webui_handler_)
223    webui_handler_->ShowSigninUI(email);
224}
225
226// WebUILoginDisplay, NativeWindowDelegate implementation: ---------------------
227gfx::NativeWindow WebUILoginDisplay::GetNativeWindow() const {
228  return parent_window();
229}
230
231// WebUILoginDisplay, SigninScreenHandlerDelegate implementation: --------------
232void WebUILoginDisplay::CancelPasswordChangedFlow() {
233  DCHECK(delegate_);
234  if (delegate_)
235    delegate_->CancelPasswordChangedFlow();
236}
237
238void WebUILoginDisplay::CancelUserAdding() {
239  if (!UserAddingScreen::Get()->IsRunning()) {
240    LOG(ERROR) << "User adding screen not running.";
241    return;
242  }
243  UserAddingScreen::Get()->Cancel();
244}
245
246void WebUILoginDisplay::CreateAccount() {
247  DCHECK(delegate_);
248  if (delegate_)
249    delegate_->CreateAccount();
250}
251
252void WebUILoginDisplay::CompleteLogin(const UserContext& user_context) {
253  DCHECK(delegate_);
254  if (delegate_)
255    delegate_->CompleteLogin(user_context);
256}
257
258void WebUILoginDisplay::Login(const UserContext& user_context,
259                              const SigninSpecifics& specifics) {
260  DCHECK(delegate_);
261  if (delegate_)
262    delegate_->Login(user_context, specifics);
263}
264
265void WebUILoginDisplay::MigrateUserData(const std::string& old_password) {
266  DCHECK(delegate_);
267  if (delegate_)
268    delegate_->MigrateUserData(old_password);
269}
270
271void WebUILoginDisplay::LoadWallpaper(const std::string& username) {
272  WallpaperManager::Get()->SetUserWallpaperDelayed(username);
273}
274
275void WebUILoginDisplay::LoadSigninWallpaper() {
276  WallpaperManager::Get()->SetDefaultWallpaperDelayed(
277      chromeos::login::kSignInUser);
278}
279
280void WebUILoginDisplay::OnSigninScreenReady() {
281  if (delegate_)
282    delegate_->OnSigninScreenReady();
283}
284
285void WebUILoginDisplay::RemoveUser(const std::string& username) {
286  user_manager::UserManager::Get()->RemoveUser(username, this);
287}
288
289void WebUILoginDisplay::ResyncUserData() {
290  DCHECK(delegate_);
291  if (delegate_)
292    delegate_->ResyncUserData();
293}
294
295void WebUILoginDisplay::ShowEnterpriseEnrollmentScreen() {
296  if (delegate_)
297    delegate_->OnStartEnterpriseEnrollment();
298}
299
300void WebUILoginDisplay::ShowKioskEnableScreen() {
301  if (delegate_)
302    delegate_->OnStartKioskEnableScreen();
303}
304
305void WebUILoginDisplay::ShowKioskAutolaunchScreen() {
306  if (delegate_)
307    delegate_->OnStartKioskAutolaunchScreen();
308}
309
310void WebUILoginDisplay::ShowWrongHWIDScreen() {
311  if (delegate_)
312    delegate_->ShowWrongHWIDScreen();
313}
314
315void WebUILoginDisplay::SetWebUIHandler(
316    LoginDisplayWebUIHandler* webui_handler) {
317  webui_handler_ = webui_handler;
318  gaia_screen_->SetHandler(webui_handler_);
319  user_selection_screen_->SetHandler(webui_handler_);
320}
321
322void WebUILoginDisplay::ShowSigninScreenForCreds(
323    const std::string& username,
324    const std::string& password) {
325  if (webui_handler_)
326    webui_handler_->ShowSigninScreenForCreds(username, password);
327}
328
329bool WebUILoginDisplay::IsShowGuest() const {
330  return show_guest_;
331}
332
333bool WebUILoginDisplay::IsShowUsers() const {
334  return show_users_;
335}
336
337bool WebUILoginDisplay::IsSigninInProgress() const {
338  return delegate_->IsSigninInProgress();
339}
340
341bool WebUILoginDisplay::IsUserSigninCompleted() const {
342  return is_signin_completed();
343}
344
345void WebUILoginDisplay::SetDisplayEmail(const std::string& email) {
346  if (delegate_)
347    delegate_->SetDisplayEmail(email);
348}
349
350void WebUILoginDisplay::Signout() {
351  delegate_->Signout();
352}
353
354void WebUILoginDisplay::OnUserActivity(const ui::Event* event) {
355  if (delegate_)
356    delegate_->ResetPublicSessionAutoLoginTimer();
357}
358
359
360}  // namespace chromeos
361