blob: b121daf8786509dd41c377b4eff286ed42fc5ebd [file] [log] [blame]
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_SESSION_TEST_SESSION_CONTROLLER_CLIENT_H_
#define ASH_SESSION_TEST_SESSION_CONTROLLER_CLIENT_H_
#include <stdint.h>
#include <memory>
#include <optional>
#include <string>
#include <variant>
#include "ash/public/cpp/session/session_controller_client.h"
#include "ash/public/cpp/session/session_types.h"
#include "ash/test/login_info.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/token.h"
#include "components/prefs/pref_service.h"
#include "components/user_manager/user_type.h"
namespace views {
class Widget;
}
class AccountId;
class PrefService;
namespace ash {
enum class AddUserSessionPolicy;
class SessionControllerImpl;
class TestPrefServiceProvider;
// Implement SessionControllerClient to simulate chrome behavior
// in tests. This breaks the ash/chrome dependency to allow testing ash code in
// isolation. Note that tests that have an instance of SessionControllerClient
// should NOT use this, i.e. tests that run BrowserMain to have chrome's
// SessionControllerClient created, e.g. InProcessBrowserTest based tests. On
// the other hand, tests code in chrome can use this class as long as it does
// not run BrowserMain, e.g. testing::Test based test.
class TestSessionControllerClient final : public SessionControllerClient {
public:
TestSessionControllerClient(SessionControllerImpl* controller,
TestPrefServiceProvider* prefs_provider,
bool create_signin_pref_service);
TestSessionControllerClient(const TestSessionControllerClient&) = delete;
TestSessionControllerClient& operator=(const TestSessionControllerClient&) =
delete;
~TestSessionControllerClient() override;
// Initialize using existing info in |controller| and set as its client.
void InitializeAndSetClient();
// Sets up the default state of SessionController.
void Reset();
int attempt_restart_chrome_count() const {
return attempt_restart_chrome_count_;
}
int request_hide_lock_screen_count() const {
return request_hide_lock_screen_count_;
}
int request_sign_out_count() const { return request_sign_out_count_; }
int request_restart_for_update_count() const {
return request_restart_for_update_count_;
}
// Helpers to set SessionController state.
void SetCanLockScreen(bool can_lock);
void SetShouldLockScreenAutomatically(bool should_lock);
void SetAddUserSessionPolicy(AddUserSessionPolicy policy);
void SetSessionState(session_manager::SessionState state);
void SetIsRunningInAppMode(bool app_mode);
void SetIsDemoSession();
// Adds a user session from a given LoginInfo, `acount_id' and `pref_service`.
// For convenience, `LoginInfo.user_email` can be used to create an AccountId,
// in which case, the `account_id` should be std::nulopt. For testing
// behavior where |AccountId|s are compared, prefer the method of the same
// name that takes an |AccountId| created with a valid storage key
// instead. See the documentation for|AccountId::GetUserEmail| for discussion.
//
// If `pref_service1 is provided, the new session will use it, or it will
// create a new PrefService. However, if `pref_service_must_exist_` is set to
// true, the PrefService for the account must already exist, or it will result
// in CHCEK failure.
AccountId AddUserSession(LoginInfo login_info,
std::optional<AccountId> account_id = std::nullopt,
std::unique_ptr<PrefService> pref_service = nullptr);
// Synchronously lock screen by requesting screen lock and waiting for the
// request to complete.
void LockScreen();
// Simulates screen unlocking. It is virtual so that test cases can override
// it. The default implementation sets the session state of SessionController
// to be ACTIVE.
void UnlockScreen();
// Spins message loop to finish pending lock screen request if any.
void FlushForTest();
// Use |pref_service| for sign-in profile pref service.
void SetSigninScreenPrefService(std::unique_ptr<PrefService> pref_service);
// Use |pref_service| for the user identified by |account_id|.
void SetUnownedUserPrefService(const AccountId& account_id,
raw_ptr<PrefService> unowned_pref_service);
// ash::SessionControllerClient:
void RequestLockScreen() override;
void RequestHideLockScreen() override;
void RequestSignOut() override;
void RequestRestartForUpdate() override;
void AttemptRestartChrome() override;
void SwitchActiveUser(const AccountId& account_id) override;
void CycleActiveUser(CycleUserDirection direction) override;
void ShowMultiProfileLogin() override;
void EmitAshInitialized() override;
PrefService* GetSigninScreenPrefService() override;
PrefService* GetUserPrefService(const AccountId& account_id) override;
base::FilePath GetProfilePath(const AccountId& account_id) override;
std::tuple<bool, bool> IsEligibleForSeaPen(
const AccountId& account_id) override;
std::optional<int> GetExistingUsersCount() const override;
// By default `LockScreen()` only changes the session state but no UI views
// will be created. If your tests requires the lock screen to be created,
// please set this to true.
void set_show_lock_screen_views(bool should_show) {
should_show_lock_screen_ = should_show;
}
void set_is_eligible_for_background_replace(
const std::tuple<bool, bool>& is_eligible_for_background_replace) {
is_eligible_for_background_replace_ = is_eligible_for_background_replace;
}
void set_existing_users_count(int existing_users_count) {
existing_users_count_ = existing_users_count;
}
void set_pref_service_must_exist(bool pref_service_must_exist) {
pref_service_must_exist_ = pref_service_must_exist;
}
int NumberOfLoggedInUsers() const;
private:
void DoSwitchUser(const AccountId& account_id, bool switch_user);
// Notify first session ready if the notification has not sent, there
// is at least one user session created, and session state is ACTIVE.
void MaybeNotifyFirstSessionReady();
const raw_ptr<SessionControllerImpl, DanglingUntriaged> controller_;
const raw_ptr<TestPrefServiceProvider> prefs_provider_;
int fake_session_id_ = 0;
SessionInfo session_info_;
bool first_session_ready_fired_ = false;
// If true, pref service must exist when adding a session, or fail with CHECK.
bool pref_service_must_exist_ = false;
int request_hide_lock_screen_count_ = 0;
int request_sign_out_count_ = 0;
int request_restart_for_update_count_ = 0;
int attempt_restart_chrome_count_ = 0;
bool should_show_lock_screen_ = false;
std::tuple<bool, bool> is_eligible_for_background_replace_ = {true, true};
int existing_users_count_ = 0;
bool reuse_pref_service_ = false;
std::unique_ptr<views::Widget> multi_profile_login_widget_;
base::WeakPtrFactory<TestSessionControllerClient> weak_ptr_factory_{this};
};
} // namespace ash
#endif // ASH_SESSION_TEST_SESSION_CONTROLLER_CLIENT_H_