| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/webui_screen_locker.h" | 5 #include "chrome/browser/chromeos/login/webui_screen_locker.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/utf_string_conversions.h" | 8 #include "base/utf_string_conversions.h" |
| 9 #include "base/values.h" | 9 #include "base/values.h" |
| 10 #include "chrome/browser/chromeos/cros/cros_library.h" | 10 #include "chrome/browser/chromeos/cros/cros_library.h" |
| 11 #include "chrome/browser/chromeos/cros/network_library.h" | 11 #include "chrome/browser/chromeos/cros/network_library.h" |
| 12 #include "chrome/browser/chromeos/legacy_window_manager/wm_ipc.h" | |
| 13 #include "chrome/browser/chromeos/login/helper.h" | 12 #include "chrome/browser/chromeos/login/helper.h" |
| 14 #include "chrome/browser/chromeos/login/screen_locker.h" | 13 #include "chrome/browser/chromeos/login/screen_locker.h" |
| 15 #include "chrome/browser/chromeos/login/user_manager.h" | 14 #include "chrome/browser/chromeos/login/user_manager.h" |
| 16 #include "chrome/browser/chromeos/login/webui_login_display.h" | 15 #include "chrome/browser/chromeos/login/webui_login_display.h" |
| 17 #include "chrome/browser/ui/views/dom_view.h" | 16 #include "chrome/browser/ui/views/dom_view.h" |
| 18 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" | 17 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" |
| 19 #include "chrome/common/chrome_notification_types.h" | 18 #include "chrome/common/chrome_notification_types.h" |
| 20 #include "chrome/common/url_constants.h" | 19 #include "chrome/common/url_constants.h" |
| 21 #include "content/browser/renderer_host/render_widget_host_view.h" | 20 #include "content/browser/renderer_host/render_widget_host_view.h" |
| 22 #include "content/public/browser/notification_service.h" | 21 #include "content/public/browser/notification_service.h" |
| 23 #include "content/public/browser/notification_types.h" | 22 #include "content/public/browser/notification_types.h" |
| 24 #include "ui/base/l10n/l10n_util.h" | 23 #include "ui/base/l10n/l10n_util.h" |
| 25 #include "ui/base/x/x11_util.h" | 24 #include "ui/base/x/x11_util.h" |
| 26 #include "ui/gfx/screen.h" | 25 #include "ui/gfx/screen.h" |
| 27 #include "ui/views/widget/native_widget_gtk.h" | |
| 28 | |
| 29 // These conflict with some of the Chrome headers, so must be included last. | |
| 30 #include <X11/extensions/XTest.h> | |
| 31 #include <X11/keysym.h> | |
| 32 #include <gdk/gdkkeysyms.h> | |
| 33 #include <gdk/gdkx.h> | |
| 34 | 26 |
| 35 namespace { | 27 namespace { |
| 36 | 28 |
| 37 // URL which corresponds to the login WebUI. | 29 // URL which corresponds to the login WebUI. |
| 38 const char kLoginURL[] = "chrome://oobe/login"; | 30 const char kLoginURL[] = "chrome://oobe/login"; |
| 39 | 31 |
| 40 // The maximum duration for which locker should try to grab the keyboard and | |
| 41 // mouse and its interval for regrabbing on failure. | |
| 42 const int kMaxGrabFailureSec = 30; | |
| 43 const int64 kRetryGrabIntervalMs = 500; | |
| 44 | |
| 45 // Maximum number of times we'll try to grab the keyboard and mouse before | |
| 46 // giving up. If we hit the limit, Chrome exits and the session is terminated. | |
| 47 const int kMaxGrabFailures = kMaxGrabFailureSec * 1000 / kRetryGrabIntervalMs; | |
| 48 | |
| 49 // A ScreenLock window that covers entire screen to keep the keyboard | |
| 50 // focus/events inside the grab widget. | |
| 51 class LockWindow : public views::NativeWidgetGtk { | |
| 52 public: | |
| 53 explicit LockWindow(chromeos::WebUIScreenLocker* webui_screen_locker) | |
| 54 : views::NativeWidgetGtk(new views::Widget), | |
| 55 toplevel_focus_widget_(NULL), | |
| 56 webui_screen_locker_(webui_screen_locker) { | |
| 57 EnableDoubleBuffer(true); | |
| 58 } | |
| 59 | |
| 60 virtual gboolean OnButtonPress(GtkWidget* widget, | |
| 61 GdkEventButton* event) OVERRIDE { | |
| 62 // Never propagate mouse events to parent. | |
| 63 return true; | |
| 64 } | |
| 65 | |
| 66 virtual void OnDestroy(GtkWidget* object) OVERRIDE { | |
| 67 VLOG(1) << "OnDestroy: LockWindow destroyed"; | |
| 68 views::NativeWidgetGtk::OnDestroy(object); | |
| 69 } | |
| 70 | |
| 71 virtual void ClearNativeFocus() OVERRIDE { | |
| 72 DCHECK(toplevel_focus_widget_); | |
| 73 gtk_widget_grab_focus(toplevel_focus_widget_); | |
| 74 } | |
| 75 | |
| 76 virtual void HandleGtkGrabBroke() OVERRIDE { | |
| 77 webui_screen_locker_->HandleGtkGrabBroke(); | |
| 78 } | |
| 79 | |
| 80 // Sets the widget to move the focus to when clearning the native | |
| 81 // widget's focus. | |
| 82 void set_toplevel_focus_widget(GtkWidget* widget) { | |
| 83 gtk_widget_set_can_focus(widget, TRUE); | |
| 84 toplevel_focus_widget_ = widget; | |
| 85 } | |
| 86 | |
| 87 private: | |
| 88 // The widget we set focus to when clearning the focus on native | |
| 89 // widget. Gdk input is grabbed in WebUIScreenLocker, and resetting the focus | |
| 90 // by using gtk_window_set_focus seems to confuse gtk and doesn't let focus | |
| 91 // move to native widget under this. | |
| 92 GtkWidget* toplevel_focus_widget_; | |
| 93 | |
| 94 // The WebUI screen locker. | |
| 95 chromeos::WebUIScreenLocker* webui_screen_locker_; | |
| 96 | |
| 97 DISALLOW_COPY_AND_ASSIGN(LockWindow); | |
| 98 }; | |
| 99 | |
| 100 // Define separate methods for each error code so that stack trace | |
| 101 // will tell which error the grab failed with. | |
| 102 void FailedWithGrabAlreadyGrabbed() { | |
| 103 LOG(FATAL) << "Grab already grabbed"; | |
| 104 } | |
| 105 void FailedWithGrabInvalidTime() { | |
| 106 LOG(FATAL) << "Grab invalid time"; | |
| 107 } | |
| 108 void FailedWithGrabNotViewable() { | |
| 109 LOG(FATAL) << "Grab not viewable"; | |
| 110 } | |
| 111 void FailedWithGrabFrozen() { | |
| 112 LOG(FATAL) << "Grab frozen"; | |
| 113 } | |
| 114 void FailedWithUnknownError() { | |
| 115 LOG(FATAL) << "Grab uknown"; | |
| 116 } | |
| 117 | |
| 118 } // namespace | 32 } // namespace |
| 119 | 33 |
| 120 namespace chromeos { | 34 namespace chromeos { |
| 121 | 35 |
| 122 //////////////////////////////////////////////////////////////////////////////// | 36 //////////////////////////////////////////////////////////////////////////////// |
| 123 // WebUIScreenLocker implementation. | 37 // WebUIScreenLocker implementation. |
| 124 | 38 |
| 125 WebUIScreenLocker::WebUIScreenLocker(ScreenLocker* screen_locker) | 39 WebUIScreenLocker::WebUIScreenLocker(ScreenLocker* screen_locker) |
| 126 : ScreenLockerDelegate(screen_locker), | 40 : ScreenLockerDelegate(screen_locker), |
| 127 drawn_(false), | 41 lock_ready_(false), |
| 128 input_grabbed_(false), | 42 webui_ready_(false) { |
| 129 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), | |
| 130 grab_failure_count_(0), | |
| 131 kbd_grab_status_(GDK_GRAB_INVALID_TIME), | |
| 132 mouse_grab_status_(GDK_GRAB_INVALID_TIME) { | |
| 133 } | 43 } |
| 134 | 44 |
| 135 void WebUIScreenLocker::LockScreen(bool unlock_on_input) { | 45 void WebUIScreenLocker::LockScreen(bool unlock_on_input) { |
| 136 static const GdkColor kGdkBlack = {0, 0, 0, 0}; | |
| 137 | |
| 138 gfx::Rect bounds(gfx::Screen::GetMonitorAreaNearestWindow(NULL)); | 46 gfx::Rect bounds(gfx::Screen::GetMonitorAreaNearestWindow(NULL)); |
| 139 | 47 |
| 140 LockWindow* lock_window = new LockWindow(this); | 48 LockWindow* lock_window = LockWindow::Create(); |
| 49 lock_window->set_observer(this); |
| 141 lock_window_ = lock_window->GetWidget(); | 50 lock_window_ = lock_window->GetWidget(); |
| 142 views::Widget::InitParams params( | |
| 143 views::Widget::InitParams::TYPE_WINDOW_FRAMELESS); | |
| 144 params.bounds = bounds; | |
| 145 params.native_widget = lock_window; | |
| 146 lock_window_->Init(params); | |
| 147 gtk_widget_modify_bg( | |
| 148 lock_window_->GetNativeView(), GTK_STATE_NORMAL, &kGdkBlack); | |
| 149 | |
| 150 g_signal_connect(lock_window_->GetNativeView(), "client-event", | |
| 151 G_CALLBACK(OnClientEventThunk), this); | |
| 152 | |
| 153 // TODO(flackr): Obscure the screen with black / a screensaver if | |
| 154 // unlock_on_input. | |
| 155 DCHECK(GTK_WIDGET_REALIZED(lock_window_->GetNativeView())); | |
| 156 WmIpc::instance()->SetWindowType( | |
| 157 lock_window_->GetNativeView(), | |
| 158 WM_IPC_WINDOW_CHROME_SCREEN_LOCKER, | |
| 159 NULL); | |
| 160 | |
| 161 WebUILoginView::Init(lock_window_); | 51 WebUILoginView::Init(lock_window_); |
| 162 lock_window_->SetContentsView(this); | 52 lock_window_->SetContentsView(this); |
| 163 lock_window_->Show(); | 53 lock_window_->Show(); |
| 164 OnWindowCreated(); | 54 OnWindowCreated(); |
| 165 LoadURL(GURL(kLoginURL)); | 55 LoadURL(GURL(kLoginURL)); |
| 56 lock_window->Grab(webui_login_); |
| 57 |
| 166 // User list consisting of a single logged-in user. | 58 // User list consisting of a single logged-in user. |
| 167 UserList users(1, &chromeos::UserManager::Get()->logged_in_user()); | 59 UserList users(1, &chromeos::UserManager::Get()->logged_in_user()); |
| 168 login_display_.reset(new WebUILoginDisplay(this)); | 60 login_display_.reset(new WebUILoginDisplay(this)); |
| 169 login_display_->set_background_bounds(bounds); | 61 login_display_->set_background_bounds(bounds); |
| 170 login_display_->set_parent_window( | |
| 171 GTK_WINDOW(lock_window_->GetNativeView())); | |
| 172 login_display_->Init(users, false, false); | 62 login_display_->Init(users, false, false); |
| 173 | 63 |
| 174 static_cast<OobeUI*>(GetWebUI())->ShowSigninScreen(login_display_.get()); | 64 static_cast<OobeUI*>(GetWebUI())->ShowSigninScreen(login_display_.get()); |
| 175 | 65 |
| 176 registrar_.Add(this, | 66 registrar_.Add(this, |
| 177 chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED, | 67 chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED, |
| 178 content::NotificationService::AllSources()); | 68 content::NotificationService::AllSources()); |
| 179 | |
| 180 ClearGtkGrab(); | |
| 181 | |
| 182 // Call this after lock_window_->Show(); otherwise the 1st invocation | |
| 183 // of gdk_xxx_grab() will always fail. | |
| 184 TryGrabAllInputs(); | |
| 185 | |
| 186 // Add the window to its own group so that its grab won't be stolen if | |
| 187 // gtk_grab_add() gets called on behalf on a non-screen-locker widget (e.g. | |
| 188 // a modal dialog) -- see http://crosbug.com/8999. We intentionally do this | |
| 189 // after calling ClearGtkGrab(), as want to be in the default window group | |
| 190 // then so we can break any existing GTK grabs. | |
| 191 GtkWindowGroup* window_group = gtk_window_group_new(); | |
| 192 gtk_window_group_add_window(window_group, | |
| 193 GTK_WINDOW(lock_window_->GetNativeView())); | |
| 194 g_object_unref(window_group); | |
| 195 | |
| 196 lock_window->set_toplevel_focus_widget(lock_window->window_contents()); | |
| 197 } | |
| 198 | |
| 199 void WebUIScreenLocker::OnGrabInputs() { | |
| 200 DVLOG(1) << "OnGrabInputs"; | |
| 201 input_grabbed_ = true; | |
| 202 if (drawn_) | |
| 203 ScreenLockReady(); | |
| 204 } | |
| 205 | |
| 206 void WebUIScreenLocker::OnWindowManagerReady() { | |
| 207 DVLOG(1) << "OnClientEvent: drawn for lock"; | |
| 208 drawn_ = true; | |
| 209 if (input_grabbed_) | |
| 210 ScreenLockReady(); | |
| 211 } | 69 } |
| 212 | 70 |
| 213 void WebUIScreenLocker::ScreenLockReady() { | 71 void WebUIScreenLocker::ScreenLockReady() { |
| 214 ScreenLockerDelegate::ScreenLockReady(); | 72 ScreenLockerDelegate::ScreenLockReady(); |
| 215 SetInputEnabled(true); | 73 SetInputEnabled(true); |
| 216 } | 74 } |
| 217 | 75 |
| 218 void WebUIScreenLocker::ClearGtkGrab() { | |
| 219 GtkWidget* current_grab_window; | |
| 220 // Grab gtk input first so that the menu holding gtk grab will | |
| 221 // close itself. | |
| 222 gtk_grab_add(webui_login_->native_view()); | |
| 223 | |
| 224 // Make sure there is no gtk grab widget so that gtk simply propagates | |
| 225 // an event. GTK maintains grab widgets in a linked-list, so we need to | |
| 226 // remove until it's empty. | |
| 227 while ((current_grab_window = gtk_grab_get_current()) != NULL) | |
| 228 gtk_grab_remove(current_grab_window); | |
| 229 } | |
| 230 | |
| 231 void WebUIScreenLocker::TryGrabAllInputs() { | |
| 232 // Grab on the RenderWidgetHostView hosting the WebUI login screen. | |
| 233 GdkWindow* grab_widget = webui_login_->dom_contents()->tab_contents()-> | |
| 234 GetRenderWidgetHostView()->GetNativeView()->window; | |
| 235 // Grab x server so that we can atomically grab and take | |
| 236 // action when grab fails. | |
| 237 gdk_x11_grab_server(); | |
| 238 gtk_grab_add(webui_login_->native_view()); | |
| 239 if (kbd_grab_status_ != GDK_GRAB_SUCCESS) | |
| 240 kbd_grab_status_ = gdk_keyboard_grab(grab_widget, FALSE, GDK_CURRENT_TIME); | |
| 241 if (mouse_grab_status_ != GDK_GRAB_SUCCESS) { | |
| 242 mouse_grab_status_ = | |
| 243 gdk_pointer_grab(grab_widget, | |
| 244 FALSE, | |
| 245 static_cast<GdkEventMask>( | |
| 246 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | | |
| 247 GDK_POINTER_MOTION_MASK), | |
| 248 NULL, | |
| 249 NULL, | |
| 250 GDK_CURRENT_TIME); | |
| 251 } | |
| 252 if ((kbd_grab_status_ != GDK_GRAB_SUCCESS || | |
| 253 mouse_grab_status_ != GDK_GRAB_SUCCESS) && | |
| 254 grab_failure_count_++ < kMaxGrabFailures) { | |
| 255 LOG(WARNING) << "Failed to grab inputs. Trying again in " | |
| 256 << kRetryGrabIntervalMs << " ms: kbd=" | |
| 257 << kbd_grab_status_ << ", mouse=" << mouse_grab_status_; | |
| 258 TryUngrabOtherClients(); | |
| 259 gdk_x11_ungrab_server(); | |
| 260 MessageLoop::current()->PostDelayedTask( | |
| 261 FROM_HERE, | |
| 262 base::Bind(&WebUIScreenLocker::TryGrabAllInputs, | |
| 263 weak_factory_.GetWeakPtr()), | |
| 264 kRetryGrabIntervalMs); | |
| 265 } else { | |
| 266 gdk_x11_ungrab_server(); | |
| 267 GdkGrabStatus status = kbd_grab_status_; | |
| 268 if (status == GDK_GRAB_SUCCESS) { | |
| 269 status = mouse_grab_status_; | |
| 270 } | |
| 271 switch (status) { | |
| 272 case GDK_GRAB_SUCCESS: | |
| 273 break; | |
| 274 case GDK_GRAB_ALREADY_GRABBED: | |
| 275 FailedWithGrabAlreadyGrabbed(); | |
| 276 break; | |
| 277 case GDK_GRAB_INVALID_TIME: | |
| 278 FailedWithGrabInvalidTime(); | |
| 279 break; | |
| 280 case GDK_GRAB_NOT_VIEWABLE: | |
| 281 FailedWithGrabNotViewable(); | |
| 282 break; | |
| 283 case GDK_GRAB_FROZEN: | |
| 284 FailedWithGrabFrozen(); | |
| 285 break; | |
| 286 default: | |
| 287 FailedWithUnknownError(); | |
| 288 break; | |
| 289 } | |
| 290 DVLOG(1) << "Grab Success"; | |
| 291 OnGrabInputs(); | |
| 292 } | |
| 293 } | |
| 294 | |
| 295 void WebUIScreenLocker::TryUngrabOtherClients() { | |
| 296 #if !defined(NDEBUG) | |
| 297 { | |
| 298 int event_base, error_base; | |
| 299 int major, minor; | |
| 300 // Make sure we have XTest extension. | |
| 301 DCHECK(XTestQueryExtension(ui::GetXDisplay(), | |
| 302 &event_base, &error_base, | |
| 303 &major, &minor)); | |
| 304 } | |
| 305 #endif | |
| 306 | |
| 307 // The following code is an attempt to grab inputs by closing | |
| 308 // supposedly opened menu. This happens when a plugin has a menu | |
| 309 // opened. | |
| 310 if (mouse_grab_status_ == GDK_GRAB_ALREADY_GRABBED || | |
| 311 mouse_grab_status_ == GDK_GRAB_FROZEN) { | |
| 312 // Successfully grabbed the keyboard, but pointer is still | |
| 313 // grabbed by other client. Another attempt to close supposedly | |
| 314 // opened menu by emulating keypress at the left top corner. | |
| 315 Display* display = ui::GetXDisplay(); | |
| 316 Window root, child; | |
| 317 int root_x, root_y, win_x, winy; | |
| 318 unsigned int mask; | |
| 319 XQueryPointer(display, | |
| 320 ui::GetX11WindowFromGtkWidget( | |
| 321 static_cast<LockWindow*>(lock_window_->native_widget())-> | |
| 322 window_contents()), | |
| 323 &root, &child, &root_x, &root_y, | |
| 324 &win_x, &winy, &mask); | |
| 325 XTestFakeMotionEvent(display, -1, -10000, -10000, CurrentTime); | |
| 326 XTestFakeButtonEvent(display, 1, True, CurrentTime); | |
| 327 XTestFakeButtonEvent(display, 1, False, CurrentTime); | |
| 328 // Move the pointer back. | |
| 329 XTestFakeMotionEvent(display, -1, root_x, root_y, CurrentTime); | |
| 330 XFlush(display); | |
| 331 } else if (kbd_grab_status_ == GDK_GRAB_ALREADY_GRABBED || | |
| 332 kbd_grab_status_ == GDK_GRAB_FROZEN) { | |
| 333 // Successfully grabbed the pointer, but keyboard is still grabbed | |
| 334 // by other client. Another attempt to close supposedly opened | |
| 335 // menu by emulating escape key. Such situation must be very | |
| 336 // rare, but handling this just in case | |
| 337 Display* display = ui::GetXDisplay(); | |
| 338 KeyCode escape = XKeysymToKeycode(display, XK_Escape); | |
| 339 XTestFakeKeyEvent(display, escape, True, CurrentTime); | |
| 340 XTestFakeKeyEvent(display, escape, False, CurrentTime); | |
| 341 XFlush(display); | |
| 342 } | |
| 343 } | |
| 344 | |
| 345 void WebUIScreenLocker::HandleGtkGrabBroke() { | |
| 346 // Input should never be stolen from ScreenLocker once it's | |
| 347 // grabbed. If this happens, it's a bug and has to be fixed. We | |
| 348 // let chrome crash to get a crash report and dump, and | |
| 349 // SessionManager will terminate the session to logout. | |
| 350 CHECK_NE(GDK_GRAB_SUCCESS, kbd_grab_status_); | |
| 351 CHECK_NE(GDK_GRAB_SUCCESS, mouse_grab_status_); | |
| 352 } | |
| 353 | |
| 354 void WebUIScreenLocker::OnAuthenticate() { | 76 void WebUIScreenLocker::OnAuthenticate() { |
| 355 } | 77 } |
| 356 | 78 |
| 357 void WebUIScreenLocker::SetInputEnabled(bool enabled) { | 79 void WebUIScreenLocker::SetInputEnabled(bool enabled) { |
| 358 login_display_->SetUIEnabled(enabled); | 80 login_display_->SetUIEnabled(enabled); |
| 359 SetStatusAreaEnabled(enabled); | 81 SetStatusAreaEnabled(enabled); |
| 360 } | 82 } |
| 361 | 83 |
| 362 void WebUIScreenLocker::SetSignoutEnabled(bool enabled) { | 84 void WebUIScreenLocker::SetSignoutEnabled(bool enabled) { |
| 363 // TODO(flackr): Implement (crbug.com/105267). | 85 // TODO(flackr): Implement (crbug.com/105267). |
| (...skipping 23 matching lines...) Expand all Loading... |
| 387 | 109 |
| 388 void WebUIScreenLocker::ClearErrors() { | 110 void WebUIScreenLocker::ClearErrors() { |
| 389 GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.clearErrors"); | 111 GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.clearErrors"); |
| 390 } | 112 } |
| 391 | 113 |
| 392 WebUIScreenLocker::~WebUIScreenLocker() { | 114 WebUIScreenLocker::~WebUIScreenLocker() { |
| 393 DCHECK(lock_window_); | 115 DCHECK(lock_window_); |
| 394 lock_window_->Close(); | 116 lock_window_->Close(); |
| 395 } | 117 } |
| 396 | 118 |
| 397 void WebUIScreenLocker::OnClientEvent(GtkWidget* widge, GdkEventClient* event) { | |
| 398 WmIpc::Message msg; | |
| 399 WmIpc::instance()->DecodeMessage(*event, &msg); | |
| 400 if (msg.type() == WM_IPC_MESSAGE_CHROME_NOTIFY_SCREEN_REDRAWN_FOR_LOCK) | |
| 401 OnWindowManagerReady(); | |
| 402 } | |
| 403 | |
| 404 //////////////////////////////////////////////////////////////////////////////// | 119 //////////////////////////////////////////////////////////////////////////////// |
| 405 // WebUIScreenLocker, content::NotificationObserver implementation: | 120 // WebUIScreenLocker, content::NotificationObserver implementation: |
| 406 | 121 |
| 407 void WebUIScreenLocker::Observe( | 122 void WebUIScreenLocker::Observe( |
| 408 int type, | 123 int type, |
| 409 const content::NotificationSource& source, | 124 const content::NotificationSource& source, |
| 410 const content::NotificationDetails& details) { | 125 const content::NotificationDetails& details) { |
| 411 if (type != chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED) | 126 if (type != chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED) |
| 412 return; | 127 return; |
| 413 | 128 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 447 NOTREACHED(); | 162 NOTREACHED(); |
| 448 } | 163 } |
| 449 | 164 |
| 450 void WebUIScreenLocker::OnUserSelected(const std::string& username) { | 165 void WebUIScreenLocker::OnUserSelected(const std::string& username) { |
| 451 } | 166 } |
| 452 | 167 |
| 453 void WebUIScreenLocker::OnStartEnterpriseEnrollment() { | 168 void WebUIScreenLocker::OnStartEnterpriseEnrollment() { |
| 454 NOTREACHED(); | 169 NOTREACHED(); |
| 455 } | 170 } |
| 456 | 171 |
| 172 //////////////////////////////////////////////////////////////////////////////// |
| 173 // LockWindow::Observer implementation: |
| 174 |
| 175 void WebUIScreenLocker::OnLockWindowReady() { |
| 176 lock_ready_ = true; |
| 177 if (webui_ready_) |
| 178 ScreenLockReady(); |
| 179 } |
| 180 |
| 181 //////////////////////////////////////////////////////////////////////////////// |
| 182 // Overridden from WebUILoginView: |
| 183 |
| 184 void WebUIScreenLocker::OnTabMainFrameFirstRender() { |
| 185 WebUILoginView::OnTabMainFrameFirstRender(); |
| 186 webui_ready_ = true; |
| 187 if (lock_ready_) |
| 188 ScreenLockReady(); |
| 189 } |
| 190 |
| 457 } // namespace chromeos | 191 } // namespace chromeos |
| OLD | NEW |