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 <string>
9#include <vector>
10
11#include "base/basictypes.h"
12#include "base/files/file_path.h"
13#include "base/gtest_prod_util.h"
14#include "chrome/browser/prefs/session_startup_pref.h"
15#include "chrome/browser/profiles/profile.h"
16#include "chrome/browser/ui/startup/startup_tab.h"
17#include "chrome/browser/ui/startup/startup_types.h"
18#include "url/gurl.h"
19
20class Browser;
21class GURL;
22class PrefService;
23
24namespace base {
25class CommandLine;
26}
27
28// class containing helpers for BrowserMain to spin up a new instance and
29// initialize the profile.
30class StartupBrowserCreator {
31 public:
32  typedef std::vector<Profile*> Profiles;
33
34  StartupBrowserCreator();
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  // This function is equivalent to ProcessCommandLine but should only be
42  // called during actual process startup.
43  bool Start(const base::CommandLine& cmd_line,
44             const base::FilePath& cur_dir,
45             Profile* last_used_profile,
46             const Profiles& last_opened_profiles,
47             int* return_code) {
48    return ProcessCmdLineImpl(cmd_line, cur_dir, true, last_used_profile,
49                              last_opened_profiles, return_code, this);
50  }
51
52  // This function performs command-line handling and is invoked only after
53  // start up (for example when we get a start request for another process).
54  // |command_line| holds the command line we need to process.
55  // |cur_dir| is the current working directory that the original process was
56  // invoked from.
57  // |startup_profile_dir| is the directory that contains the profile that the
58  // command line arguments will be executed under.
59  static void ProcessCommandLineAlreadyRunning(
60      const base::CommandLine& command_line,
61      const base::FilePath& cur_dir,
62      const base::FilePath& startup_profile_dir);
63
64  // Returns true if we're launching a profile synchronously. In that case, the
65  // opened window should not cause a session restore.
66  static bool InSynchronousProfileLaunch();
67
68  // Launches a browser window associated with |profile|. |command_line| should
69  // be the command line passed to this process. |cur_dir| can be empty, which
70  // implies that the directory of the executable should be used.
71  // |process_startup| indicates whether this is the first browser.
72  // |is_first_run| indicates that this is a new profile.
73  bool LaunchBrowser(const base::CommandLine& command_line,
74                     Profile* profile,
75                     const base::FilePath& cur_dir,
76                     chrome::startup::IsProcessStartup is_process_startup,
77                     chrome::startup::IsFirstRun is_first_run,
78                     int* return_code);
79
80  // When called the first time, reads the value of the preference kWasRestarted
81  // and resets it to false. Subsequent calls return the value which was read
82  // the first time.
83  static bool WasRestarted();
84
85  static SessionStartupPref GetSessionStartupPref(
86      const base::CommandLine& command_line,
87      Profile* profile);
88
89  void set_is_default_browser_dialog_suppressed(bool new_value) {
90    is_default_browser_dialog_suppressed_ = new_value;
91  }
92
93  bool is_default_browser_dialog_suppressed() const {
94    return is_default_browser_dialog_suppressed_;
95  }
96
97  void set_show_main_browser_window(bool show_main_browser_window) {
98    show_main_browser_window_ = show_main_browser_window;
99  }
100
101  bool show_main_browser_window() const {
102    return show_main_browser_window_;
103  }
104
105  // For faking that no profiles have been launched yet.
106  static void ClearLaunchedProfilesForTesting();
107
108 private:
109  friend class CloudPrintProxyPolicyTest;
110  friend class CloudPrintProxyPolicyStartupTest;
111  friend class StartupBrowserCreatorImpl;
112  FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest,
113                           ReadingWasRestartedAfterNormalStart);
114  FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest,
115                           ReadingWasRestartedAfterRestart);
116  FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest, UpdateWithTwoProfiles);
117  FRIEND_TEST_ALL_PREFIXES(StartupBrowserCreatorTest, LastUsedProfileActivated);
118
119  // Returns the list of URLs to open from the command line. The returned
120  // vector is empty if the user didn't specify any URLs on the command line.
121  static std::vector<GURL> GetURLsFromCommandLine(
122      const base::CommandLine& command_line,
123      const base::FilePath& cur_dir,
124      Profile* profile);
125
126  static bool ProcessCmdLineImpl(const base::CommandLine& command_line,
127                                 const base::FilePath& cur_dir,
128                                 bool process_startup,
129                                 Profile* last_used_profile,
130                                 const Profiles& last_opened_profiles,
131                                 int* return_code,
132                                 StartupBrowserCreator* browser_creator);
133
134  // Callback after a profile has been created.
135  static void ProcessCommandLineOnProfileCreated(
136      const base::CommandLine& command_line,
137      const base::FilePath& cur_dir,
138      Profile* profile,
139      Profile::CreateStatus status);
140
141  // Returns true once a profile was activated. Used by the
142  // StartupBrowserCreatorTest.LastUsedProfileActivated test.
143  static bool ActivatedProfile();
144
145  // Additional tabs to open during first run.
146  std::vector<GURL> first_run_tabs_;
147
148  // True if the set-as-default dialog has been explicitly suppressed.
149  // This information is used to allow the default browser prompt to show on
150  // first-run when the dialog has been suppressed.
151  bool is_default_browser_dialog_suppressed_;
152
153  // Whether the browser window should be shown immediately after it has been
154  // created. Default is true.
155  bool show_main_browser_window_;
156
157  // True if we have already read and reset the preference kWasRestarted. (A
158  // member variable instead of a static variable inside WasRestarted because
159  // of testing.)
160  static bool was_restarted_read_;
161
162  static bool in_synchronous_profile_launch_;
163
164  DISALLOW_COPY_AND_ASSIGN(StartupBrowserCreator);
165};
166
167// Returns true if |profile| has exited uncleanly and has not been launched
168// after the unclean exit.
169bool HasPendingUncleanExit(Profile* profile);
170
171// Returns the path that contains the profile that should be loaded on process
172// startup.
173base::FilePath GetStartupProfilePath(const base::FilePath& user_data_dir,
174                                     const base::CommandLine& command_line);
175
176#endif  // CHROME_BROWSER_UI_STARTUP_STARTUP_BROWSER_CREATOR_H_
177