OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/chrome_browser_main_win.h" | 5 #include "chrome/browser/chrome_browser_main_win.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 #include <shellapi.h> | 8 #include <shellapi.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 void WarnAboutMinimumSystemRequirements() { | 67 void WarnAboutMinimumSystemRequirements() { |
68 if (base::win::GetVersion() < base::win::VERSION_XP) { | 68 if (base::win::GetVersion() < base::win::VERSION_XP) { |
69 // Display a warning message if the user is running chrome on Windows 2000. | 69 // Display a warning message if the user is running chrome on Windows 2000. |
70 const string16 text = | 70 const string16 text = |
71 l10n_util::GetStringUTF16(IDS_UNSUPPORTED_OS_PRE_WIN_XP); | 71 l10n_util::GetStringUTF16(IDS_UNSUPPORTED_OS_PRE_WIN_XP); |
72 const string16 caption = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); | 72 const string16 caption = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); |
73 ui::MessageBox(NULL, text, caption, MB_OK | MB_ICONWARNING | MB_TOPMOST); | 73 ui::MessageBox(NULL, text, caption, MB_OK | MB_ICONWARNING | MB_TOPMOST); |
74 } | 74 } |
75 } | 75 } |
76 | 76 |
77 #if !defined(USE_AURA) | |
78 void ShowMissingLocaleMessageBox() { | |
79 ui::MessageBox(NULL, ASCIIToUTF16(chrome_browser::kMissingLocaleDataMessage), | |
80 ASCIIToUTF16(chrome_browser::kMissingLocaleDataTitle), | |
81 MB_OK | MB_ICONERROR | MB_TOPMOST); | |
82 } | |
83 #endif | |
84 | |
85 void RecordBrowserStartupTime() { | 77 void RecordBrowserStartupTime() { |
86 // Calculate the time that has elapsed from our own process creation. | 78 // Calculate the time that has elapsed from our own process creation. |
87 FILETIME creation_time = {}; | 79 FILETIME creation_time = {}; |
88 FILETIME ignore = {}; | 80 FILETIME ignore = {}; |
89 ::GetProcessTimes(::GetCurrentProcess(), &creation_time, &ignore, &ignore, | 81 ::GetProcessTimes(::GetCurrentProcess(), &creation_time, &ignore, &ignore, |
90 &ignore); | 82 &ignore); |
91 | 83 |
92 RecordPreReadExperimentTime("Startup.BrowserMessageLoopStartTime", | 84 RecordPreReadExperimentTime("Startup.BrowserMessageLoopStartTime", |
93 base::Time::Now() - base::Time::FromFileTime(creation_time)); | 85 base::Time::Now() - base::Time::FromFileTime(creation_time)); |
94 } | 86 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 if (!ShellUtil::RemoveChromeDesktopShortcut(dist, ShellUtil::CURRENT_USER, | 126 if (!ShellUtil::RemoveChromeDesktopShortcut(dist, ShellUtil::CURRENT_USER, |
135 false)) | 127 false)) |
136 VLOG(1) << "Failed to delete desktop shortcut."; | 128 VLOG(1) << "Failed to delete desktop shortcut."; |
137 if (!ShellUtil::RemoveChromeQuickLaunchShortcut(dist, | 129 if (!ShellUtil::RemoveChromeQuickLaunchShortcut(dist, |
138 ShellUtil::CURRENT_USER)) | 130 ShellUtil::CURRENT_USER)) |
139 VLOG(1) << "Failed to delete quick launch shortcut."; | 131 VLOG(1) << "Failed to delete quick launch shortcut."; |
140 } | 132 } |
141 return ret; | 133 return ret; |
142 } | 134 } |
143 | 135 |
144 // Prepares the localized strings that are going to be displayed to | 136 // ChromeBrowserMainPartsWin --------------------------------------------------- |
145 // the user if the browser process dies. These strings are stored in the | |
146 // environment block so they are accessible in the early stages of the | |
147 // chrome executable's lifetime. | |
148 void PrepareRestartOnCrashEnviroment(const CommandLine& parsed_command_line) { | |
149 // Clear this var so child processes don't show the dialog by default. | |
150 scoped_ptr<base::Environment> env(base::Environment::Create()); | |
151 env->UnSetVar(env_vars::kShowRestart); | |
152 | 137 |
153 // For non-interactive tests we don't restart on crash. | 138 ChromeBrowserMainPartsWin::ChromeBrowserMainPartsWin( |
154 if (env->HasVar(env_vars::kHeadless)) | 139 const MainFunctionParams& parameters) |
155 return; | 140 : ChromeBrowserMainParts(parameters) { |
156 | |
157 // If the known command-line test options are used we don't create the | |
158 // environment block which means we don't get the restart dialog. | |
159 if (parsed_command_line.HasSwitch(switches::kBrowserCrashTest) || | |
160 parsed_command_line.HasSwitch(switches::kBrowserAssertTest) || | |
161 parsed_command_line.HasSwitch(switches::kNoErrorDialogs)) | |
162 return; | |
163 | |
164 // The encoding we use for the info is "title|context|direction" where | |
165 // direction is either env_vars::kRtlLocale or env_vars::kLtrLocale depending | |
166 // on the current locale. | |
167 string16 dlg_strings(l10n_util::GetStringUTF16(IDS_CRASH_RECOVERY_TITLE)); | |
168 dlg_strings.push_back('|'); | |
169 string16 adjusted_string( | |
170 l10n_util::GetStringUTF16(IDS_CRASH_RECOVERY_CONTENT)); | |
171 base::i18n::AdjustStringForLocaleDirection(&adjusted_string); | |
172 dlg_strings.append(adjusted_string); | |
173 dlg_strings.push_back('|'); | |
174 dlg_strings.append(ASCIIToUTF16( | |
175 base::i18n::IsRTL() ? env_vars::kRtlLocale : env_vars::kLtrLocale)); | |
176 | |
177 env->SetVar(env_vars::kRestartInfo, UTF16ToUTF8(dlg_strings)); | |
178 } | 141 } |
179 | 142 |
180 void RegisterApplicationRestart(const CommandLine& parsed_command_line) { | 143 void ChromeBrowserMainPartsWin::PreMainMessageLoopStart() { |
181 DCHECK(base::win::GetVersion() >= base::win::VERSION_VISTA); | 144 if (!parameters().ui_task) { |
182 base::ScopedNativeLibrary library(FilePath(L"kernel32.dll")); | 145 // Make sure that we know how to handle exceptions from the message loop. |
183 // Get the function pointer for RegisterApplicationRestart. | 146 InitializeWindowProcExceptions(); |
184 RegisterApplicationRestartProc register_application_restart = | |
185 static_cast<RegisterApplicationRestartProc>( | |
186 library.GetFunctionPointer("RegisterApplicationRestart")); | |
187 if (!register_application_restart) { | |
188 LOG(WARNING) << "Cannot find RegisterApplicationRestart in kernel32.dll"; | |
189 return; | |
190 } | 147 } |
191 // The Windows Restart Manager expects a string of command line flags only, | 148 } |
192 // without the program. | |
193 CommandLine command_line(CommandLine::NO_PROGRAM); | |
194 command_line.AppendArguments(parsed_command_line, false); | |
195 if (!command_line.HasSwitch(switches::kRestoreLastSession)) | |
196 command_line.AppendSwitch(switches::kRestoreLastSession); | |
197 if (command_line.GetCommandLineString().length() > RESTART_MAX_CMD_LINE) { | |
198 LOG(WARNING) << "Command line too long for RegisterApplicationRestart"; | |
199 return; | |
200 } | |
201 | 149 |
202 // Restart Chrome if the computer is restarted as the result of an update. | 150 void ChromeBrowserMainPartsWin::ShowMissingLocaleMessageBox() { |
203 // This could be extended to handle crashes, hangs, and patches. | 151 ui::MessageBox(NULL, ASCIIToUTF16(chrome_browser::kMissingLocaleDataMessage), |
204 HRESULT hr = register_application_restart( | 152 ASCIIToUTF16(chrome_browser::kMissingLocaleDataTitle), |
205 command_line.GetCommandLineString().c_str(), | 153 MB_OK | MB_ICONERROR | MB_TOPMOST); |
206 RESTART_NO_CRASH | RESTART_NO_HANG | RESTART_NO_PATCH); | |
207 DCHECK(SUCCEEDED(hr)) << "RegisterApplicationRestart failed."; | |
208 } | 154 } |
209 | 155 |
210 // This method handles the --hide-icons and --show-icons command line options | 156 // This method handles the --hide-icons and --show-icons command line options |
211 // for chrome that get triggered by Windows from registry entries | 157 // for chrome that get triggered by Windows from registry entries |
212 // HideIconsCommand & ShowIconsCommand. Chrome doesn't support hide icons | 158 // HideIconsCommand & ShowIconsCommand. Chrome doesn't support hide icons |
213 // functionality so we just ask the users if they want to uninstall Chrome. | 159 // functionality so we just ask the users if they want to uninstall Chrome. |
214 int HandleIconsCommands(const CommandLine& parsed_command_line) { | 160 int ChromeBrowserMainPartsWin::HandleIconsCommands() { |
215 if (parsed_command_line.HasSwitch(switches::kHideIcons)) { | 161 if (parsed_command_line().HasSwitch(switches::kHideIcons)) { |
216 string16 cp_applet; | 162 string16 cp_applet; |
217 base::win::Version version = base::win::GetVersion(); | 163 base::win::Version version = base::win::GetVersion(); |
218 if (version >= base::win::VERSION_VISTA) { | 164 if (version >= base::win::VERSION_VISTA) { |
219 cp_applet.assign(L"Programs and Features"); // Windows Vista and later. | 165 cp_applet.assign(L"Programs and Features"); // Windows Vista and later. |
220 } else if (version >= base::win::VERSION_XP) { | 166 } else if (version >= base::win::VERSION_XP) { |
221 cp_applet.assign(L"Add/Remove Programs"); // Windows XP. | 167 cp_applet.assign(L"Add/Remove Programs"); // Windows XP. |
222 } else { | 168 } else { |
223 return chrome::RESULT_CODE_UNSUPPORTED_PARAM; // Not supported | 169 return chrome::RESULT_CODE_UNSUPPORTED_PARAM; // Not supported |
224 } | 170 } |
225 | 171 |
226 const string16 msg = | 172 const string16 msg = |
227 l10n_util::GetStringFUTF16(IDS_HIDE_ICONS_NOT_SUPPORTED, cp_applet); | 173 l10n_util::GetStringFUTF16(IDS_HIDE_ICONS_NOT_SUPPORTED, cp_applet); |
228 const string16 caption = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); | 174 const string16 caption = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); |
229 const UINT flags = MB_OKCANCEL | MB_ICONWARNING | MB_TOPMOST; | 175 const UINT flags = MB_OKCANCEL | MB_ICONWARNING | MB_TOPMOST; |
230 if (IDOK == ui::MessageBox(NULL, msg, caption, flags)) | 176 if (IDOK == ui::MessageBox(NULL, msg, caption, flags)) |
231 ShellExecute(NULL, NULL, L"appwiz.cpl", NULL, NULL, SW_SHOWNORMAL); | 177 ShellExecute(NULL, NULL, L"appwiz.cpl", NULL, NULL, SW_SHOWNORMAL); |
232 | 178 |
233 // Exit as we are not launching the browser. | 179 // Exit as we are not launching the browser. |
234 return content::RESULT_CODE_NORMAL_EXIT; | 180 return content::RESULT_CODE_NORMAL_EXIT; |
235 } | 181 } |
236 // We don't hide icons so we shouldn't do anything special to show them | 182 // We don't hide icons so we shouldn't do anything special to show them |
237 return chrome::RESULT_CODE_UNSUPPORTED_PARAM; | 183 return chrome::RESULT_CODE_UNSUPPORTED_PARAM; |
238 } | 184 } |
239 | 185 |
240 // Check if there is any machine level Chrome installed on the current | 186 // Check if there is any machine level Chrome installed on the current |
241 // machine. If yes and the current Chrome process is user level, we do not | 187 // machine. If yes and the current Chrome process is user level, we do not |
242 // allow the user level Chrome to run. So we notify the user and uninstall | 188 // allow the user level Chrome to run. So we notify the user and uninstall |
243 // user level Chrome. | 189 // user level Chrome. |
244 bool CheckMachineLevelInstall() { | 190 bool ChromeBrowserMainPartsWin::CheckMachineLevelInstall() { |
245 // TODO(tommi): Check if using the default distribution is always the right | 191 // TODO(tommi): Check if using the default distribution is always the right |
246 // thing to do. | 192 // thing to do. |
247 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); | 193 BrowserDistribution* dist = BrowserDistribution::GetDistribution(); |
248 scoped_ptr<Version> version(InstallUtil::GetChromeVersion(dist, true)); | 194 scoped_ptr<Version> version(InstallUtil::GetChromeVersion(dist, true)); |
249 if (version.get()) { | 195 if (version.get()) { |
250 FilePath exe_path; | 196 FilePath exe_path; |
251 PathService::Get(base::DIR_EXE, &exe_path); | 197 PathService::Get(base::DIR_EXE, &exe_path); |
252 std::wstring exe = exe_path.value(); | 198 std::wstring exe = exe_path.value(); |
253 FilePath user_exe_path(installer::GetChromeInstallPath(false, dist)); | 199 FilePath user_exe_path(installer::GetChromeInstallPath(false, dist)); |
254 if (FilePath::CompareEqualIgnoreCase(exe, user_exe_path.value())) { | 200 if (FilePath::CompareEqualIgnoreCase(exe, user_exe_path.value())) { |
255 const string16 text = | 201 const string16 text = |
256 l10n_util::GetStringUTF16(IDS_MACHINE_LEVEL_INSTALL_CONFLICT); | 202 l10n_util::GetStringUTF16(IDS_MACHINE_LEVEL_INSTALL_CONFLICT); |
257 const string16 caption = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); | 203 const string16 caption = l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); |
258 const UINT flags = MB_OK | MB_ICONERROR | MB_TOPMOST; | 204 const UINT flags = MB_OK | MB_ICONERROR | MB_TOPMOST; |
259 ui::MessageBox(NULL, text, caption, flags); | 205 ui::MessageBox(NULL, text, caption, flags); |
260 CommandLine uninstall_cmd( | 206 CommandLine uninstall_cmd( |
261 InstallUtil::GetChromeUninstallCmd(false, dist->GetType())); | 207 InstallUtil::GetChromeUninstallCmd(false, dist->GetType())); |
262 if (!uninstall_cmd.GetProgram().empty()) { | 208 if (!uninstall_cmd.GetProgram().empty()) { |
263 uninstall_cmd.AppendSwitch(installer::switches::kForceUninstall); | 209 uninstall_cmd.AppendSwitch(installer::switches::kForceUninstall); |
264 uninstall_cmd.AppendSwitch( | 210 uninstall_cmd.AppendSwitch( |
265 installer::switches::kDoNotRemoveSharedItems); | 211 installer::switches::kDoNotRemoveSharedItems); |
266 base::LaunchProcess(uninstall_cmd, base::LaunchOptions(), NULL); | 212 base::LaunchProcess(uninstall_cmd, base::LaunchOptions(), NULL); |
267 } | 213 } |
268 return true; | 214 return true; |
269 } | 215 } |
270 } | 216 } |
271 return false; | 217 return false; |
272 } | 218 } |
273 | 219 |
274 // ChromeBrowserMainPartsWin --------------------------------------------------- | 220 // Prepares the localized strings that are going to be displayed to |
| 221 // the user if the browser process dies. These strings are stored in the |
| 222 // environment block so they are accessible in the early stages of the |
| 223 // chrome executable's lifetime. |
| 224 void ChromeBrowserMainPartsWin::PrepareRestartOnCrashEnviroment() { |
| 225 // Clear this var so child processes don't show the dialog by default. |
| 226 scoped_ptr<base::Environment> env(base::Environment::Create()); |
| 227 env->UnSetVar(env_vars::kShowRestart); |
275 | 228 |
276 ChromeBrowserMainPartsWin::ChromeBrowserMainPartsWin( | 229 // For non-interactive tests we don't restart on crash. |
277 const MainFunctionParams& parameters) | 230 if (env->HasVar(env_vars::kHeadless)) |
278 : ChromeBrowserMainParts(parameters) { | 231 return; |
| 232 |
| 233 // If the known command-line test options are used we don't create the |
| 234 // environment block which means we don't get the restart dialog. |
| 235 if (parsed_command_line().HasSwitch(switches::kBrowserCrashTest) || |
| 236 parsed_command_line().HasSwitch(switches::kBrowserAssertTest) || |
| 237 parsed_command_line().HasSwitch(switches::kNoErrorDialogs)) |
| 238 return; |
| 239 |
| 240 // The encoding we use for the info is "title|context|direction" where |
| 241 // direction is either env_vars::kRtlLocale or env_vars::kLtrLocale depending |
| 242 // on the current locale. |
| 243 string16 dlg_strings(l10n_util::GetStringUTF16(IDS_CRASH_RECOVERY_TITLE)); |
| 244 dlg_strings.push_back('|'); |
| 245 string16 adjusted_string( |
| 246 l10n_util::GetStringUTF16(IDS_CRASH_RECOVERY_CONTENT)); |
| 247 base::i18n::AdjustStringForLocaleDirection(&adjusted_string); |
| 248 dlg_strings.append(adjusted_string); |
| 249 dlg_strings.push_back('|'); |
| 250 dlg_strings.append(ASCIIToUTF16( |
| 251 base::i18n::IsRTL() ? env_vars::kRtlLocale : env_vars::kLtrLocale)); |
| 252 |
| 253 env->SetVar(env_vars::kRestartInfo, UTF16ToUTF8(dlg_strings)); |
279 } | 254 } |
280 | 255 |
281 void ChromeBrowserMainPartsWin::PreMainMessageLoopStart() { | 256 void ChromeBrowserMainPartsWin::RegisterApplicationRestart() { |
282 if (!parameters().ui_task) { | 257 DCHECK(base::win::GetVersion() >= base::win::VERSION_VISTA); |
283 // Make sure that we know how to handle exceptions from the message loop. | 258 base::ScopedNativeLibrary library(FilePath(L"kernel32.dll")); |
284 InitializeWindowProcExceptions(); | 259 // Get the function pointer for RegisterApplicationRestart. |
| 260 RegisterApplicationRestartProc register_application_restart = |
| 261 static_cast<RegisterApplicationRestartProc>( |
| 262 library.GetFunctionPointer("RegisterApplicationRestart")); |
| 263 if (!register_application_restart) { |
| 264 LOG(WARNING) << "Cannot find RegisterApplicationRestart in kernel32.dll"; |
| 265 return; |
285 } | 266 } |
| 267 // The Windows Restart Manager expects a string of command line flags only, |
| 268 // without the program. |
| 269 CommandLine command_line(CommandLine::NO_PROGRAM); |
| 270 command_line.AppendArguments(parsed_command_line(), false); |
| 271 if (!command_line.HasSwitch(switches::kRestoreLastSession)) |
| 272 command_line.AppendSwitch(switches::kRestoreLastSession); |
| 273 if (command_line.GetCommandLineString().length() > RESTART_MAX_CMD_LINE) { |
| 274 LOG(WARNING) << "Command line too long for RegisterApplicationRestart"; |
| 275 return; |
| 276 } |
| 277 |
| 278 // Restart Chrome if the computer is restarted as the result of an update. |
| 279 // This could be extended to handle crashes, hangs, and patches. |
| 280 HRESULT hr = register_application_restart( |
| 281 command_line.GetCommandLineString().c_str(), |
| 282 RESTART_NO_CRASH | RESTART_NO_HANG | RESTART_NO_PATCH); |
| 283 DCHECK(SUCCEEDED(hr)) << "RegisterApplicationRestart failed."; |
286 } | 284 } |
OLD | NEW |