1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <set>
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile_manager.h"
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/command_line.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_util.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/path_service.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser_process.h"
144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/ui/browser_list.h"
154a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/ui/browser_window.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_constants.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_paths.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_switches.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/logging_chrome.h"
20dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h"
22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_type.h"
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h"
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/http/http_transaction_factory.h"
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/url_request/url_request_context.h"
26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/url_request/url_request_context_getter.h"
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/url_request/url_request_job.h"
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/url_request/url_request_job_tracker.h"
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/cros/cros_library.h"
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/chromeos/cros/cryptohome_library.h"
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace {
36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SuspendURLRequestJobs() {
38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (net::URLRequestJobTracker::JobIterator i =
40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen           net::g_url_request_job_tracker.begin();
41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen       i != net::g_url_request_job_tracker.end(); ++i)
42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    (*i)->Kill();
43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid SuspendRequestContext(
46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    net::URLRequestContextGetter* request_context_getter) {
47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<net::URLRequestContext> request_context =
50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      request_context_getter->GetURLRequestContext();
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  request_context->http_transaction_factory()->Suspend(true);
53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ResumeRequestContext(
56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    net::URLRequestContextGetter* request_context_getter) {
57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<net::URLRequestContext> request_context =
60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      request_context_getter->GetURLRequestContext();
61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  request_context->http_transaction_factory()->Suspend(false);
62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}  // namespace
65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileManager::ShutdownSessionServices() {
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ProfileManager* pm = g_browser_process->profile_manager();
6972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!pm)  // Is NULL when running unit tests.
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<Profile*> profiles(pm->GetLoadedProfiles());
72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (size_t i = 0; i < profiles.size(); ++i)
73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    profiles[i]->ShutdownSessionService();
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochProfile* ProfileManager::GetDefaultProfile() {
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath user_data_dir;
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ProfileManager* profile_manager = g_browser_process->profile_manager();
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return profile_manager->GetDefaultProfile(user_data_dir);
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochProfileManager::ProfileManager() : logged_in_(false) {
8572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ui::SystemMonitor::Get()->AddObserver(this);
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      this,
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationType::LOGIN_USER_CHANGED,
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::AllSources());
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochProfileManager::~ProfileManager() {
9572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ui::SystemMonitor* system_monitor = ui::SystemMonitor::Get();
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (system_monitor)
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    system_monitor->RemoveObserver(this);
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochFilePath ProfileManager::GetDefaultProfileDir(
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const FilePath& user_data_dir) {
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath default_profile_dir(user_data_dir);
103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  default_profile_dir =
104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      default_profile_dir.AppendASCII(chrome::kNotSignedInProfile);
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return default_profile_dir;
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochFilePath ProfileManager::GetProfilePrefsPath(
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const FilePath &profile_dir) {
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath default_prefs_path(profile_dir);
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  default_prefs_path = default_prefs_path.Append(chrome::kPreferencesFilename);
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return default_prefs_path;
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochFilePath ProfileManager::GetCurrentProfileDir() {
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath relative_profile_dir;
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (logged_in_) {
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    FilePath profile_dir;
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // If the user has logged in, pick up the new profile.
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (command_line.HasSwitch(switches::kLoginProfile)) {
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      profile_dir = command_line.GetSwitchValuePath(switches::kLoginProfile);
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // We should never be logged in with no profile dir.
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTREACHED();
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return FilePath("");
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    relative_profile_dir = relative_profile_dir.Append(profile_dir);
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return relative_profile_dir;
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  relative_profile_dir =
134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      relative_profile_dir.AppendASCII(chrome::kNotSignedInProfile);
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return relative_profile_dir;
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochProfile* ProfileManager::GetDefaultProfile(const FilePath& user_data_dir) {
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath default_profile_dir(user_data_dir);
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  default_profile_dir = default_profile_dir.Append(GetCurrentProfileDir());
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!logged_in_) {
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Profile* profile;
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const CommandLine& command_line = *CommandLine::ForCurrentProcess();
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // For cros, return the OTR profile so we never accidentally keep
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // user data in an unencrypted profile. But doing this makes
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // many of the browser and ui tests fail. We do return the OTR profile
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // if the login-profile switch is passed so that we can test this.
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // TODO(davemoore) Fix the tests so they allow OTR profiles.
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!command_line.HasSwitch(switches::kTestType) ||
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        command_line.HasSwitch(switches::kLoginProfile)) {
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Don't init extensions for this profile
154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      profile = GetProfile(default_profile_dir);
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      profile = profile->GetOffTheRecordProfile();
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      profile = GetProfile(default_profile_dir);
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return profile;
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return GetProfile(default_profile_dir);
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
165dc0f95d653279beabeb9817299e2902918ba123eKristian MonsenProfile* ProfileManager::GetProfileWithId(ProfileId profile_id) {
166dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  DCHECK_NE(Profile::kInvalidProfileId, profile_id);
167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (ProfilesInfoMap::iterator iter = profiles_info_.begin();
168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen       iter != profiles_info_.end(); ++iter) {
169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (iter->second->created) {
170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      Profile* candidate = iter->second->profile.get();
171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (candidate->GetRuntimeId() == profile_id)
172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        return candidate;
173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (candidate->HasOffTheRecordProfile()) {
174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        candidate = candidate->GetOffTheRecordProfile();
175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        if (candidate->GetRuntimeId() == profile_id)
176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          return candidate;
177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
178dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    }
179dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
180dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return NULL;
181dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
182dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
183dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool ProfileManager::IsValidProfile(Profile* profile) {
184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (ProfilesInfoMap::iterator iter = profiles_info_.begin();
185ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen       iter != profiles_info_.end(); ++iter) {
186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (iter->second->created) {
187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      Profile* candidate = iter->second->profile.get();
188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      if (candidate == profile ||
189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          (candidate->HasOffTheRecordProfile() &&
190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen           candidate->GetOffTheRecordProfile() == profile)) {
191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        return true;
192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
193dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    }
194dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  }
195dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return false;
196dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
197dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenstd::vector<Profile*> ProfileManager::GetLoadedProfiles() const {
199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<Profile*> profiles;
200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (ProfilesInfoMap::const_iterator iter = profiles_info_.begin();
201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen       iter != profiles_info_.end(); ++iter) {
202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (iter->second->created)
203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      profiles.push_back(iter->second->profile.get());
204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return profiles;
206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenProfile* ProfileManager::GetProfile(const FilePath& profile_dir) {
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // If the profile is already loaded (e.g., chrome.exe launched twice), just
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // return it.
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Profile* profile = GetProfileByPath(profile_dir);
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (NULL != profile)
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return profile;
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  profile = Profile::CreateProfile(profile_dir);
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(profile);
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (profile) {
218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    bool result = AddProfile(profile);
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(result);
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return profile;
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ProfileManager::CreateProfileAsync(const FilePath& user_data_dir,
225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                        Observer* observer) {
226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ProfilesInfoMap::iterator iter = profiles_info_.find(user_data_dir);
228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (iter != profiles_info_.end()) {
229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ProfileInfo* info = iter->second.get();
230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (info->created) {
231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Profile has already been created. Call observer immediately.
232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      observer->OnProfileCreated(info->profile.get());
233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // Profile is being created. Add observer to list.
235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      info->observers.push_back(observer);
236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else {
238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Initiate asynchronous creation process.
239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ProfileInfo* info =
240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        RegisterProfile(Profile::CreateProfileAsync(user_data_dir, this),
241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                        false);
242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    info->observers.push_back(observer);
243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static
247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ProfileManager::CreateDefaultProfileAsync(Observer* observer) {
248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ProfileManager* profile_manager = g_browser_process->profile_manager();
250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FilePath default_profile_dir;
252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PathService::Get(chrome::DIR_USER_DATA, &default_profile_dir);
253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  default_profile_dir = default_profile_dir.Append(
254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      profile_manager->GetCurrentProfileDir());
255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  profile_manager->CreateProfileAsync(default_profile_dir,
257ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                      observer);
258dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
259dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
260ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenbool ProfileManager::AddProfile(Profile* profile) {
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(profile);
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make sure that we're not loading a profile with the same ID as a profile
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // that's already loaded.
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (GetProfileByPath(profile->GetPath())) {
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED() << "Attempted to add profile with the same path (" <<
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    profile->GetPath().value() <<
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    ") as an already-loaded profile.";
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  RegisterProfile(profile, true);
273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DoFinalInit(profile);
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenProfileManager::ProfileInfo* ProfileManager::RegisterProfile(Profile* profile,
278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                                             bool created) {
279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ProfileInfo* info = new ProfileInfo(profile, created);
280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ProfilesInfoMap::iterator new_elem =
281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      (profiles_info_.insert(std::make_pair(profile->GetPath(), info))).first;
282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return info;
283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
285ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenProfile* ProfileManager::GetProfileByPath(const FilePath& path) const {
286ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ProfilesInfoMap::const_iterator iter = profiles_info_.find(path);
287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return (iter == profiles_info_.end()) ? NULL : iter->second->profile.get();
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileManager::OnSuspend() {
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(CalledOnValidThread());
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
293ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool posted = BrowserThread::PostTask(
294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      BrowserThread::IO, FROM_HERE,
295ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      NewRunnableFunction(&SuspendURLRequestJobs));
296ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(posted);
297ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<net::URLRequestContextGetter> request_context;
299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<Profile*> profiles(GetLoadedProfiles());
300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (size_t i = 0; i < profiles.size(); ++i) {
301ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    request_context = profiles[i]->GetRequestContext();
302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    posted = BrowserThread::PostTask(
303731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        BrowserThread::IO, FROM_HERE,
304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        NewRunnableFunction(&SuspendRequestContext, request_context));
305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK(posted);
306ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    request_context = profiles[i]->GetRequestContextForMedia();
307ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    posted = BrowserThread::PostTask(
308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        BrowserThread::IO, FROM_HERE,
309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        NewRunnableFunction(&SuspendRequestContext, request_context));
310ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK(posted);
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileManager::OnResume() {
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(CalledOnValidThread());
316ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  scoped_refptr<net::URLRequestContextGetter> request_context;
318ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<Profile*> profiles(GetLoadedProfiles());
319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (size_t i = 0; i < profiles.size(); ++i) {
320ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    request_context = profiles[i]->GetRequestContext();
321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    bool posted = BrowserThread::PostTask(
322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        BrowserThread::IO, FROM_HERE,
323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        NewRunnableFunction(&ResumeRequestContext, request_context));
324ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK(posted);
325ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    request_context = profiles[i]->GetRequestContextForMedia();
326ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    posted = BrowserThread::PostTask(
327731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        BrowserThread::IO, FROM_HERE,
328ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        NewRunnableFunction(&ResumeRequestContext, request_context));
329ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK(posted);
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ProfileManager::Observe(
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NotificationType type,
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const NotificationSource& source,
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const NotificationDetails& details) {
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_CHROMEOS)
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (type == NotificationType::LOGIN_USER_CHANGED) {
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const CommandLine& command_line = *CommandLine::ForCurrentProcess();
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!command_line.HasSwitch(switches::kTestType)) {
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // This will fail when running on non cros os.
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // TODO(davemoore) Need to mock this enough to enable testing.
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      CHECK(chromeos::CrosLibrary::Get()->EnsureLoaded());
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // If we don't have a mounted profile directory we're in trouble.
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // TODO(davemoore) Once we have better api this check should ensure that
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // our profile directory is the one that's mounted, and that it's mounted
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // as the current user.
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      CHECK(chromeos::CrosLibrary::Get()->GetCryptohomeLibrary()->IsMounted());
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    logged_in_ = true;
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
355ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ProfileManager::DoFinalInit(Profile* profile) {
356ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
357ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool init_extensions = true;
358ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(OS_CHROMEOS)
359ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!logged_in_ &&
360ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      (!command_line.HasSwitch(switches::kTestType) ||
361ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        command_line.HasSwitch(switches::kLoginProfile))) {
362ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    init_extensions = false;
363ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
364ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
365ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  profile->InitExtensions(init_extensions);
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
367ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!command_line.HasSwitch(switches::kDisableWebResources))
368ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    profile->InitPromoResources();
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
371ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid ProfileManager::OnProfileCreated(Profile* profile, bool success) {
372ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
374ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ProfilesInfoMap::iterator iter = profiles_info_.find(profile->GetPath());
375ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK(iter != profiles_info_.end());
376ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ProfileInfo* info = iter->second.get();
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
378ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::vector<Observer*> observers;
379ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  info->observers.swap(observers);
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
381ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (success) {
382ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DoFinalInit(profile);
383ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    info->created = true;
384ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#if defined(OS_CHROMEOS)
385ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const CommandLine& command_line = *CommandLine::ForCurrentProcess();
386ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!logged_in_ &&
387ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        (!command_line.HasSwitch(switches::kTestType) ||
388ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         command_line.HasSwitch(switches::kLoginProfile))) {
389ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      profile = profile->GetOffTheRecordProfile();
390ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
391ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#endif
392ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else {
393ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    profile = NULL;
394ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    profiles_info_.erase(iter);
395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
397ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  for (size_t i = 0; i < observers.size(); ++i) {
398ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    observers[i]->OnProfileCreated(profile);
399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
401