chromium/components/session_manager/core/session_manager.cc

// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/session_manager/core/session_manager.h"

#include "base/containers/contains.h"
#include "base/logging.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "components/session_manager/core/session_manager_observer.h"
#include "components/user_manager/user_manager.h"

namespace session_manager {

// static
SessionManager* SessionManager::instance = nullptr;

SessionManager::SessionManager() {
  DCHECK(!SessionManager::Get());
  SessionManager::SetInstance(this);
}

SessionManager::~SessionManager() {
  DCHECK_EQ(instance, this);
  SessionManager::SetInstance(nullptr);
}

// static
SessionManager* SessionManager::Get() {
  return SessionManager::instance;
}

void SessionManager::SetSessionState(SessionState state) {
  if (session_state_ == state)
    return;

  VLOG(1) << "Changing session state to: " << static_cast<int>(state);

  session_state_ = state;
  for (auto& observer : observers_)
    observer.OnSessionStateChanged();
}

void SessionManager::CreateSession(const AccountId& user_account_id,
                                   const std::string& user_id_hash,
                                   bool is_child) {
  CreateSessionInternal(user_account_id, user_id_hash,
                        false /* browser_restart */, is_child);
}

void SessionManager::CreateSessionForRestart(const AccountId& user_account_id,
                                             const std::string& user_id_hash) {
  auto* user_manager = user_manager::UserManager::Get();
  if (!user_manager)
    return;
  const user_manager::User* user = user_manager->FindUser(user_account_id);
  // Tests do not always create users.
  const bool is_child =
      user && user->GetType() == user_manager::UserType::kChild;
  CreateSessionInternal(user_account_id, user_id_hash,
                        true /* browser_restart */, is_child);
}

bool SessionManager::IsSessionStarted() const {
  return session_started_;
}

bool SessionManager::IsUserSessionStartUpTaskCompleted() const {
  return user_session_start_up_task_completed_;
}

void SessionManager::SessionStarted() {
  TRACE_EVENT0("login", "SessionManager::SessionStarted");
  session_started_ = true;

  bool is_primary = sessions_.size() == 1;
  for (auto& observer : observers_)
    observer.OnUserSessionStarted(is_primary);
}

bool SessionManager::HasSessionForAccountId(
    const AccountId& user_account_id) const {
  return base::Contains(sessions_, user_account_id, &Session::user_account_id);
}

bool SessionManager::IsInSecondaryLoginScreen() const {
  return session_state_ == SessionState::LOGIN_SECONDARY;
}

bool SessionManager::IsScreenLocked() const {
  return session_state_ == SessionState::LOCKED;
}

bool SessionManager::IsUserSessionBlocked() const {
  return session_state_ != SessionState::ACTIVE;
}

void SessionManager::AddObserver(SessionManagerObserver* observer) {
  observers_.AddObserver(observer);
}

void SessionManager::RemoveObserver(SessionManagerObserver* observer) {
  observers_.RemoveObserver(observer);
}

void SessionManager::NotifyUserProfileLoaded(const AccountId& account_id) {
  for (auto& observer : observers_)
    observer.OnUserProfileLoaded(account_id);
}

void SessionManager::NotifyLoginOrLockScreenVisible() {
  login_or_lock_screen_shown_for_test_ = true;
  for (auto& observer : observers_)
    observer.OnLoginOrLockScreenVisible();
}

void SessionManager::NotifyUnlockAttempt(const bool success,
                                         const UnlockType unlock_type) {
  for (auto& observer : observers_)
    observer.OnUnlockScreenAttempt(success, unlock_type);
}

void SessionManager::NotifyUserLoggedIn(const AccountId& user_account_id,
                                        const std::string& user_id_hash,
                                        bool browser_restart,
                                        bool is_child) {
  auto* user_manager = user_manager::UserManager::Get();
  if (!user_manager)
    return;
  user_manager->UserLoggedIn(user_account_id, user_id_hash, browser_restart,
                             is_child);
}

void SessionManager::HandleUserSessionStartUpTaskCompleted() {
  user_session_start_up_task_completed_ = true;
  for (auto& observer : observers_) {
    observer.OnUserSessionStartUpTaskCompleted();
  }
}

// static
void SessionManager::SetInstance(SessionManager* session_manager) {
  SessionManager::instance = session_manager;
}

void SessionManager::CreateSessionInternal(const AccountId& user_account_id,
                                           const std::string& user_id_hash,
                                           bool browser_restart,
                                           bool is_child) {
  DCHECK(!HasSessionForAccountId(user_account_id));
  sessions_.push_back({next_id_++, user_account_id});
  NotifyUserLoggedIn(user_account_id, user_id_hash, browser_restart, is_child);
}

}  // namespace session_manager