OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/startup/startup_browser_creator.h" | 5 #include "chrome/browser/ui/startup/startup_browser_creator.h" |
6 | 6 |
7 #include <algorithm> // For max(). | 7 #include <algorithm> // For max(). |
8 #include <set> | 8 #include <set> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/bind_helpers.h" | 11 #include "base/bind_helpers.h" |
| 12 #include "base/command_line.h" |
12 #include "base/compiler_specific.h" | 13 #include "base/compiler_specific.h" |
13 #include "base/environment.h" | 14 #include "base/environment.h" |
14 #include "base/event_recorder.h" | |
15 #include "base/file_path.h" | 15 #include "base/file_path.h" |
16 #include "base/lazy_instance.h" | 16 #include "base/lazy_instance.h" |
17 #include "base/memory/scoped_ptr.h" | 17 #include "base/memory/scoped_ptr.h" |
18 #include "base/metrics/histogram.h" | 18 #include "base/metrics/histogram.h" |
19 #include "base/path_service.h" | 19 #include "base/path_service.h" |
20 #include "base/string_number_conversions.h" | 20 #include "base/string_number_conversions.h" |
21 #include "base/string_split.h" | 21 #include "base/string_split.h" |
22 #include "base/threading/thread_restrictions.h" | 22 #include "base/threading/thread_restrictions.h" |
23 #include "base/utf_string_conversions.h" | 23 #include "base/utf_string_conversions.h" |
24 #include "chrome/browser/auto_launch_trial.h" | 24 #include "chrome/browser/auto_launch_trial.h" |
25 #include "chrome/browser/automation/automation_provider.h" | 25 #include "chrome/browser/automation/automation_provider.h" |
26 #include "chrome/browser/automation/automation_provider_list.h" | 26 #include "chrome/browser/automation/automation_provider_list.h" |
27 #include "chrome/browser/automation/chrome_frame_automation_provider.h" | 27 #include "chrome/browser/automation/chrome_frame_automation_provider.h" |
28 #include "chrome/browser/automation/testing_automation_provider.h" | 28 #include "chrome/browser/automation/testing_automation_provider.h" |
29 #include "chrome/browser/browser_process.h" | 29 #include "chrome/browser/browser_process.h" |
30 #include "chrome/browser/component_updater/component_updater_service.h" | 30 #include "chrome/browser/component_updater/component_updater_service.h" |
31 #include "chrome/browser/component_updater/flash_component_installer.h" | 31 #include "chrome/browser/component_updater/flash_component_installer.h" |
32 #include "chrome/browser/component_updater/pnacl/pnacl_component_installer.h" | 32 #include "chrome/browser/component_updater/pnacl/pnacl_component_installer.h" |
33 #include "chrome/browser/component_updater/recovery_component_installer.h" | 33 #include "chrome/browser/component_updater/recovery_component_installer.h" |
34 #include "chrome/browser/component_updater/swiftshader_component_installer.h" | 34 #include "chrome/browser/component_updater/swiftshader_component_installer.h" |
35 #include "chrome/browser/custom_handlers/protocol_handler_registry.h" | 35 #include "chrome/browser/custom_handlers/protocol_handler_registry.h" |
36 #include "chrome/browser/defaults.h" | |
37 #include "chrome/browser/extensions/extension_creator.h" | |
38 #include "chrome/browser/extensions/extension_service.h" | |
39 #include "chrome/browser/extensions/pack_extension_job.h" | |
40 #include "chrome/browser/first_run/first_run.h" | 36 #include "chrome/browser/first_run/first_run.h" |
41 #include "chrome/browser/google/google_util.h" | 37 #include "chrome/browser/google/google_util.h" |
42 #include "chrome/browser/infobars/infobar_tab_helper.h" | |
43 #include "chrome/browser/net/crl_set_fetcher.h" | 38 #include "chrome/browser/net/crl_set_fetcher.h" |
44 #include "chrome/browser/net/predictor.h" | |
45 #include "chrome/browser/net/url_fixer_upper.h" | 39 #include "chrome/browser/net/url_fixer_upper.h" |
46 #include "chrome/browser/notifications/desktop_notification_service.h" | 40 #include "chrome/browser/notifications/desktop_notification_service.h" |
47 #include "chrome/browser/prefs/incognito_mode_prefs.h" | 41 #include "chrome/browser/prefs/incognito_mode_prefs.h" |
48 #include "chrome/browser/prefs/pref_service.h" | 42 #include "chrome/browser/prefs/pref_service.h" |
49 #include "chrome/browser/prefs/session_startup_pref.h" | 43 #include "chrome/browser/prefs/session_startup_pref.h" |
50 #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service.h" | 44 #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service.h" |
51 #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service_factory.
h" | 45 #include "chrome/browser/printing/cloud_print/cloud_print_proxy_service_factory.
h" |
52 #include "chrome/browser/printing/print_dialog_cloud.h" | 46 #include "chrome/browser/printing/print_dialog_cloud.h" |
53 #include "chrome/browser/profiles/profile.h" | 47 #include "chrome/browser/profiles/profile.h" |
54 #include "chrome/browser/profiles/profile_io_data.h" | |
55 #include "chrome/browser/profiles/profile_manager.h" | 48 #include "chrome/browser/profiles/profile_manager.h" |
56 #include "chrome/browser/protector/base_setting_change.h" | |
57 #include "chrome/browser/protector/protected_prefs_watcher.h" | |
58 #include "chrome/browser/protector/protector_service.h" | |
59 #include "chrome/browser/protector/protector_service_factory.h" | |
60 #include "chrome/browser/protector/protector_utils.h" | |
61 #include "chrome/browser/search_engines/template_url.h" | 49 #include "chrome/browser/search_engines/template_url.h" |
62 #include "chrome/browser/search_engines/template_url_service.h" | 50 #include "chrome/browser/search_engines/template_url_service.h" |
63 #include "chrome/browser/search_engines/template_url_service_factory.h" | 51 #include "chrome/browser/search_engines/template_url_service_factory.h" |
64 #include "chrome/browser/sessions/session_restore.h" | 52 #include "chrome/browser/ui/startup/startup_browser_creator_impl.h" |
65 #include "chrome/browser/sessions/session_service.h" | |
66 #include "chrome/browser/sessions/session_service_factory.h" | |
67 #include "chrome/browser/shell_integration.h" | |
68 #include "chrome/browser/tab_contents/link_infobar_delegate.h" | |
69 #include "chrome/browser/tabs/pinned_tab_codec.h" | |
70 #include "chrome/browser/tabs/tab_strip_model.h" | |
71 #include "chrome/browser/ui/browser_list.h" | |
72 #include "chrome/browser/ui/browser_navigator.h" | |
73 #include "chrome/browser/ui/browser_window.h" | |
74 #include "chrome/browser/ui/startup/autolaunch_prompt.h" | |
75 #include "chrome/browser/ui/startup/bad_flags_prompt.h" | |
76 #include "chrome/browser/ui/startup/default_browser_prompt.h" | |
77 #include "chrome/browser/ui/startup/obsolete_os_prompt.h" | |
78 #include "chrome/browser/ui/startup/session_crashed_prompt.h" | |
79 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" | |
80 #include "chrome/browser/ui/webui/ntp/app_launcher_handler.h" | |
81 #include "chrome/browser/ui/webui/sync_promo/sync_promo_trial.h" | |
82 #include "chrome/browser/ui/webui/sync_promo/sync_promo_ui.h" | |
83 #include "chrome/common/chrome_constants.h" | 53 #include "chrome/common/chrome_constants.h" |
84 #include "chrome/common/chrome_notification_types.h" | 54 #include "chrome/common/chrome_notification_types.h" |
85 #include "chrome/common/chrome_paths.h" | 55 #include "chrome/common/chrome_paths.h" |
86 #include "chrome/common/chrome_result_codes.h" | 56 #include "chrome/common/chrome_result_codes.h" |
87 #include "chrome/common/chrome_switches.h" | 57 #include "chrome/common/chrome_switches.h" |
88 #include "chrome/common/chrome_version_info.h" | 58 #include "chrome/common/chrome_version_info.h" |
89 #include "chrome/common/extensions/extension_constants.h" | |
90 #include "chrome/common/pref_names.h" | 59 #include "chrome/common/pref_names.h" |
91 #include "chrome/common/url_constants.h" | 60 #include "chrome/common/url_constants.h" |
92 #include "chrome/installer/util/browser_distribution.h" | 61 #include "chrome/installer/util/browser_distribution.h" |
93 #include "content/public/browser/browser_thread.h" | 62 #include "content/public/browser/browser_thread.h" |
94 #include "content/public/browser/child_process_security_policy.h" | 63 #include "content/public/browser/child_process_security_policy.h" |
95 #include "content/public/browser/web_contents.h" | |
96 #include "content/public/browser/web_contents_view.h" | |
97 #include "grit/locale_settings.h" | 64 #include "grit/locale_settings.h" |
98 #include "net/base/net_util.h" | 65 #include "net/base/net_util.h" |
99 #include "ui/base/l10n/l10n_util.h" | 66 #include "ui/base/l10n/l10n_util.h" |
100 #include "ui/base/resource/resource_bundle.h" | 67 #include "ui/base/resource/resource_bundle.h" |
101 | 68 |
102 #if defined(OS_CHROMEOS) | 69 #if defined(OS_CHROMEOS) |
103 #include "chrome/browser/chromeos/profile_startup.h" | 70 #include "chrome/browser/chromeos/profile_startup.h" |
104 #endif | 71 #endif |
105 | 72 |
106 #if defined(OS_MACOSX) | |
107 #include "base/mac/mac_util.h" | |
108 #include "chrome/browser/ui/cocoa/keystone_infobar_delegate.h" | |
109 #endif | |
110 | |
111 #if defined(TOOLKIT_GTK) | |
112 #include "chrome/browser/ui/gtk/gtk_util.h" | |
113 #endif | |
114 | |
115 #if defined(TOOLKIT_VIEWS) && defined(OS_LINUX) | 73 #if defined(TOOLKIT_VIEWS) && defined(OS_LINUX) |
116 #include "ui/base/touch/touch_factory.h" | 74 #include "ui/base/touch/touch_factory.h" |
117 #endif | 75 #endif |
118 | 76 |
119 #if defined(OS_WIN) | 77 #if defined(OS_WIN) |
120 #include "base/win/windows_version.h" | |
121 #include "chrome/browser/ui/startup/startup_browser_creator_win.h" | 78 #include "chrome/browser/ui/startup/startup_browser_creator_win.h" |
122 #endif | 79 #endif |
123 | 80 |
124 using content::BrowserThread; | 81 using content::BrowserThread; |
125 using content::ChildProcessSecurityPolicy; | 82 using content::ChildProcessSecurityPolicy; |
126 using content::WebContents; | |
127 using protector::BaseSettingChange; | |
128 using protector::ProtectedPrefsWatcher; | |
129 using protector::ProtectorService; | |
130 using protector::ProtectorServiceFactory; | |
131 | |
132 namespace { | |
133 | 83 |
134 bool in_synchronous_profile_launch = false; | 84 bool in_synchronous_profile_launch = false; |
135 | 85 |
136 // Utility functions ---------------------------------------------------------- | 86 namespace { |
137 | |
138 enum LaunchMode { | |
139 LM_TO_BE_DECIDED = 0, // Possibly direct launch or via a shortcut. | |
140 LM_AS_WEBAPP, // Launched as a installed web application. | |
141 LM_WITH_URLS, // Launched with urls in the cmd line. | |
142 LM_SHORTCUT_NONE, // Not launched from a shortcut. | |
143 LM_SHORTCUT_NONAME, // Launched from shortcut but no name available. | |
144 LM_SHORTCUT_UNKNOWN, // Launched from user-defined shortcut. | |
145 LM_SHORTCUT_QUICKLAUNCH, // Launched from the quick launch bar. | |
146 LM_SHORTCUT_DESKTOP, // Launched from a desktop shortcut. | |
147 LM_SHORTCUT_TASKBAR, // Launched from the taskbar. | |
148 LM_LINUX_MAC_BEOS // Other OS buckets start here. | |
149 }; | |
150 | |
151 #if defined(OS_WIN) | |
152 // Undocumented flag in the startup info structure tells us what shortcut was | |
153 // used to launch the browser. See http://www.catch22.net/tuts/undoc01 for | |
154 // more information. Confirmed to work on XP, Vista and Win7. | |
155 LaunchMode GetLaunchShortcutKind() { | |
156 STARTUPINFOW si = { sizeof(si) }; | |
157 GetStartupInfoW(&si); | |
158 if (si.dwFlags & 0x800) { | |
159 if (!si.lpTitle) | |
160 return LM_SHORTCUT_NONAME; | |
161 string16 shortcut(si.lpTitle); | |
162 // The windows quick launch path is not localized. | |
163 if (shortcut.find(L"\\Quick Launch\\") != string16::npos) { | |
164 if (base::win::GetVersion() >= base::win::VERSION_WIN7) | |
165 return LM_SHORTCUT_TASKBAR; | |
166 else | |
167 return LM_SHORTCUT_QUICKLAUNCH; | |
168 } | |
169 scoped_ptr<base::Environment> env(base::Environment::Create()); | |
170 std::string appdata_path; | |
171 env->GetVar("USERPROFILE", &appdata_path); | |
172 if (!appdata_path.empty() && | |
173 shortcut.find(ASCIIToWide(appdata_path)) != std::wstring::npos) | |
174 return LM_SHORTCUT_DESKTOP; | |
175 return LM_SHORTCUT_UNKNOWN; | |
176 } | |
177 return LM_SHORTCUT_NONE; | |
178 } | |
179 #else | |
180 // TODO(cpu): Port to other platforms. | |
181 LaunchMode GetLaunchShortcutKind() { | |
182 return LM_LINUX_MAC_BEOS; | |
183 } | |
184 #endif | |
185 | |
186 // Log in a histogram the frequency of launching by the different methods. See | |
187 // LaunchMode enum for the actual values of the buckets. | |
188 void RecordLaunchModeHistogram(LaunchMode mode) { | |
189 int bucket = (mode == LM_TO_BE_DECIDED) ? GetLaunchShortcutKind() : mode; | |
190 UMA_HISTOGRAM_COUNTS_100("Launch.Modes", bucket); | |
191 } | |
192 | |
193 GURL GetWelcomePageURL() { | |
194 std::string welcome_url = l10n_util::GetStringUTF8(IDS_WELCOME_PAGE_URL); | |
195 return GURL(welcome_url); | |
196 } | |
197 | |
198 void UrlsToTabs( | |
199 const std::vector<GURL>& urls, | |
200 std::vector<StartupBrowserCreator::LaunchWithProfile::Tab>* tabs) { | |
201 for (size_t i = 0; i < urls.size(); ++i) { | |
202 StartupBrowserCreator::LaunchWithProfile::Tab tab; | |
203 tab.is_pinned = false; | |
204 tab.url = urls[i]; | |
205 tabs->push_back(tab); | |
206 } | |
207 } | |
208 | |
209 // Return true if the command line option --app-id is used. Set | |
210 // |out_extension| to the app to open, and |out_launch_container| | |
211 // to the type of window into which the app should be open. | |
212 bool GetAppLaunchContainer( | |
213 Profile* profile, | |
214 const std::string& app_id, | |
215 const Extension** out_extension, | |
216 extension_misc::LaunchContainer* out_launch_container) { | |
217 | |
218 ExtensionService* extensions_service = profile->GetExtensionService(); | |
219 const Extension* extension = | |
220 extensions_service->GetExtensionById(app_id, false); | |
221 | |
222 // The extension with id |app_id| may have been uninstalled. | |
223 if (!extension) | |
224 return false; | |
225 | |
226 // Look at preferences to find the right launch container. If no | |
227 // preference is set, launch as a window. | |
228 extension_misc::LaunchContainer launch_container = | |
229 extensions_service->extension_prefs()->GetLaunchContainer( | |
230 extension, ExtensionPrefs::LAUNCH_WINDOW); | |
231 | |
232 *out_extension = extension; | |
233 *out_launch_container = launch_container; | |
234 return true; | |
235 } | |
236 | |
237 void RecordCmdLineAppHistogram() { | |
238 AppLauncherHandler::RecordAppLaunchType( | |
239 extension_misc::APP_LAUNCH_CMD_LINE_APP); | |
240 } | |
241 | |
242 void RecordAppLaunches( | |
243 Profile* profile, | |
244 const std::vector<GURL>& cmd_line_urls, | |
245 const std::vector<StartupBrowserCreator::LaunchWithProfile::Tab>& | |
246 autolaunch_tabs) { | |
247 ExtensionService* extension_service = profile->GetExtensionService(); | |
248 DCHECK(extension_service); | |
249 for (size_t i = 0; i < cmd_line_urls.size(); ++i) { | |
250 if (extension_service->IsInstalledApp(cmd_line_urls.at(i))) { | |
251 AppLauncherHandler::RecordAppLaunchType( | |
252 extension_misc::APP_LAUNCH_CMD_LINE_URL); | |
253 } | |
254 } | |
255 for (size_t i = 0; i < autolaunch_tabs.size(); ++i) { | |
256 if (extension_service->IsInstalledApp(autolaunch_tabs.at(i).url)) { | |
257 AppLauncherHandler::RecordAppLaunchType( | |
258 extension_misc::APP_LAUNCH_AUTOLAUNCH); | |
259 } | |
260 } | |
261 } | |
262 | 87 |
263 void RegisterComponentsForUpdate(const CommandLine& command_line) { | 88 void RegisterComponentsForUpdate(const CommandLine& command_line) { |
264 ComponentUpdateService* cus = g_browser_process->component_updater(); | 89 ComponentUpdateService* cus = g_browser_process->component_updater(); |
265 if (!cus) | 90 if (!cus) |
266 return; | 91 return; |
267 // Registration can be before of after cus->Start() so it is ok to post | 92 // Registration can be before of after cus->Start() so it is ok to post |
268 // a task to the UI thread to do registration once you done the necessary | 93 // a task to the UI thread to do registration once you done the necessary |
269 // file IO to know you existing component version. | 94 // file IO to know you existing component version. |
270 RegisterRecoveryComponent(cus, g_browser_process->local_state()); | 95 RegisterRecoveryComponent(cus, g_browser_process->local_state()); |
271 RegisterPepperFlashComponent(cus); | 96 RegisterPepperFlashComponent(cus); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 private: | 144 private: |
320 std::set<const Profile*> launched_profiles; | 145 std::set<const Profile*> launched_profiles; |
321 content::NotificationRegistrar registrar_; | 146 content::NotificationRegistrar registrar_; |
322 | 147 |
323 DISALLOW_COPY_AND_ASSIGN(ProfileLaunchObserver); | 148 DISALLOW_COPY_AND_ASSIGN(ProfileLaunchObserver); |
324 }; | 149 }; |
325 | 150 |
326 base::LazyInstance<ProfileLaunchObserver> profile_launch_observer = | 151 base::LazyInstance<ProfileLaunchObserver> profile_launch_observer = |
327 LAZY_INSTANCE_INITIALIZER; | 152 LAZY_INSTANCE_INITIALIZER; |
328 | 153 |
329 // Returns true if |profile| has exited uncleanly and has not been launched | |
330 // after the unclean exit. | |
331 bool HasPendingUncleanExit(Profile* profile) { | |
332 return !profile->DidLastSessionExitCleanly() && | |
333 !profile_launch_observer.Get().HasBeenLaunched(profile); | |
334 } | |
335 | |
336 } // namespace | 154 } // namespace |
337 | 155 |
338 StartupBrowserCreator::StartupBrowserCreator() {} | 156 StartupBrowserCreator::StartupBrowserCreator() {} |
339 | 157 |
340 StartupBrowserCreator::~StartupBrowserCreator() {} | 158 StartupBrowserCreator::~StartupBrowserCreator() {} |
341 | 159 |
342 // static | 160 // static |
343 bool StartupBrowserCreator::was_restarted_read_ = false; | 161 bool StartupBrowserCreator::was_restarted_read_ = false; |
344 | 162 |
345 void StartupBrowserCreator::AddFirstRunTab(const GURL& url) { | 163 void StartupBrowserCreator::AddFirstRunTab(const GURL& url) { |
346 first_run_tabs_.push_back(url); | 164 first_run_tabs_.push_back(url); |
347 } | 165 } |
348 | 166 |
349 // static | 167 // static |
350 bool StartupBrowserCreator::InSynchronousProfileLaunch() { | 168 bool StartupBrowserCreator::InSynchronousProfileLaunch() { |
351 return in_synchronous_profile_launch; | 169 return in_synchronous_profile_launch; |
352 } | 170 } |
353 | 171 |
354 bool StartupBrowserCreator::LaunchBrowser(const CommandLine& command_line, | 172 bool StartupBrowserCreator::LaunchBrowser( |
355 Profile* profile, | 173 const CommandLine& command_line, |
356 const FilePath& cur_dir, | 174 Profile* profile, |
357 IsProcessStartup process_startup, | 175 const FilePath& cur_dir, |
358 IsFirstRun is_first_run, | 176 browser::startup::IsProcessStartup process_startup, |
359 int* return_code) { | 177 browser::startup::IsFirstRun is_first_run, |
360 in_synchronous_profile_launch = process_startup == IS_PROCESS_STARTUP; | 178 int* return_code) { |
| 179 in_synchronous_profile_launch = |
| 180 process_startup == browser::startup::IS_PROCESS_STARTUP; |
361 DCHECK(profile); | 181 DCHECK(profile); |
362 | 182 |
363 // Continue with the incognito profile from here on if Incognito mode | 183 // Continue with the incognito profile from here on if Incognito mode |
364 // is forced. | 184 // is forced. |
365 if (IncognitoModePrefs::ShouldLaunchIncognito(command_line, | 185 if (IncognitoModePrefs::ShouldLaunchIncognito(command_line, |
366 profile->GetPrefs())) { | 186 profile->GetPrefs())) { |
367 profile = profile->GetOffTheRecordProfile(); | 187 profile = profile->GetOffTheRecordProfile(); |
368 } else if (command_line.HasSwitch(switches::kIncognito)) { | 188 } else if (command_line.HasSwitch(switches::kIncognito)) { |
369 LOG(WARNING) << "Incognito mode disabled by policy, launching a normal " | 189 LOG(WARNING) << "Incognito mode disabled by policy, launching a normal " |
370 << "browser session."; | 190 << "browser session."; |
371 } | 191 } |
372 | 192 |
373 StartupBrowserCreator::LaunchWithProfile lwp(cur_dir, command_line, this, | 193 StartupBrowserCreatorImpl lwp(cur_dir, command_line, this, is_first_run); |
374 is_first_run); | |
375 std::vector<GURL> urls_to_launch = | 194 std::vector<GURL> urls_to_launch = |
376 StartupBrowserCreator::GetURLsFromCommandLine(command_line, cur_dir, | 195 StartupBrowserCreator::GetURLsFromCommandLine(command_line, cur_dir, |
377 profile); | 196 profile); |
378 bool launched = lwp.Launch(profile, urls_to_launch, | 197 bool launched = lwp.Launch(profile, urls_to_launch, |
379 in_synchronous_profile_launch); | 198 in_synchronous_profile_launch); |
380 in_synchronous_profile_launch = false; | 199 in_synchronous_profile_launch = false; |
381 | 200 |
382 if (!launched) { | 201 if (!launched) { |
383 LOG(ERROR) << "launch error"; | 202 LOG(ERROR) << "launch error"; |
384 if (return_code) | 203 if (return_code) |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 IncognitoModePrefs::ShouldLaunchIncognito(command_line, | 244 IncognitoModePrefs::ShouldLaunchIncognito(command_line, |
426 profile->GetPrefs())) { | 245 profile->GetPrefs())) { |
427 // We don't store session information when incognito. If the user has | 246 // We don't store session information when incognito. If the user has |
428 // chosen to restore last session and launched incognito, fallback to | 247 // chosen to restore last session and launched incognito, fallback to |
429 // default launch behavior. | 248 // default launch behavior. |
430 pref.type = SessionStartupPref::DEFAULT; | 249 pref.type = SessionStartupPref::DEFAULT; |
431 } | 250 } |
432 return pref; | 251 return pref; |
433 } | 252 } |
434 | 253 |
435 | |
436 // StartupBrowserCreator::LaunchWithProfile::Tab ------------------------------- | |
437 | |
438 StartupBrowserCreator::LaunchWithProfile::Tab::Tab() | |
439 : is_app(false), | |
440 is_pinned(true) { | |
441 } | |
442 | |
443 StartupBrowserCreator::LaunchWithProfile::Tab::~Tab() { | |
444 } | |
445 | |
446 // StartupBrowserCreator::LaunchWithProfile ------------------------------------ | |
447 | |
448 StartupBrowserCreator::LaunchWithProfile::LaunchWithProfile( | |
449 const FilePath& cur_dir, | |
450 const CommandLine& command_line, | |
451 IsFirstRun is_first_run) | |
452 : cur_dir_(cur_dir), | |
453 command_line_(command_line), | |
454 profile_(NULL), | |
455 browser_creator_(NULL), | |
456 is_first_run_(is_first_run == IS_FIRST_RUN) { | |
457 } | |
458 | |
459 StartupBrowserCreator::LaunchWithProfile::LaunchWithProfile( | |
460 const FilePath& cur_dir, | |
461 const CommandLine& command_line, | |
462 StartupBrowserCreator* browser_creator, | |
463 IsFirstRun is_first_run) | |
464 : cur_dir_(cur_dir), | |
465 command_line_(command_line), | |
466 profile_(NULL), | |
467 browser_creator_(browser_creator), | |
468 is_first_run_(is_first_run == IS_FIRST_RUN) { | |
469 } | |
470 | |
471 StartupBrowserCreator::LaunchWithProfile::~LaunchWithProfile() { | |
472 } | |
473 | |
474 bool StartupBrowserCreator::LaunchWithProfile::Launch( | |
475 Profile* profile, | |
476 const std::vector<GURL>& urls_to_open, | |
477 bool process_startup) { | |
478 DCHECK(profile); | |
479 profile_ = profile; | |
480 | |
481 if (command_line_.HasSwitch(switches::kDnsLogDetails)) | |
482 chrome_browser_net::EnablePredictorDetailedLog(true); | |
483 if (command_line_.HasSwitch(switches::kDnsPrefetchDisable) && | |
484 profile->GetNetworkPredictor()) { | |
485 profile->GetNetworkPredictor()->EnablePredictor(false); | |
486 } | |
487 | |
488 if (command_line_.HasSwitch(switches::kDumpHistogramsOnExit)) | |
489 base::StatisticsRecorder::set_dump_on_exit(true); | |
490 | |
491 if (command_line_.HasSwitch(switches::kRemoteDebuggingPort)) { | |
492 std::string port_str = | |
493 command_line_.GetSwitchValueASCII(switches::kRemoteDebuggingPort); | |
494 int64 port; | |
495 if (base::StringToInt64(port_str, &port) && port > 0 && port < 65535) { | |
496 std::string frontend_str; | |
497 if (command_line_.HasSwitch(switches::kRemoteDebuggingFrontend)) { | |
498 frontend_str = command_line_.GetSwitchValueASCII( | |
499 switches::kRemoteDebuggingFrontend); | |
500 } | |
501 g_browser_process->InitDevToolsHttpProtocolHandler( | |
502 profile, | |
503 "127.0.0.1", | |
504 static_cast<int>(port), | |
505 frontend_str); | |
506 } else { | |
507 DLOG(WARNING) << "Invalid http debugger port number " << port; | |
508 } | |
509 } | |
510 | |
511 // Open the required browser windows and tabs. First, see if | |
512 // we're being run as an application window. If so, the user | |
513 // opened an app shortcut. Don't restore tabs or open initial | |
514 // URLs in that case. The user should see the window as an app, | |
515 // not as chrome. | |
516 // Special case is when app switches are passed but we do want to restore | |
517 // session. In that case open app window + focus it after session is restored. | |
518 if (OpenApplicationWindow(profile) && !browser_defaults::kAppRestoreSession) { | |
519 RecordLaunchModeHistogram(LM_AS_WEBAPP); | |
520 } else { | |
521 Browser* browser_to_focus = NULL; | |
522 // In case of app mode + session restore we want to focus that app. | |
523 if (browser_defaults::kAppRestoreSession) | |
524 browser_to_focus = BrowserList::GetLastActive(); | |
525 | |
526 RecordLaunchModeHistogram(urls_to_open.empty()? | |
527 LM_TO_BE_DECIDED : LM_WITH_URLS); | |
528 | |
529 // Notify user if the Preferences backup is invalid or changes to settings | |
530 // affecting browser startup have been detected. | |
531 CheckPreferencesBackup(profile); | |
532 | |
533 ProcessLaunchURLs(process_startup, urls_to_open); | |
534 | |
535 // If this is an app launch, but we didn't open an app window, it may | |
536 // be an app tab. | |
537 OpenApplicationTab(profile); | |
538 | |
539 if (browser_to_focus) | |
540 browser_to_focus->GetSelectedWebContents()->GetView()->SetInitialFocus(); | |
541 | |
542 if (process_startup) { | |
543 if (browser_defaults::kOSSupportsOtherBrowsers && | |
544 !command_line_.HasSwitch(switches::kNoDefaultBrowserCheck)) { | |
545 if (!browser::ShowAutolaunchPrompt(profile)) | |
546 browser::ShowDefaultBrowserPrompt(profile); | |
547 } | |
548 #if defined(OS_MACOSX) | |
549 // Check whether the auto-update system needs to be promoted from user | |
550 // to system. | |
551 KeystoneInfoBar::PromotionInfoBar(profile); | |
552 #endif | |
553 } | |
554 } | |
555 | |
556 #if defined(OS_WIN) | |
557 // Print the selected page if the command line switch exists. Note that the | |
558 // current selected tab would be the page which will be printed. | |
559 if (command_line_.HasSwitch(switches::kPrint)) { | |
560 Browser* browser = BrowserList::GetLastActive(); | |
561 browser->Print(); | |
562 } | |
563 #endif | |
564 | |
565 // If we're recording or playing back, startup the EventRecorder now | |
566 // unless otherwise specified. | |
567 if (!command_line_.HasSwitch(switches::kNoEvents)) { | |
568 FilePath script_path; | |
569 PathService::Get(chrome::FILE_RECORDED_SCRIPT, &script_path); | |
570 | |
571 bool record_mode = command_line_.HasSwitch(switches::kRecordMode); | |
572 bool playback_mode = command_line_.HasSwitch(switches::kPlaybackMode); | |
573 | |
574 if (record_mode && chrome::kRecordModeEnabled) | |
575 base::EventRecorder::current()->StartRecording(script_path); | |
576 if (playback_mode) | |
577 base::EventRecorder::current()->StartPlayback(script_path); | |
578 } | |
579 | |
580 #if defined(OS_WIN) | |
581 if (process_startup) | |
582 ShellIntegration::MigrateChromiumShortcuts(); | |
583 #endif // defined(OS_WIN) | |
584 | |
585 return true; | |
586 } | |
587 | |
588 bool StartupBrowserCreator::LaunchWithProfile::IsAppLaunch( | |
589 std::string* app_url, | |
590 std::string* app_id) { | |
591 if (command_line_.HasSwitch(switches::kApp)) { | |
592 if (app_url) | |
593 *app_url = command_line_.GetSwitchValueASCII(switches::kApp); | |
594 return true; | |
595 } | |
596 if (command_line_.HasSwitch(switches::kAppId)) { | |
597 if (app_id) | |
598 *app_id = command_line_.GetSwitchValueASCII(switches::kAppId); | |
599 return true; | |
600 } | |
601 return false; | |
602 } | |
603 | |
604 bool StartupBrowserCreator::LaunchWithProfile::OpenApplicationTab( | |
605 Profile* profile) { | |
606 std::string app_id; | |
607 // App shortcuts to URLs always open in an app window. Because this | |
608 // function will open an app that should be in a tab, there is no need | |
609 // to look at the app URL. OpenApplicationWindow() will open app url | |
610 // shortcuts. | |
611 if (!IsAppLaunch(NULL, &app_id) || app_id.empty()) | |
612 return false; | |
613 | |
614 extension_misc::LaunchContainer launch_container; | |
615 const Extension* extension; | |
616 if (!GetAppLaunchContainer(profile, app_id, &extension, &launch_container)) | |
617 return false; | |
618 | |
619 // If the user doesn't want to open a tab, fail. | |
620 if (launch_container != extension_misc::LAUNCH_TAB) | |
621 return false; | |
622 | |
623 RecordCmdLineAppHistogram(); | |
624 | |
625 WebContents* app_tab = Browser::OpenApplicationTab(profile, extension, GURL(), | |
626 NEW_FOREGROUND_TAB); | |
627 return (app_tab != NULL); | |
628 } | |
629 | |
630 bool StartupBrowserCreator::LaunchWithProfile::OpenApplicationWindow( | |
631 Profile* profile) { | |
632 std::string url_string, app_id; | |
633 if (!IsAppLaunch(&url_string, &app_id)) | |
634 return false; | |
635 | |
636 // This can fail if the app_id is invalid. It can also fail if the | |
637 // extension is external, and has not yet been installed. | |
638 // TODO(skerner): Do something reasonable here. Pop up a warning panel? | |
639 // Open an URL to the gallery page of the extension id? | |
640 if (!app_id.empty()) { | |
641 extension_misc::LaunchContainer launch_container; | |
642 const Extension* extension; | |
643 if (!GetAppLaunchContainer(profile, app_id, &extension, &launch_container)) | |
644 return false; | |
645 | |
646 // TODO(skerner): Could pass in |extension| and |launch_container|, | |
647 // and avoid calling GetAppLaunchContainer() both here and in | |
648 // OpenApplicationTab(). | |
649 | |
650 if (launch_container == extension_misc::LAUNCH_TAB) | |
651 return false; | |
652 | |
653 RecordCmdLineAppHistogram(); | |
654 WebContents* tab_in_app_window = Browser::OpenApplication( | |
655 profile, extension, launch_container, GURL(), NEW_WINDOW); | |
656 // Platform apps fire off a launch event which may or may not open a window. | |
657 return (tab_in_app_window != NULL || extension->is_platform_app()); | |
658 } | |
659 | |
660 if (url_string.empty()) | |
661 return false; | |
662 | |
663 #if defined(OS_WIN) // Fix up Windows shortcuts. | |
664 ReplaceSubstringsAfterOffset(&url_string, 0, "\\x", "%"); | |
665 #endif | |
666 GURL url(url_string); | |
667 | |
668 // Restrict allowed URLs for --app switch. | |
669 if (!url.is_empty() && url.is_valid()) { | |
670 ChildProcessSecurityPolicy *policy = | |
671 ChildProcessSecurityPolicy::GetInstance(); | |
672 if (policy->IsWebSafeScheme(url.scheme()) || | |
673 url.SchemeIs(chrome::kFileScheme)) { | |
674 | |
675 if (profile->GetExtensionService()->IsInstalledApp(url)) { | |
676 RecordCmdLineAppHistogram(); | |
677 } else { | |
678 AppLauncherHandler::RecordAppLaunchType( | |
679 extension_misc::APP_LAUNCH_CMD_LINE_APP_LEGACY); | |
680 } | |
681 WebContents* app_tab = Browser::OpenAppShortcutWindow( | |
682 profile, | |
683 url, | |
684 true); // Update app info. | |
685 return (app_tab != NULL); | |
686 } | |
687 } | |
688 return false; | |
689 } | |
690 | |
691 void StartupBrowserCreator::LaunchWithProfile::ProcessLaunchURLs( | |
692 bool process_startup, | |
693 const std::vector<GURL>& urls_to_open) { | |
694 // If we're starting up in "background mode" (no open browser window) then | |
695 // don't open any browser windows, unless kAutoLaunchAtStartup is also | |
696 // specified. | |
697 if (process_startup && | |
698 command_line_.HasSwitch(switches::kNoStartupWindow) && | |
699 !command_line_.HasSwitch(switches::kAutoLaunchAtStartup)) { | |
700 return; | |
701 } | |
702 | |
703 if (process_startup && ProcessStartupURLs(urls_to_open)) { | |
704 // ProcessStartupURLs processed the urls, nothing else to do. | |
705 return; | |
706 } | |
707 | |
708 IsProcessStartup is_process_startup = process_startup ? | |
709 IS_PROCESS_STARTUP : IS_NOT_PROCESS_STARTUP; | |
710 if (!process_startup) { | |
711 // Even if we're not starting a new process, this may conceptually be | |
712 // "startup" for the user and so should be handled in a similar way. Eg., | |
713 // Chrome may have been running in the background due to an app with a | |
714 // background page being installed, or running with only an app window | |
715 // displayed. | |
716 SessionService* service = SessionServiceFactory::GetForProfile(profile_); | |
717 if (service && service->ShouldNewWindowStartSession()) { | |
718 // Restore the last session if any. | |
719 if (!HasPendingUncleanExit(profile_) && | |
720 service->RestoreIfNecessary(urls_to_open)) { | |
721 return; | |
722 } | |
723 // Open user-specified URLs like pinned tabs and startup tabs. | |
724 Browser* browser = ProcessSpecifiedURLs(urls_to_open); | |
725 if (browser) { | |
726 AddInfoBarsIfNecessary(browser, is_process_startup); | |
727 return; | |
728 } | |
729 } | |
730 } | |
731 | |
732 // Session startup didn't occur, open the urls. | |
733 | |
734 Browser* browser = NULL; | |
735 std::vector<GURL> adjust_urls = urls_to_open; | |
736 if (adjust_urls.empty()) | |
737 AddStartupURLs(&adjust_urls); | |
738 else if (!command_line_.HasSwitch(switches::kOpenInNewWindow)) | |
739 browser = BrowserList::GetLastActiveWithProfile(profile_); | |
740 | |
741 // This will launch a browser; prevent session restore. | |
742 in_synchronous_profile_launch = true; | |
743 browser = OpenURLsInBrowser(browser, process_startup, adjust_urls); | |
744 in_synchronous_profile_launch = false; | |
745 AddInfoBarsIfNecessary(browser, is_process_startup); | |
746 } | |
747 | |
748 bool StartupBrowserCreator::LaunchWithProfile::ProcessStartupURLs( | |
749 const std::vector<GURL>& urls_to_open) { | |
750 SessionStartupPref pref = GetSessionStartupPref(command_line_, profile_); | |
751 | |
752 if (pref.type == SessionStartupPref::LAST) { | |
753 if (!profile_->DidLastSessionExitCleanly() && | |
754 !command_line_.HasSwitch(switches::kRestoreLastSession)) { | |
755 // The last session crashed. It's possible automatically loading the | |
756 // page will trigger another crash, locking the user out of chrome. | |
757 // To avoid this, don't restore on startup but instead show the crashed | |
758 // infobar. | |
759 return false; | |
760 } | |
761 | |
762 uint32 restore_behavior = SessionRestore::SYNCHRONOUS | | |
763 SessionRestore::ALWAYS_CREATE_TABBED_BROWSER; | |
764 #if defined(OS_MACOSX) | |
765 // On Mac, when restoring a session with no windows, suppress the creation | |
766 // of a new window in the case where the system is launching Chrome via a | |
767 // login item or Lion's resume feature. | |
768 if (base::mac::WasLaunchedAsLoginOrResumeItem()) { | |
769 restore_behavior = restore_behavior & | |
770 ~SessionRestore::ALWAYS_CREATE_TABBED_BROWSER; | |
771 } | |
772 #endif | |
773 | |
774 Browser* browser = SessionRestore::RestoreSession(profile_, | |
775 NULL, | |
776 restore_behavior, | |
777 urls_to_open); | |
778 AddInfoBarsIfNecessary(browser, IS_PROCESS_STARTUP); | |
779 return true; | |
780 } | |
781 | |
782 Browser* browser = ProcessSpecifiedURLs(urls_to_open); | |
783 if (!browser) | |
784 return false; | |
785 | |
786 AddInfoBarsIfNecessary(browser, IS_PROCESS_STARTUP); | |
787 return true; | |
788 } | |
789 | |
790 Browser* StartupBrowserCreator::LaunchWithProfile::ProcessSpecifiedURLs( | |
791 const std::vector<GURL>& urls_to_open) { | |
792 SessionStartupPref pref = GetSessionStartupPref(command_line_, profile_); | |
793 std::vector<Tab> tabs; | |
794 // Pinned tabs should not be displayed when chrome is launched in incognito | |
795 // mode. Also, no pages should be opened automatically if the session | |
796 // crashed. Otherwise it might trigger another crash, locking the user out of | |
797 // chrome. The crash infobar is shown in this case. | |
798 if (!IncognitoModePrefs::ShouldLaunchIncognito(command_line_, | |
799 profile_->GetPrefs()) && | |
800 !HasPendingUncleanExit(profile_)) { | |
801 tabs = PinnedTabCodec::ReadPinnedTabs(profile_); | |
802 } | |
803 | |
804 RecordAppLaunches(profile_, urls_to_open, tabs); | |
805 | |
806 if (!urls_to_open.empty()) { | |
807 // If urls were specified on the command line, use them. | |
808 UrlsToTabs(urls_to_open, &tabs); | |
809 } else if (pref.type == SessionStartupPref::URLS && !pref.urls.empty() && | |
810 !HasPendingUncleanExit(profile_)) { | |
811 // Only use the set of urls specified in preferences if nothing was | |
812 // specified on the command line. Filter out any urls that are to be | |
813 // restored by virtue of having been previously pinned. | |
814 AddUniqueURLs(pref.urls, &tabs); | |
815 } else if (pref.type == SessionStartupPref::DEFAULT) { | |
816 std::vector<GURL> urls; | |
817 AddStartupURLs(&urls); | |
818 UrlsToTabs(urls, &tabs); | |
819 | |
820 } else if (pref.type == SessionStartupPref::HOMEPAGE) { | |
821 // If 'homepage' selected, either by the user or by a policy, we should | |
822 // have migrated them to another value. | |
823 NOTREACHED() << "SessionStartupPref has deprecated type HOMEPAGE"; | |
824 } | |
825 | |
826 if (tabs.empty()) | |
827 return NULL; | |
828 | |
829 Browser* browser = OpenTabsInBrowser(NULL, true, tabs); | |
830 return browser; | |
831 } | |
832 | |
833 void StartupBrowserCreator::LaunchWithProfile::AddUniqueURLs( | |
834 const std::vector<GURL>& urls, | |
835 std::vector<Tab>* tabs) { | |
836 size_t num_existing_tabs = tabs->size(); | |
837 for (size_t i = 0; i < urls.size(); ++i) { | |
838 bool in_tabs = false; | |
839 for (size_t j = 0; j < num_existing_tabs; ++j) { | |
840 if (urls[i] == (*tabs)[j].url) { | |
841 in_tabs = true; | |
842 break; | |
843 } | |
844 } | |
845 if (!in_tabs) { | |
846 StartupBrowserCreator::LaunchWithProfile::Tab tab; | |
847 tab.is_pinned = false; | |
848 tab.url = urls[i]; | |
849 tabs->push_back(tab); | |
850 } | |
851 } | |
852 } | |
853 | |
854 Browser* StartupBrowserCreator::LaunchWithProfile::OpenURLsInBrowser( | |
855 Browser* browser, | |
856 bool process_startup, | |
857 const std::vector<GURL>& urls) { | |
858 std::vector<Tab> tabs; | |
859 UrlsToTabs(urls, &tabs); | |
860 return OpenTabsInBrowser(browser, process_startup, tabs); | |
861 } | |
862 | |
863 Browser* StartupBrowserCreator::LaunchWithProfile::OpenTabsInBrowser( | |
864 Browser* browser, | |
865 bool process_startup, | |
866 const std::vector<Tab>& tabs) { | |
867 DCHECK(!tabs.empty()); | |
868 | |
869 // If we don't yet have a profile, try to use the one we're given from | |
870 // |browser|. While we may not end up actually using |browser| (since it | |
871 // could be a popup window), we can at least use the profile. | |
872 if (!profile_ && browser) | |
873 profile_ = browser->profile(); | |
874 | |
875 if (!browser || !browser->is_type_tabbed()) { | |
876 browser = Browser::Create(profile_); | |
877 } else { | |
878 #if defined(TOOLKIT_GTK) | |
879 // Setting the time of the last action on the window here allows us to steal | |
880 // focus, which is what the user wants when opening a new tab in an existing | |
881 // browser window. | |
882 gtk_util::SetWMLastUserActionTime(browser->window()->GetNativeHandle()); | |
883 #endif | |
884 } | |
885 | |
886 #if !defined(OS_MACOSX) | |
887 // In kiosk mode, we want to always be fullscreen, so switch to that now. | |
888 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kKioskMode)) | |
889 browser->ToggleFullscreenMode(); | |
890 #endif | |
891 | |
892 bool first_tab = true; | |
893 for (size_t i = 0; i < tabs.size(); ++i) { | |
894 // We skip URLs that we'd have to launch an external protocol handler for. | |
895 // This avoids us getting into an infinite loop asking ourselves to open | |
896 // a URL, should the handler be (incorrectly) configured to be us. Anyone | |
897 // asking us to open such a URL should really ask the handler directly. | |
898 bool handled_by_chrome = ProfileIOData::IsHandledURL(tabs[i].url) || | |
899 (profile_ && profile_->GetProtocolHandlerRegistry()->IsHandledProtocol( | |
900 tabs[i].url.scheme())); | |
901 if (!process_startup && !handled_by_chrome) | |
902 continue; | |
903 | |
904 int add_types = first_tab ? TabStripModel::ADD_ACTIVE : | |
905 TabStripModel::ADD_NONE; | |
906 add_types |= TabStripModel::ADD_FORCE_INDEX; | |
907 if (tabs[i].is_pinned) | |
908 add_types |= TabStripModel::ADD_PINNED; | |
909 int index = browser->GetIndexForInsertionDuringRestore(i); | |
910 | |
911 browser::NavigateParams params(browser, tabs[i].url, | |
912 content::PAGE_TRANSITION_START_PAGE); | |
913 params.disposition = first_tab ? NEW_FOREGROUND_TAB : | |
914 NEW_BACKGROUND_TAB; | |
915 params.tabstrip_index = index; | |
916 params.tabstrip_add_types = add_types; | |
917 params.extension_app_id = tabs[i].app_id; | |
918 browser::Navigate(¶ms); | |
919 | |
920 first_tab = false; | |
921 } | |
922 if (!browser->GetSelectedWebContents()) { | |
923 // TODO: this is a work around for 110909. Figure out why it's needed. | |
924 if (!browser->tab_count()) | |
925 browser->AddBlankTab(true); | |
926 else | |
927 browser->ActivateTabAt(0, false); | |
928 } | |
929 | |
930 browser->window()->Show(); | |
931 // TODO(jcampan): http://crbug.com/8123 we should not need to set the initial | |
932 // focus explicitly. | |
933 browser->GetSelectedWebContents()->GetView()->SetInitialFocus(); | |
934 | |
935 return browser; | |
936 } | |
937 | |
938 void StartupBrowserCreator::LaunchWithProfile::AddInfoBarsIfNecessary( | |
939 Browser* browser, | |
940 IsProcessStartup is_process_startup) { | |
941 if (!browser || !profile_ || browser->tab_count() == 0) | |
942 return; | |
943 | |
944 if (HasPendingUncleanExit(browser->profile())) | |
945 browser::ShowSessionCrashedPrompt(browser); | |
946 | |
947 // The bad flags info bar and the obsolete system info bar are only added to | |
948 // the first profile which is launched. Other profiles might be restoring the | |
949 // browsing sessions asynchronously, so we cannot add the info bars to the | |
950 // focused tabs here. | |
951 if (is_process_startup == IS_PROCESS_STARTUP) { | |
952 browser::ShowBadFlagsPrompt(browser); | |
953 browser::ShowObsoleteOSPrompt(browser); | |
954 } | |
955 } | |
956 | |
957 | |
958 void StartupBrowserCreator::LaunchWithProfile::AddStartupURLs( | |
959 std::vector<GURL>* startup_urls) const { | |
960 // If we have urls specified beforehand (i.e. from command line) use them | |
961 // and nothing else. | |
962 if (!startup_urls->empty()) | |
963 return; | |
964 | |
965 // If we have urls specified by the first run master preferences use them | |
966 // and nothing else. | |
967 if (browser_creator_) { | |
968 if (!browser_creator_->first_run_tabs_.empty()) { | |
969 std::vector<GURL>::iterator it = | |
970 browser_creator_->first_run_tabs_.begin(); | |
971 while (it != browser_creator_->first_run_tabs_.end()) { | |
972 // Replace magic names for the actual urls. | |
973 if (it->host() == "new_tab_page") { | |
974 startup_urls->push_back(GURL(chrome::kChromeUINewTabURL)); | |
975 } else if (it->host() == "welcome_page") { | |
976 startup_urls->push_back(GetWelcomePageURL()); | |
977 } else { | |
978 startup_urls->push_back(*it); | |
979 } | |
980 ++it; | |
981 } | |
982 browser_creator_->first_run_tabs_.clear(); | |
983 } | |
984 } | |
985 | |
986 // Otherwise open at least the new tab page (and the welcome page, if this | |
987 // is the first time the browser is being started), or the set of URLs | |
988 // specified on the command line. | |
989 if (startup_urls->empty()) { | |
990 startup_urls->push_back(GURL(chrome::kChromeUINewTabURL)); | |
991 PrefService* prefs = g_browser_process->local_state(); | |
992 if (prefs->FindPreference(prefs::kShouldShowWelcomePage) && | |
993 prefs->GetBoolean(prefs::kShouldShowWelcomePage)) { | |
994 // Reset the preference so we don't show the welcome page next time. | |
995 prefs->ClearPref(prefs::kShouldShowWelcomePage); | |
996 startup_urls->push_back(GetWelcomePageURL()); | |
997 } | |
998 } | |
999 | |
1000 // If the sync promo page is going to be displayed then insert it at the front | |
1001 // of the list. | |
1002 if (SyncPromoUI::ShouldShowSyncPromoAtStartup(profile_, is_first_run_)) { | |
1003 SyncPromoUI::DidShowSyncPromoAtStartup(profile_); | |
1004 GURL old_url = (*startup_urls)[0]; | |
1005 (*startup_urls)[0] = | |
1006 SyncPromoUI::GetSyncPromoURL(GURL(chrome::kChromeUINewTabURL), | |
1007 SyncPromoUI::SOURCE_START_PAGE); | |
1008 | |
1009 // An empty URL means to go to the home page. | |
1010 if (old_url.is_empty() && | |
1011 profile_->GetHomePage() == GURL(chrome::kChromeUINewTabURL)) { | |
1012 old_url = GURL(chrome::kChromeUINewTabURL); | |
1013 } | |
1014 | |
1015 // If the old URL is not the NTP then insert it right after the sync promo. | |
1016 if (old_url != GURL(chrome::kChromeUINewTabURL)) | |
1017 startup_urls->insert(startup_urls->begin() + 1, old_url); | |
1018 | |
1019 // If we have more than two startup tabs then skip the welcome page. | |
1020 if (startup_urls->size() > 2) { | |
1021 std::vector<GURL>::iterator it = std::find( | |
1022 startup_urls->begin(), startup_urls->end(), GetWelcomePageURL()); | |
1023 if (it != startup_urls->end()) | |
1024 startup_urls->erase(it); | |
1025 } | |
1026 } | |
1027 } | |
1028 | |
1029 void StartupBrowserCreator::LaunchWithProfile::CheckPreferencesBackup( | |
1030 Profile* profile) { | |
1031 ProtectorService* protector_service = | |
1032 ProtectorServiceFactory::GetForProfile(profile); | |
1033 ProtectedPrefsWatcher* prefs_watcher = protector_service->GetPrefsWatcher(); | |
1034 | |
1035 // Check if backup is valid. | |
1036 if (!prefs_watcher->is_backup_valid()) { | |
1037 protector_service->ShowChange(protector::CreatePrefsBackupInvalidChange()); | |
1038 // Further checks make no sense. | |
1039 return; | |
1040 } | |
1041 | |
1042 // Check for session startup (including pinned tabs) changes. | |
1043 if (SessionStartupPref::DidStartupPrefChange(profile) || | |
1044 prefs_watcher->DidPrefChange(prefs::kPinnedTabs)) { | |
1045 LOG(WARNING) << "Session startup settings have changed"; | |
1046 SessionStartupPref new_pref = SessionStartupPref::GetStartupPref(profile); | |
1047 PinnedTabCodec::Tabs new_tabs = PinnedTabCodec::ReadPinnedTabs(profile); | |
1048 const base::Value* tabs_backup = | |
1049 prefs_watcher->GetBackupForPref(prefs::kPinnedTabs); | |
1050 protector_service->ShowChange(protector::CreateSessionStartupChange( | |
1051 new_pref, | |
1052 new_tabs, | |
1053 SessionStartupPref::GetStartupPrefBackup(profile), | |
1054 PinnedTabCodec::ReadPinnedTabs(tabs_backup))); | |
1055 } | |
1056 | |
1057 // Check for homepage changes. | |
1058 if (prefs_watcher->DidPrefChange(prefs::kHomePage) || | |
1059 prefs_watcher->DidPrefChange(prefs::kHomePageIsNewTabPage) || | |
1060 prefs_watcher->DidPrefChange(prefs::kShowHomeButton)) { | |
1061 LOG(WARNING) << "Homepage has changed"; | |
1062 PrefService* prefs = profile->GetPrefs(); | |
1063 std::string backup_homepage; | |
1064 bool backup_homepage_is_ntp; | |
1065 bool backup_show_home_button; | |
1066 if (!prefs_watcher->GetBackupForPref(prefs::kHomePage)-> | |
1067 GetAsString(&backup_homepage) || | |
1068 !prefs_watcher->GetBackupForPref(prefs::kHomePageIsNewTabPage)-> | |
1069 GetAsBoolean(&backup_homepage_is_ntp) || | |
1070 !prefs_watcher->GetBackupForPref(prefs::kShowHomeButton)-> | |
1071 GetAsBoolean(&backup_show_home_button)) { | |
1072 NOTREACHED(); | |
1073 } | |
1074 protector_service->ShowChange(protector::CreateHomepageChange( | |
1075 // New: | |
1076 prefs->GetString(prefs::kHomePage), | |
1077 prefs->GetBoolean(prefs::kHomePageIsNewTabPage), | |
1078 prefs->GetBoolean(prefs::kShowHomeButton), | |
1079 // Backup: | |
1080 backup_homepage, | |
1081 backup_homepage_is_ntp, | |
1082 backup_show_home_button)); | |
1083 } | |
1084 } | |
1085 | |
1086 std::vector<GURL> StartupBrowserCreator::GetURLsFromCommandLine( | 254 std::vector<GURL> StartupBrowserCreator::GetURLsFromCommandLine( |
1087 const CommandLine& command_line, | 255 const CommandLine& command_line, |
1088 const FilePath& cur_dir, | 256 const FilePath& cur_dir, |
1089 Profile* profile) { | 257 Profile* profile) { |
1090 std::vector<GURL> urls; | 258 std::vector<GURL> urls; |
1091 const CommandLine::StringVector& params = command_line.GetArgs(); | 259 const CommandLine::StringVector& params = command_line.GetArgs(); |
1092 | 260 |
1093 for (size_t i = 0; i < params.size(); ++i) { | 261 for (size_t i = 0; i < params.size(); ++i) { |
1094 FilePath param = FilePath(params[i]); | 262 FilePath param = FilePath(params[i]); |
1095 // Handle Vista way of searching - "? <search-term>" | 263 // Handle Vista way of searching - "? <search-term>" |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1141 // search charm or via a url navigation in metro, then fetch the | 309 // search charm or via a url navigation in metro, then fetch the |
1142 // corresponding url. | 310 // corresponding url. |
1143 GURL url = browser::GetURLToOpen(profile); | 311 GURL url = browser::GetURLToOpen(profile); |
1144 if (url.is_valid()) | 312 if (url.is_valid()) |
1145 urls.push_back(GURL(url)); | 313 urls.push_back(GURL(url)); |
1146 } | 314 } |
1147 #endif // OS_WIN | 315 #endif // OS_WIN |
1148 return urls; | 316 return urls; |
1149 } | 317 } |
1150 | 318 |
| 319 // static |
1151 bool StartupBrowserCreator::ProcessCmdLineImpl( | 320 bool StartupBrowserCreator::ProcessCmdLineImpl( |
1152 const CommandLine& command_line, | 321 const CommandLine& command_line, |
1153 const FilePath& cur_dir, | 322 const FilePath& cur_dir, |
1154 bool process_startup, | 323 bool process_startup, |
1155 Profile* last_used_profile, | 324 Profile* last_used_profile, |
1156 const Profiles& last_opened_profiles, | 325 const Profiles& last_opened_profiles, |
1157 int* return_code, | 326 int* return_code, |
1158 StartupBrowserCreator* browser_creator) { | 327 StartupBrowserCreator* browser_creator) { |
1159 DCHECK(last_used_profile); | 328 DCHECK(last_used_profile); |
1160 if (process_startup) { | 329 if (process_startup) { |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1287 else | 456 else |
1288 DLOG(WARNING) << "Invalid touch-device id: " << *iter; | 457 DLOG(WARNING) << "Invalid touch-device id: " << *iter; |
1289 } | 458 } |
1290 ui::TouchFactory::GetInstance()->SetTouchDeviceList(device_ids); | 459 ui::TouchFactory::GetInstance()->SetTouchDeviceList(device_ids); |
1291 } | 460 } |
1292 #endif | 461 #endif |
1293 | 462 |
1294 // If we don't want to launch a new browser window or tab (in the case | 463 // If we don't want to launch a new browser window or tab (in the case |
1295 // of an automation request), we are done here. | 464 // of an automation request), we are done here. |
1296 if (!silent_launch) { | 465 if (!silent_launch) { |
1297 IsProcessStartup is_process_startup = process_startup ? | 466 browser::startup::IsProcessStartup is_process_startup = process_startup ? |
1298 IS_PROCESS_STARTUP : IS_NOT_PROCESS_STARTUP; | 467 browser::startup::IS_PROCESS_STARTUP : |
1299 IsFirstRun is_first_run = first_run::IsChromeFirstRun() ? | 468 browser::startup::IS_NOT_PROCESS_STARTUP; |
1300 IS_FIRST_RUN : IS_NOT_FIRST_RUN; | 469 browser::startup::IsFirstRun is_first_run = first_run::IsChromeFirstRun() ? |
| 470 browser::startup::IS_FIRST_RUN : browser::startup::IS_NOT_FIRST_RUN; |
1301 // |last_opened_profiles| will be empty in the following circumstances: | 471 // |last_opened_profiles| will be empty in the following circumstances: |
1302 // - This is the first launch. |last_used_profile| is the initial profile. | 472 // - This is the first launch. |last_used_profile| is the initial profile. |
1303 // - The user exited the browser by closing all windows for all | 473 // - The user exited the browser by closing all windows for all |
1304 // profiles. |last_used_profile| is the profile which owned the last open | 474 // profiles. |last_used_profile| is the profile which owned the last open |
1305 // window. | 475 // window. |
1306 // - Only incognito windows were open when the browser exited. | 476 // - Only incognito windows were open when the browser exited. |
1307 // |last_used_profile| is the last used incognito profile. Restoring it will | 477 // |last_used_profile| is the last used incognito profile. Restoring it will |
1308 // create a browser window for the corresponding original profile. | 478 // create a browser window for the corresponding original profile. |
1309 if (last_opened_profiles.empty()) { | 479 if (last_opened_profiles.empty()) { |
1310 if (!browser_creator->LaunchBrowser(command_line, last_used_profile, | 480 if (!browser_creator->LaunchBrowser(command_line, last_used_profile, |
(...skipping 21 matching lines...) Expand all Loading... |
1332 GetSessionStartupPref(command_line, *it); | 502 GetSessionStartupPref(command_line, *it); |
1333 if (*it != last_used_profile && | 503 if (*it != last_used_profile && |
1334 startup_pref.type == SessionStartupPref::DEFAULT && | 504 startup_pref.type == SessionStartupPref::DEFAULT && |
1335 !HasPendingUncleanExit(*it)) | 505 !HasPendingUncleanExit(*it)) |
1336 continue; | 506 continue; |
1337 if (!browser_creator->LaunchBrowser((*it == last_used_profile) ? | 507 if (!browser_creator->LaunchBrowser((*it == last_used_profile) ? |
1338 command_line : command_line_without_urls, *it, cur_dir, | 508 command_line : command_line_without_urls, *it, cur_dir, |
1339 is_process_startup, is_first_run, return_code)) | 509 is_process_startup, is_first_run, return_code)) |
1340 return false; | 510 return false; |
1341 // We've launched at least one browser. | 511 // We've launched at least one browser. |
1342 is_process_startup = StartupBrowserCreator::IS_NOT_PROCESS_STARTUP; | 512 is_process_startup = browser::startup::IS_NOT_PROCESS_STARTUP; |
1343 } | 513 } |
1344 } | 514 } |
1345 } | 515 } |
1346 return true; | 516 return true; |
1347 } | 517 } |
1348 | 518 |
1349 template <class AutomationProviderClass> | 519 template <class AutomationProviderClass> |
1350 bool StartupBrowserCreator::CreateAutomationProvider( | 520 bool StartupBrowserCreator::CreateAutomationProvider( |
1351 const std::string& channel_id, | 521 const std::string& channel_id, |
1352 Profile* profile, | 522 Profile* profile, |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1393 | 563 |
1394 Profile* profile = ProfileManager::GetLastUsedProfile(); | 564 Profile* profile = ProfileManager::GetLastUsedProfile(); |
1395 if (!profile) { | 565 if (!profile) { |
1396 // We should only be able to get here if the profile already exists and | 566 // We should only be able to get here if the profile already exists and |
1397 // has been created. | 567 // has been created. |
1398 NOTREACHED(); | 568 NOTREACHED(); |
1399 return; | 569 return; |
1400 } | 570 } |
1401 ProcessCmdLineImpl(cmd_line, cur_dir, false, profile, Profiles(), NULL, NULL); | 571 ProcessCmdLineImpl(cmd_line, cur_dir, false, profile, Profiles(), NULL, NULL); |
1402 } | 572 } |
| 573 |
| 574 bool HasPendingUncleanExit(Profile* profile) { |
| 575 return !profile->DidLastSessionExitCleanly() && |
| 576 !profile_launch_observer.Get().HasBeenLaunched(profile); |
| 577 } |
| 578 |
OLD | NEW |