Remove profile info cache entry on user removal on Chrome OS.
Chrome OS removes users when profiles are not loaded, and Chrome does not know
the exact profile path until it is mounted. So we need to be able to remove
entries from ProfileInfoCache based solely on AccountId.
This Cl implements removal of cache entries given the AccountId and engages it
on Chrome OS.
Bug: 808125
Change-Id: I9f8e3a5f1004d119425b92a4bdc3d8011a526dd5
Reviewed-on: https://chromium-review.googlesource.com/905751
Reviewed-by: anthonyvd <[email protected]>
Reviewed-by: Bernhard Bauer <[email protected]>
Commit-Queue: Alexander Alekseev <[email protected]>
Cr-Commit-Position: refs/heads/master@{#537905}
diff --git a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc
index 46c6d86..34cbff6 100644
--- a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc
+++ b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc
@@ -59,6 +59,8 @@
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/extensions/permissions_updater.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/profiles/profile_attributes_storage.h"
+#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/signin/easy_unlock_service.h"
#include "chrome/browser/supervised_user/chromeos/manager_password_service_factory.h"
#include "chrome/browser/supervised_user/chromeos/supervised_user_password_service_factory.h"
@@ -471,6 +473,9 @@
// Owner is not allowed to be removed from the device.
return;
}
+ g_browser_process->profile_manager()
+ ->GetProfileAttributesStorage()
+ .RemoveProfileByAccountId(account_id);
RemoveNonOwnerUserInternal(account_id, delegate);
}
diff --git a/chrome/browser/profiles/profile_attributes_storage.h b/chrome/browser/profiles/profile_attributes_storage.h
index 9c88220..425b3452 100644
--- a/chrome/browser/profiles/profile_attributes_storage.h
+++ b/chrome/browser/profiles/profile_attributes_storage.h
@@ -30,6 +30,7 @@
class Image;
}
+class AccountId;
class PrefService;
class ProfileAttributesEntry;
class ProfileAvatarDownloader;
@@ -54,6 +55,11 @@
const base::string16& user_name,
size_t icon_index,
const std::string& supervised_user_id) = 0;
+
+ // Removes the profile matching given |account_id| from this storage.
+ // Calculates profile path and calls RemoveProfile() on it.
+ virtual void RemoveProfileByAccountId(const AccountId& account_id) = 0;
+
// Removes the profile at |profile_path| from this storage. Does not delete or
// affect the actual profile's data.
virtual void RemoveProfile(const base::FilePath& profile_path) = 0;
diff --git a/chrome/browser/profiles/profile_info_cache.cc b/chrome/browser/profiles/profile_info_cache.cc
index 696181a..637576a 100644
--- a/chrome/browser/profiles/profile_info_cache.cc
+++ b/chrome/browser/profiles/profile_info_cache.cc
@@ -27,6 +27,7 @@
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
+#include "components/signin/core/account_id/account_id.h"
#include "components/signin/core/browser/profile_management_switches.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
@@ -739,6 +740,31 @@
profile_path, name, gaia_id, user_name, icon_index, supervised_user_id);
}
+void ProfileInfoCache::RemoveProfileByAccountId(const AccountId& account_id) {
+ // TODO(rsorokin): https://crbug.com/810167 profile.info_cache entries for
+ // AD accounts should have enough information to be deletable.
+ if (account_id.GetAccountType() == AccountType::ACTIVE_DIRECTORY) {
+ LOG(ERROR)
+ << "Removing of AD profile.info_cache entries is NOTIMPLEMENTED.";
+ }
+
+ for (size_t i = 0; i < GetNumberOfProfiles(); i++) {
+ std::string gaia_id;
+ std::string user_name;
+ const base::DictionaryValue* info = GetInfoForProfileAtIndex(i);
+ if ((info->GetString(kGAIAIdKey, &gaia_id) && !gaia_id.empty() &&
+ account_id.GetGaiaId() == gaia_id) ||
+ (info->GetString(ProfileAttributesEntry::kUserNameKey, &user_name) &&
+ !user_name.empty() && account_id.GetUserEmail() == user_name)) {
+ RemoveProfile(GetPathOfProfileAtIndex(i));
+ return;
+ }
+ }
+ LOG(ERROR) << "Failed to remove profile.info_cache entry for account type "
+ << static_cast<int>(account_id.GetAccountType())
+ << ": matching entry not found.";
+}
+
void ProfileInfoCache::RemoveProfile(const base::FilePath& profile_path) {
DeleteProfileFromCache(profile_path);
}
diff --git a/chrome/browser/profiles/profile_info_cache.h b/chrome/browser/profiles/profile_info_cache.h
index 023ba92f..19a8246b 100644
--- a/chrome/browser/profiles/profile_info_cache.h
+++ b/chrome/browser/profiles/profile_info_cache.h
@@ -144,6 +144,7 @@
const base::string16& user_name,
size_t icon_index,
const std::string& supervised_user_id) override;
+ void RemoveProfileByAccountId(const AccountId& account_id) override;
void RemoveProfile(const base::FilePath& profile_path) override;
bool GetProfileAttributesWithPath(const base::FilePath& path,
diff --git a/chrome/browser/profiles/profile_info_cache_unittest.cc b/chrome/browser/profiles/profile_info_cache_unittest.cc
index 2838bf6..a77172e 100644
--- a/chrome/browser/profiles/profile_info_cache_unittest.cc
+++ b/chrome/browser/profiles/profile_info_cache_unittest.cc
@@ -26,6 +26,7 @@
#include "chrome/common/pref_names.h"
#include "chrome/test/base/testing_browser_process.h"
#include "components/prefs/testing_pref_service.h"
+#include "components/signin/core/account_id/account_id.h"
#include "components/signin/core/browser/profile_management_switches.h"
#include "components/sync_preferences/pref_service_syncable.h"
#include "content/public/test/test_browser_thread_bundle.h"
@@ -764,3 +765,66 @@
GetCache()->GetIndexOfProfileWithPath(path_4)));
}
#endif
+
+TEST_F(ProfileInfoCacheTest, RemoveProfileByAccountId) {
+ EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles());
+
+ base::FilePath path_1 = GetProfilePath("path_1");
+ const AccountId account_id_1(
+ AccountId::FromUserEmailGaiaId("email1", "111111"));
+ base::string16 name_1 = ASCIIToUTF16("name_1");
+ GetCache()->AddProfileToCache(path_1, name_1, account_id_1.GetGaiaId(),
+ UTF8ToUTF16(account_id_1.GetUserEmail()), 0,
+ std::string());
+ EXPECT_EQ(1u, GetCache()->GetNumberOfProfiles());
+
+ base::FilePath path_2 = GetProfilePath("path_2");
+ base::string16 name_2 = ASCIIToUTF16("name_2");
+ const AccountId account_id_2(
+ AccountId::FromUserEmailGaiaId("email2", "222222"));
+ GetCache()->AddProfileToCache(path_2, name_2, account_id_2.GetGaiaId(),
+ UTF8ToUTF16(account_id_2.GetUserEmail()), 0,
+ std::string());
+ EXPECT_EQ(2u, GetCache()->GetNumberOfProfiles());
+
+ base::FilePath path_3 = GetProfilePath("path_3");
+ base::string16 name_3 = ASCIIToUTF16("name_3");
+ const AccountId account_id_3(
+ AccountId::FromUserEmailGaiaId("email3", "333333"));
+ GetCache()->AddProfileToCache(path_3, name_3, account_id_3.GetGaiaId(),
+ UTF8ToUTF16(account_id_3.GetUserEmail()), 0,
+ std::string());
+ EXPECT_EQ(3u, GetCache()->GetNumberOfProfiles());
+
+ base::FilePath path_4 = GetProfilePath("path_4");
+ base::string16 name_4 = ASCIIToUTF16("name_4");
+ const AccountId account_id_4(
+ AccountId::FromUserEmailGaiaId("email4", "444444"));
+ GetCache()->AddProfileToCache(path_4, name_4, account_id_4.GetGaiaId(),
+ UTF8ToUTF16(account_id_4.GetUserEmail()), 0,
+ std::string());
+ EXPECT_EQ(4u, GetCache()->GetNumberOfProfiles());
+
+ GetCache()->RemoveProfileByAccountId(account_id_3);
+ EXPECT_EQ(3u, GetCache()->GetNumberOfProfiles());
+ EXPECT_EQ(name_1, GetCache()->GetNameOfProfileAtIndex(0));
+
+ GetCache()->RemoveProfileByAccountId(account_id_1);
+ EXPECT_EQ(2u, GetCache()->GetNumberOfProfiles());
+ EXPECT_EQ(name_2, GetCache()->GetNameOfProfileAtIndex(0));
+
+ // this profile is already deleted.
+ GetCache()->RemoveProfileByAccountId(account_id_3);
+ EXPECT_EQ(2u, GetCache()->GetNumberOfProfiles());
+ EXPECT_EQ(name_2, GetCache()->GetNameOfProfileAtIndex(0));
+
+ // Remove profile by partial match
+ GetCache()->RemoveProfileByAccountId(
+ AccountId::FromUserEmail(account_id_2.GetUserEmail()));
+ EXPECT_EQ(1u, GetCache()->GetNumberOfProfiles());
+ EXPECT_EQ(name_4, GetCache()->GetNameOfProfileAtIndex(0));
+
+ // Remove last profile
+ GetCache()->RemoveProfileByAccountId(account_id_4);
+ EXPECT_EQ(0u, GetCache()->GetNumberOfProfiles());
+}