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