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 #ifndef CHROME_BROWSER_UI_STARTUP_STARTUP_BROWSER_CREATOR_H_
6 #define CHROME_BROWSER_UI_STARTUP_STARTUP_BROWSER_CREATOR_H_
7 
8 #include <memory>
9 #include <vector>
10 
11 #include "base/files/file_path.h"
12 #include "base/gtest_prod_util.h"
13 #include "chrome/browser/prefs/session_startup_pref.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/ui/startup/startup_types.h"
16 
17 class Browser;
18 class GURL;
19 class LaunchModeRecorder;
20 class PrefRegistrySimple;
21 
22 namespace base {
23 class CommandLine;
24 }
25 
26 // class containing helpers for BrowserMain to spin up a new instance and
27 // initialize the profile.
28 class StartupBrowserCreator {
29  public:
30   typedef std::vector<Profile*> Profiles;
31 
32   StartupBrowserCreator();
33   StartupBrowserCreator(const StartupBrowserCreator&) = delete;
34   StartupBrowserCreator& operator=(const StartupBrowserCreator&) = delete;
35   ~StartupBrowserCreator();
36 
37   // Adds a url to be opened during first run. This overrides the standard
38   // tabs shown at first run.
39   void AddFirstRunTab(const GURL& url);
40 
41   // Configures the instance to include the specified "welcome back" page in a
42   // tab before other tabs (e.g., those from session restore). This is used for
43   // specific launches via retention experiments for which no URLs are provided
44   // on the command line. No "welcome back" page is shown to supervised users.
set_welcome_back_page(bool welcome_back_page)45   void set_welcome_back_page(bool welcome_back_page) {
46     welcome_back_page_ = welcome_back_page;
47   }
welcome_back_page()48   bool welcome_back_page() const { return welcome_back_page_; }
49 
50   // This function is equivalent to ProcessCommandLine but should only be
51   // called during actual process startup.
52   bool Start(const base::CommandLine& cmd_line,
53              const base::FilePath& cur_dir,
54              Profile* last_used_profile,
55              const Profiles& last_opened_profiles);
56 
57   // This function performs command-line handling and is invoked only after
58   // start up (for example when we get a start request for another process).
59   // |command_line| holds the command line we need to process.
60   // |cur_dir| is the current working directory that the original process was
61   // invoked from.
62   // |startup_profile_dir| is the directory that contains the profile that the
63   // command line arguments will be executed under.
64   static void ProcessCommandLineAlreadyRunning(
65       const base::CommandLine& command_line,
66       const base::FilePath& cur_dir,
67       const base::FilePath& startup_profile_dir);
68 
69   // Opens the set of startup pages from the current session startup prefs.
70   static void OpenStartupPages(Browser* browser, bool process_startup);
71 
72   // Returns true if we're launching a profile synchronously. In that case, the
73   // opened window should not cause a session restore.
74   static bool InSynchronousProfileLaunch();
75 
76   // Launches a browser window associated with |profile|. |command_line| should
77   // be the command line passed to this process. |cur_dir| can be empty, which
78   // implies that the directory of the executable should be used.
79   // |process_startup| indicates whether this is the first browser.
80   // |is_first_run| indicates that this is a new profile.
81   // If |launch_mode_recorder| is non null, and a browser is launched, a launch
82   // mode histogram will be recorded.
83   bool LaunchBrowser(const base::CommandLine& command_line,
84                      Profile* profile,
85                      const base::FilePath& cur_dir,
86                      chrome::startup::IsProcessStartup is_process_startup,
87                      chrome::startup::IsFirstRun is_first_run,
88                      std::unique_ptr<LaunchModeRecorder> launch_mode_recorder);
89 
90   // When called the first time, reads the value of the preference kWasRestarted
91   // and resets it to false. Subsequent calls return the value which was read
92   // the first time.
93   static bool WasRestarted();
94 
95   static SessionStartupPref GetSessionStartupPref(
96       const base::CommandLine& command_line,
97       const Profile* profile);
98 
99   // For faking that no profiles have been launched yet.
100   static void ClearLaunchedProfilesForTesting();
101 
102   static void RegisterLocalStatePrefs(PrefRegistrySimple* registry);
103   static void RegisterProfilePrefs(PrefRegistrySimple* registry);
104 
105  private:
106   friend class CloudPrintProxyPolicyTest;
107   friend class CloudPrintProxyPolicyStartupTest;
108   friend class StartupBrowserCreatorImpl;
109   // TODO(crbug.com/642442): Remove this when first_run_tabs gets refactored.
110   friend class StartupTabProviderImpl;
111   FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest,
112                            ReadingWasRestartedAfterNormalStart);
113   FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest,
114                            ReadingWasRestartedAfterRestart);
115   FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest, UpdateWithTwoProfiles);
116   FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest, LastUsedProfileActivated);
117   FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest,
118                            ValidNotificationLaunchId);
119   FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest,
120                            InvalidNotificationLaunchId);
121 
122   bool ProcessCmdLineImpl(const base::CommandLine& command_line,
123                           const base::FilePath& cur_dir,
124                           bool process_startup,
125                           Profile* last_used_profile,
126                           const Profiles& last_opened_profiles);
127 
128   // Launch browser for |last_opened_profiles| if it's not empty. Otherwise,
129   // launch browser for |last_used_profile|. Return false if any browser is
130   // failed to be launched. Otherwise, return true.
131   bool LaunchBrowserForLastProfiles(const base::CommandLine& command_line,
132                                     const base::FilePath& cur_dir,
133                                     bool process_startup,
134                                     Profile* last_used_profile,
135                                     const Profiles& last_opened_profiles);
136 
137   // Launch the |last_used_profile| with the full command line, and the other
138   // |last_opened_profiles| without the URLs to launch. Return false if any
139   // browser is failed to be launched. Otherwise, return true.
140 
141   bool ProcessLastOpenedProfiles(
142       const base::CommandLine& command_line,
143       const base::FilePath& cur_dir,
144       chrome::startup::IsProcessStartup is_process_startup,
145       chrome::startup::IsFirstRun is_first_run,
146       Profile* last_used_profile,
147       const Profiles& last_opened_profiles);
148 
149   // Returns the list of URLs to open from the command line.
150   static std::vector<GURL> GetURLsFromCommandLine(
151       const base::CommandLine& command_line,
152       const base::FilePath& cur_dir,
153       Profile* profile);
154 
155   // This function performs command-line handling and is invoked only after
156   // start up (for example when we get a start request for another process).
157   // |command_line| holds the command line being processed.
158   // |cur_dir| is the current working directory that the original process was
159   // invoked from.
160   // |profile| is the profile the apps will be launched in.
161   static bool ProcessLoadApps(const base::CommandLine& command_line,
162                               const base::FilePath& cur_dir,
163                               Profile* profile);
164 
165   // Callback after a profile has been created.
166   static void ProcessCommandLineOnProfileCreated(
167       const base::CommandLine& command_line,
168       const base::FilePath& cur_dir,
169       Profile* profile,
170       Profile::CreateStatus status);
171 
172   // Returns true once a profile was activated. Used by the
173   // StartupBrowserCreatorTest.LastUsedProfileActivated test.
174   static bool ActivatedProfile();
175 
176   // Additional tabs to open during first run.
177   std::vector<GURL> first_run_tabs_;
178 
179   // The page to be shown in a tab when welcoming a user back to Chrome.
180   bool welcome_back_page_ = false;
181 
182   // True if we have already read and reset the preference kWasRestarted. (A
183   // member variable instead of a static variable inside WasRestarted because
184   // of testing.)
185   static bool was_restarted_read_;
186 
187   static bool in_synchronous_profile_launch_;
188 };
189 
190 // Returns true if |profile| has exited uncleanly and has not been launched
191 // after the unclean exit.
192 bool HasPendingUncleanExit(Profile* profile);
193 
194 // Returns the path that contains the profile that should be loaded on process
195 // startup.
196 base::FilePath GetStartupProfilePath(const base::FilePath& user_data_dir,
197                                      const base::CommandLine& command_line);
198 
199 #if !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
200 // Returns the profile that should be loaded on process startup. This is either
201 // the profile returned by GetStartupProfilePath, or the guest profile if the
202 // above profile is locked. The guest profile denotes that we should open the
203 // user manager. Returns null if the above profile cannot be opened. In case of
204 // opening the user manager, returns null if either the guest profile or the
205 // system profile cannot be opened.
206 Profile* GetStartupProfile(const base::FilePath& user_data_dir,
207                            const base::CommandLine& command_line);
208 
209 // Returns the profile that should be loaded on process startup when
210 // GetStartupProfile() returns null. As with GetStartupProfile(), returning the
211 // guest profile means the caller should open the user manager. This may return
212 // null if neither any profile nor the user manager can be opened.
213 Profile* GetFallbackStartupProfile();
214 #endif  // !defined(OS_CHROMEOS) && !defined(OS_ANDROID)
215 
216 #endif  // CHROME_BROWSER_UI_STARTUP_STARTUP_BROWSER_CREATOR_H_
217