OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/login/screen_locker.h" | 5 #include "chrome/browser/chromeos/login/screen_locker.h" |
6 | 6 |
7 #include "app/l10n_util.h" | 7 #include "app/l10n_util.h" |
8 #include "app/resource_bundle.h" | 8 #include "app/resource_bundle.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/singleton.h" | 10 #include "base/singleton.h" |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 | 124 |
125 // The number times the widget tried to grab all focus. | 125 // The number times the widget tried to grab all focus. |
126 int grab_failure_count_; | 126 int grab_failure_count_; |
127 // Status of keyboard and mouse grab. | 127 // Status of keyboard and mouse grab. |
128 GdkGrabStatus kbd_grab_status_; | 128 GdkGrabStatus kbd_grab_status_; |
129 GdkGrabStatus mouse_grab_status_; | 129 GdkGrabStatus mouse_grab_status_; |
130 | 130 |
131 DISALLOW_COPY_AND_ASSIGN(GrabWidget); | 131 DISALLOW_COPY_AND_ASSIGN(GrabWidget); |
132 }; | 132 }; |
133 | 133 |
134 | |
135 void GrabWidget::TryGrabAllInputs() { | 134 void GrabWidget::TryGrabAllInputs() { |
136 if (kbd_grab_status_ != GDK_GRAB_SUCCESS) | 135 if (kbd_grab_status_ != GDK_GRAB_SUCCESS) |
137 kbd_grab_status_ = gdk_keyboard_grab(window_contents()->window, FALSE, | 136 kbd_grab_status_ = gdk_keyboard_grab(window_contents()->window, FALSE, |
138 GDK_CURRENT_TIME); | 137 GDK_CURRENT_TIME); |
139 if (mouse_grab_status_ != GDK_GRAB_SUCCESS) { | 138 if (mouse_grab_status_ != GDK_GRAB_SUCCESS) { |
140 mouse_grab_status_ = | 139 mouse_grab_status_ = |
141 gdk_pointer_grab(window_contents()->window, | 140 gdk_pointer_grab(window_contents()->window, |
142 FALSE, | 141 FALSE, |
143 static_cast<GdkEventMask>( | 142 static_cast<GdkEventMask>( |
144 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | | 143 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | |
(...skipping 10 matching lines...) Expand all Loading... |
155 MessageLoop::current()->PostDelayedTask( | 154 MessageLoop::current()->PostDelayedTask( |
156 FROM_HERE, | 155 FROM_HERE, |
157 task_factory_.NewRunnableMethod(&GrabWidget::TryGrabAllInputs), | 156 task_factory_.NewRunnableMethod(&GrabWidget::TryGrabAllInputs), |
158 kRetryGrabIntervalMs); | 157 kRetryGrabIntervalMs); |
159 } else { | 158 } else { |
160 CHECK_EQ(GDK_GRAB_SUCCESS, kbd_grab_status_) | 159 CHECK_EQ(GDK_GRAB_SUCCESS, kbd_grab_status_) |
161 << "Failed to grab keyboard input:" << kbd_grab_status_; | 160 << "Failed to grab keyboard input:" << kbd_grab_status_; |
162 CHECK_EQ(GDK_GRAB_SUCCESS, mouse_grab_status_) | 161 CHECK_EQ(GDK_GRAB_SUCCESS, mouse_grab_status_) |
163 << "Failed to grab pointer input:" << mouse_grab_status_; | 162 << "Failed to grab pointer input:" << mouse_grab_status_; |
164 DLOG(INFO) << "Grab Success"; | 163 DLOG(INFO) << "Grab Success"; |
165 screen_locker_->ScreenLockReady(); | 164 screen_locker_->OnGrabInputs(); |
166 } | 165 } |
167 } | 166 } |
168 | 167 |
169 } // namespace | 168 } // namespace |
170 | 169 |
171 namespace chromeos { | 170 namespace chromeos { |
172 | 171 |
173 // static | 172 // static |
174 ScreenLocker* ScreenLocker::screen_locker_ = NULL; | 173 ScreenLocker* ScreenLocker::screen_locker_ = NULL; |
175 | 174 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 // Offset from src_'s origin to dest_'s origin. | 223 // Offset from src_'s origin to dest_'s origin. |
225 gfx::Point offset_; | 224 gfx::Point offset_; |
226 | 225 |
227 DISALLOW_COPY_AND_ASSIGN(MouseEventRelay); | 226 DISALLOW_COPY_AND_ASSIGN(MouseEventRelay); |
228 }; | 227 }; |
229 | 228 |
230 } // namespace chromeos | 229 } // namespace chromeos |
231 | 230 |
232 namespace chromeos { | 231 namespace chromeos { |
233 | 232 |
| 233 //////////////////////////////////////////////////////////////////////////////// |
| 234 // ScreenLocker, public: |
| 235 |
234 ScreenLocker::ScreenLocker(const UserManager::User& user) | 236 ScreenLocker::ScreenLocker(const UserManager::User& user) |
235 : lock_window_(NULL), | 237 : lock_window_(NULL), |
236 lock_widget_(NULL), | 238 lock_widget_(NULL), |
237 screen_lock_view_(NULL), | 239 screen_lock_view_(NULL), |
238 user_(user), | 240 user_(user), |
239 error_info_(NULL) { | 241 error_info_(NULL), |
| 242 mapped_(false), |
| 243 input_grabbed_(false) { |
240 DCHECK(!screen_locker_); | 244 DCHECK(!screen_locker_); |
241 screen_locker_ = this; | 245 screen_locker_ = this; |
242 } | 246 } |
243 | 247 |
244 ScreenLocker::~ScreenLocker() { | |
245 ClearErrors(); | |
246 DCHECK(lock_window_); | |
247 lock_window_->Close(); | |
248 // lock_widget_ will be deleted by gtk's destroy signal. | |
249 screen_locker_ = NULL; | |
250 if (CrosLibrary::Get()->EnsureLoaded()) | |
251 CrosLibrary::Get()->GetScreenLockLibrary()->NotifyScreenUnlockCompleted(); | |
252 } | |
253 | |
254 void ScreenLocker::Init(const gfx::Rect& bounds) { | 248 void ScreenLocker::Init(const gfx::Rect& bounds) { |
255 // TODO(oshima): Figure out which UI to keep and remove in the background. | 249 // TODO(oshima): Figure out which UI to keep and remove in the background. |
256 views::View* screen = new BackgroundView(); | 250 views::View* screen = new BackgroundView(); |
257 lock_window_ = new views::WidgetGtk(views::WidgetGtk::TYPE_POPUP); | 251 lock_window_ = new views::WidgetGtk(views::WidgetGtk::TYPE_POPUP); |
258 lock_window_->Init(NULL, bounds); | 252 lock_window_->Init(NULL, bounds); |
| 253 g_signal_connect(lock_window_->GetNativeView(), |
| 254 "map-event", |
| 255 G_CALLBACK(&OnMapThunk), |
| 256 this); |
259 DCHECK(GTK_WIDGET_REALIZED(lock_window_->GetNativeView())); | 257 DCHECK(GTK_WIDGET_REALIZED(lock_window_->GetNativeView())); |
260 WmIpc::instance()->SetWindowType( | 258 WmIpc::instance()->SetWindowType( |
261 lock_window_->GetNativeView(), | 259 lock_window_->GetNativeView(), |
262 WM_IPC_WINDOW_CHROME_SCREEN_LOCKER, | 260 WM_IPC_WINDOW_CHROME_SCREEN_LOCKER, |
263 NULL); | 261 NULL); |
264 lock_window_->SetContentsView(screen); | 262 lock_window_->SetContentsView(screen); |
265 lock_window_->Show(); | 263 lock_window_->Show(); |
266 | |
267 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); | 264 authenticator_ = LoginUtils::Get()->CreateAuthenticator(this); |
268 screen_lock_view_ = new ScreenLockView(this); | 265 screen_lock_view_ = new ScreenLockView(this); |
269 screen_lock_view_->Init(); | 266 screen_lock_view_->Init(); |
270 | 267 |
271 gfx::Size size = screen_lock_view_->GetPreferredSize(); | 268 gfx::Size size = screen_lock_view_->GetPreferredSize(); |
272 | 269 |
273 lock_widget_ = new GrabWidget(this); | 270 lock_widget_ = new GrabWidget(this); |
274 lock_widget_->MakeTransparent(); | 271 lock_widget_->MakeTransparent(); |
275 lock_widget_->InitWithWidget(lock_window_, | 272 lock_widget_->InitWithWidget(lock_window_, |
276 gfx::Rect((bounds.width() - size.width()) / 2, | 273 gfx::Rect((bounds.width() - size.width()) / 2, |
277 (bounds.height() - size.width()) / 2, | 274 (bounds.height() - size.width()) / 2, |
278 size.width(), | 275 size.width(), |
279 size.height())); | 276 size.height())); |
280 lock_widget_->SetContentsView(screen_lock_view_); | 277 lock_widget_->SetContentsView(screen_lock_view_); |
281 lock_widget_->GetRootView()->SetVisible(false); | 278 lock_widget_->GetRootView()->SetVisible(false); |
282 lock_widget_->Show(); | 279 lock_widget_->Show(); |
283 } | 280 } |
284 | 281 |
285 void ScreenLocker::SetAuthenticator(Authenticator* authenticator) { | |
286 authenticator_ = authenticator; | |
287 } | |
288 | |
289 void ScreenLocker::OnLoginFailure(const std::string& error) { | 282 void ScreenLocker::OnLoginFailure(const std::string& error) { |
290 DLOG(INFO) << "OnLoginFailure"; | 283 DLOG(INFO) << "OnLoginFailure"; |
291 EnableInput(); | 284 EnableInput(); |
292 // Don't enable signout button here as we're showing | 285 // Don't enable signout button here as we're showing |
293 // MessageBubble. | 286 // MessageBubble. |
294 gfx::Rect rect = screen_lock_view_->GetPasswordBoundsRelativeTo( | 287 gfx::Rect rect = screen_lock_view_->GetPasswordBoundsRelativeTo( |
295 lock_widget_->GetRootView()); | 288 lock_widget_->GetRootView()); |
296 gfx::Rect lock_widget_bounds; | 289 gfx::Rect lock_widget_bounds; |
297 lock_widget_->GetBounds(&lock_widget_bounds, false); | 290 lock_widget_->GetBounds(&lock_widget_bounds, false); |
298 rect.Offset(lock_widget_bounds.x(), lock_widget_bounds.y()); | 291 rect.Offset(lock_widget_bounds.x(), lock_widget_bounds.y()); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
363 void ScreenLocker::Signout() { | 356 void ScreenLocker::Signout() { |
364 if (!error_info_) { | 357 if (!error_info_) { |
365 // TODO(oshima): record this action in user metrics. | 358 // TODO(oshima): record this action in user metrics. |
366 BrowserList::CloseAllBrowsersAndExit(); | 359 BrowserList::CloseAllBrowsersAndExit(); |
367 | 360 |
368 // Don't hide yet the locker because the chrome screen may become visible | 361 // Don't hide yet the locker because the chrome screen may become visible |
369 // briefly. | 362 // briefly. |
370 } | 363 } |
371 } | 364 } |
372 | 365 |
373 void ScreenLocker::ScreenLockReady() { | 366 void ScreenLocker::OnGrabInputs() { |
374 // Don't show the password field until we grab all inputs. | 367 DLOG(INFO) << "OnGrabInputs"; |
375 lock_widget_->GetRootView()->SetVisible(true); | 368 input_grabbed_ = true; |
376 EnableInput(); | 369 if (mapped_) |
377 if (CrosLibrary::Get()->EnsureLoaded()) | 370 ScreenLockReady(); |
378 CrosLibrary::Get()->GetScreenLockLibrary()->NotifyScreenLockCompleted(); | |
379 } | 371 } |
380 | 372 |
381 // static | 373 // static |
382 void ScreenLocker::Show() { | 374 void ScreenLocker::Show() { |
383 DCHECK(MessageLoop::current()->type() == MessageLoop::TYPE_UI); | 375 DCHECK(MessageLoop::current()->type() == MessageLoop::TYPE_UI); |
384 // TODO(oshima): Currently, PowerManager may send a lock screen event | 376 // TODO(oshima): Currently, PowerManager may send a lock screen event |
385 // even if a screen is locked. Investigate & solve the issue and | 377 // even if a screen is locked. Investigate & solve the issue and |
386 // enable this again if it's possible. | 378 // enable this again if it's possible. |
387 // DCHECK(!screen_locker_); | 379 // DCHECK(!screen_locker_); |
388 if (!screen_locker_) { | 380 if (!screen_locker_) { |
(...skipping 25 matching lines...) Expand all Loading... |
414 // This'd be extremely rare, but may still happen. | 406 // This'd be extremely rare, but may still happen. |
415 LOG(INFO) << "Screen is unlocked"; | 407 LOG(INFO) << "Screen is unlocked"; |
416 } | 408 } |
417 } | 409 } |
418 | 410 |
419 // static | 411 // static |
420 void ScreenLocker::InitClass() { | 412 void ScreenLocker::InitClass() { |
421 Singleton<ScreenLockObserver>::get(); | 413 Singleton<ScreenLockObserver>::get(); |
422 } | 414 } |
423 | 415 |
| 416 //////////////////////////////////////////////////////////////////////////////// |
| 417 // ScreenLocker, private: |
| 418 |
| 419 ScreenLocker::~ScreenLocker() { |
| 420 ClearErrors(); |
| 421 DCHECK(lock_window_); |
| 422 lock_window_->Close(); |
| 423 // lock_widget_ will be deleted by gtk's destroy signal. |
| 424 screen_locker_ = NULL; |
| 425 if (CrosLibrary::Get()->EnsureLoaded()) |
| 426 CrosLibrary::Get()->GetScreenLockLibrary()->NotifyScreenUnlockCompleted(); |
| 427 } |
| 428 |
| 429 void ScreenLocker::SetAuthenticator(Authenticator* authenticator) { |
| 430 authenticator_ = authenticator; |
| 431 } |
| 432 |
| 433 void ScreenLocker::ScreenLockReady() { |
| 434 DLOG(INFO) << "ScreenLockReady"; |
| 435 // Don't show the password field until we grab all inputs. |
| 436 lock_widget_->GetRootView()->SetVisible(true); |
| 437 EnableInput(); |
| 438 if (CrosLibrary::Get()->EnsureLoaded()) |
| 439 CrosLibrary::Get()->GetScreenLockLibrary()->NotifyScreenLockCompleted(); |
| 440 } |
| 441 |
| 442 void ScreenLocker::OnMap(GtkWidget* widget, GdkEvent* event) { |
| 443 DLOG(INFO) << "OnMap"; |
| 444 mapped_ = true; |
| 445 if (input_grabbed_) |
| 446 ScreenLockReady(); |
| 447 } |
| 448 |
424 } // namespace chromeos | 449 } // namespace chromeos |
OLD | NEW |