1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/test/base/testing_profile_manager.h"
6
7 #include <stddef.h>
8 #include <utility>
9
10 #include "base/bind.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/test/test_file_util.h"
14 #include "build/build_config.h"
15 #include "chrome/browser/profiles/profile_attributes_entry.h"
16 #include "chrome/browser/profiles/profile_attributes_storage.h"
17 #include "chrome/browser/profiles/profile_info_cache.h"
18 #include "chrome/browser/profiles/profile_manager.h"
19 #include "chrome/common/chrome_constants.h"
20 #include "chrome/common/chrome_paths.h"
21 #include "chrome/test/base/testing_browser_process.h"
22 #include "components/sync_preferences/pref_service_syncable.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24
25 #if defined(OS_CHROMEOS)
26 #include "chrome/browser/chromeos/profiles/profile_helper.h"
27 #endif
28
29 const char kGuestProfileName[] = "Guest";
30 const char kSystemProfileName[] = "System";
31
32 namespace testing {
33
34 class ProfileManager : public ::ProfileManagerWithoutInit {
35 public:
ProfileManager(const base::FilePath & user_data_dir)36 explicit ProfileManager(const base::FilePath& user_data_dir)
37 : ::ProfileManagerWithoutInit(user_data_dir) {}
38
39 protected:
CreateProfileHelper(const base::FilePath & path)40 std::unique_ptr<Profile> CreateProfileHelper(
41 const base::FilePath& path) override {
42 return std::make_unique<TestingProfile>(path);
43 }
44 };
45
46 } // namespace testing
47
TestingProfileManager(TestingBrowserProcess * process)48 TestingProfileManager::TestingProfileManager(TestingBrowserProcess* process)
49 : called_set_up_(false),
50 browser_process_(process),
51 owned_local_state_(std::make_unique<ScopedTestingLocalState>(process)),
52 profile_manager_(nullptr) {
53 local_state_ = owned_local_state_.get();
54 }
55
TestingProfileManager(TestingBrowserProcess * process,ScopedTestingLocalState * local_state)56 TestingProfileManager::TestingProfileManager(
57 TestingBrowserProcess* process,
58 ScopedTestingLocalState* local_state)
59 : called_set_up_(false),
60 browser_process_(process),
61 local_state_(local_state),
62 profile_manager_(nullptr) {}
63
~TestingProfileManager()64 TestingProfileManager::~TestingProfileManager() {
65 // Destroying this class also destroys the LocalState, so make sure the
66 // associated ProfileManager is also destroyed.
67 browser_process_->SetProfileManager(NULL);
68 }
69
SetUp(const base::FilePath & profiles_path)70 bool TestingProfileManager::SetUp(const base::FilePath& profiles_path) {
71 SetUpInternal(profiles_path);
72 return called_set_up_;
73 }
74
CreateTestingProfile(const std::string & profile_name,std::unique_ptr<sync_preferences::PrefServiceSyncable> prefs,const base::string16 & user_name,int avatar_id,const std::string & supervised_user_id,TestingProfile::TestingFactories testing_factories,base::Optional<bool> override_new_profile,base::Optional<std::unique_ptr<policy::PolicyService>> policy_service)75 TestingProfile* TestingProfileManager::CreateTestingProfile(
76 const std::string& profile_name,
77 std::unique_ptr<sync_preferences::PrefServiceSyncable> prefs,
78 const base::string16& user_name,
79 int avatar_id,
80 const std::string& supervised_user_id,
81 TestingProfile::TestingFactories testing_factories,
82 base::Optional<bool> override_new_profile,
83 base::Optional<std::unique_ptr<policy::PolicyService>> policy_service) {
84 DCHECK(called_set_up_);
85
86 // Create a path for the profile based on the name.
87 base::FilePath profile_path(profiles_path_);
88 #if defined(OS_CHROMEOS)
89 if (profile_name != chrome::kInitialProfile &&
90 profile_name != chromeos::ProfileHelper::GetLockScreenAppProfileName()) {
91 profile_path =
92 profile_path.Append(chromeos::ProfileHelper::Get()->GetUserProfileDir(
93 chromeos::ProfileHelper::GetUserIdHashByUserIdForTesting(
94 profile_name)));
95 } else {
96 profile_path = profile_path.AppendASCII(profile_name);
97 }
98 #else
99 profile_path = profile_path.AppendASCII(profile_name);
100 #endif
101
102 // Create the profile and register it.
103 TestingProfile::Builder builder;
104 builder.SetPath(profile_path);
105 builder.SetPrefService(std::move(prefs));
106 builder.SetSupervisedUserId(supervised_user_id);
107 builder.SetProfileName(profile_name);
108 if (override_new_profile)
109 builder.OverrideIsNewProfile(*override_new_profile);
110 if (policy_service)
111 builder.SetPolicyService(std::move(*policy_service));
112
113 for (TestingProfile::TestingFactories::value_type& pair : testing_factories)
114 builder.AddTestingFactory(pair.first, std::move(pair.second));
115 testing_factories.clear();
116
117 std::unique_ptr<TestingProfile> profile = builder.Build();
118 TestingProfile* profile_ptr = profile.get();
119 profile_manager_->AddProfile(std::move(profile));
120
121 // Update the user metadata.
122 ProfileAttributesEntry* entry;
123 bool success = profile_manager_->GetProfileAttributesStorage()
124 .GetProfileAttributesWithPath(profile_path, &entry);
125 DCHECK(success);
126 entry->SetAvatarIconIndex(avatar_id);
127 entry->SetSupervisedUserId(supervised_user_id);
128 entry->SetLocalProfileName(user_name);
129
130 testing_profiles_.insert(std::make_pair(profile_name, profile_ptr));
131
132 return profile_ptr;
133 }
134
CreateTestingProfile(const std::string & name)135 TestingProfile* TestingProfileManager::CreateTestingProfile(
136 const std::string& name) {
137 DCHECK(called_set_up_);
138 return CreateTestingProfile(name, /*testing_factories=*/{});
139 }
140
CreateTestingProfile(const std::string & name,TestingProfile::TestingFactories testing_factories)141 TestingProfile* TestingProfileManager::CreateTestingProfile(
142 const std::string& name,
143 TestingProfile::TestingFactories testing_factories) {
144 DCHECK(called_set_up_);
145 return CreateTestingProfile(
146 name, std::unique_ptr<sync_preferences::PrefServiceSyncable>(),
147 base::UTF8ToUTF16(name), 0, std::string(), std::move(testing_factories));
148 }
149
CreateGuestProfile()150 TestingProfile* TestingProfileManager::CreateGuestProfile() {
151 DCHECK(called_set_up_);
152
153 // Create the profile and register it.
154 TestingProfile::Builder builder;
155 builder.SetGuestSession();
156 builder.SetPath(ProfileManager::GetGuestProfilePath());
157
158 // Add the guest profile to the profile manager, but not to the info cache.
159 std::unique_ptr<TestingProfile> profile = builder.Build();
160 TestingProfile* profile_ptr = profile.get();
161 profile_ptr->set_profile_name(kGuestProfileName);
162
163 // Set up a profile with an off the record profile.
164 if (!TestingProfile::IsEphemeralGuestProfileEnabled()) {
165 TestingProfile::Builder off_the_record_builder;
166 off_the_record_builder.SetGuestSession();
167 off_the_record_builder.BuildIncognito(profile_ptr);
168 }
169
170 profile_manager_->AddProfile(std::move(profile));
171 profile_manager_->SetNonPersonalProfilePrefs(profile_ptr);
172
173 testing_profiles_.insert(std::make_pair(kGuestProfileName, profile_ptr));
174
175 return profile_ptr;
176 }
177
CreateSystemProfile()178 TestingProfile* TestingProfileManager::CreateSystemProfile() {
179 DCHECK(called_set_up_);
180
181 // Create the profile and register it.
182 TestingProfile::Builder builder;
183 builder.SetPath(ProfileManager::GetSystemProfilePath());
184
185 // Add the system profile to the profile manager, but not to the info cache.
186 std::unique_ptr<TestingProfile> profile = builder.Build();
187 TestingProfile* profile_ptr = profile.get();
188 profile_ptr->set_profile_name(kSystemProfileName);
189
190 profile_manager_->AddProfile(std::move(profile));
191
192 testing_profiles_.insert(std::make_pair(kSystemProfileName, profile_ptr));
193
194 return profile_ptr;
195 }
196
DeleteTestingProfile(const std::string & name)197 void TestingProfileManager::DeleteTestingProfile(const std::string& name) {
198 DCHECK(called_set_up_);
199
200 auto it = testing_profiles_.find(name);
201 DCHECK(it != testing_profiles_.end());
202
203 TestingProfile* profile = it->second;
204
205 profile_manager_->GetProfileAttributesStorage().RemoveProfile(
206 profile->GetPath());
207
208 profile_manager_->profiles_info_.erase(profile->GetPath());
209
210 testing_profiles_.erase(it);
211 }
212
DeleteAllTestingProfiles()213 void TestingProfileManager::DeleteAllTestingProfiles() {
214 ProfileAttributesStorage& storage =
215 profile_manager_->GetProfileAttributesStorage();
216 for (auto it = testing_profiles_.begin(); it != testing_profiles_.end();
217 ++it) {
218 TestingProfile* profile = it->second;
219 storage.RemoveProfile(profile->GetPath());
220 }
221 testing_profiles_.clear();
222 }
223
224
DeleteGuestProfile()225 void TestingProfileManager::DeleteGuestProfile() {
226 DCHECK(called_set_up_);
227
228 auto it = testing_profiles_.find(kGuestProfileName);
229 DCHECK(it != testing_profiles_.end());
230
231 profile_manager_->profiles_info_.erase(ProfileManager::GetGuestProfilePath());
232 }
233
DeleteSystemProfile()234 void TestingProfileManager::DeleteSystemProfile() {
235 DCHECK(called_set_up_);
236
237 auto it = testing_profiles_.find(kSystemProfileName);
238 DCHECK(it != testing_profiles_.end());
239
240 profile_manager_->profiles_info_.erase(
241 ProfileManager::GetSystemProfilePath());
242 }
243
DeleteProfileInfoCache()244 void TestingProfileManager::DeleteProfileInfoCache() {
245 profile_manager_->profile_info_cache_.reset(NULL);
246 }
247
UpdateLastUser(Profile * last_active)248 void TestingProfileManager::UpdateLastUser(Profile* last_active) {
249 #if !defined(OS_ANDROID)
250 profile_manager_->UpdateLastUser(last_active);
251 #endif
252 }
253
profiles_dir()254 const base::FilePath& TestingProfileManager::profiles_dir() {
255 DCHECK(called_set_up_);
256 return profiles_path_;
257 }
258
profile_manager()259 ProfileManager* TestingProfileManager::profile_manager() {
260 DCHECK(called_set_up_);
261 return profile_manager_;
262 }
263
profile_info_cache()264 ProfileInfoCache* TestingProfileManager::profile_info_cache() {
265 DCHECK(called_set_up_);
266 return &profile_manager_->GetProfileInfoCache();
267 }
268
profile_attributes_storage()269 ProfileAttributesStorage* TestingProfileManager::profile_attributes_storage() {
270 return profile_info_cache();
271 }
272
SetUpInternal(const base::FilePath & profiles_path)273 void TestingProfileManager::SetUpInternal(const base::FilePath& profiles_path) {
274 ASSERT_FALSE(browser_process_->profile_manager())
275 << "ProfileManager already exists";
276
277 // Set up the directory for profiles.
278 if (profiles_path.empty()) {
279 profiles_path_ = base::CreateUniqueTempDirectoryScopedToTest();
280 } else {
281 profiles_path_ = profiles_path;
282 }
283 user_data_dir_override_ = std::make_unique<base::ScopedPathOverride>(
284 chrome::DIR_USER_DATA, profiles_path_);
285
286 profile_manager_ = new testing::ProfileManager(profiles_path_);
287 browser_process_->SetProfileManager(profile_manager_); // Takes ownership.
288
289 profile_manager_->GetProfileInfoCache().
290 set_disable_avatar_download_for_testing(true);
291 called_set_up_ = true;
292 }
293