1 // Copyright (c) 2013 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/browser/chromeos/profiles/profile_helper.h" 6 7 #include "base/callback.h" 8 #include "base/command_line.h" 9 #include "chrome/browser/browser_process.h" 10 #include "chrome/browser/browsing_data/browsing_data_helper.h" 11 #include "chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.h" 12 #include "chrome/browser/chromeos/login/users/user.h" 13 #include "chrome/browser/chromeos/login/users/user_manager.h" 14 #include "chrome/browser/profiles/profile.h" 15 #include "chrome/browser/profiles/profile_manager.h" 16 #include "chrome/browser/profiles/profiles_state.h" 17 #include "chrome/common/chrome_constants.h" 18 #include "chrome/common/chrome_switches.h" 19 #include "chromeos/chromeos_switches.h" 20 21 namespace chromeos { 22 23 namespace { 24 25 bool ShouldAddProfileDirPrefix(const std::string& user_id_hash) { 26 // Do not add profile dir prefix for legacy profile dir and test 27 // user profile. The reason of not adding prefix for test user profile 28 // is to keep the promise that TestingProfile::kTestUserProfileDir and 29 // chrome::kTestUserProfileDir are always in sync. Otherwise, 30 // TestingProfile::kTestUserProfileDir needs to be dynamically calculated 31 // based on whether multi profile is enabled or not. 32 return user_id_hash != chrome::kLegacyProfileDir && 33 user_id_hash != chrome::kTestUserProfileDir; 34 } 35 36 } // anonymous namespace 37 38 //////////////////////////////////////////////////////////////////////////////// 39 // ProfileHelper, public 40 41 ProfileHelper::ProfileHelper() 42 : signin_profile_clear_requested_(false) { 43 } 44 45 ProfileHelper::~ProfileHelper() { 46 // Checking whether UserManager is initialized covers case 47 // when ScopedTestUserManager is used. 48 if (UserManager::IsInitialized()) 49 UserManager::Get()->RemoveSessionStateObserver(this); 50 } 51 52 // static 53 Profile* ProfileHelper::GetProfileByUserIdHash( 54 const std::string& user_id_hash) { 55 ProfileManager* profile_manager = g_browser_process->profile_manager(); 56 return profile_manager->GetProfile(GetProfilePathByUserIdHash(user_id_hash)); 57 } 58 59 // static 60 base::FilePath ProfileHelper::GetProfilePathByUserIdHash( 61 const std::string& user_id_hash) { 62 // Fails for KioskTest.InstallAndLaunchApp test - crbug.com/238985 63 // Will probably fail for Guest session / restart after a crash - 64 // crbug.com/238998 65 // TODO(nkostylev): Remove this check once these bugs are fixed. 66 DCHECK(!user_id_hash.empty()); 67 ProfileManager* profile_manager = g_browser_process->profile_manager(); 68 base::FilePath profile_path = profile_manager->user_data_dir(); 69 70 return profile_path.Append(GetUserProfileDir(user_id_hash)); 71 } 72 73 // static 74 base::FilePath ProfileHelper::GetProfileDirByLegacyLoginProfileSwitch() { 75 const std::string login_profile_value = 76 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 77 chromeos::switches::kLoginProfile); 78 return ProfileHelper::GetUserProfileDir(login_profile_value); 79 } 80 81 // static 82 base::FilePath ProfileHelper::GetSigninProfileDir() { 83 ProfileManager* profile_manager = g_browser_process->profile_manager(); 84 base::FilePath user_data_dir = profile_manager->user_data_dir(); 85 return user_data_dir.AppendASCII(chrome::kInitialProfile); 86 } 87 88 // static 89 Profile* ProfileHelper::GetSigninProfile() { 90 ProfileManager* profile_manager = g_browser_process->profile_manager(); 91 return profile_manager->GetProfile(GetSigninProfileDir())-> 92 GetOffTheRecordProfile(); 93 } 94 95 // static 96 std::string ProfileHelper::GetUserIdHashFromProfile(Profile* profile) { 97 if (!profile) 98 return std::string(); 99 100 std::string profile_dir = profile->GetPath().BaseName().value(); 101 102 // Don't strip prefix if the dir is not supposed to be prefixed. 103 if (!ShouldAddProfileDirPrefix(profile_dir)) 104 return profile_dir; 105 106 // Check that profile directory starts with the correct prefix. 107 std::string prefix(chrome::kProfileDirPrefix); 108 if (profile_dir.find(prefix) != 0) { 109 // This happens when creating a TestingProfile in browser tests. 110 return std::string(); 111 } 112 113 return profile_dir.substr(prefix.length(), 114 profile_dir.length() - prefix.length()); 115 } 116 117 // static 118 base::FilePath ProfileHelper::GetUserProfileDir( 119 const std::string& user_id_hash) { 120 DCHECK(!user_id_hash.empty()); 121 return ShouldAddProfileDirPrefix(user_id_hash) 122 ? base::FilePath(chrome::kProfileDirPrefix + user_id_hash) 123 : base::FilePath(user_id_hash); 124 } 125 126 // static 127 bool ProfileHelper::IsSigninProfile(Profile* profile) { 128 return profile->GetPath().BaseName().value() == chrome::kInitialProfile; 129 } 130 131 // static 132 bool ProfileHelper::IsOwnerProfile(Profile* profile) { 133 if (!profile) 134 return false; 135 chromeos::UserManager* manager = chromeos::UserManager::Get(); 136 chromeos::User* user = manager->GetUserByProfile(profile); 137 if (!user) 138 return false; 139 return user->email() == manager->GetOwnerEmail(); 140 } 141 142 void ProfileHelper::ProfileStartup(Profile* profile, bool process_startup) { 143 // Initialize Chrome OS preferences like touch pad sensitivity. For the 144 // preferences to work in the guest mode, the initialization has to be 145 // done after |profile| is switched to the incognito profile (which 146 // is actually GuestSessionProfile in the guest mode). See the 147 // GetOffTheRecordProfile() call above. 148 profile->InitChromeOSPreferences(); 149 150 // Add observer so we can see when the first profile's session restore is 151 // completed. After that, we won't need the default profile anymore. 152 if (!IsSigninProfile(profile) && 153 UserManager::Get()->IsLoggedInAsRegularUser() && 154 !UserManager::Get()->IsLoggedInAsStub()) { 155 chromeos::OAuth2LoginManager* login_manager = 156 chromeos::OAuth2LoginManagerFactory::GetInstance()->GetForProfile( 157 profile); 158 if (login_manager) 159 login_manager->AddObserver(this); 160 } 161 } 162 163 base::FilePath ProfileHelper::GetActiveUserProfileDir() { 164 return ProfileHelper::GetUserProfileDir(active_user_id_hash_); 165 } 166 167 void ProfileHelper::Initialize() { 168 UserManager::Get()->AddSessionStateObserver(this); 169 } 170 171 void ProfileHelper::ClearSigninProfile(const base::Closure& on_clear_callback) { 172 on_clear_callbacks_.push_back(on_clear_callback); 173 if (signin_profile_clear_requested_) 174 return; 175 ProfileManager* profile_manager = g_browser_process->profile_manager(); 176 // Check if signin profile was loaded. 177 if (!profile_manager->GetProfileByPath(GetSigninProfileDir())) { 178 OnBrowsingDataRemoverDone(); 179 return; 180 } 181 signin_profile_clear_requested_ = true; 182 BrowsingDataRemover* remover = 183 BrowsingDataRemover::CreateForUnboundedRange(GetSigninProfile()); 184 remover->AddObserver(this); 185 remover->Remove(BrowsingDataRemover::REMOVE_SITE_DATA, 186 BrowsingDataHelper::ALL); 187 } 188 189 //////////////////////////////////////////////////////////////////////////////// 190 // ProfileHelper, BrowsingDataRemover::Observer implementation: 191 192 void ProfileHelper::OnBrowsingDataRemoverDone() { 193 signin_profile_clear_requested_ = false; 194 for (size_t i = 0; i < on_clear_callbacks_.size(); ++i) { 195 if (!on_clear_callbacks_[i].is_null()) 196 on_clear_callbacks_[i].Run(); 197 } 198 on_clear_callbacks_.clear(); 199 } 200 201 //////////////////////////////////////////////////////////////////////////////// 202 // ProfileHelper, OAuth2LoginManager::Observer implementation: 203 204 void ProfileHelper::OnSessionRestoreStateChanged( 205 Profile* user_profile, 206 OAuth2LoginManager::SessionRestoreState state) { 207 if (state == OAuth2LoginManager::SESSION_RESTORE_DONE || 208 state == OAuth2LoginManager::SESSION_RESTORE_FAILED || 209 state == OAuth2LoginManager::SESSION_RESTORE_CONNECTION_FAILED) { 210 chromeos::OAuth2LoginManager* login_manager = 211 chromeos::OAuth2LoginManagerFactory::GetInstance()-> 212 GetForProfile(user_profile); 213 login_manager->RemoveObserver(this); 214 ClearSigninProfile(base::Closure()); 215 } 216 } 217 218 //////////////////////////////////////////////////////////////////////////////// 219 // ProfileHelper, UserManager::UserSessionStateObserver implementation: 220 221 void ProfileHelper::ActiveUserHashChanged(const std::string& hash) { 222 active_user_id_hash_ = hash; 223 base::FilePath profile_path = GetProfilePathByUserIdHash(hash); 224 VLOG(1) << "Switching to profile path: " << profile_path.value(); 225 } 226 227 } // namespace chromeos 228