// Copyright 2016 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. #ifndef ASH_SESSION_SESSION_CONTROLLER_IMPL_H_ #define ASH_SESSION_SESSION_CONTROLLER_IMPL_H_ #include #include #include #include "ash/ash_export.h" #include "ash/login_status.h" #include "ash/public/cpp/session/session_controller.h" #include "ash/public/cpp/session/session_types.h" #include "ash/session/session_activation_observer_holder.h" #include "base/callback.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" #include "base/time/time.h" class AccountId; class PrefService; namespace ash { class FullscreenController; class SessionControllerClient; class SessionObserver; class TestSessionControllerClient; // Implements mojom::SessionController to cache session related info such as // session state, meta data about user sessions to support synchronous // queries for ash. class ASH_EXPORT SessionControllerImpl : public SessionController { public: using UserSessions = std::vector>; SessionControllerImpl(); SessionControllerImpl(const SessionControllerImpl&) = delete; SessionControllerImpl& operator=(const SessionControllerImpl&) = delete; ~SessionControllerImpl() override; base::TimeDelta session_length_limit() const { return session_length_limit_; } base::Time session_start_time() const { return session_start_time_; } bool session_state_change_in_progress() const { return session_state_change_in_progress_; } // Returns the number of signed in users. If 0 is returned, there is either // no session in progress or no active user. int NumberOfLoggedInUsers() const; // Returns the active account. If no users are logged in this returns an empty // AccountId. AccountId GetActiveAccountId() const; // Gets the policy of adding a user session to ash. AddUserSessionPolicy GetAddUserPolicy() const; // Returns |true| if the session has been fully started for the active user. // When a user becomes active, the profile and browser UI are not immediately // available. Only once this method starts returning |true| is the browser // startup complete and both profile and UI are fully available. bool IsActiveUserSessionStarted() const; // Returns true if the screen can be locked. bool CanLockScreen() const; // Returns true if the screen should be locked automatically when the screen // is turned off or the system is suspended. bool ShouldLockScreenAutomatically() const; // Returns true if the session is in a kiosk-like mode running a single app. bool IsRunningInAppMode() const; // Returns true if the current session is a demo session for Demo Mode. bool IsDemoSession() const; // Returns true if user session blocked by some overlying UI. It can be // login screen, lock screen or screen for adding users into multi-profile // session. bool IsUserSessionBlocked() const; // Convenience function that returns true if session state is LOGIN_SECONDARY. bool IsInSecondaryLoginScreen() const; // Returns true if the settings icon should be enabled in the system tray. bool ShouldEnableSettings() const; // Returns true if the notification tray should appear. bool ShouldShowNotificationTray() const; // Gets the ash session state. session_manager::SessionState GetSessionState() const; // Gets the user sessions in LRU order with the active session being first. const UserSessions& GetUserSessions() const; // Convenience helper to get the user session at a given index. Returns // nullptr if no user session is found for the index. const UserSession* GetUserSession(UserIndex index) const; // Convenience helper to get the user session with the given account id. // Returns nullptr if no user session is found for the account id. const UserSession* GetUserSessionByAccountId( const AccountId& account_id) const; // Gets the primary user session. const UserSession* GetPrimaryUserSession() const; // Returns true if the current user is a child account. bool IsUserChild() const; // Returns true if the current user is a public account. bool IsUserPublicAccount() const; // Returns the type of the current user, or empty if there is no current user // logged in. absl::optional GetUserType() const; // Returns true if the current user is the primary user in a multi-profile // scenario. This always return true if there is only one user logged in. bool IsUserPrimary() const; // Returns true if the current user has the profile newly created on the // device (i.e. first time login on the device). bool IsUserFirstLogin() const; // Returns true if the device is enterprise managed. bool IsEnterpriseManaged() const; // Returns true if should display managed icon for current session, // and false otherwise. bool ShouldDisplayManagedUI() const; // Locks the screen. The locking happens asynchronously. void LockScreen(); // Hides the lock screen. void HideLockScreen(); // Requests signing out all users, ending the current session. // NOTE: This should only be called from LockStateController, other callers // should use LockStateController::RequestSignOut() instead. void RequestSignOut(); // Attempts to restart the chrome browser. void AttemptRestartChrome(); // Switches to another active user with |account_id| (if that user has // already signed in). void SwitchActiveUser(const AccountId& account_id); // Switches the active user to the next or previous user, with the same // ordering as user sessions are created. void CycleActiveUser(CycleUserDirection direction); // Show the multi-profile login UI to add another user to this session. void ShowMultiProfileLogin(); // Returns the PrefService used at the signin screen, which is tied to an // incognito profile in chrome and is valid until the browser exits. PrefService* GetSigninScreenPrefService() const; // Returns the PrefService for |account_id| or null if one does not exist. PrefService* GetUserPrefServiceForUser(const AccountId& account_id) const; // Returns the PrefService for the primary user or null if no user is signed // in or the PrefService connection hasn't been established. PrefService* GetPrimaryUserPrefService() const; // Returns the PrefService for the last active user that had one or null if no // PrefService connection has been successfully established. PrefService* GetLastActiveUserPrefService() const; // Before login returns the signin screen profile prefs. After login returns // the active user profile prefs. Returns null early during startup. PrefService* GetActivePrefService() const; // Returns the ash notion of login status. // NOTE: Prefer GetSessionState() in new code because the concept of // SessionState more closes matches the state in chrome. LoginStatus login_status() const { return login_status_; } // SessionController void SetClient(SessionControllerClient* client) override; void SetSessionInfo(const SessionInfo& info) override; void UpdateUserSession(const UserSession& user_session) override; void SetUserSessionOrder( const std::vector& user_session_order) override; void PrepareForLock(PrepareForLockCallback callback) override; void StartLock(StartLockCallback callback) override; void NotifyChromeLockAnimationsComplete() override; void RunUnlockAnimation(RunUnlockAnimationCallback callback) override; void NotifyChromeTerminating() override; void SetSessionLengthLimit(base::TimeDelta length_limit, base::Time start_time) override; void CanSwitchActiveUser(CanSwitchActiveUserCallback callback) override; void ShowMultiprofilesIntroDialog( ShowMultiprofilesIntroDialogCallback callback) override; void ShowTeleportWarningDialog( ShowTeleportWarningDialogCallback callback) override; void ShowMultiprofilesSessionAbortedDialog( const std::string& user_email) override; void AddSessionActivationObserverForAccountId( const AccountId& account_id, SessionActivationObserver* observer) override; void RemoveSessionActivationObserverForAccountId( const AccountId& account_id, SessionActivationObserver* observer) override; void AddObserver(SessionObserver* observer) override; void RemoveObserver(SessionObserver* observer) override; bool IsScreenLocked() const override; // Test helpers. void ClearUserSessionsForTest(); private: friend class TestSessionControllerClient; // Marks the session as a demo session for Demo Mode. void SetIsDemoSession(); void SetSessionState(session_manager::SessionState state); void AddUserSession(const UserSession& user_session); // Calculate login status based on session state and active user session. LoginStatus CalculateLoginStatus() const; // Helper that returns login status when the session state is ACTIVE. LoginStatus CalculateLoginStatusForActiveSession() const; // Update the |login_status_| and notify observers. void UpdateLoginStatus(); // Used as lock screen displayed callback of LockStateController and invoked // when post lock animation finishes and ash is fully locked. It would then // run |start_lock_callback_| to indicate ash is locked successfully. void OnLockAnimationFinished(); // Ensure that the sign-in screen PrefService is obtained. void EnsureSigninScreenPrefService(); void OnSigninScreenPrefServiceInitialized(PrefService* pref_service); void OnProfilePrefServiceInitialized(const AccountId& account_id, PrefService* pref_service); // Notifies observers that the active user pref service changed only if the // signin profile pref service has been connected and observers were notified // via OnSigninScreenPrefServiceInitialized(). Otherwise, defer the // notification until that happens. void MaybeNotifyOnActiveUserPrefServiceChanged(); // Called when IsUserSessionBlocked() becomes true. If there isn't an active // window, tries to activate one. void EnsureActiveWindowAfterUnblockingUserSession(); // Client interface to session manager code (chrome). SessionControllerClient* client_ = nullptr; // Cached session info. bool can_lock_ = false; bool should_lock_screen_automatically_ = false; bool is_running_in_app_mode_ = false; bool is_demo_session_ = false; AddUserSessionPolicy add_user_session_policy_ = AddUserSessionPolicy::ALLOWED; session_manager::SessionState state_ = session_manager::SessionState::UNKNOWN; // Cached user session info sorted by the order from SetUserSessionOrder. // Currently the session manager code (chrome) sets a LRU order with the // active session being the first. UserSessions user_sessions_; // The user session id of the current active user session. User session id // is managed by session manager code, starting at 1. 0u is an invalid id // to detect first active user session. uint32_t active_session_id_ = 0u; // The user session id of the primary user session. The primary user session // is the very first user session of the current ash session. uint32_t primary_session_id_ = 0u; // Last known login status. Used to track login status changes. LoginStatus login_status_ = LoginStatus::NOT_LOGGED_IN; // Whether unlocking is in progress. The flag is set when the pre-unlock // animation starts and reset when session state is no longer LOCKED. bool is_unlocking_ = false; // Pending callback for the StartLock request. base::OnceCallback start_lock_callback_; // The session length limit; set to zero if there is no limit. base::TimeDelta session_length_limit_; // The session start time, set at login or on the first user activity; set to // null if there is no session length limit. This value is also stored in a // pref in case of a crash during the session. base::Time session_start_time_; // Set to true if the active user's pref is received before the signin prefs. // This is so that we can guarantee that observers are notified with // OnActiveUserPrefServiceChanged() after // OnSigninScreenPrefServiceInitialized(). bool on_active_user_prefs_changed_notify_deferred_ = false; base::ObserverList observers_; SessionActivationObserverHolder session_activation_observer_holder_; bool signin_screen_prefs_obtained_ = false; PrefService* last_active_user_prefs_ = nullptr; std::unique_ptr fullscreen_controller_; // Indicate if the session state is being changed. bool session_state_change_in_progress_ = false; base::WeakPtrFactory weak_ptr_factory_{this}; }; } // namespace ash #endif // ASH_SESSION_SESSION_CONTROLLER_IMPL_H_