root/chrome/browser/chromeos/login/webui_screen_locker.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. weak_factory_
  2. LockScreen
  3. ScreenLockReady
  4. OnAuthenticate
  5. SetInputEnabled
  6. ShowBannerMessage
  7. ShowUserPodButton
  8. HideUserPodButton
  9. SetAuthType
  10. GetAuthType
  11. ShowErrorMessage
  12. AnimateAuthenticationSuccess
  13. ClearErrors
  14. GetNativeWindow
  15. GetAssociatedWebUI
  16. FocusUserPod
  17. OnLockWebUIReady
  18. OnLockBackgroundDisplayed
  19. Observe
  20. CancelPasswordChangedFlow
  21. CreateAccount
  22. CompleteLogin
  23. GetConnectedNetworkName
  24. IsSigninInProgress
  25. Login
  26. LoginAsRetailModeUser
  27. LoginAsGuest
  28. MigrateUserData
  29. LoginAsPublicAccount
  30. OnSigninScreenReady
  31. OnUserSelected
  32. OnStartEnterpriseEnrollment
  33. OnStartKioskEnableScreen
  34. OnStartDeviceReset
  35. OnStartKioskAutolaunchScreen
  36. ShowWrongHWIDScreen
  37. ResetPublicSessionAutoLoginTimer
  38. ResyncUserData
  39. SetDisplayEmail
  40. Signout
  41. LoginAsKioskApp
  42. OnLockWindowReady
  43. OnLockStateEvent
  44. OnWidgetDestroying
  45. LidEventReceived
  46. SystemResumed
  47. RenderProcessGone

// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/chromeos/login/webui_screen_locker.h"

#include "ash/shell.h"
#include "ash/wm/lock_state_controller.h"
#include "ash/wm/lock_state_observer.h"
#include "base/command_line.h"
#include "base/metrics/histogram.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/browser_shutdown.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/chromeos/accessibility/accessibility_util.h"
#include "chrome/browser/chromeos/login/helper.h"
#include "chrome/browser/chromeos/login/screen_locker.h"
#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/chromeos/login/webui_login_display.h"
#include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
#include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
#include "chrome/common/url_constants.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_ui.h"
#include "ui/aura/client/capture_client.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/x/x11_util.h"
#include "ui/gfx/screen.h"
#include "ui/views/controls/webview/webview.h"

namespace {

// URL which corresponds to the login WebUI.
const char kLoginURL[] = "chrome://oobe/lock";

}  // namespace

namespace chromeos {

////////////////////////////////////////////////////////////////////////////////
// WebUIScreenLocker implementation.

WebUIScreenLocker::WebUIScreenLocker(ScreenLocker* screen_locker)
    : ScreenLockerDelegate(screen_locker),
      lock_ready_(false),
      webui_ready_(false),
      network_state_helper_(new login::NetworkStateHelper),
      weak_factory_(this) {
  set_should_emit_login_prompt_visible(false);
  ash::Shell::GetInstance()->lock_state_controller()->AddObserver(this);
  DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver(this);
}

void WebUIScreenLocker::LockScreen() {
  gfx::Rect bounds(ash::Shell::GetScreen()->GetPrimaryDisplay().bounds());

  lock_time_ = base::TimeTicks::Now();
  LockWindow* lock_window = LockWindow::Create();
  lock_window->set_observer(this);
  lock_window_ = lock_window->GetWidget();
  lock_window_->AddObserver(this);
  WebUILoginView::Init();
  lock_window_->SetContentsView(this);
  lock_window_->Show();
  LoadURL(GURL(kLoginURL));
  lock_window->Grab();

  login_display_.reset(new WebUILoginDisplay(this));
  login_display_->set_background_bounds(bounds);
  login_display_->set_parent_window(GetNativeWindow());
  login_display_->Init(screen_locker()->users(), false, true, false);

  static_cast<OobeUI*>(GetWebUI()->GetController())->ShowSigninScreen(
      LoginScreenContext(), login_display_.get(), login_display_.get());

  registrar_.Add(this,
                 chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED,
                 content::NotificationService::AllSources());
}

void WebUIScreenLocker::ScreenLockReady() {
  UMA_HISTOGRAM_TIMES("LockScreen.LockReady",
                      base::TimeTicks::Now() - lock_time_);
  ScreenLockerDelegate::ScreenLockReady();
  SetInputEnabled(true);
}

void WebUIScreenLocker::OnAuthenticate() {
}

void WebUIScreenLocker::SetInputEnabled(bool enabled) {
  login_display_->SetUIEnabled(enabled);
}

void WebUIScreenLocker::ShowBannerMessage(const std::string& message) {
  if (!webui_ready_)
    return;
  login_display_->ShowBannerMessage(message);
}

void WebUIScreenLocker::ShowUserPodButton(
    const std::string& username,
    const std::string& iconURL,
    const base::Closure& click_callback) {
  if (!webui_ready_)
    return;
  login_display_->ShowUserPodButton(username, iconURL, click_callback);
}

void WebUIScreenLocker::HideUserPodButton(const std::string& username) {
  if (!webui_ready_)
    return;
  login_display_->HideUserPodButton(username);
}

void WebUIScreenLocker::SetAuthType(const std::string& username,
                                    LoginDisplay::AuthType auth_type,
                                    const std::string& initial_value) {
  if (!webui_ready_)
    return;
  login_display_->SetAuthType(username, auth_type, initial_value);
}

LoginDisplay::AuthType WebUIScreenLocker::GetAuthType(
    const std::string& username) const {
  // Return default auth type if login display is not ready.
  if (!webui_ready_)
    return LoginDisplay::OFFLINE_PASSWORD;
  return login_display_->GetAuthType(username);
}

void WebUIScreenLocker::ShowErrorMessage(
    int error_msg_id,
    HelpAppLauncher::HelpTopic help_topic_id) {
  login_display_->ShowError(error_msg_id,
                  0 /* login_attempts */,
                  help_topic_id);
}

void WebUIScreenLocker::AnimateAuthenticationSuccess() {
  GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.animateAuthenticationSuccess");
}

void WebUIScreenLocker::ClearErrors() {
  GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.clearErrors");
}

gfx::NativeWindow WebUIScreenLocker::GetNativeWindow() const {
  return lock_window_->GetNativeWindow();
}

content::WebUI* WebUIScreenLocker::GetAssociatedWebUI() {
  return GetWebUI();
}

void WebUIScreenLocker::FocusUserPod() {
  if (!webui_ready_)
    return;
  webui_login_->RequestFocus();
  GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.forceLockedUserPodFocus");
}

WebUIScreenLocker::~WebUIScreenLocker() {
  DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(this);
  ash::Shell::GetInstance()->
      lock_state_controller()->RemoveObserver(this);
  // In case of shutdown, lock_window_ may be deleted before WebUIScreenLocker.
  if (lock_window_) {
    lock_window_->RemoveObserver(this);
    lock_window_->Close();
  }
  // If LockScreen() was called, we need to clear the signin screen handler
  // delegate set in ShowSigninScreen so that it no longer points to us.
  if (login_display_.get()) {
    static_cast<OobeUI*>(GetWebUI()->GetController())->
        ResetSigninScreenHandlerDelegate();
  }
}

void WebUIScreenLocker::OnLockWebUIReady() {
  VLOG(1) << "WebUI ready; lock window is "
          << (lock_ready_ ? "too" : "not");
  webui_ready_ = true;
  if (lock_ready_)
    ScreenLockReady();
}

void WebUIScreenLocker::OnLockBackgroundDisplayed() {
  UMA_HISTOGRAM_TIMES("LockScreen.BackgroundReady",
                      base::TimeTicks::Now() - lock_time_);
}

////////////////////////////////////////////////////////////////////////////////
// WebUIScreenLocker, content::NotificationObserver implementation:

void WebUIScreenLocker::Observe(
    int type,
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
  switch (type) {
    case chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED: {
      const User& user = *content::Details<User>(details).ptr();
      login_display_->OnUserImageChanged(user);
      break;
    }
    default:
      WebUILoginView::Observe(type, source, details);
  }
}

////////////////////////////////////////////////////////////////////////////////
// WebUIScreenLocker, LoginDisplay::Delegate implementation:

void WebUIScreenLocker::CancelPasswordChangedFlow()  {
  NOTREACHED();
}

void WebUIScreenLocker::CreateAccount() {
  NOTREACHED();
}

void WebUIScreenLocker::CompleteLogin(const UserContext& user_context) {
  NOTREACHED();
}

base::string16 WebUIScreenLocker::GetConnectedNetworkName() {
  return network_state_helper_->GetCurrentNetworkName();
}

bool WebUIScreenLocker::IsSigninInProgress() const {
  // The way how screen locker is implemented right now there's no
  // GAIA sign in in progress in any case.
  return false;
}

void WebUIScreenLocker::Login(const UserContext& user_context) {
  chromeos::ScreenLocker::default_screen_locker()->Authenticate(user_context);
}

void WebUIScreenLocker::LoginAsRetailModeUser() {
  NOTREACHED();
}

void WebUIScreenLocker::LoginAsGuest() {
  NOTREACHED();
}

void WebUIScreenLocker::MigrateUserData(const std::string& old_password) {
  NOTREACHED();
}

void WebUIScreenLocker::LoginAsPublicAccount(const std::string& username) {
  NOTREACHED();
}

void WebUIScreenLocker::OnSigninScreenReady() {
}

void WebUIScreenLocker::OnUserSelected(const std::string& username) {
}

void WebUIScreenLocker::OnStartEnterpriseEnrollment() {
  NOTREACHED();
}

void WebUIScreenLocker::OnStartKioskEnableScreen() {
  NOTREACHED();
}

void WebUIScreenLocker::OnStartDeviceReset() {
  NOTREACHED();
}

void WebUIScreenLocker::OnStartKioskAutolaunchScreen() {
  NOTREACHED();
}

void WebUIScreenLocker::ShowWrongHWIDScreen() {
  NOTREACHED();
}

void WebUIScreenLocker::ResetPublicSessionAutoLoginTimer() {
}

void WebUIScreenLocker::ResyncUserData() {
  NOTREACHED();
}

void WebUIScreenLocker::SetDisplayEmail(const std::string& email) {
  NOTREACHED();
}

void WebUIScreenLocker::Signout() {
  chromeos::ScreenLocker::default_screen_locker()->Signout();
}

void WebUIScreenLocker::LoginAsKioskApp(const std::string& app_id,
                                        bool diagnostic_mode) {
  NOTREACHED();
}

////////////////////////////////////////////////////////////////////////////////
// LockWindow::Observer implementation:

void WebUIScreenLocker::OnLockWindowReady() {
  VLOG(1) << "Lock window ready; WebUI is " << (webui_ready_ ? "too" : "not");
  lock_ready_ = true;
  if (webui_ready_)
    ScreenLockReady();
}

////////////////////////////////////////////////////////////////////////////////
// SessionLockStateObserver override.

void WebUIScreenLocker::OnLockStateEvent(
    ash::LockStateObserver::EventType event) {
  if (event == ash::LockStateObserver::EVENT_LOCK_ANIMATION_FINISHED) {
    // Release capture if any.
    aura::client::GetCaptureClient(GetNativeWindow()->GetRootWindow())->
        SetCapture(NULL);
    GetWebUI()->CallJavascriptFunction("cr.ui.Oobe.animateOnceFullyDisplayed");
  }
}

////////////////////////////////////////////////////////////////////////////////
// WidgetObserver override.

void WebUIScreenLocker::OnWidgetDestroying(views::Widget* widget) {
  lock_window_->RemoveObserver(this);
  lock_window_ = NULL;
}

////////////////////////////////////////////////////////////////////////////////
// PowerManagerClient::Observer overrides.

void WebUIScreenLocker::LidEventReceived(bool open,
                                         const base::TimeTicks& time) {
  content::BrowserThread::PostTask(
      content::BrowserThread::UI,
      FROM_HERE,
      base::Bind(&WebUIScreenLocker::FocusUserPod, weak_factory_.GetWeakPtr()));
}

void WebUIScreenLocker::SystemResumed(const base::TimeDelta& sleep_duration) {
  content::BrowserThread::PostTask(
      content::BrowserThread::UI,
      FROM_HERE,
      base::Bind(&WebUIScreenLocker::FocusUserPod, weak_factory_.GetWeakPtr()));
}

void WebUIScreenLocker::RenderProcessGone(base::TerminationStatus status) {
  if (browser_shutdown::GetShutdownType() == browser_shutdown::NOT_VALID &&
      status != base::TERMINATION_STATUS_NORMAL_TERMINATION) {
    LOG(ERROR) << "Renderer crash on lock screen";
    Signout();
  }
}

}  // namespace chromeos

/* [<][>][^][v][top][bottom][index][help] */