[iOS] Add unload profile api in profile manager
Fixed: 335630301
Change-Id: I39a271044647169c21117a8cac62c78586f776a1
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6049746
Commit-Queue: Aliona Dangla <alionadangla@chromium.org>
Reviewed-by: Sylvain Defresne <sdefresne@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1389369}
diff --git a/ios/chrome/browser/profile/model/profile_manager_ios_impl.h b/ios/chrome/browser/profile/model/profile_manager_ios_impl.h
index f892bf5..71da0be 100644
--- a/ios/chrome/browser/profile/model/profile_manager_ios_impl.h
+++ b/ios/chrome/browser/profile/model/profile_manager_ios_impl.h
@@ -60,6 +60,7 @@
ProfileLoadedCallback created_callback) override;
ProfileIOS* LoadProfile(std::string_view name) override;
ProfileIOS* CreateProfile(std::string_view name) override;
+ void UnloadProfile(std::string_view name) override;
void UnloadAllProfiles() override;
ProfileAttributesStorageIOS* GetProfileAttributesStorage() override;
diff --git a/ios/chrome/browser/profile/model/profile_manager_ios_impl.mm b/ios/chrome/browser/profile/model/profile_manager_ios_impl.mm
index 2c54b6f..5b42555 100644
--- a/ios/chrome/browser/profile/model/profile_manager_ios_impl.mm
+++ b/ios/chrome/browser/profile/model/profile_manager_ios_impl.mm
@@ -355,21 +355,30 @@
return iter->second.profile();
}
+void ProfileManagerIOSImpl::UnloadProfile(std::string_view name) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ auto iter = profiles_map_.find(name);
+ DCHECK(iter != profiles_map_.end());
+ ProfileInfo profile_info = std::move(iter->second);
+ profiles_map_.erase(iter);
+ if (!profile_info.is_loaded()) {
+ // The profile is unloaded before it could be fully loaded, notify
+ // any pending callback that the load has failed.
+ for (auto& callback : profile_info.TakeCallbacks()) {
+ std::move(callback).Run(nullptr);
+ }
+ } else {
+ for (auto& observer : observers_) {
+ observer.OnProfileUnloaded(this, profile_info.profile());
+ }
+ }
+}
+
void ProfileManagerIOSImpl::UnloadAllProfiles() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- ProfileMap profiles_map = std::exchange(profiles_map_, {});
- for (auto& [_, profile_info] : profiles_map) {
- if (!profile_info.is_loaded()) {
- // The profile is unloaded before it could be fully loaded, notify
- // any pending callback that the load has failed.
- for (auto& callback : profile_info.TakeCallbacks()) {
- std::move(callback).Run(nullptr);
- }
- } else {
- for (auto& observer : observers_) {
- observer.OnProfileUnloaded(this, profile_info.profile());
- }
- }
+ while (!profiles_map_.empty()) {
+ const std::string& name = profiles_map_.begin()->first;
+ UnloadProfile(name);
}
}
diff --git a/ios/chrome/browser/profile/model/profile_manager_ios_impl_unittest.mm b/ios/chrome/browser/profile/model/profile_manager_ios_impl_unittest.mm
index 8854aae..ebe1781 100644
--- a/ios/chrome/browser/profile/model/profile_manager_ios_impl_unittest.mm
+++ b/ios/chrome/browser/profile/model/profile_manager_ios_impl_unittest.mm
@@ -750,6 +750,29 @@
kIOSChromeInitialProfile);
}
+// Tests that unloading a profile invoke OnProfileUnloaded(...) on the
+// observers.
+TEST_F(ProfileManagerIOSImplTest, UnloadProfile) {
+ // Create a few profiles synchronously.
+ ASSERT_TRUE(profile_manager().CreateProfile(kProfileName1));
+ ASSERT_TRUE(profile_manager().CreateProfile(kProfileName2));
+
+ ScopedTestProfileManagerObserverIOS observer(profile_manager());
+ EXPECT_FALSE(observer.on_profile_unloaded_called());
+
+ // Check that the profiles are accessible.
+ EXPECT_TRUE(profile_manager().GetProfileWithName(kProfileName1));
+ EXPECT_TRUE(profile_manager().GetProfileWithName(kProfileName2));
+
+ // Unload a profile, it should not longer be accessible and the
+ // observer must have been notified of that.
+ profile_manager().UnloadProfile(kProfileName1);
+
+ EXPECT_FALSE(profile_manager().GetProfileWithName(kProfileName1));
+ EXPECT_TRUE(profile_manager().GetProfileWithName(kProfileName2));
+ EXPECT_TRUE(observer.on_profile_unloaded_called());
+}
+
// Tests that unloading all profiles invoke OnProfileUnloaded(...) on the
// observers.
TEST_F(ProfileManagerIOSImplTest, UnloadAllProfiles) {
diff --git a/ios/chrome/browser/shared/model/profile/profile_manager_ios.h b/ios/chrome/browser/shared/model/profile/profile_manager_ios.h
index 291f6a85..c6ef701d 100644
--- a/ios/chrome/browser/shared/model/profile/profile_manager_ios.h
+++ b/ios/chrome/browser/shared/model/profile/profile_manager_ios.h
@@ -89,6 +89,9 @@
// null if loading or creating the Profile failed.
virtual ProfileIOS* CreateProfile(std::string_view name) = 0;
+ // Unloads the given loaded Profile objects.
+ virtual void UnloadProfile(std::string_view name) = 0;
+
// Unloads all loaded Profile objects. Meant to be called right before the
// ProfileManagerIOS itself is destroyed.
virtual void UnloadAllProfiles() = 0;
diff --git a/ios/chrome/browser/shared/model/profile/test/test_profile_manager_ios.h b/ios/chrome/browser/shared/model/profile/test/test_profile_manager_ios.h
index 3d520a1..df34708 100644
--- a/ios/chrome/browser/shared/model/profile/test/test_profile_manager_ios.h
+++ b/ios/chrome/browser/shared/model/profile/test/test_profile_manager_ios.h
@@ -46,6 +46,7 @@
ProfileLoadedCallback created_callback) override;
ProfileIOS* LoadProfile(std::string_view name) override;
ProfileIOS* CreateProfile(std::string_view name) override;
+ void UnloadProfile(std::string_view name) override;
void UnloadAllProfiles() override;
ProfileAttributesStorageIOS* GetProfileAttributesStorage() override;
diff --git a/ios/chrome/browser/shared/model/profile/test/test_profile_manager_ios.mm b/ios/chrome/browser/shared/model/profile/test/test_profile_manager_ios.mm
index aa15826..8ed28f3 100644
--- a/ios/chrome/browser/shared/model/profile/test/test_profile_manager_ios.mm
+++ b/ios/chrome/browser/shared/model/profile/test/test_profile_manager_ios.mm
@@ -124,6 +124,16 @@
return GetProfileWithName(name);
}
+void TestProfileManagerIOS::UnloadProfile(std::string_view name) {
+ auto iter = profiles_map_.find(name);
+ DCHECK(iter != profiles_map_.end());
+ std::unique_ptr<ProfileIOS> profile = std::move(iter->second);
+ profiles_map_.erase(iter);
+ for (auto& observer : observers_) {
+ observer.OnProfileUnloaded(this, profile.get());
+ }
+}
+
void TestProfileManagerIOS::UnloadAllProfiles() {
ProfileMap profiles_map = std::exchange(profiles_map_, {});
for (auto& [_, profile] : profiles_map) {
diff --git a/ios/chrome/browser/signin/model/account_profile_mapper_unittest.mm b/ios/chrome/browser/signin/model/account_profile_mapper_unittest.mm
index db40574d..501a09c 100644
--- a/ios/chrome/browser/signin/model/account_profile_mapper_unittest.mm
+++ b/ios/chrome/browser/signin/model/account_profile_mapper_unittest.mm
@@ -177,6 +177,7 @@
ProfileIOS* LoadProfile(std::string_view name) override { NOTREACHED(); }
ProfileIOS* CreateProfile(std::string_view name) override { NOTREACHED(); }
+ void UnloadProfile(std::string_view name) override { NOTREACHED(); }
void UnloadAllProfiles() override { NOTREACHED(); }
ProfileAttributesStorageIOS* GetProfileAttributesStorage() override {