#include <stddef.h>
#include <string>
#include "base/command_line.h"
#include "base/containers/to_vector.h"
#include "base/files/file_path_watcher.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/ranges/algorithm.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind.h"
#include "base/test/test_future.h"
#include "base/test/test_timeouts.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/apps/platform_apps/shortcut_manager.h"
#include "chrome/browser/browser_features.h"
#include "chrome/browser/password_manager/profile_password_store_factory.h"
#include "chrome/browser/policy/policy_test_utils.h"
#include "chrome/browser/profiles/keep_alive/profile_keep_alive_types.h"
#include "chrome/browser/profiles/keep_alive/scoped_profile_keep_alive.h"
#include "chrome/browser/profiles/profile_attributes_entry.h"
#include "chrome/browser/profiles/profile_attributes_storage.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profile_metrics.h"
#include "chrome/browser/profiles/profile_test_util.h"
#include "chrome/browser/profiles/profile_window.h"
#include "chrome/browser/profiles/profiles_state.h"
#include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/profile_deletion_observer.h"
#include "chrome/test/base/testing_browser_process.h"
#include "components/keep_alive_registry/keep_alive_types.h"
#include "components/keep_alive_registry/scoped_keep_alive.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/password_manager/core/browser/password_form.h"
#include "components/password_manager/core/browser/password_store/password_store_consumer.h"
#include "components/password_manager/core/browser/password_store/password_store_interface.h"
#include "components/policy/core/common/policy_map.h"
#include "components/policy/policy_constants.h"
#include "components/prefs/pref_service.h"
#include "components/supervised_user/core/common/pref_names.h"
#include "content/public/browser/browsing_data_remover.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/test_utils.h"
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "ash/constants/ash_switches.h"
#include "base/path_service.h"
#include "chrome/common/chrome_paths.h"
#include "chromeos/ash/components/browser_context_helper/browser_context_helper.h"
#include "chromeos/ash/components/browser_context_helper/browser_context_types.h"
#include "testing/gtest/include/gtest/gtest.h"
#endif
#if BUILDFLAG(IS_CHROMEOS_LACROS)
#include "chromeos/crosapi/mojom/crosapi.mojom.h"
#include "chromeos/lacros/lacros_test_helper.h"
#include "chromeos/startup/browser_init_params.h"
#include "components/supervised_user/core/common/supervised_user_constants.h"
#include "content/public/test/test_launcher.h"
#endif
namespace {
void ProfileCreationComplete(base::OnceClosure completion_callback,
Profile* profile) { … }
class MultipleProfileDeletionObserver
: public ProfileAttributesStorage::Observer { … };
void EphemeralProfileCreationComplete(base::OnceClosure completion_callback,
Profile* profile) { … }
class ProfileRemovalObserver : public ProfileAttributesStorage::Observer { … };
class PasswordStoreConsumerVerifier
: public password_manager::PasswordStoreConsumer { … };
base::FilePath GetFirstNonSigninNonLockScreenAppProfile(
ProfileAttributesStorage* storage) { … }
}
class ProfileManagerBrowserTestBase : public InProcessBrowserTest { … };
class ProfileManagerBrowserTest : public ProfileManagerBrowserTestBase,
public testing::WithParamInterface<bool> { … };
#if !BUILDFLAG(IS_CHROMEOS_ASH)
#if BUILDFLAG(IS_MAC)
#define MAYBE_DeleteSingletonProfile …
#else
#define MAYBE_DeleteSingletonProfile …
#endif
#if !BUILDFLAG(IS_CHROMEOS_LACROS)
IN_PROC_BROWSER_TEST_P(ProfileManagerBrowserTest,
MAYBE_DeleteSingletonProfile) { … }
#endif
IN_PROC_BROWSER_TEST_P(ProfileManagerBrowserTest, DeleteInactiveProfile) { … }
IN_PROC_BROWSER_TEST_P(ProfileManagerBrowserTest, DeleteCurrentProfile) { … }
#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
#define MAYBE_DeleteAllProfiles …
#else
#define MAYBE_DeleteAllProfiles …
#endif
IN_PROC_BROWSER_TEST_P(ProfileManagerBrowserTest, MAYBE_DeleteAllProfiles) { … }
#endif
IN_PROC_BROWSER_TEST_P(ProfileManagerBrowserTest, ProfileFromProfileKey) { … }
#if BUILDFLAG(IS_CHROMEOS_ASH)
class ProfileManagerCrOSBrowserTest : public ProfileManagerBrowserTest {
protected:
void SetUpCommandLine(base::CommandLine* command_line) override {
command_line->AppendSwitchASCII(ash::switches::kLoginProfile,
"test-user-hash");
}
};
IN_PROC_BROWSER_TEST_P(ProfileManagerCrOSBrowserTest, GetLastUsedProfile) {
Profile* last_used_profile = ProfileManager::GetLastUsedProfile();
EXPECT_TRUE(last_used_profile != nullptr);
base::FilePath profile_path;
base::PathService::Get(chrome::DIR_USER_DATA, &profile_path);
profile_path = profile_path.Append(
ash::BrowserContextHelper::GetUserBrowserContextDirName(
"test-user-hash"));
EXPECT_EQ(profile_path.value(), last_used_profile->GetPath().value());
}
#endif
#if !BUILDFLAG(IS_CHROMEOS_ASH)
IN_PROC_BROWSER_TEST_P(ProfileManagerBrowserTest, CreateProfileWithCallback) { … }
#endif
IN_PROC_BROWSER_TEST_P(ProfileManagerBrowserTest, SwitchToProfile) { … }
IN_PROC_BROWSER_TEST_P(ProfileManagerBrowserTest, PRE_AddMultipleProfiles) { … }
IN_PROC_BROWSER_TEST_P(ProfileManagerBrowserTest, AddMultipleProfiles) { … }
IN_PROC_BROWSER_TEST_F(ProfileManagerBrowserTestBase,
ConcurrentCreationAsyncAndSync) { … }
IN_PROC_BROWSER_TEST_P(ProfileManagerBrowserTest, EphemeralProfile) { … }
#if !BUILDFLAG(IS_WIN) && !BUILDFLAG(IS_CHROMEOS_ASH)
IN_PROC_BROWSER_TEST_P(ProfileManagerBrowserTest, DeletePasswords) { … }
#endif
IN_PROC_BROWSER_TEST_P(ProfileManagerBrowserTest, IncognitoProfile) { … }
#if BUILDFLAG(IS_CHROMEOS_ASH)
INSTANTIATE_TEST_SUITE_P(DestroyProfileOnBrowserClose,
ProfileManagerBrowserTest,
testing::Values(false));
INSTANTIATE_TEST_SUITE_P(DestroyProfileOnBrowserClose,
ProfileManagerCrOSBrowserTest,
testing::Bool());
#else
INSTANTIATE_TEST_SUITE_P(…);
#endif
#if !BUILDFLAG(IS_CHROMEOS_ASH)
const base::FilePath::CharType kNonAsciiProfileDir[] = …);
class ProfileManagerNonAsciiBrowserTest : public ProfileManagerBrowserTestBase { … };
IN_PROC_BROWSER_TEST_F(ProfileManagerNonAsciiBrowserTest,
LaunchInNonAsciiProfileDirectoryDoesntCrash) { … }
#endif
#if BUILDFLAG(IS_CHROMEOS_LACROS)
enum class TransitionType {
kChildToRegular,
kRegularToChild,
};
class ChildProfileTransitionBrowserTest
: public ProfileManagerBrowserTestBase,
public testing::WithParamInterface<enum TransitionType> {
protected:
ChildProfileTransitionBrowserTest() = default;
~ChildProfileTransitionBrowserTest() = default;
void CreatedBrowserMainParts(
content::BrowserMainParts* browser_main_parts) override {
crosapi::mojom::BrowserInitParamsPtr init_params =
crosapi::mojom::BrowserInitParams::New();
const TransitionType transition = GetParam();
if (transition == TransitionType::kChildToRegular) {
init_params->session_type =
content::IsPreTest() ? crosapi::mojom::SessionType::kChildSession
: crosapi::mojom::SessionType::kRegularSession;
} else if (transition == TransitionType::kRegularToChild) {
init_params->session_type =
content::IsPreTest() ? crosapi::mojom::SessionType::kRegularSession
: crosapi::mojom::SessionType::kChildSession;
} else {
NOTREACHED_IN_MIGRATION();
}
chromeos::BrowserInitParams::SetInitParamsForTests(std::move(init_params));
ProfileManagerBrowserTestBase::CreatedBrowserMainParts(browser_main_parts);
}
bool IsChildProfileExpected() const {
const TransitionType transition = GetParam();
const bool is_pre_test = content::IsPreTest();
if (transition == TransitionType::kChildToRegular) {
return is_pre_test;
}
if (transition == TransitionType::kRegularToChild) {
return !is_pre_test;
}
NOTREACHED_IN_MIGRATION();
return false;
}
const ProfileAttributesEntry* GetProfileAttributesEntry(
const Profile* profile) const {
ProfileAttributesStorage& storage =
g_browser_process->profile_manager()->GetProfileAttributesStorage();
return storage.GetProfileAttributesWithPath(profile->GetPath());
}
};
INSTANTIATE_TEST_SUITE_P(ChildToRegular,
ChildProfileTransitionBrowserTest,
testing::Values(TransitionType::kChildToRegular));
INSTANTIATE_TEST_SUITE_P(RegularToChild,
ChildProfileTransitionBrowserTest,
testing::Values(TransitionType::kRegularToChild));
IN_PROC_BROWSER_TEST_P(ChildProfileTransitionBrowserTest, PRE_Transition) {
const bool is_child_profile_expected = IsChildProfileExpected();
const Profile* profile = browser()->profile();
ASSERT_TRUE(profile);
EXPECT_EQ(is_child_profile_expected, profile->IsChild());
EXPECT_EQ(profile->GetPrefs()->GetString(prefs::kSupervisedUserId),
is_child_profile_expected ? supervised_user::kChildAccountSUID
: std::string());
const ProfileAttributesEntry* entry = GetProfileAttributesEntry(profile);
ASSERT_NE(entry, nullptr);
EXPECT_EQ(is_child_profile_expected, entry->IsSupervised());
}
IN_PROC_BROWSER_TEST_P(ChildProfileTransitionBrowserTest, Transition) {
const bool is_child_profile_expected = IsChildProfileExpected();
const Profile* profile = browser()->profile();
ASSERT_TRUE(profile);
EXPECT_EQ(is_child_profile_expected, profile->IsChild());
EXPECT_EQ(profile->GetPrefs()->GetString(prefs::kSupervisedUserId),
is_child_profile_expected ? supervised_user::kChildAccountSUID
: std::string());
const ProfileAttributesEntry* entry = GetProfileAttributesEntry(profile);
ASSERT_NE(entry, nullptr);
EXPECT_EQ(is_child_profile_expected, entry->IsSupervised());
}
#endif