CrOS user management cleanup - profiles

* Add ProfileHelper::Get() which hides dependency
g_browser_process()->platform_part()->profile_helper()
* Move OverrideHomedir() to SessionManager
* Move GetUserProfileDir() to ProfileHelper
* Move GetUserByProfile/GetProfileByUser to ProfileHelper

BUG=387614
[email protected], [email protected]

Review URL: https://codereview.chromium.org/351063002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@280596 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/chromeos/profiles/profile_helper.cc b/chrome/browser/chromeos/profiles/profile_helper.cc
index a341a642..70edd29 100644
--- a/chrome/browser/chromeos/profiles/profile_helper.cc
+++ b/chrome/browser/chromeos/profiles/profile_helper.cc
@@ -17,6 +17,7 @@
 #include "chrome/common/chrome_constants.h"
 #include "chrome/common/chrome_switches.h"
 #include "chromeos/chromeos_switches.h"
+#include "content/public/browser/browser_thread.h"
 
 namespace chromeos {
 
@@ -33,13 +34,28 @@
       user_id_hash != chrome::kTestUserProfileDir;
 }
 
+class UsernameHashMatcher {
+ public:
+  explicit UsernameHashMatcher(const std::string& h) : username_hash(h) {}
+  bool operator()(const User* user) const {
+    return user->username_hash() == username_hash;
+  }
+
+ private:
+  const std::string& username_hash;
+};
+
 }  // anonymous namespace
 
+// static
+bool ProfileHelper::enable_profile_to_user_testing = false;
+bool ProfileHelper::always_return_primary_user_for_testing = false;
+
 ////////////////////////////////////////////////////////////////////////////////
 // ProfileHelper, public
 
 ProfileHelper::ProfileHelper()
-  : signin_profile_clear_requested_(false) {
+    : signin_profile_clear_requested_(false) {
 }
 
 ProfileHelper::~ProfileHelper() {
@@ -50,6 +66,11 @@
 }
 
 // static
+ProfileHelper* ProfileHelper::Get() {
+  return g_browser_process->platform_part()->profile_helper();
+}
+
+// static
 Profile* ProfileHelper::GetProfileByUserIdHash(
     const std::string& user_id_hash) {
   ProfileManager* profile_manager = g_browser_process->profile_manager();
@@ -124,6 +145,23 @@
 }
 
 // static
+base::FilePath ProfileHelper::GetUserProfileDirByUserId(
+    const std::string& user_id) {
+  // TODO(dpolukhin): Remove Chrome OS specific profile path logic from
+  // ProfileManager and use only this function to construct profile path.
+  // TODO(nkostylev): Cleanup profile dir related code paths crbug.com/294233
+  base::FilePath profile_dir;
+  const User* user = UserManager::Get()->FindUser(user_id);
+  if (user && !user->username_hash().empty())
+    profile_dir = ProfileHelper::GetUserProfileDir(user->username_hash());
+
+  ProfileManager* profile_manager = g_browser_process->profile_manager();
+  profile_dir = profile_manager->user_data_dir().Append(profile_dir);
+
+  return profile_dir;
+}
+
+// static
 bool ProfileHelper::IsSigninProfile(Profile* profile) {
   return profile->GetPath().BaseName().value() == chrome::kInitialProfile;
 }
@@ -132,11 +170,11 @@
 bool ProfileHelper::IsOwnerProfile(Profile* profile) {
   if (!profile)
     return false;
-  chromeos::UserManager* manager = chromeos::UserManager::Get();
-  chromeos::User* user = manager->GetUserByProfile(profile);
+  chromeos::User* user = ProfileHelper::Get()->GetUserByProfile(profile);
   if (!user)
     return false;
-  return user->email() == manager->GetOwnerEmail();
+
+  return user->email() == chromeos::UserManager::Get()->GetOwnerEmail();
 }
 
 void ProfileHelper::ProfileStartup(Profile* profile, bool process_startup) {
@@ -186,6 +224,80 @@
                   BrowsingDataHelper::ALL);
 }
 
+Profile* ProfileHelper::GetProfileByUser(const User* user) {
+  // This map is non-empty only in tests.
+  if (!user_to_profile_for_testing_.empty()) {
+    std::map<const User*, Profile*>::const_iterator it =
+        user_to_profile_for_testing_.find(user);
+    return it == user_to_profile_for_testing_.end() ? NULL : it->second;
+  }
+
+  Profile* profile = NULL;
+  if (user->is_profile_created())
+    profile = ProfileHelper::GetProfileByUserIdHash(user->username_hash());
+  else
+    profile = ProfileManager::GetActiveUserProfile();
+
+  // GetActiveUserProfile() or GetProfileByUserIdHash() returns a new instance
+  // of ProfileImpl(), but actually its OffTheRecordProfile() should be used.
+  if (profile && UserManager::Get()->IsLoggedInAsGuest())
+    profile = profile->GetOffTheRecordProfile();
+  return profile;
+}
+
+User* ProfileHelper::GetUserByProfile(Profile* profile) {
+  // This map is non-empty only in tests.
+  if (enable_profile_to_user_testing || !user_list_for_testing_.empty()) {
+    if (always_return_primary_user_for_testing)
+      return const_cast<User*>(UserManager::Get()->GetPrimaryUser());
+
+    const std::string& user_name = profile->GetProfileName();
+    for (UserList::const_iterator it = user_list_for_testing_.begin();
+         it != user_list_for_testing_.end();
+         ++it) {
+      if ((*it)->email() == user_name)
+        return *it;
+    }
+
+    // In case of test setup we should always default to primary user.
+    return const_cast<User*>(UserManager::Get()->GetPrimaryUser());
+  }
+
+  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
+  if (ProfileHelper::IsSigninProfile(profile))
+    return NULL;
+
+  UserManager* user_manager = UserManager::Get();
+
+  // Special case for non-CrOS tests that do create several profiles
+  // and don't really care about mapping to the real user.
+  // Without multi-profiles on Chrome OS such tests always got active_user_.
+  // Now these tests will specify special flag to continue working.
+  // In future those tests can get a proper CrOS configuration i.e. register
+  // and login several users if they want to work with an additional profile.
+  if (CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kIgnoreUserProfileMappingForTests)) {
+    return user_manager->GetActiveUser();
+  }
+
+  const std::string username_hash =
+      ProfileHelper::GetUserIdHashFromProfile(profile);
+  const UserList& users = user_manager->GetUsers();
+  const UserList::const_iterator pos = std::find_if(
+      users.begin(), users.end(), UsernameHashMatcher(username_hash));
+  if (pos != users.end())
+    return *pos;
+
+  // Many tests do not have their users registered with UserManager and
+  // runs here. If |active_user_| matches |profile|, returns it.
+  const User* active_user = user_manager->GetActiveUser();
+  return active_user &&
+                 ProfileHelper::GetProfilePathByUserIdHash(
+                     active_user->username_hash()) == profile->GetPath()
+             ? const_cast<User*>(active_user)
+             : NULL;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 // ProfileHelper, BrowsingDataRemover::Observer implementation:
 
@@ -224,4 +336,24 @@
   VLOG(1) << "Switching to profile path: " << profile_path.value();
 }
 
+void ProfileHelper::SetProfileToUserMappingForTesting(User* user) {
+  user_list_for_testing_.push_back(user);
+}
+
+// static
+void ProfileHelper::SetProfileToUserForTestingEnabled(bool enabled) {
+  enable_profile_to_user_testing = enabled;
+}
+
+// static
+void ProfileHelper::SetAlwaysReturnPrimaryUserForTesting(bool value) {
+  always_return_primary_user_for_testing = true;
+  ProfileHelper::SetProfileToUserForTestingEnabled(true);
+}
+
+void ProfileHelper::SetUserToProfileMappingForTesting(const User* user,
+                                                      Profile* profile) {
+  user_to_profile_for_testing_[user] = profile;
+}
+
 }  // namespace chromeos