Commit 24bb2443 authored by skuhne's avatar skuhne Committed by Commit bot

Fixing problem that after a browser crash in multi user mode, an incorrect user might show up.

BUG=409226
TEST=unittest and visual

Review URL: https://codereview.chromium.org/544383003

Cr-Commit-Position: refs/heads/master@{#293769}
parent b9129716
...@@ -817,6 +817,15 @@ void ProfileManager::Observe( ...@@ -817,6 +817,15 @@ void ProfileManager::Observe(
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
if (type == chrome::NOTIFICATION_LOGIN_USER_CHANGED) { if (type == chrome::NOTIFICATION_LOGIN_USER_CHANGED) {
logged_in_ = true; logged_in_ = true;
// Find out what the current user is and update it. This has only to be done
// when the profile was already loaded, since otherwise this will be set by
// the profile loading process.
user_manager::UserManager* manager = user_manager::UserManager::Get();
const user_manager::User* user = manager->GetActiveUser();
if (user && user->is_profile_created()) {
UpdateLastUser(
chromeos::ProfileHelper::Get()->GetProfileByUser(user));
}
const CommandLine& command_line = *CommandLine::ForCurrentProcess(); const CommandLine& command_line = *CommandLine::ForCurrentProcess();
if (!command_line.HasSwitch(switches::kTestType)) { if (!command_line.HasSwitch(switches::kTestType)) {
...@@ -1217,6 +1226,22 @@ ProfileManager::ProfileInfo::~ProfileInfo() { ...@@ -1217,6 +1226,22 @@ ProfileManager::ProfileInfo::~ProfileInfo() {
} }
#if !defined(OS_ANDROID) && !defined(OS_IOS) #if !defined(OS_ANDROID) && !defined(OS_IOS)
void ProfileManager::UpdateLastUser(Profile* last_active) {
PrefService* local_state = g_browser_process->local_state();
DCHECK(local_state);
// Only keep track of profiles that we are managing; tests may create others.
if (profiles_info_.find(last_active->GetPath()) != profiles_info_.end()) {
local_state->SetString(prefs::kProfileLastUsed,
last_active->GetPath().BaseName().MaybeAsASCII());
ProfileInfoCache& cache = GetProfileInfoCache();
size_t profile_index =
cache.GetIndexOfProfileWithPath(last_active->GetPath());
if (profile_index != std::string::npos)
cache.SetProfileActiveTimeAtIndex(profile_index);
}
}
ProfileManager::BrowserListObserver::BrowserListObserver( ProfileManager::BrowserListObserver::BrowserListObserver(
ProfileManager* manager) ProfileManager* manager)
: profile_manager_(manager) { : profile_manager_(manager) {
...@@ -1265,20 +1290,7 @@ void ProfileManager::BrowserListObserver::OnBrowserSetLastActive( ...@@ -1265,20 +1290,7 @@ void ProfileManager::BrowserListObserver::OnBrowserSetLastActive(
if (last_active->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles)) if (last_active->GetPrefs()->GetBoolean(prefs::kForceEphemeralProfiles))
return; return;
PrefService* local_state = g_browser_process->local_state(); profile_manager_->UpdateLastUser(last_active);
DCHECK(local_state);
// Only keep track of profiles that we are managing; tests may create others.
if (profile_manager_->profiles_info_.find(
last_active->GetPath()) != profile_manager_->profiles_info_.end()) {
local_state->SetString(prefs::kProfileLastUsed,
last_active->GetPath().BaseName().MaybeAsASCII());
ProfileInfoCache& cache = profile_manager_->GetProfileInfoCache();
size_t profile_index =
cache.GetIndexOfProfileWithPath(last_active->GetPath());
if (profile_index != std::string::npos)
cache.SetProfileActiveTimeAtIndex(profile_index);
}
} }
#endif // !defined(OS_ANDROID) && !defined(OS_IOS) #endif // !defined(OS_ANDROID) && !defined(OS_IOS)
......
...@@ -278,6 +278,9 @@ class ProfileManager : public base::NonThreadSafe, ...@@ -278,6 +278,9 @@ class ProfileManager : public base::NonThreadSafe,
Profile::CreateStatus status); Profile::CreateStatus status);
#if !defined(OS_ANDROID) && !defined(OS_IOS) #if !defined(OS_ANDROID) && !defined(OS_IOS)
// Updates the last active user of the current session.
void UpdateLastUser(Profile* last_active);
class BrowserListObserver : public chrome::BrowserListObserver { class BrowserListObserver : public chrome::BrowserListObserver {
public: public:
explicit BrowserListObserver(ProfileManager* manager); explicit BrowserListObserver(ProfileManager* manager);
......
...@@ -202,6 +202,17 @@ TEST_F(ProfileManagerTest, DefaultProfileDir) { ...@@ -202,6 +202,17 @@ TEST_F(ProfileManagerTest, DefaultProfileDir) {
g_browser_process->profile_manager()->GetInitialProfileDir().value()); g_browser_process->profile_manager()->GetInitialProfileDir().value());
} }
MATCHER(NotFail, "Profile creation failure status is not reported.") {
return arg == Profile::CREATE_STATUS_CREATED ||
arg == Profile::CREATE_STATUS_INITIALIZED;
}
MATCHER(SameNotNull, "The same non-NULL value for all calls.") {
if (!g_created_profile)
g_created_profile = arg;
return arg != NULL && arg == g_created_profile;
}
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
// This functionality only exists on Chrome OS. // This functionality only exists on Chrome OS.
...@@ -232,6 +243,48 @@ TEST_F(ProfileManagerTest, LoggedInProfileDir) { ...@@ -232,6 +243,48 @@ TEST_F(ProfileManagerTest, LoggedInProfileDir) {
profile_manager->GetInitialProfileDir()).value(); profile_manager->GetInitialProfileDir()).value();
} }
// Switching the user should switch also the last used user.
TEST_F(ProfileManagerTest, ActiveProfileChanged) {
ProfileManager* profile_manager = g_browser_process->profile_manager();
ASSERT_TRUE(profile_manager);
// Create and load two profiles.
const std::string user_name1 = "user1@example.com";
base::FilePath dest_path1 = temp_dir_.path().AppendASCII(user_name1);
MockObserver mock_observer;
EXPECT_CALL(mock_observer, OnProfileCreated(
testing::NotNull(), NotFail())).Times(testing::AtLeast(2));
CreateProfileAsync(profile_manager, user_name1, false, &mock_observer);
base::RunLoop().RunUntilIdle();
chromeos::FakeUserManager* user_manager = new chromeos::FakeUserManager();
chromeos::ScopedUserManagerEnabler enabler(user_manager);
PrefService* local_state = g_browser_process->local_state();
local_state->SetString(prefs::kProfileLastUsed, "");
const user_manager::User* active_user = user_manager->AddUser(user_name1);
user_manager->LoginUser(user_name1);
// None of the calls above should have changed the last user.
EXPECT_EQ("", local_state->GetString(prefs::kProfileLastUsed));
// The FakeUserManager will not switch the user either.
user_manager->SwitchActiveUser(user_name1);
EXPECT_EQ("", local_state->GetString(prefs::kProfileLastUsed));
// After triggering the LOGIN_USER_CHANGED observer call ourselves, the user
// has changed.
profile_manager->Observe(
chrome::NOTIFICATION_LOGIN_USER_CHANGED,
content::NotificationService::AllSources(),
content::Details<const user_manager::User>(active_user));
EXPECT_EQ("u-" + user_name1 + "-hash",
local_state->GetString(prefs::kProfileLastUsed));
}
#endif #endif
TEST_F(ProfileManagerTest, CreateAndUseTwoProfiles) { TEST_F(ProfileManagerTest, CreateAndUseTwoProfiles) {
...@@ -273,17 +326,6 @@ TEST_F(ProfileManagerTest, CreateAndUseTwoProfiles) { ...@@ -273,17 +326,6 @@ TEST_F(ProfileManagerTest, CreateAndUseTwoProfiles) {
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
} }
MATCHER(NotFail, "Profile creation failure status is not reported.") {
return arg == Profile::CREATE_STATUS_CREATED ||
arg == Profile::CREATE_STATUS_INITIALIZED;
}
MATCHER(SameNotNull, "The same non-NULL value for all calls.") {
if (!g_created_profile)
g_created_profile = arg;
return arg != NULL && arg == g_created_profile;
}
TEST_F(ProfileManagerTest, CreateProfileAsyncMultipleRequests) { TEST_F(ProfileManagerTest, CreateProfileAsyncMultipleRequests) {
g_created_profile = NULL; g_created_profile = NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment