1 // Copyright 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/profiles/profile_window.h" 6 7 #include "base/command_line.h" 8 #include "base/files/file_path.h" 9 #include "chrome/browser/browser_process.h" 10 #include "chrome/browser/profiles/profile.h" 11 #include "chrome/browser/profiles/profile_manager.h" 12 #include "chrome/browser/ui/browser.h" 13 #include "chrome/browser/ui/browser_dialogs.h" 14 #include "content/public/browser/browser_thread.h" 15 #include "content/public/browser/user_metrics.h" 16 17 #if !defined(OS_IOS) 18 #include "chrome/browser/ui/browser_finder.h" 19 #include "chrome/browser/ui/browser_list.h" 20 #include "chrome/browser/ui/browser_list_observer.h" 21 #include "chrome/browser/ui/browser_window.h" 22 #include "chrome/browser/ui/startup/startup_browser_creator.h" 23 #endif // !defined (OS_IOS) 24 25 using content::BrowserThread; 26 using content::UserMetricsAction; 27 28 namespace { 29 30 // Handles running a callback when a new Browser has been completely created. 31 class BrowserAddedObserver : public chrome::BrowserListObserver { 32 public: 33 explicit BrowserAddedObserver( 34 profiles::ProfileSwitchingDoneCallback callback) : callback_(callback) { 35 BrowserList::AddObserver(this); 36 } 37 virtual ~BrowserAddedObserver() { 38 BrowserList::RemoveObserver(this); 39 } 40 41 private: 42 // Overridden from BrowserListObserver: 43 virtual void OnBrowserAdded(Browser* browser) OVERRIDE { 44 DCHECK(!callback_.is_null()); 45 callback_.Run(); 46 } 47 48 profiles::ProfileSwitchingDoneCallback callback_; 49 50 DISALLOW_COPY_AND_ASSIGN(BrowserAddedObserver); 51 }; 52 53 void OpenBrowserWindowForProfile( 54 profiles::ProfileSwitchingDoneCallback callback, 55 bool always_create, 56 bool is_new_profile, 57 chrome::HostDesktopType desktop_type, 58 Profile* profile, 59 Profile::CreateStatus status) { 60 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 61 62 if (status != Profile::CREATE_STATUS_INITIALIZED) 63 return; 64 65 chrome::startup::IsProcessStartup is_process_startup = 66 chrome::startup::IS_NOT_PROCESS_STARTUP; 67 chrome::startup::IsFirstRun is_first_run = chrome::startup::IS_NOT_FIRST_RUN; 68 69 // If this is a brand new profile, then start a first run window. 70 if (is_new_profile) { 71 is_process_startup = chrome::startup::IS_PROCESS_STARTUP; 72 is_first_run = chrome::startup::IS_FIRST_RUN; 73 } 74 75 // If we are not showing any browsers windows (we could be showing the 76 // desktop User Manager, for example), then this is a process startup browser. 77 if (BrowserList::GetInstance(desktop_type)->size() == 0) 78 is_process_startup = chrome::startup::IS_PROCESS_STARTUP; 79 80 // If there is a callback, create an observer to make sure it is only 81 // run when the browser has been completely created. 82 scoped_ptr<BrowserAddedObserver> browser_added_observer; 83 if (!callback.is_null()) 84 browser_added_observer.reset(new BrowserAddedObserver(callback)); 85 86 profiles::FindOrCreateNewWindowForProfile( 87 profile, 88 is_process_startup, 89 is_first_run, 90 desktop_type, 91 always_create); 92 } 93 94 } // namespace 95 96 namespace profiles { 97 98 void FindOrCreateNewWindowForProfile( 99 Profile* profile, 100 chrome::startup::IsProcessStartup process_startup, 101 chrome::startup::IsFirstRun is_first_run, 102 chrome::HostDesktopType desktop_type, 103 bool always_create) { 104 #if defined(OS_IOS) 105 NOTREACHED(); 106 #else 107 DCHECK(profile); 108 109 if (!always_create) { 110 Browser* browser = chrome::FindTabbedBrowser(profile, false, desktop_type); 111 if (browser) { 112 browser->window()->Activate(); 113 return; 114 } 115 } 116 117 content::RecordAction(UserMetricsAction("NewWindow")); 118 CommandLine command_line(CommandLine::NO_PROGRAM); 119 int return_code; 120 StartupBrowserCreator browser_creator; 121 browser_creator.LaunchBrowser(command_line, profile, base::FilePath(), 122 process_startup, is_first_run, &return_code); 123 #endif // defined(OS_IOS) 124 } 125 126 void SwitchToProfile( 127 const base::FilePath& path, 128 chrome::HostDesktopType desktop_type, 129 bool always_create, 130 ProfileSwitchingDoneCallback callback) { 131 g_browser_process->profile_manager()->CreateProfileAsync( 132 path, 133 base::Bind(&OpenBrowserWindowForProfile, 134 callback, 135 always_create, 136 false, 137 desktop_type), 138 base::string16(), 139 base::string16(), 140 std::string()); 141 } 142 143 void SwitchToGuestProfile(chrome::HostDesktopType desktop_type, 144 ProfileSwitchingDoneCallback callback) { 145 g_browser_process->profile_manager()->CreateProfileAsync( 146 ProfileManager::GetGuestProfilePath(), 147 base::Bind(&OpenBrowserWindowForProfile, 148 callback, 149 false, 150 false, 151 desktop_type), 152 base::string16(), 153 base::string16(), 154 std::string()); 155 } 156 157 void CreateAndSwitchToNewProfile(chrome::HostDesktopType desktop_type, 158 ProfileSwitchingDoneCallback callback) { 159 ProfileManager::CreateMultiProfileAsync( 160 base::string16(), 161 base::string16(), 162 base::Bind(&OpenBrowserWindowForProfile, 163 callback, 164 true, 165 true, 166 desktop_type), 167 std::string()); 168 } 169 170 void CloseGuestProfileWindows() { 171 ProfileManager* profile_manager = g_browser_process->profile_manager(); 172 Profile* profile = profile_manager->GetProfileByPath( 173 ProfileManager::GetGuestProfilePath()); 174 175 if (profile) { 176 BrowserList::CloseAllBrowsersWithProfile(profile); 177 } 178 } 179 180 void LockProfile(Profile* profile) { 181 DCHECK(profile); 182 ProfileInfoCache& cache = 183 g_browser_process->profile_manager()->GetProfileInfoCache(); 184 185 size_t index = cache.GetIndexOfProfileWithPath(profile->GetPath()); 186 cache.SetProfileSigninRequiredAtIndex(index, true); 187 chrome::ShowUserManager(profile->GetPath()); 188 BrowserList::CloseAllBrowsersWithProfile(profile); 189 } 190 191 } // namespace profiles 192