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// This class keeps track of the currently-active profiles in the runtime.
6
7#ifndef CHROME_BROWSER_PROFILES_PROFILE_MANAGER_H_
8#define CHROME_BROWSER_PROFILES_PROFILE_MANAGER_H_
9
10#include <list>
11#include <vector>
12
13#include "base/basictypes.h"
14#include "base/containers/hash_tables.h"
15#include "base/files/file_path.h"
16#include "base/gtest_prod_util.h"
17#include "base/memory/linked_ptr.h"
18#include "base/memory/scoped_ptr.h"
19#include "base/message_loop/message_loop.h"
20#include "base/threading/non_thread_safe.h"
21#include "chrome/browser/profiles/profile.h"
22#include "chrome/browser/profiles/profile_shortcut_manager.h"
23#include "chrome/browser/ui/browser_list_observer.h"
24#include "content/public/browser/notification_observer.h"
25#include "content/public/browser/notification_registrar.h"
26
27class NewProfileLauncher;
28class ProfileInfoCache;
29
30class ProfileManager : public base::NonThreadSafe,
31                       public content::NotificationObserver,
32                       public Profile::Delegate {
33 public:
34  typedef base::Callback<void(Profile*, Profile::CreateStatus)> CreateCallback;
35
36  explicit ProfileManager(const base::FilePath& user_data_dir);
37  virtual ~ProfileManager();
38
39#if defined(ENABLE_SESSION_SERVICE)
40  // Invokes SessionServiceFactory::ShutdownForProfile() for all profiles.
41  static void ShutdownSessionServices();
42#endif
43
44  // Physically remove deleted profile directories from disk.
45  static void NukeDeletedProfilesFromDisk();
46
47  // Same as instance method but provides the default user_data_dir as well.
48  // If the Profile is going to be used to open a new window then consider using
49  // GetLastUsedProfileAllowedByPolicy() instead.
50  static Profile* GetLastUsedProfile();
51
52  // Same as GetLastUsedProfile() but returns the incognito Profile if
53  // incognito mode is forced. This should be used if the last used Profile
54  // will be used to open new browser windows.
55  static Profile* GetLastUsedProfileAllowedByPolicy();
56
57  // Same as instance method but provides the default user_data_dir as well.
58  static std::vector<Profile*> GetLastOpenedProfiles();
59
60  // Get the profile for the user which created the current session.
61  // Note that in case of a guest account this will return a 'suitable' profile.
62  // This function is temporary and will soon be moved to ash. As such avoid
63  // using it at all cost.
64  // TODO(skuhne): Move into ash's new user management function.
65  static Profile* GetPrimaryUserProfile();
66
67  // Get the profile for the currently active user.
68  // Note that in case of a guest account this will return a 'suitable' profile.
69  // This function is temporary and will soon be moved to ash. As such avoid
70  // using it at all cost.
71  // TODO(skuhne): Move into ash's new user management function.
72  static Profile* GetActiveUserProfile();
73
74  // Returns a profile for a specific profile directory within the user data
75  // dir. This will return an existing profile it had already been created,
76  // otherwise it will create and manage it.
77  Profile* GetProfile(const base::FilePath& profile_dir);
78
79  // Returns total number of profiles available on this machine.
80  size_t GetNumberOfProfiles();
81
82  // Explicit asynchronous creation of a profile located at |profile_path|.
83  // If the profile has already been created then callback is called
84  // immediately. Should be called on the UI thread.
85  void CreateProfileAsync(const base::FilePath& profile_path,
86                          const CreateCallback& callback,
87                          const base::string16& name,
88                          const base::string16& icon_url,
89                          const std::string& supervised_user_id);
90
91  // Returns true if the profile pointer is known to point to an existing
92  // profile.
93  bool IsValidProfile(Profile* profile);
94
95  // Returns the directory where the first created profile is stored,
96  // relative to the user data directory currently in use.
97  base::FilePath GetInitialProfileDir();
98
99  // Get the Profile last used (the Profile to which owns the most recently
100  // focused window) with this Chrome build. If no signed profile has been
101  // stored in Local State, hand back the Default profile.
102  Profile* GetLastUsedProfile(const base::FilePath& user_data_dir);
103
104  // Get the path of the last used profile, or if that's undefined, the default
105  // profile.
106  base::FilePath GetLastUsedProfileDir(const base::FilePath& user_data_dir);
107
108  // Get the Profiles which are currently open, i.e., have open browsers, or
109  // were open the last time Chrome was running. The Profiles appear in the
110  // order they were opened. The last used profile will be on the list, but its
111  // index on the list will depend on when it was opened (it is not necessarily
112  // the last one).
113  std::vector<Profile*> GetLastOpenedProfiles(
114      const base::FilePath& user_data_dir);
115
116  // Returns created profiles. Note, profiles order is NOT guaranteed to be
117  // related with the creation order.
118  std::vector<Profile*> GetLoadedProfiles() const;
119
120  // If a profile with the given path is currently managed by this object,
121  // return a pointer to the corresponding Profile object;
122  // otherwise return NULL.
123  Profile* GetProfileByPath(const base::FilePath& path) const;
124
125  // Creates a new profile in the next available multiprofile directory.
126  // Directories are named "profile_1", "profile_2", etc., in sequence of
127  // creation. (Because directories can be removed, however, it may be the case
128  // that at some point the list of numbered profiles is not continuous.)
129  // |callback| may be invoked multiple times (for CREATE_STATUS_INITIALIZED
130  // and CREATE_STATUS_CREATED) so binding parameters with bind::Passed() is
131  // prohibited. Returns the file path to the profile that will be created
132  // asynchronously.
133  static base::FilePath CreateMultiProfileAsync(
134      const base::string16& name,
135      const base::string16& icon_url,
136      const CreateCallback& callback,
137      const std::string& supervised_user_id);
138
139  // Returns the full path to be used for guest profiles.
140  static base::FilePath GetGuestProfilePath();
141
142  // Get the path of the next profile directory and increment the internal
143  // count.
144  // Lack of side effects:
145  // This function doesn't actually create the directory or touch the file
146  // system.
147  base::FilePath GenerateNextProfileDirectoryPath();
148
149  // Returns a ProfileInfoCache object which can be used to get information
150  // about profiles without having to load them from disk.
151  ProfileInfoCache& GetProfileInfoCache();
152
153  // Returns a ProfileShortcut Manager that enables the caller to create
154  // profile specfic desktop shortcuts.
155  ProfileShortcutManager* profile_shortcut_manager();
156
157  // Schedules the profile at the given path to be deleted on shutdown. If we're
158  // deleting the last profile, a new one will be created in its place, and in
159  // that case the callback will be called when profile creation is complete.
160  void ScheduleProfileForDeletion(const base::FilePath& profile_dir,
161                                  const CreateCallback& callback);
162
163  // Called on start-up if there are any stale ephemeral profiles to be deleted.
164  // This can be the case if the browser has crashed and the clean-up code had
165  // no chance to run then.
166  static void CleanUpStaleProfiles(
167      const std::vector<base::FilePath>& profile_paths);
168
169  // Autoloads profiles if they are running background apps.
170  void AutoloadProfiles();
171
172  // Initializes user prefs of |profile|. This includes profile name and
173  // avatar values.
174  void InitProfileUserPrefs(Profile* profile);
175
176  // Register and add testing profile to the ProfileManager. Use ONLY in tests.
177  // This allows the creation of Profiles outside of the standard creation path
178  // for testing. If |addToCache|, adds to ProfileInfoCache as well.
179  // If |start_deferred_task_runners|, starts the deferred task runners.
180  // Use ONLY in tests.
181  void RegisterTestingProfile(Profile* profile,
182                              bool addToCache,
183                              bool start_deferred_task_runners);
184
185  const base::FilePath& user_data_dir() const { return user_data_dir_; }
186
187  // For ChromeOS, determines if the user has logged in to a real profile.
188  bool IsLoggedIn() const { return logged_in_; }
189
190  // content::NotificationObserver implementation.
191  virtual void Observe(int type,
192                       const content::NotificationSource& source,
193                       const content::NotificationDetails& details) OVERRIDE;
194
195  // Profile::Delegate implementation:
196  virtual void OnProfileCreated(Profile* profile,
197                                bool success,
198                                bool is_new_profile) OVERRIDE;
199
200 protected:
201  // Does final initial actions.
202  virtual void DoFinalInit(Profile* profile, bool go_off_the_record);
203  virtual void DoFinalInitForServices(Profile* profile, bool go_off_the_record);
204  virtual void DoFinalInitLogging(Profile* profile);
205
206  // Creates a new profile by calling into the profile's profile creation
207  // method. Virtual so that unittests can return a TestingProfile instead
208  // of the Profile's result.
209  virtual Profile* CreateProfileHelper(const base::FilePath& path);
210
211  // Creates a new profile asynchronously by calling into the profile's
212  // asynchronous profile creation method. Virtual so that unittests can return
213  // a TestingProfile instead of the Profile's result.
214  virtual Profile* CreateProfileAsyncHelper(const base::FilePath& path,
215                                            Delegate* delegate);
216
217 private:
218  friend class TestingProfileManager;
219  FRIEND_TEST_ALL_PREFIXES(ProfileManagerBrowserTest, DeleteAllProfiles);
220  FRIEND_TEST_ALL_PREFIXES(ProfileManagerBrowserTest, SwitchToProfile);
221
222  // This struct contains information about profiles which are being loaded or
223  // were loaded.
224  struct ProfileInfo {
225    ProfileInfo(Profile* profile, bool created);
226
227    ~ProfileInfo();
228
229    scoped_ptr<Profile> profile;
230    // Whether profile has been fully loaded (created and initialized).
231    bool created;
232    // Whether or not this profile should have a shortcut.
233    bool create_shortcut;
234    // List of callbacks to run when profile initialization is done. Note, when
235    // profile is fully loaded this vector will be empty.
236    std::vector<CreateCallback> callbacks;
237
238   private:
239    DISALLOW_COPY_AND_ASSIGN(ProfileInfo);
240  };
241
242  // Returns the profile of the active user and / or the off the record profile
243  // if needed. This adds the profile to the ProfileManager if it doesn't
244  // already exist. The method will return NULL if the profile doesn't exist
245  // and we can't create it.
246  // The profile used can be overridden by using --login-profile on cros.
247  Profile* GetActiveUserOrOffTheRecordProfileFromPath(
248               const base::FilePath& user_data_dir);
249
250  // Adds a pre-existing Profile object to the set managed by this
251  // ProfileManager. This ProfileManager takes ownership of the Profile.
252  // The Profile should not already be managed by this ProfileManager.
253  // Returns true if the profile was added, false otherwise.
254  bool AddProfile(Profile* profile);
255
256  // Schedules the profile at the given path to be deleted on shutdown.
257  void FinishDeletingProfile(const base::FilePath& profile_dir);
258
259  // Registers profile with given info. Returns pointer to created ProfileInfo
260  // entry.
261  ProfileInfo* RegisterProfile(Profile* profile, bool created);
262
263  // Returns ProfileInfo associated with given |path|, registred earlier with
264  // RegisterProfile.
265  ProfileInfo* GetProfileInfoByPath(const base::FilePath& path) const;
266
267  // Adds |profile| to the profile info cache if it hasn't been added yet.
268  void AddProfileToCache(Profile* profile);
269
270  // Apply settings for (desktop) Guest User profile.
271  void SetGuestProfilePrefs(Profile* profile);
272
273  // For ChromeOS, determines if profile should be otr.
274  bool ShouldGoOffTheRecord(Profile* profile);
275
276  void RunCallbacks(const std::vector<CreateCallback>& callbacks,
277                    Profile* profile,
278                    Profile::CreateStatus status);
279
280#if !defined(OS_ANDROID) && !defined(OS_IOS)
281  // Updates the last active user of the current session.
282  // On Chrome OS updating this user will have no effect since when browser is
283  // restored after crash there's another preference that is taken into account.
284  // See kLastActiveUser in UserManagerBase.
285  void UpdateLastUser(Profile* last_active);
286
287  class BrowserListObserver : public chrome::BrowserListObserver {
288   public:
289    explicit BrowserListObserver(ProfileManager* manager);
290    virtual ~BrowserListObserver();
291
292    // chrome::BrowserListObserver implementation.
293    virtual void OnBrowserAdded(Browser* browser) OVERRIDE;
294    virtual void OnBrowserRemoved(Browser* browser) OVERRIDE;
295    virtual void OnBrowserSetLastActive(Browser* browser) OVERRIDE;
296
297   private:
298    ProfileManager* profile_manager_;
299    DISALLOW_COPY_AND_ASSIGN(BrowserListObserver);
300  };
301#endif  // !defined(OS_ANDROID) && !defined(OS_IOS)
302
303#if defined(OS_MACOSX)
304  // If the |loaded_profile| has been loaded successfully (according to
305  // |status|) and isn't already scheduled for deletion, then finishes adding
306  // |profile_to_delete_dir| to the queue of profiles to be deleted, and updates
307  // the kProfileLastUsed preference based on
308  // |last_non_supervised_profile_path|.
309  void OnNewActiveProfileLoaded(
310      const base::FilePath& profile_to_delete_path,
311      const base::FilePath& last_non_supervised_profile_path,
312      const CreateCallback& original_callback,
313      Profile* loaded_profile,
314      Profile::CreateStatus status);
315#endif
316
317  content::NotificationRegistrar registrar_;
318
319  // The path to the user data directory (DIR_USER_DATA).
320  const base::FilePath user_data_dir_;
321
322  // Indicates that a user has logged in and that the profile specified
323  // in the --login-profile command line argument should be used as the
324  // default.
325  bool logged_in_;
326
327#if !defined(OS_ANDROID) && !defined(OS_IOS)
328  BrowserListObserver browser_list_observer_;
329#endif  // !defined(OS_ANDROID) && !defined(OS_IOS)
330
331  // Maps profile path to ProfileInfo (if profile has been created). Use
332  // RegisterProfile() to add into this map. This map owns all loaded profile
333  // objects in a running instance of Chrome.
334  typedef std::map<base::FilePath, linked_ptr<ProfileInfo> > ProfilesInfoMap;
335  ProfilesInfoMap profiles_info_;
336
337  // Object to cache various information about profiles. Contains information
338  // about every profile which has been created for this instance of Chrome,
339  // if it has not been explicitly deleted.
340  scoped_ptr<ProfileInfoCache> profile_info_cache_;
341
342  // Manages the process of creating, deleteing and updating Desktop shortcuts.
343  scoped_ptr<ProfileShortcutManager> profile_shortcut_manager_;
344
345  // For keeping track of the last active profiles.
346  std::map<Profile*, int> browser_counts_;
347  // On startup we launch the active profiles in the order they became active
348  // during the last run. This is why they are kept in a list, not in a set.
349  std::vector<Profile*> active_profiles_;
350  bool closing_all_browsers_;
351
352  DISALLOW_COPY_AND_ASSIGN(ProfileManager);
353};
354
355// Same as the ProfileManager, but doesn't initialize some services of the
356// profile. This one is useful in unittests.
357class ProfileManagerWithoutInit : public ProfileManager {
358 public:
359  explicit ProfileManagerWithoutInit(const base::FilePath& user_data_dir);
360
361 protected:
362  virtual void DoFinalInitForServices(Profile*, bool) OVERRIDE {}
363  virtual void DoFinalInitLogging(Profile*) OVERRIDE {}
364};
365
366#endif  // CHROME_BROWSER_PROFILES_PROFILE_MANAGER_H_
367