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