Chromium Code Reviews| 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/process_singleton.h" | 5 #include "chrome/browser/process_singleton.h" |
| 6 | 6 |
| 7 #include <shellapi.h> | 7 #include <shellapi.h> |
| 8 | 8 |
| 9 #include "base/base_paths.h" | 9 #include "base/base_paths.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 188 // Move this function to a common place as the Windows 8 delegate_execute | 188 // Move this function to a common place as the Windows 8 delegate_execute |
| 189 // handler can possibly use this. | 189 // handler can possibly use this. |
| 190 bool ShouldLaunchInWindows8ImmersiveMode(const base::FilePath& user_data_dir) { | 190 bool ShouldLaunchInWindows8ImmersiveMode(const base::FilePath& user_data_dir) { |
| 191 // Returning false from this function doesn't mean we don't launch immersive | 191 // Returning false from this function doesn't mean we don't launch immersive |
| 192 // mode in Aura. This function is specifically called in case when we need | 192 // mode in Aura. This function is specifically called in case when we need |
| 193 // to relaunch desktop launched chrome into immersive mode through 'relaunch' | 193 // to relaunch desktop launched chrome into immersive mode through 'relaunch' |
| 194 // menu. In case of Aura, we will use delegate_execute to do the relaunch. | 194 // menu. In case of Aura, we will use delegate_execute to do the relaunch. |
| 195 return false; | 195 return false; |
| 196 } | 196 } |
| 197 | 197 |
| 198 bool DisplayShouldKillMessageBox() { | |
| 199 return | |
| 200 chrome::ShowMessageBox( | |
| 201 NULL, | |
| 202 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), | |
| 203 l10n_util::GetStringUTF16(IDS_BROWSER_HUNGBROWSER_MESSAGE), | |
| 204 chrome::MESSAGE_BOX_TYPE_QUESTION) != chrome::MESSAGE_BOX_RESULT_NO; | |
| 205 } | |
| 206 | |
| 198 } // namespace | 207 } // namespace |
| 199 | 208 |
| 200 // Microsoft's Softricity virtualization breaks the sandbox processes. | 209 // Microsoft's Softricity virtualization breaks the sandbox processes. |
| 201 // So, if we detect the Softricity DLL we use WMI Win32_Process.Create to | 210 // So, if we detect the Softricity DLL we use WMI Win32_Process.Create to |
| 202 // break out of the virtualization environment. | 211 // break out of the virtualization environment. |
| 203 // http://code.google.com/p/chromium/issues/detail?id=43650 | 212 // http://code.google.com/p/chromium/issues/detail?id=43650 |
| 204 bool ProcessSingleton::EscapeVirtualization( | 213 bool ProcessSingleton::EscapeVirtualization( |
| 205 const base::FilePath& user_data_dir) { | 214 const base::FilePath& user_data_dir) { |
| 206 if (::GetModuleHandle(L"sftldr_wow64.dll") || | 215 if (::GetModuleHandle(L"sftldr_wow64.dll") || |
| 207 ::GetModuleHandle(L"sftldr.dll")) { | 216 ::GetModuleHandle(L"sftldr.dll")) { |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 226 return true; | 235 return true; |
| 227 } | 236 } |
| 228 return false; | 237 return false; |
| 229 } | 238 } |
| 230 | 239 |
| 231 ProcessSingleton::ProcessSingleton( | 240 ProcessSingleton::ProcessSingleton( |
| 232 const base::FilePath& user_data_dir, | 241 const base::FilePath& user_data_dir, |
| 233 const NotificationCallback& notification_callback) | 242 const NotificationCallback& notification_callback) |
| 234 : notification_callback_(notification_callback), | 243 : notification_callback_(notification_callback), |
| 235 is_virtualized_(false), lock_file_(INVALID_HANDLE_VALUE), | 244 is_virtualized_(false), lock_file_(INVALID_HANDLE_VALUE), |
| 236 user_data_dir_(user_data_dir) { | 245 user_data_dir_(user_data_dir), |
| 246 display_should_kill_messagebox_callback_( | |
| 247 base::Bind(&DisplayShouldKillMessageBox)) { | |
| 237 } | 248 } |
| 238 | 249 |
| 239 ProcessSingleton::~ProcessSingleton() { | 250 ProcessSingleton::~ProcessSingleton() { |
| 240 if (lock_file_ != INVALID_HANDLE_VALUE) | 251 if (lock_file_ != INVALID_HANDLE_VALUE) |
| 241 ::CloseHandle(lock_file_); | 252 ::CloseHandle(lock_file_); |
| 242 } | 253 } |
| 243 | 254 |
| 244 // Code roughly based on Mozilla. | 255 // Code roughly based on Mozilla. |
| 245 ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() { | 256 ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() { |
| 246 if (is_virtualized_) | 257 if (is_virtualized_) |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 272 } | 283 } |
| 273 base::Process process = base::Process::Open(process_id); | 284 base::Process process = base::Process::Open(process_id); |
| 274 | 285 |
| 275 // The window is hung. Scan for every window to find a visible one. | 286 // The window is hung. Scan for every window to find a visible one. |
| 276 bool visible_window = false; | 287 bool visible_window = false; |
| 277 ::EnumThreadWindows(thread_id, | 288 ::EnumThreadWindows(thread_id, |
| 278 &BrowserWindowEnumeration, | 289 &BrowserWindowEnumeration, |
| 279 reinterpret_cast<LPARAM>(&visible_window)); | 290 reinterpret_cast<LPARAM>(&visible_window)); |
| 280 | 291 |
| 281 // If there is a visible browser window, ask the user before killing it. | 292 // If there is a visible browser window, ask the user before killing it. |
| 282 if (visible_window && | 293 if (visible_window && !display_should_kill_messagebox_callback_.Run()) { |
| 283 chrome::ShowMessageBox( | |
| 284 NULL, | |
| 285 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), | |
| 286 l10n_util::GetStringUTF16(IDS_BROWSER_HUNGBROWSER_MESSAGE), | |
| 287 chrome::MESSAGE_BOX_TYPE_QUESTION) == chrome::MESSAGE_BOX_RESULT_NO) { | |
| 288 // The user denied. Quit silently. | 294 // The user denied. Quit silently. |
| 289 return PROCESS_NOTIFIED; | 295 return PROCESS_NOTIFIED; |
| 290 } | 296 } |
| 291 | 297 |
| 292 // Record the termination event in the hung process' exit funnel. | 298 // Record the termination event in the hung process' exit funnel. |
| 293 browser_watcher::ExitFunnel funnel; | 299 browser_watcher::ExitFunnel funnel; |
| 294 if (funnel.Init(chrome::kBrowserExitCodesRegistryPath, process.Handle())) | 300 if (funnel.Init(chrome::kBrowserExitCodesRegistryPath, process.Handle())) |
| 295 funnel.RecordEvent(L"HungBrowserTerminated"); | 301 funnel.RecordEvent(L"HungBrowserTerminated"); |
| 296 | 302 |
| 297 // Time to take action. Kill the browser process. | 303 // Time to take action. Kill the browser process. |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 430 ::SetEvent(metro_activation_event.Get()); | 436 ::SetEvent(metro_activation_event.Get()); |
| 431 } | 437 } |
| 432 } | 438 } |
| 433 } | 439 } |
| 434 | 440 |
| 435 return window_.hwnd() != NULL; | 441 return window_.hwnd() != NULL; |
| 436 } | 442 } |
| 437 | 443 |
| 438 void ProcessSingleton::Cleanup() { | 444 void ProcessSingleton::Cleanup() { |
| 439 } | 445 } |
| 446 | |
| 447 void ProcessSingleton::OverrideKillMessageBoxCallbackForTesting( | |
|
erikwright (departed)
2015/03/10 19:22:49
extra space after void
Sigurður Ásgeirsson
2015/03/10 19:48:15
Done.
| |
| 448 const DisplayShouldKillMessageBoxCallback& display_dialog_callback) { | |
| 449 display_should_kill_messagebox_callback_ = display_dialog_callback; | |
| 450 } | |
| OLD | NEW |