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/common/url_constants.h"
23 #include "chromeos/dbus/dbus_thread_manager.h"
24 #include "content/public/browser/browser_thread.h"
25 #include "content/public/browser/notification_service.h"
26 #include "content/public/browser/notification_types.h"
27 #include "content/public/browser/render_widget_host_view.h"
28 #include "content/public/browser/web_ui.h"
29 #include "ui/aura/client/capture_client.h"
30 #include "ui/aura/root_window.h"
31 #include "ui/base/l10n/l10n_util.h"
32 #include "ui/base/x/x11_util.h"
33 #include "ui/gfx/screen.h"
34 #include "ui/views/controls/webview/webview.h"
38 // URL which corresponds to the login WebUI.
39 const char kLoginURL[] = "chrome://oobe/lock";
45 ////////////////////////////////////////////////////////////////////////////////
46 // WebUIScreenLocker implementation.
48 WebUIScreenLocker::WebUIScreenLocker(ScreenLocker* screen_locker)
49 : ScreenLockerDelegate(screen_locker),
52 network_state_helper_(new login::NetworkStateHelper),
54 set_should_emit_login_prompt_visible(false);
55 ash::Shell::GetInstance()->lock_state_controller()->AddObserver(this);
56 DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(this);
59 void WebUIScreenLocker::LockScreen() {
60 gfx::Rect bounds(ash::Shell::GetScreen()->GetPrimaryDisplay().bounds());
62 lock_time_ = base::TimeTicks::Now();
63 LockWindow* lock_window = LockWindow::Create();
64 lock_window->set_observer(this);
65 lock_window_ = lock_window->GetWidget();
66 lock_window_->AddObserver(this);
67 WebUILoginView::Init();
68 lock_window_->SetContentsView(this);
70 LoadURL(GURL(kLoginURL));
73 login_display_.reset(new WebUILoginDisplay(this));
74 login_display_->set_background_bounds(bounds);
75 login_display_->set_parent_window(GetNativeWindow());
76 login_display_->Init(screen_locker()->users(), false, true, false);
78 static_cast<OobeUI*>(GetWebUI()->GetController())->ShowSigninScreen(
79 login_display_.get(), login_display_.get());
82 chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED,
83 content::NotificationService::AllSources());
86 void WebUIScreenLocker::ScreenLockReady() {
87 UMA_HISTOGRAM_TIMES("LockScreen.LockReady",
88 base::TimeTicks::Now() - lock_time_);
89 ScreenLockerDelegate::ScreenLockReady();
90 SetInputEnabled(true);
93 void WebUIScreenLocker::OnAuthenticate() {
96 void WebUIScreenLocker::SetInputEnabled(bool enabled) {
97 login_display_->SetUIEnabled(enabled);
100 void WebUIScreenLocker::ShowErrorMessage(
102 HelpAppLauncher::HelpTopic help_topic_id) {
103 login_display_->ShowError(error_msg_id,
104 0 /* login_attempts */,
108 void WebUIScreenLocker::AnimateAuthenticationSuccess() {
109 GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.animateAuthenticationSuccess");
112 void WebUIScreenLocker::ClearErrors() {
113 GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.clearErrors");
116 gfx::NativeWindow WebUIScreenLocker::GetNativeWindow() const {
117 return lock_window_->GetNativeWindow();
120 content::WebUI* WebUIScreenLocker::GetAssociatedWebUI() {
124 void WebUIScreenLocker::FocusUserPod() {
127 webui_login_->RequestFocus();
128 GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.forceLockedUserPodFocus");
131 WebUIScreenLocker::~WebUIScreenLocker() {
132 DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(this);
133 ash::Shell::GetInstance()->
134 lock_state_controller()->RemoveObserver(this);
135 // In case of shutdown, lock_window_ may be deleted before WebUIScreenLocker.
137 lock_window_->RemoveObserver(this);
138 lock_window_->Close();
140 // If LockScreen() was called, we need to clear the signin screen handler
141 // delegate set in ShowSigninScreen so that it no longer points to us.
142 if (login_display_.get()) {
143 static_cast<OobeUI*>(GetWebUI()->GetController())->
144 ResetSigninScreenHandlerDelegate();
148 void WebUIScreenLocker::OnLockWebUIReady() {
149 VLOG(1) << "WebUI ready; lock window is "
150 << (lock_ready_ ? "too" : "not");
156 void WebUIScreenLocker::OnLockBackgroundDisplayed() {
157 UMA_HISTOGRAM_TIMES("LockScreen.BackgroundReady",
158 base::TimeTicks::Now() - lock_time_);
161 ////////////////////////////////////////////////////////////////////////////////
162 // WebUIScreenLocker, content::NotificationObserver implementation:
164 void WebUIScreenLocker::Observe(
166 const content::NotificationSource& source,
167 const content::NotificationDetails& details) {
169 case chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED: {
170 const User& user = *content::Details<User>(details).ptr();
171 login_display_->OnUserImageChanged(user);
175 WebUILoginView::Observe(type, source, details);
179 ////////////////////////////////////////////////////////////////////////////////
180 // WebUIScreenLocker, LoginDisplay::Delegate implementation:
182 void WebUIScreenLocker::CancelPasswordChangedFlow() {
186 void WebUIScreenLocker::CreateAccount() {
190 void WebUIScreenLocker::CompleteLogin(const UserContext& user_context) {
194 string16 WebUIScreenLocker::GetConnectedNetworkName() {
195 return network_state_helper_->GetCurrentNetworkName();
198 bool WebUIScreenLocker::IsSigninInProgress() const {
199 // The way how screen locker is implemented right now there's no
200 // GAIA sign in in progress in any case.
204 void WebUIScreenLocker::Login(const UserContext& user_context) {
205 chromeos::ScreenLocker::default_screen_locker()->Authenticate(user_context);
208 void WebUIScreenLocker::LoginAsRetailModeUser() {
212 void WebUIScreenLocker::LoginAsGuest() {
216 void WebUIScreenLocker::MigrateUserData(const std::string& old_password) {
220 void WebUIScreenLocker::LoginAsPublicAccount(const std::string& username) {
224 void WebUIScreenLocker::OnSigninScreenReady() {
227 void WebUIScreenLocker::OnUserSelected(const std::string& username) {
230 void WebUIScreenLocker::OnStartEnterpriseEnrollment() {
234 void WebUIScreenLocker::OnStartKioskEnableScreen() {
238 void WebUIScreenLocker::OnStartDeviceReset() {
242 void WebUIScreenLocker::OnStartKioskAutolaunchScreen() {
246 void WebUIScreenLocker::ShowWrongHWIDScreen() {
250 void WebUIScreenLocker::ResetPublicSessionAutoLoginTimer() {
253 void WebUIScreenLocker::ResyncUserData() {
257 void WebUIScreenLocker::SetDisplayEmail(const std::string& email) {
261 void WebUIScreenLocker::Signout() {
262 chromeos::ScreenLocker::default_screen_locker()->Signout();
265 void WebUIScreenLocker::LoginAsKioskApp(const std::string& app_id) {
269 ////////////////////////////////////////////////////////////////////////////////
270 // LockWindow::Observer implementation:
272 void WebUIScreenLocker::OnLockWindowReady() {
273 VLOG(1) << "Lock window ready; WebUI is " << (webui_ready_ ? "too" : "not");
279 ////////////////////////////////////////////////////////////////////////////////
280 // SessionLockStateObserver override.
282 void WebUIScreenLocker::OnLockStateEvent(
283 ash::LockStateObserver::EventType event) {
284 if (event == ash::LockStateObserver::EVENT_LOCK_ANIMATION_FINISHED) {
285 // Release capture if any.
286 aura::client::GetCaptureClient(GetNativeWindow()->GetRootWindow())->
288 GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.animateOnceFullyDisplayed");
292 ////////////////////////////////////////////////////////////////////////////////
293 // WidgetObserver override.
295 void WebUIScreenLocker::OnWidgetDestroying(views::Widget* widget) {
296 lock_window_->RemoveObserver(this);
300 ////////////////////////////////////////////////////////////////////////////////
301 // PowerManagerClient::Observer overrides.
303 void WebUIScreenLocker::LidEventReceived(bool open,
304 const base::TimeTicks& time) {
305 content::BrowserThread::PostTask(
306 content::BrowserThread::UI,
308 base::Bind(&WebUIScreenLocker::FocusUserPod, weak_factory_.GetWeakPtr()));
311 void WebUIScreenLocker::SystemResumed(const base::TimeDelta& sleep_duration) {
312 content::BrowserThread::PostTask(
313 content::BrowserThread::UI,
315 base::Bind(&WebUIScreenLocker::FocusUserPod, weak_factory_.GetWeakPtr()));
318 void WebUIScreenLocker::RenderProcessGone(base::TerminationStatus status) {
319 if (browser_shutdown::GetShutdownType() == browser_shutdown::NOT_VALID &&
320 status != base::TERMINATION_STATUS_NORMAL_TERMINATION) {
321 LOG(ERROR) << "Renderer crash on lock screen";
326 } // namespace chromeos