ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / chrome / browser / chromeos / login / lock / webui_screen_locker.cc
blob08cdae9e7979eb22314d03329318ef51f3e499f7
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.
5 #include "chrome/browser/chromeos/login/lock/webui_screen_locker.h"
7 #include "ash/shell.h"
8 #include "ash/system/chromeos/power/power_event_observer.h"
9 #include "ash/wm/lock_state_controller.h"
10 #include "ash/wm/lock_state_observer.h"
11 #include "base/command_line.h"
12 #include "base/metrics/histogram.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/values.h"
15 #include "chrome/browser/browser_shutdown.h"
16 #include "chrome/browser/chrome_notification_types.h"
17 #include "chrome/browser/chromeos/accessibility/accessibility_util.h"
18 #include "chrome/browser/chromeos/login/helper.h"
19 #include "chrome/browser/chromeos/login/lock/screen_locker.h"
20 #include "chrome/browser/chromeos/login/ui/webui_login_display.h"
21 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
22 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
23 #include "chrome/common/url_constants.h"
24 #include "chromeos/dbus/dbus_thread_manager.h"
25 #include "components/user_manager/user.h"
26 #include "content/public/browser/browser_thread.h"
27 #include "content/public/browser/notification_service.h"
28 #include "content/public/browser/notification_types.h"
29 #include "content/public/browser/render_widget_host_view.h"
30 #include "content/public/browser/web_ui.h"
31 #include "ui/aura/client/capture_client.h"
32 #include "ui/aura/window_event_dispatcher.h"
33 #include "ui/base/x/x11_util.h"
34 #include "ui/gfx/screen.h"
35 #include "ui/keyboard/keyboard_controller.h"
36 #include "ui/keyboard/keyboard_util.h"
37 #include "ui/views/controls/webview/webview.h"
39 namespace {
41 // URL which corresponds to the login WebUI.
42 const char kLoginURL[] = "chrome://oobe/lock";
44 // Disables virtual keyboard overscroll. Login UI will scroll user pods
45 // into view on JS side when virtual keyboard is shown.
46 void DisableKeyboardOverscroll() {
47 keyboard::SetKeyboardOverscrollOverride(
48 keyboard::KEYBOARD_OVERSCROLL_OVERRIDE_DISABLED);
51 void ResetKeyboardOverscrollOverride() {
52 keyboard::SetKeyboardOverscrollOverride(
53 keyboard::KEYBOARD_OVERSCROLL_OVERRIDE_NONE);
56 } // namespace
58 namespace chromeos {
60 ////////////////////////////////////////////////////////////////////////////////
61 // WebUIScreenLocker implementation.
63 WebUIScreenLocker::WebUIScreenLocker(ScreenLocker* screen_locker)
64 : ScreenLockerDelegate(screen_locker),
65 lock_ready_(false),
66 webui_ready_(false),
67 network_state_helper_(new login::NetworkStateHelper),
68 is_observing_keyboard_(false),
69 weak_factory_(this) {
70 set_should_emit_login_prompt_visible(false);
71 ash::Shell::GetInstance()->lock_state_controller()->AddObserver(this);
72 ash::Shell::GetInstance()->delegate()->AddVirtualKeyboardStateObserver(this);
73 ash::Shell::GetScreen()->AddObserver(this);
74 DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(this);
76 if (keyboard::KeyboardController::GetInstance()) {
77 keyboard::KeyboardController::GetInstance()->AddObserver(this);
78 is_observing_keyboard_ = true;
82 void WebUIScreenLocker::LockScreen() {
83 gfx::Rect bounds =
84 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().bounds();
86 lock_time_ = base::TimeTicks::Now();
87 LockWindow* lock_window = LockWindow::Create();
88 lock_window->set_observer(this);
89 lock_window->set_initially_focused_view(this);
90 lock_window_ = lock_window->GetWidget();
91 lock_window_->AddObserver(this);
92 WebUILoginView::Init();
93 lock_window_->SetContentsView(this);
94 lock_window_->SetBounds(bounds);
95 lock_window_->Show();
96 LoadURL(GURL(kLoginURL));
97 lock_window->Grab();
99 signin_screen_controller_.reset(
100 new SignInScreenController(GetOobeUI(), this));
102 login_display_.reset(new WebUILoginDisplay(this));
103 login_display_->set_background_bounds(bounds);
104 login_display_->set_parent_window(GetNativeWindow());
105 login_display_->Init(screen_locker()->users(), false, true, false);
107 GetOobeUI()->ShowSigninScreen(
108 LoginScreenContext(), login_display_.get(), login_display_.get());
110 if (login::LoginScrollIntoViewEnabled())
111 DisableKeyboardOverscroll();
114 void WebUIScreenLocker::ScreenLockReady() {
115 UMA_HISTOGRAM_TIMES("LockScreen.LockReady",
116 base::TimeTicks::Now() - lock_time_);
117 ScreenLockerDelegate::ScreenLockReady();
118 SetInputEnabled(true);
121 void WebUIScreenLocker::OnAuthenticate() {
124 void WebUIScreenLocker::SetInputEnabled(bool enabled) {
125 login_display_->SetUIEnabled(enabled);
128 void WebUIScreenLocker::ShowErrorMessage(
129 int error_msg_id,
130 HelpAppLauncher::HelpTopic help_topic_id) {
131 login_display_->ShowError(error_msg_id,
132 0 /* login_attempts */,
133 help_topic_id);
136 void WebUIScreenLocker::AnimateAuthenticationSuccess() {
137 GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.animateAuthenticationSuccess");
140 void WebUIScreenLocker::ClearErrors() {
141 GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.clearErrors");
144 gfx::NativeWindow WebUIScreenLocker::GetNativeWindow() const {
145 return lock_window_->GetNativeWindow();
148 content::WebUI* WebUIScreenLocker::GetAssociatedWebUI() {
149 return GetWebUI();
152 void WebUIScreenLocker::FocusUserPod() {
153 if (!webui_ready_)
154 return;
155 webui_login_->RequestFocus();
156 GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.forceLockedUserPodFocus");
159 void WebUIScreenLocker::ResetAndFocusUserPod() {
160 if (!webui_ready_)
161 return;
162 GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.clearUserPodPassword");
163 FocusUserPod();
166 WebUIScreenLocker::~WebUIScreenLocker() {
167 DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(this);
168 ash::Shell::GetScreen()->RemoveObserver(this);
169 ash::Shell::GetInstance()->
170 lock_state_controller()->RemoveObserver(this);
172 ash::Shell::GetInstance()->delegate()->
173 RemoveVirtualKeyboardStateObserver(this);
174 // In case of shutdown, lock_window_ may be deleted before WebUIScreenLocker.
175 if (lock_window_) {
176 lock_window_->RemoveObserver(this);
177 lock_window_->Close();
179 // If LockScreen() was called, we need to clear the signin screen handler
180 // delegate set in ShowSigninScreen so that it no longer points to us.
181 if (login_display_.get()) {
182 static_cast<OobeUI*>(GetWebUI()->GetController())->
183 ResetSigninScreenHandlerDelegate();
186 if (keyboard::KeyboardController::GetInstance() && is_observing_keyboard_) {
187 keyboard::KeyboardController::GetInstance()->RemoveObserver(this);
188 is_observing_keyboard_ = false;
191 if (login::LoginScrollIntoViewEnabled())
192 ResetKeyboardOverscrollOverride();
195 void WebUIScreenLocker::OnLockWebUIReady() {
196 VLOG(1) << "WebUI ready; lock window is "
197 << (lock_ready_ ? "too" : "not");
198 webui_ready_ = true;
199 if (lock_ready_)
200 ScreenLockReady();
203 void WebUIScreenLocker::OnLockBackgroundDisplayed() {
204 UMA_HISTOGRAM_TIMES("LockScreen.BackgroundReady",
205 base::TimeTicks::Now() - lock_time_);
208 void WebUIScreenLocker::OnHeaderBarVisible() {
209 DCHECK(ash::Shell::HasInstance());
211 ash::Shell::GetInstance()->power_event_observer()->OnLockAnimationsComplete();
214 OobeUI* WebUIScreenLocker::GetOobeUI() {
215 return static_cast<OobeUI*>(GetWebUI()->GetController());
218 ////////////////////////////////////////////////////////////////////////////////
219 // WebUIScreenLocker, LoginDisplay::Delegate:
221 void WebUIScreenLocker::CancelPasswordChangedFlow() {
222 NOTREACHED();
225 void WebUIScreenLocker::CreateAccount() {
226 NOTREACHED();
229 void WebUIScreenLocker::CompleteLogin(const UserContext& user_context) {
230 NOTREACHED();
233 base::string16 WebUIScreenLocker::GetConnectedNetworkName() {
234 return network_state_helper_->GetCurrentNetworkName();
237 bool WebUIScreenLocker::IsSigninInProgress() const {
238 // The way how screen locker is implemented right now there's no
239 // GAIA sign in in progress in any case.
240 return false;
243 void WebUIScreenLocker::Login(const UserContext& user_context,
244 const SigninSpecifics& specifics) {
245 chromeos::ScreenLocker::default_screen_locker()->Authenticate(user_context);
248 void WebUIScreenLocker::MigrateUserData(const std::string& old_password) {
249 NOTREACHED();
252 void WebUIScreenLocker::OnSigninScreenReady() {
255 void WebUIScreenLocker::OnStartEnterpriseEnrollment() {
256 NOTREACHED();
259 void WebUIScreenLocker::OnStartEnableDebuggingScreen() {
260 NOTREACHED();
263 void WebUIScreenLocker::OnStartKioskEnableScreen() {
264 NOTREACHED();
267 void WebUIScreenLocker::OnStartKioskAutolaunchScreen() {
268 NOTREACHED();
271 void WebUIScreenLocker::ShowWrongHWIDScreen() {
272 NOTREACHED();
275 void WebUIScreenLocker::ResetPublicSessionAutoLoginTimer() {
278 void WebUIScreenLocker::ResyncUserData() {
279 NOTREACHED();
282 void WebUIScreenLocker::SetDisplayEmail(const std::string& email) {
283 NOTREACHED();
286 void WebUIScreenLocker::Signout() {
287 chromeos::ScreenLocker::default_screen_locker()->Signout();
290 ////////////////////////////////////////////////////////////////////////////////
291 // LockWindow::Observer:
293 void WebUIScreenLocker::OnLockWindowReady() {
294 VLOG(1) << "Lock window ready; WebUI is " << (webui_ready_ ? "too" : "not");
295 lock_ready_ = true;
296 if (webui_ready_)
297 ScreenLockReady();
300 ////////////////////////////////////////////////////////////////////////////////
301 // SessionLockStateObserver:
303 void WebUIScreenLocker::OnLockStateEvent(
304 ash::LockStateObserver::EventType event) {
305 if (event == ash::LockStateObserver::EVENT_LOCK_ANIMATION_FINISHED) {
306 // Release capture if any.
307 aura::client::GetCaptureClient(GetNativeWindow()->GetRootWindow())->
308 SetCapture(NULL);
309 GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.animateOnceFullyDisplayed");
313 ////////////////////////////////////////////////////////////////////////////////
314 // WidgetObserver:
316 void WebUIScreenLocker::OnWidgetDestroying(views::Widget* widget) {
317 lock_window_->RemoveObserver(this);
318 lock_window_ = NULL;
321 ////////////////////////////////////////////////////////////////////////////////
322 // PowerManagerClient::Observer:
324 void WebUIScreenLocker::LidEventReceived(bool open,
325 const base::TimeTicks& time) {
326 if (open) {
327 content::BrowserThread::PostTask(
328 content::BrowserThread::UI, FROM_HERE,
329 base::Bind(&WebUIScreenLocker::FocusUserPod,
330 weak_factory_.GetWeakPtr()));
334 void WebUIScreenLocker::SuspendImminent() {
335 content::BrowserThread::PostTask(
336 content::BrowserThread::UI, FROM_HERE,
337 base::Bind(&WebUIScreenLocker::ResetAndFocusUserPod,
338 weak_factory_.GetWeakPtr()));
341 void WebUIScreenLocker::SuspendDone(const base::TimeDelta& sleep_duration) {
342 content::BrowserThread::PostTask(
343 content::BrowserThread::UI,
344 FROM_HERE,
345 base::Bind(&WebUIScreenLocker::FocusUserPod, weak_factory_.GetWeakPtr()));
348 void WebUIScreenLocker::RenderProcessGone(base::TerminationStatus status) {
349 if (browser_shutdown::GetShutdownType() == browser_shutdown::NOT_VALID &&
350 status != base::TERMINATION_STATUS_NORMAL_TERMINATION) {
351 LOG(ERROR) << "Renderer crash on lock screen";
352 Signout();
356 ////////////////////////////////////////////////////////////////////////////////
357 // ash::KeyboardStateObserver overrides.
359 void WebUIScreenLocker::OnVirtualKeyboardStateChanged(bool activated) {
360 if (keyboard::KeyboardController::GetInstance()) {
361 if (activated) {
362 if (!is_observing_keyboard_) {
363 keyboard::KeyboardController::GetInstance()->AddObserver(this);
364 is_observing_keyboard_ = true;
366 } else {
367 keyboard::KeyboardController::GetInstance()->RemoveObserver(this);
368 is_observing_keyboard_ = false;
373 ////////////////////////////////////////////////////////////////////////////////
374 // keyboard::KeyboardControllerObserver:
376 void WebUIScreenLocker::OnKeyboardBoundsChanging(
377 const gfx::Rect& new_bounds) {
378 if (new_bounds.IsEmpty() && !keyboard_bounds_.IsEmpty()) {
379 // Keyboard has been hidden.
380 if (GetOobeUI()) {
381 GetOobeUI()->GetCoreOobeActor()->ShowControlBar(true);
382 if (login::LoginScrollIntoViewEnabled())
383 GetOobeUI()->GetCoreOobeActor()->SetKeyboardState(false, new_bounds);
385 } else if (!new_bounds.IsEmpty() && keyboard_bounds_.IsEmpty()) {
386 // Keyboard has been shown.
387 if (GetOobeUI()) {
388 GetOobeUI()->GetCoreOobeActor()->ShowControlBar(false);
389 if (login::LoginScrollIntoViewEnabled())
390 GetOobeUI()->GetCoreOobeActor()->SetKeyboardState(true, new_bounds);
394 keyboard_bounds_ = new_bounds;
397 ////////////////////////////////////////////////////////////////////////////////
398 // gfx::DisplayObserver:
400 void WebUIScreenLocker::OnDisplayAdded(const gfx::Display& new_display) {
403 void WebUIScreenLocker::OnDisplayRemoved(const gfx::Display& old_display) {
406 void WebUIScreenLocker::OnDisplayMetricsChanged(const gfx::Display& display,
407 uint32_t changed_metrics) {
408 gfx::Display primary_display =
409 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
410 if (display.id() != primary_display.id() ||
411 !(changed_metrics & DISPLAY_METRIC_BOUNDS)) {
412 return;
415 if (GetOobeUI()) {
416 const gfx::Size& size = primary_display.size();
417 GetOobeUI()->GetCoreOobeActor()->SetClientAreaSize(size.width(),
418 size.height());
422 } // namespace chromeos