• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "chrome/browser/chromeos/login/webui_screen_locker.h"
6 
7 #include "ash/shell.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"
36 
37 namespace {
38 
39 // URL which corresponds to the login WebUI.
40 const char kLoginURL[] = "chrome://oobe/lock";
41 
42 }  // namespace
43 
44 namespace chromeos {
45 
46 ////////////////////////////////////////////////////////////////////////////////
47 // WebUIScreenLocker implementation.
48 
WebUIScreenLocker(ScreenLocker * screen_locker)49 WebUIScreenLocker::WebUIScreenLocker(ScreenLocker* screen_locker)
50     : ScreenLockerDelegate(screen_locker),
51       lock_ready_(false),
52       webui_ready_(false),
53       network_state_helper_(new login::NetworkStateHelper),
54       weak_factory_(this) {
55   set_should_emit_login_prompt_visible(false);
56   ash::Shell::GetInstance()->lock_state_controller()->AddObserver(this);
57   DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(this);
58 }
59 
LockScreen()60 void WebUIScreenLocker::LockScreen() {
61   gfx::Rect bounds(ash::Shell::GetScreen()->GetPrimaryDisplay().bounds());
62 
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);
70   lock_window_->Show();
71   LoadURL(GURL(kLoginURL));
72   lock_window->Grab();
73 
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);
78 
79   static_cast<OobeUI*>(GetWebUI()->GetController())->ShowSigninScreen(
80       LoginScreenContext(), login_display_.get(), login_display_.get());
81 
82   registrar_.Add(this,
83                  chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED,
84                  content::NotificationService::AllSources());
85 }
86 
ScreenLockReady()87 void WebUIScreenLocker::ScreenLockReady() {
88   UMA_HISTOGRAM_TIMES("LockScreen.LockReady",
89                       base::TimeTicks::Now() - lock_time_);
90   ScreenLockerDelegate::ScreenLockReady();
91   SetInputEnabled(true);
92 }
93 
OnAuthenticate()94 void WebUIScreenLocker::OnAuthenticate() {
95 }
96 
SetInputEnabled(bool enabled)97 void WebUIScreenLocker::SetInputEnabled(bool enabled) {
98   login_display_->SetUIEnabled(enabled);
99 }
100 
ShowBannerMessage(const std::string & message)101 void WebUIScreenLocker::ShowBannerMessage(const std::string& message) {
102   if (!webui_ready_)
103     return;
104   login_display_->ShowBannerMessage(message);
105 }
106 
ShowUserPodButton(const std::string & username,const std::string & iconURL,const base::Closure & click_callback)107 void WebUIScreenLocker::ShowUserPodButton(
108     const std::string& username,
109     const std::string& iconURL,
110     const base::Closure& click_callback) {
111   if (!webui_ready_)
112     return;
113   login_display_->ShowUserPodButton(username, iconURL, click_callback);
114 }
115 
ShowErrorMessage(int error_msg_id,HelpAppLauncher::HelpTopic help_topic_id)116 void WebUIScreenLocker::ShowErrorMessage(
117     int error_msg_id,
118     HelpAppLauncher::HelpTopic help_topic_id) {
119   login_display_->ShowError(error_msg_id,
120                   0 /* login_attempts */,
121                   help_topic_id);
122 }
123 
AnimateAuthenticationSuccess()124 void WebUIScreenLocker::AnimateAuthenticationSuccess() {
125   GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.animateAuthenticationSuccess");
126 }
127 
ClearErrors()128 void WebUIScreenLocker::ClearErrors() {
129   GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.clearErrors");
130 }
131 
GetNativeWindow() const132 gfx::NativeWindow WebUIScreenLocker::GetNativeWindow() const {
133   return lock_window_->GetNativeWindow();
134 }
135 
GetAssociatedWebUI()136 content::WebUI* WebUIScreenLocker::GetAssociatedWebUI() {
137   return GetWebUI();
138 }
139 
FocusUserPod()140 void WebUIScreenLocker::FocusUserPod() {
141   if (!webui_ready_)
142     return;
143   webui_login_->RequestFocus();
144   GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.forceLockedUserPodFocus");
145 }
146 
~WebUIScreenLocker()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.
152   if (lock_window_) {
153     lock_window_->RemoveObserver(this);
154     lock_window_->Close();
155   }
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();
161   }
162 }
163 
OnLockWebUIReady()164 void WebUIScreenLocker::OnLockWebUIReady() {
165   VLOG(1) << "WebUI ready; lock window is "
166           << (lock_ready_ ? "too" : "not");
167   webui_ready_ = true;
168   if (lock_ready_)
169     ScreenLockReady();
170 }
171 
OnLockBackgroundDisplayed()172 void WebUIScreenLocker::OnLockBackgroundDisplayed() {
173   UMA_HISTOGRAM_TIMES("LockScreen.BackgroundReady",
174                       base::TimeTicks::Now() - lock_time_);
175 }
176 
177 ////////////////////////////////////////////////////////////////////////////////
178 // WebUIScreenLocker, content::NotificationObserver implementation:
179 
Observe(int type,const content::NotificationSource & source,const content::NotificationDetails & details)180 void WebUIScreenLocker::Observe(
181     int type,
182     const content::NotificationSource& source,
183     const content::NotificationDetails& details) {
184   switch (type) {
185     case chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED: {
186       const User& user = *content::Details<User>(details).ptr();
187       login_display_->OnUserImageChanged(user);
188       break;
189     }
190     default:
191       WebUILoginView::Observe(type, source, details);
192   }
193 }
194 
195 ////////////////////////////////////////////////////////////////////////////////
196 // WebUIScreenLocker, LoginDisplay::Delegate implementation:
197 
CancelPasswordChangedFlow()198 void WebUIScreenLocker::CancelPasswordChangedFlow()  {
199   NOTREACHED();
200 }
201 
CreateAccount()202 void WebUIScreenLocker::CreateAccount() {
203   NOTREACHED();
204 }
205 
CompleteLogin(const UserContext & user_context)206 void WebUIScreenLocker::CompleteLogin(const UserContext& user_context) {
207   NOTREACHED();
208 }
209 
GetConnectedNetworkName()210 base::string16 WebUIScreenLocker::GetConnectedNetworkName() {
211   return network_state_helper_->GetCurrentNetworkName();
212 }
213 
IsSigninInProgress() const214 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.
217   return false;
218 }
219 
Login(const UserContext & user_context)220 void WebUIScreenLocker::Login(const UserContext& user_context) {
221   chromeos::ScreenLocker::default_screen_locker()->Authenticate(user_context);
222 }
223 
LoginAsRetailModeUser()224 void WebUIScreenLocker::LoginAsRetailModeUser() {
225   NOTREACHED();
226 }
227 
LoginAsGuest()228 void WebUIScreenLocker::LoginAsGuest() {
229   NOTREACHED();
230 }
231 
MigrateUserData(const std::string & old_password)232 void WebUIScreenLocker::MigrateUserData(const std::string& old_password) {
233   NOTREACHED();
234 }
235 
LoginAsPublicAccount(const std::string & username)236 void WebUIScreenLocker::LoginAsPublicAccount(const std::string& username) {
237   NOTREACHED();
238 }
239 
OnSigninScreenReady()240 void WebUIScreenLocker::OnSigninScreenReady() {
241 }
242 
OnUserSelected(const std::string & username)243 void WebUIScreenLocker::OnUserSelected(const std::string& username) {
244 }
245 
OnStartEnterpriseEnrollment()246 void WebUIScreenLocker::OnStartEnterpriseEnrollment() {
247   NOTREACHED();
248 }
249 
OnStartKioskEnableScreen()250 void WebUIScreenLocker::OnStartKioskEnableScreen() {
251   NOTREACHED();
252 }
253 
OnStartDeviceReset()254 void WebUIScreenLocker::OnStartDeviceReset() {
255   NOTREACHED();
256 }
257 
OnStartKioskAutolaunchScreen()258 void WebUIScreenLocker::OnStartKioskAutolaunchScreen() {
259   NOTREACHED();
260 }
261 
ShowWrongHWIDScreen()262 void WebUIScreenLocker::ShowWrongHWIDScreen() {
263   NOTREACHED();
264 }
265 
ResetPublicSessionAutoLoginTimer()266 void WebUIScreenLocker::ResetPublicSessionAutoLoginTimer() {
267 }
268 
ResyncUserData()269 void WebUIScreenLocker::ResyncUserData() {
270   NOTREACHED();
271 }
272 
SetDisplayEmail(const std::string & email)273 void WebUIScreenLocker::SetDisplayEmail(const std::string& email) {
274   NOTREACHED();
275 }
276 
Signout()277 void WebUIScreenLocker::Signout() {
278   chromeos::ScreenLocker::default_screen_locker()->Signout();
279 }
280 
LoginAsKioskApp(const std::string & app_id)281 void WebUIScreenLocker::LoginAsKioskApp(const std::string& app_id) {
282   NOTREACHED();
283 }
284 
285 ////////////////////////////////////////////////////////////////////////////////
286 // LockWindow::Observer implementation:
287 
OnLockWindowReady()288 void WebUIScreenLocker::OnLockWindowReady() {
289   VLOG(1) << "Lock window ready; WebUI is " << (webui_ready_ ? "too" : "not");
290   lock_ready_ = true;
291   if (webui_ready_)
292     ScreenLockReady();
293 }
294 
295 ////////////////////////////////////////////////////////////////////////////////
296 // SessionLockStateObserver override.
297 
OnLockStateEvent(ash::LockStateObserver::EventType event)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())->
303         SetCapture(NULL);
304     GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.animateOnceFullyDisplayed");
305   }
306 }
307 
308 ////////////////////////////////////////////////////////////////////////////////
309 // WidgetObserver override.
310 
OnWidgetDestroying(views::Widget * widget)311 void WebUIScreenLocker::OnWidgetDestroying(views::Widget* widget) {
312   lock_window_->RemoveObserver(this);
313   lock_window_ = NULL;
314 }
315 
316 ////////////////////////////////////////////////////////////////////////////////
317 // PowerManagerClient::Observer overrides.
318 
LidEventReceived(bool open,const base::TimeTicks & time)319 void WebUIScreenLocker::LidEventReceived(bool open,
320                                          const base::TimeTicks& time) {
321   content::BrowserThread::PostTask(
322       content::BrowserThread::UI,
323       FROM_HERE,
324       base::Bind(&WebUIScreenLocker::FocusUserPod, weak_factory_.GetWeakPtr()));
325 }
326 
SystemResumed(const base::TimeDelta & sleep_duration)327 void WebUIScreenLocker::SystemResumed(const base::TimeDelta& sleep_duration) {
328   content::BrowserThread::PostTask(
329       content::BrowserThread::UI,
330       FROM_HERE,
331       base::Bind(&WebUIScreenLocker::FocusUserPod, weak_factory_.GetWeakPtr()));
332 }
333 
RenderProcessGone(base::TerminationStatus status)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";
338     Signout();
339   }
340 }
341 
342 }  // namespace chromeos
343