1 // Copyright (c) 2012 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/webui_screen_locker.h"
8 #include "ash/wm/lock_state_controller.h"
9 #include "ash/wm/lock_state_observer.h"
10 #include "base/command_line.h"
11 #include "base/metrics/histogram.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/values.h"
14 #include "chrome/browser/browser_shutdown.h"
15 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/chromeos/accessibility/accessibility_util.h"
17 #include "chrome/browser/chromeos/login/helper.h"
18 #include "chrome/browser/chromeos/login/screen_locker.h"
19 #include "chrome/browser/chromeos/login/user_manager.h"
20 #include "chrome/browser/chromeos/login/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 "content/public/browser/browser_thread.h"
26 #include "content/public/browser/notification_service.h"
27 #include "content/public/browser/notification_types.h"
28 #include "content/public/browser/render_widget_host_view.h"
29 #include "content/public/browser/web_ui.h"
30 #include "ui/aura/client/capture_client.h"
31 #include "ui/aura/root_window.h"
32 #include "ui/base/l10n/l10n_util.h"
33 #include "ui/base/x/x11_util.h"
34 #include "ui/gfx/screen.h"
35 #include "ui/views/controls/webview/webview.h"
39 // URL which corresponds to the login WebUI.
40 const char kLoginURL
[] = "chrome://oobe/lock";
46 ////////////////////////////////////////////////////////////////////////////////
47 // WebUIScreenLocker implementation.
49 WebUIScreenLocker::WebUIScreenLocker(ScreenLocker
* screen_locker
)
50 : ScreenLockerDelegate(screen_locker
),
53 network_state_helper_(new login::NetworkStateHelper
),
55 set_should_emit_login_prompt_visible(false);
56 ash::Shell::GetInstance()->lock_state_controller()->AddObserver(this);
57 DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(this);
60 void WebUIScreenLocker::LockScreen() {
61 gfx::Rect
bounds(ash::Shell::GetScreen()->GetPrimaryDisplay().bounds());
63 lock_time_
= base::TimeTicks::Now();
64 LockWindow
* lock_window
= LockWindow::Create();
65 lock_window
->set_observer(this);
66 lock_window_
= lock_window
->GetWidget();
67 lock_window_
->AddObserver(this);
68 WebUILoginView::Init();
69 lock_window_
->SetContentsView(this);
71 LoadURL(GURL(kLoginURL
));
74 login_display_
.reset(new WebUILoginDisplay(this));
75 login_display_
->set_background_bounds(bounds
);
76 login_display_
->set_parent_window(GetNativeWindow());
77 login_display_
->Init(screen_locker()->users(), false, true, false);
79 static_cast<OobeUI
*>(GetWebUI()->GetController())->ShowSigninScreen(
80 LoginScreenContext(), login_display_
.get(), login_display_
.get());
83 chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED
,
84 content::NotificationService::AllSources());
87 void WebUIScreenLocker::ScreenLockReady() {
88 UMA_HISTOGRAM_TIMES("LockScreen.LockReady",
89 base::TimeTicks::Now() - lock_time_
);
90 ScreenLockerDelegate::ScreenLockReady();
91 SetInputEnabled(true);
94 void WebUIScreenLocker::OnAuthenticate() {
97 void WebUIScreenLocker::SetInputEnabled(bool enabled
) {
98 login_display_
->SetUIEnabled(enabled
);
101 void WebUIScreenLocker::ShowBannerMessage(const std::string
& message
) {
104 login_display_
->ShowBannerMessage(message
);
107 void WebUIScreenLocker::ShowUserPodButton(
108 const std::string
& username
,
109 const std::string
& iconURL
,
110 const base::Closure
& click_callback
) {
113 login_display_
->ShowUserPodButton(username
, iconURL
, click_callback
);
116 void WebUIScreenLocker::ShowErrorMessage(
118 HelpAppLauncher::HelpTopic help_topic_id
) {
119 login_display_
->ShowError(error_msg_id
,
120 0 /* login_attempts */,
124 void WebUIScreenLocker::AnimateAuthenticationSuccess() {
125 GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.animateAuthenticationSuccess");
128 void WebUIScreenLocker::ClearErrors() {
129 GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.clearErrors");
132 gfx::NativeWindow
WebUIScreenLocker::GetNativeWindow() const {
133 return lock_window_
->GetNativeWindow();
136 content::WebUI
* WebUIScreenLocker::GetAssociatedWebUI() {
140 void WebUIScreenLocker::FocusUserPod() {
143 webui_login_
->RequestFocus();
144 GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.forceLockedUserPodFocus");
147 WebUIScreenLocker::~WebUIScreenLocker() {
148 DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(this);
149 ash::Shell::GetInstance()->
150 lock_state_controller()->RemoveObserver(this);
151 // In case of shutdown, lock_window_ may be deleted before WebUIScreenLocker.
153 lock_window_
->RemoveObserver(this);
154 lock_window_
->Close();
156 // If LockScreen() was called, we need to clear the signin screen handler
157 // delegate set in ShowSigninScreen so that it no longer points to us.
158 if (login_display_
.get()) {
159 static_cast<OobeUI
*>(GetWebUI()->GetController())->
160 ResetSigninScreenHandlerDelegate();
164 void WebUIScreenLocker::OnLockWebUIReady() {
165 VLOG(1) << "WebUI ready; lock window is "
166 << (lock_ready_
? "too" : "not");
172 void WebUIScreenLocker::OnLockBackgroundDisplayed() {
173 UMA_HISTOGRAM_TIMES("LockScreen.BackgroundReady",
174 base::TimeTicks::Now() - lock_time_
);
177 ////////////////////////////////////////////////////////////////////////////////
178 // WebUIScreenLocker, content::NotificationObserver implementation:
180 void WebUIScreenLocker::Observe(
182 const content::NotificationSource
& source
,
183 const content::NotificationDetails
& details
) {
185 case chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED
: {
186 const User
& user
= *content::Details
<User
>(details
).ptr();
187 login_display_
->OnUserImageChanged(user
);
191 WebUILoginView::Observe(type
, source
, details
);
195 ////////////////////////////////////////////////////////////////////////////////
196 // WebUIScreenLocker, LoginDisplay::Delegate implementation:
198 void WebUIScreenLocker::CancelPasswordChangedFlow() {
202 void WebUIScreenLocker::CreateAccount() {
206 void WebUIScreenLocker::CompleteLogin(const UserContext
& user_context
) {
210 base::string16
WebUIScreenLocker::GetConnectedNetworkName() {
211 return network_state_helper_
->GetCurrentNetworkName();
214 bool WebUIScreenLocker::IsSigninInProgress() const {
215 // The way how screen locker is implemented right now there's no
216 // GAIA sign in in progress in any case.
220 void WebUIScreenLocker::Login(const UserContext
& user_context
) {
221 chromeos::ScreenLocker::default_screen_locker()->Authenticate(user_context
);
224 void WebUIScreenLocker::LoginAsRetailModeUser() {
228 void WebUIScreenLocker::LoginAsGuest() {
232 void WebUIScreenLocker::MigrateUserData(const std::string
& old_password
) {
236 void WebUIScreenLocker::LoginAsPublicAccount(const std::string
& username
) {
240 void WebUIScreenLocker::OnSigninScreenReady() {
243 void WebUIScreenLocker::OnUserSelected(const std::string
& username
) {
246 void WebUIScreenLocker::OnStartEnterpriseEnrollment() {
250 void WebUIScreenLocker::OnStartKioskEnableScreen() {
254 void WebUIScreenLocker::OnStartDeviceReset() {
258 void WebUIScreenLocker::OnStartKioskAutolaunchScreen() {
262 void WebUIScreenLocker::ShowWrongHWIDScreen() {
266 void WebUIScreenLocker::ResetPublicSessionAutoLoginTimer() {
269 void WebUIScreenLocker::ResyncUserData() {
273 void WebUIScreenLocker::SetDisplayEmail(const std::string
& email
) {
277 void WebUIScreenLocker::Signout() {
278 chromeos::ScreenLocker::default_screen_locker()->Signout();
281 void WebUIScreenLocker::LoginAsKioskApp(const std::string
& app_id
) {
285 ////////////////////////////////////////////////////////////////////////////////
286 // LockWindow::Observer implementation:
288 void WebUIScreenLocker::OnLockWindowReady() {
289 VLOG(1) << "Lock window ready; WebUI is " << (webui_ready_
? "too" : "not");
295 ////////////////////////////////////////////////////////////////////////////////
296 // SessionLockStateObserver override.
298 void WebUIScreenLocker::OnLockStateEvent(
299 ash::LockStateObserver::EventType event
) {
300 if (event
== ash::LockStateObserver::EVENT_LOCK_ANIMATION_FINISHED
) {
301 // Release capture if any.
302 aura::client::GetCaptureClient(GetNativeWindow()->GetRootWindow())->
304 GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.animateOnceFullyDisplayed");
308 ////////////////////////////////////////////////////////////////////////////////
309 // WidgetObserver override.
311 void WebUIScreenLocker::OnWidgetDestroying(views::Widget
* widget
) {
312 lock_window_
->RemoveObserver(this);
316 ////////////////////////////////////////////////////////////////////////////////
317 // PowerManagerClient::Observer overrides.
319 void WebUIScreenLocker::LidEventReceived(bool open
,
320 const base::TimeTicks
& time
) {
321 content::BrowserThread::PostTask(
322 content::BrowserThread::UI
,
324 base::Bind(&WebUIScreenLocker::FocusUserPod
, weak_factory_
.GetWeakPtr()));
327 void WebUIScreenLocker::SystemResumed(const base::TimeDelta
& sleep_duration
) {
328 content::BrowserThread::PostTask(
329 content::BrowserThread::UI
,
331 base::Bind(&WebUIScreenLocker::FocusUserPod
, weak_factory_
.GetWeakPtr()));
334 void WebUIScreenLocker::RenderProcessGone(base::TerminationStatus status
) {
335 if (browser_shutdown::GetShutdownType() == browser_shutdown::NOT_VALID
&&
336 status
!= base::TERMINATION_STATUS_NORMAL_TERMINATION
) {
337 LOG(ERROR
) << "Renderer crash on lock screen";
342 } // namespace chromeos