Popular sites on the NTP: check that experiment group StartsWith (rather than IS...
[chromium-blink-merge.git] / chrome / browser / chromeos / login / lock / webui_screen_locker.cc
blob742af09d32a587b600e8d2232e96478f8797b4a4
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 DisableKeyboardOverscroll();
113 void WebUIScreenLocker::ScreenLockReady() {
114 UMA_HISTOGRAM_TIMES("LockScreen.LockReady",
115 base::TimeTicks::Now() - lock_time_);
116 ScreenLockerDelegate::ScreenLockReady();
117 SetInputEnabled(true);
120 void WebUIScreenLocker::OnAuthenticate() {
123 void WebUIScreenLocker::SetInputEnabled(bool enabled) {
124 login_display_->SetUIEnabled(enabled);
127 void WebUIScreenLocker::ShowErrorMessage(
128 int error_msg_id,
129 HelpAppLauncher::HelpTopic help_topic_id) {
130 login_display_->ShowError(error_msg_id,
131 0 /* login_attempts */,
132 help_topic_id);
135 void WebUIScreenLocker::AnimateAuthenticationSuccess() {
136 GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.animateAuthenticationSuccess");
139 void WebUIScreenLocker::ClearErrors() {
140 GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.clearErrors");
143 gfx::NativeWindow WebUIScreenLocker::GetNativeWindow() const {
144 return lock_window_->GetNativeWindow();
147 content::WebUI* WebUIScreenLocker::GetAssociatedWebUI() {
148 return GetWebUI();
151 void WebUIScreenLocker::FocusUserPod() {
152 if (!webui_ready_)
153 return;
154 webui_login_->RequestFocus();
155 GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.forceLockedUserPodFocus");
158 void WebUIScreenLocker::ResetAndFocusUserPod() {
159 if (!webui_ready_)
160 return;
161 GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.clearUserPodPassword");
162 FocusUserPod();
165 WebUIScreenLocker::~WebUIScreenLocker() {
166 DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(this);
167 ash::Shell::GetScreen()->RemoveObserver(this);
168 ash::Shell::GetInstance()->
169 lock_state_controller()->RemoveObserver(this);
171 ash::Shell::GetInstance()->delegate()->
172 RemoveVirtualKeyboardStateObserver(this);
173 // In case of shutdown, lock_window_ may be deleted before WebUIScreenLocker.
174 if (lock_window_) {
175 lock_window_->RemoveObserver(this);
176 lock_window_->Close();
178 // If LockScreen() was called, we need to clear the signin screen handler
179 // delegate set in ShowSigninScreen so that it no longer points to us.
180 if (login_display_.get()) {
181 static_cast<OobeUI*>(GetWebUI()->GetController())->
182 ResetSigninScreenHandlerDelegate();
185 if (keyboard::KeyboardController::GetInstance() && is_observing_keyboard_) {
186 keyboard::KeyboardController::GetInstance()->RemoveObserver(this);
187 is_observing_keyboard_ = false;
190 ResetKeyboardOverscrollOverride();
193 void WebUIScreenLocker::OnLockWebUIReady() {
194 VLOG(1) << "WebUI ready; lock window is "
195 << (lock_ready_ ? "too" : "not");
196 webui_ready_ = true;
197 if (lock_ready_)
198 ScreenLockReady();
201 void WebUIScreenLocker::OnLockBackgroundDisplayed() {
202 UMA_HISTOGRAM_TIMES("LockScreen.BackgroundReady",
203 base::TimeTicks::Now() - lock_time_);
206 void WebUIScreenLocker::OnHeaderBarVisible() {
207 DCHECK(ash::Shell::HasInstance());
209 ash::Shell::GetInstance()->power_event_observer()->OnLockAnimationsComplete();
212 OobeUI* WebUIScreenLocker::GetOobeUI() {
213 return static_cast<OobeUI*>(GetWebUI()->GetController());
216 ////////////////////////////////////////////////////////////////////////////////
217 // WebUIScreenLocker, LoginDisplay::Delegate:
219 void WebUIScreenLocker::CancelPasswordChangedFlow() {
220 NOTREACHED();
223 void WebUIScreenLocker::CreateAccount() {
224 NOTREACHED();
227 void WebUIScreenLocker::CompleteLogin(const UserContext& user_context) {
228 NOTREACHED();
231 base::string16 WebUIScreenLocker::GetConnectedNetworkName() {
232 return network_state_helper_->GetCurrentNetworkName();
235 bool WebUIScreenLocker::IsSigninInProgress() const {
236 // The way how screen locker is implemented right now there's no
237 // GAIA sign in in progress in any case.
238 return false;
241 void WebUIScreenLocker::Login(const UserContext& user_context,
242 const SigninSpecifics& specifics) {
243 chromeos::ScreenLocker::default_screen_locker()->Authenticate(user_context);
246 void WebUIScreenLocker::MigrateUserData(const std::string& old_password) {
247 NOTREACHED();
250 void WebUIScreenLocker::OnSigninScreenReady() {
253 void WebUIScreenLocker::OnStartEnterpriseEnrollment() {
254 NOTREACHED();
257 void WebUIScreenLocker::OnStartEnableDebuggingScreen() {
258 NOTREACHED();
261 void WebUIScreenLocker::OnStartKioskEnableScreen() {
262 NOTREACHED();
265 void WebUIScreenLocker::OnStartKioskAutolaunchScreen() {
266 NOTREACHED();
269 void WebUIScreenLocker::ShowWrongHWIDScreen() {
270 NOTREACHED();
273 void WebUIScreenLocker::ResetPublicSessionAutoLoginTimer() {
276 void WebUIScreenLocker::ResyncUserData() {
277 NOTREACHED();
280 void WebUIScreenLocker::SetDisplayEmail(const std::string& email) {
281 NOTREACHED();
284 void WebUIScreenLocker::Signout() {
285 chromeos::ScreenLocker::default_screen_locker()->Signout();
288 bool WebUIScreenLocker::IsUserWhitelisted(const std::string& user_id) {
289 NOTREACHED();
290 return true;
292 ////////////////////////////////////////////////////////////////////////////////
293 // LockWindow::Observer:
295 void WebUIScreenLocker::OnLockWindowReady() {
296 VLOG(1) << "Lock window ready; WebUI is " << (webui_ready_ ? "too" : "not");
297 lock_ready_ = true;
298 if (webui_ready_)
299 ScreenLockReady();
302 ////////////////////////////////////////////////////////////////////////////////
303 // SessionLockStateObserver:
305 void WebUIScreenLocker::OnLockStateEvent(
306 ash::LockStateObserver::EventType event) {
307 if (event == ash::LockStateObserver::EVENT_LOCK_ANIMATION_FINISHED) {
308 // Release capture if any.
309 aura::client::GetCaptureClient(GetNativeWindow()->GetRootWindow())->
310 SetCapture(NULL);
311 GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.animateOnceFullyDisplayed");
315 ////////////////////////////////////////////////////////////////////////////////
316 // WidgetObserver:
318 void WebUIScreenLocker::OnWidgetDestroying(views::Widget* widget) {
319 lock_window_->RemoveObserver(this);
320 lock_window_ = NULL;
323 ////////////////////////////////////////////////////////////////////////////////
324 // PowerManagerClient::Observer:
326 void WebUIScreenLocker::LidEventReceived(bool open,
327 const base::TimeTicks& time) {
328 if (open) {
329 content::BrowserThread::PostTask(
330 content::BrowserThread::UI, FROM_HERE,
331 base::Bind(&WebUIScreenLocker::FocusUserPod,
332 weak_factory_.GetWeakPtr()));
336 void WebUIScreenLocker::SuspendImminent() {
337 content::BrowserThread::PostTask(
338 content::BrowserThread::UI, FROM_HERE,
339 base::Bind(&WebUIScreenLocker::ResetAndFocusUserPod,
340 weak_factory_.GetWeakPtr()));
343 void WebUIScreenLocker::SuspendDone(const base::TimeDelta& sleep_duration) {
344 content::BrowserThread::PostTask(
345 content::BrowserThread::UI,
346 FROM_HERE,
347 base::Bind(&WebUIScreenLocker::FocusUserPod, weak_factory_.GetWeakPtr()));
350 void WebUIScreenLocker::RenderProcessGone(base::TerminationStatus status) {
351 if (browser_shutdown::GetShutdownType() == browser_shutdown::NOT_VALID &&
352 status != base::TERMINATION_STATUS_NORMAL_TERMINATION) {
353 LOG(ERROR) << "Renderer crash on lock screen";
354 Signout();
358 ////////////////////////////////////////////////////////////////////////////////
359 // ash::KeyboardStateObserver overrides.
361 void WebUIScreenLocker::OnVirtualKeyboardStateChanged(bool activated) {
362 if (keyboard::KeyboardController::GetInstance()) {
363 if (activated) {
364 if (!is_observing_keyboard_) {
365 keyboard::KeyboardController::GetInstance()->AddObserver(this);
366 is_observing_keyboard_ = true;
368 } else {
369 keyboard::KeyboardController::GetInstance()->RemoveObserver(this);
370 is_observing_keyboard_ = false;
375 ////////////////////////////////////////////////////////////////////////////////
376 // keyboard::KeyboardControllerObserver:
378 void WebUIScreenLocker::OnKeyboardBoundsChanging(
379 const gfx::Rect& new_bounds) {
380 if (new_bounds.IsEmpty()) {
381 // Keyboard has been hidden.
382 if (GetOobeUI())
383 GetOobeUI()->GetCoreOobeActor()->ShowControlBar(true);
384 } else {
385 // Keyboard has been shown.
386 if (GetOobeUI())
387 GetOobeUI()->GetCoreOobeActor()->ShowControlBar(false);
391 ////////////////////////////////////////////////////////////////////////////////
392 // gfx::DisplayObserver:
394 void WebUIScreenLocker::OnDisplayAdded(const gfx::Display& new_display) {
397 void WebUIScreenLocker::OnDisplayRemoved(const gfx::Display& old_display) {
400 void WebUIScreenLocker::OnDisplayMetricsChanged(const gfx::Display& display,
401 uint32_t changed_metrics) {
402 gfx::Display primary_display =
403 gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
404 if (display.id() != primary_display.id() ||
405 !(changed_metrics & DISPLAY_METRIC_BOUNDS)) {
406 return;
409 if (GetOobeUI()) {
410 const gfx::Size& size = primary_display.size();
411 GetOobeUI()->GetCoreOobeActor()->SetClientAreaSize(size.width(),
412 size.height());
416 } // namespace chromeos