Index: chrome/browser/process_singleton_win.cc |
diff --git a/chrome/browser/process_singleton_win.cc b/chrome/browser/process_singleton_win.cc |
index ffdb24ee0cf832a0a2286b774909438c27484ccc..9b1dc611cbfed1909eadcd6cda899c459e4ac324 100644 |
--- a/chrome/browser/process_singleton_win.cc |
+++ b/chrome/browser/process_singleton_win.cc |
@@ -24,8 +24,9 @@ |
#include "base/win/wrapped_window_proc.h" |
#include "chrome/browser/browser_process.h" |
#include "chrome/browser/browser_process_platform_part.h" |
+#include "chrome/browser/chrome_process_finder_win.h" |
+#include "chrome/browser/metro_utils/metro_chrome_win.h" |
#include "chrome/browser/shell_integration.h" |
-#include "chrome/browser/ui/metro_chrome_win.h" |
#include "chrome/browser/ui/simple_message_box.h" |
#include "chrome/common/chrome_constants.h" |
#include "chrome/common/chrome_paths.h" |
@@ -43,9 +44,6 @@ namespace { |
const char kLockfile[] = "lockfile"; |
-const char kSearchUrl[] = |
- "http://www.google.com/search?q=%s&sourceid=chrome&ie=UTF-8"; |
- |
const int kMetroChromeActivationTimeoutMs = 3000; |
// A helper class that acquires the given |mutex| while the AutoLockMutex is in |
@@ -247,8 +245,7 @@ bool ProcessSingleton::EscapeVirtualization( |
HWND hwnd = 0; |
::Sleep(90); |
for (int tries = 200; tries; --tries) { |
- hwnd = ::FindWindowEx(HWND_MESSAGE, NULL, chrome::kMessageWindowClass, |
- user_data_dir.value().c_str()); |
+ hwnd = chrome::FindRunningChromeWindow(user_data_dir); |
if (hwnd) { |
::SetForegroundWindow(hwnd); |
break; |
@@ -291,90 +288,20 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() { |
return PROCESS_NONE; |
} |
- DWORD process_id = 0; |
- DWORD thread_id = ::GetWindowThreadProcessId(remote_window_, &process_id); |
- // It is possible that the process owning this window may have died by now. |
- if (!thread_id || !process_id) { |
- remote_window_ = NULL; |
- return PROCESS_NONE; |
- } |
- |
- if (base::win::IsMetroProcess()) { |
- // Interesting corner case. We are launched as a metro process but we |
- // found another chrome running. Since metro enforces single instance then |
- // the other chrome must be desktop chrome and this must be a search charm |
- // activation. This scenario is unique; other cases should be properly |
- // handled by the delegate_execute which will not activate a second chrome. |
- string16 terms; |
- base::win::MetroLaunchType launch = base::win::GetMetroLaunchParams(&terms); |
- if (launch != base::win::METRO_SEARCH) { |
- LOG(WARNING) << "In metro mode, but and launch is " << launch; |
- } else { |
- std::string query = net::EscapeQueryParamValue(UTF16ToUTF8(terms), true); |
- std::string url = base::StringPrintf(kSearchUrl, query.c_str()); |
- SHELLEXECUTEINFOA sei = { sizeof(sei) }; |
- sei.fMask = SEE_MASK_FLAG_LOG_USAGE; |
- sei.nShow = SW_SHOWNORMAL; |
- sei.lpFile = url.c_str(); |
- ::OutputDebugStringA(sei.lpFile); |
- sei.lpDirectory = ""; |
- ::ShellExecuteExA(&sei); |
- } |
- return PROCESS_NOTIFIED; |
- } |
- |
- CommandLine command_line(*CommandLine::ForCurrentProcess()); |
- command_line.AppendSwitchASCII( |
- switches::kOriginalProcessStartTime, |
- base::Int64ToString( |
- base::CurrentProcessInfo::CreationTime()->ToInternalValue())); |
- |
- // Non-metro mode, send our command line to the other chrome message window. |
- // format is "START\0<<<current directory>>>\0<<<commandline>>>". |
- std::wstring to_send(L"START\0", 6); // want the NULL in the string. |
- base::FilePath cur_dir; |
- if (!PathService::Get(base::DIR_CURRENT, &cur_dir)) |
- return PROCESS_NONE; |
- to_send.append(cur_dir.value()); |
- to_send.append(L"\0", 1); // Null separator. |
- to_send.append(command_line.GetCommandLineString()); |
- to_send.append(L"\0", 1); // Null separator. |
- |
- base::win::ScopedHandle process_handle; |
- if (base::win::GetVersion() >= base::win::VERSION_WIN8 && |
- base::OpenProcessHandleWithAccess( |
- process_id, PROCESS_QUERY_INFORMATION, |
- process_handle.Receive()) && |
- base::win::IsProcessImmersive(process_handle.Get())) { |
- chrome::ActivateMetroChrome(); |
- } |
- |
- // Allow the current running browser window making itself the foreground |
- // window (otherwise it will just flash in the taskbar). |
- ::AllowSetForegroundWindow(process_id); |
- |
- COPYDATASTRUCT cds; |
- cds.dwData = 0; |
- cds.cbData = static_cast<DWORD>((to_send.length() + 1) * sizeof(wchar_t)); |
- cds.lpData = const_cast<wchar_t*>(to_send.c_str()); |
- DWORD_PTR result = 0; |
- if (::SendMessageTimeout(remote_window_, |
- WM_COPYDATA, |
- NULL, |
- reinterpret_cast<LPARAM>(&cds), |
- SMTO_ABORTIFHUNG, |
- kTimeoutInSeconds * 1000, |
- &result)) { |
- // It is possible that the process owning this window may have died by now. |
- if (!result) { |
+ switch (chrome::AttemptToNotifyRunningChrome(remote_window_)) { |
+ case chrome::NOTIFY_SUCCESS: |
+ return PROCESS_NOTIFIED; |
+ case chrome::NOTIFY_FAILED: |
remote_window_ = NULL; |
return PROCESS_NONE; |
- } |
- return PROCESS_NOTIFIED; |
+ case chrome::NOTIFY_WINDOW_HUNG: |
+ remote_window_ = NULL; |
+ break; |
} |
- // It is possible that the process owning this window may have died by now. |
- if (!::IsWindow(remote_window_)) { |
+ DWORD process_id = 0; |
+ DWORD thread_id = ::GetWindowThreadProcessId(remote_window_, &process_id); |
+ if (!thread_id || !process_id) { |
remote_window_ = NULL; |
return PROCESS_NONE; |
} |
@@ -386,10 +313,12 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() { |
reinterpret_cast<LPARAM>(&visible_window)); |
// If there is a visible browser window, ask the user before killing it. |
- if (visible_window && chrome::ShowMessageBox(NULL, |
- l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), |
- l10n_util::GetStringUTF16(IDS_BROWSER_HUNGBROWSER_MESSAGE), |
- chrome::MESSAGE_BOX_TYPE_QUESTION) == chrome::MESSAGE_BOX_RESULT_NO) { |
+ if (visible_window && |
+ chrome::ShowMessageBox( |
+ NULL, |
+ l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), |
+ l10n_util::GetStringUTF16(IDS_BROWSER_HUNGBROWSER_MESSAGE), |
+ chrome::MESSAGE_BOX_TYPE_QUESTION) == chrome::MESSAGE_BOX_RESULT_NO) { |
// The user denied. Quit silently. |
return PROCESS_NOTIFIED; |
} |
@@ -400,7 +329,8 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() { |
return PROCESS_NONE; |
} |
-ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessOrCreate() { |
+ProcessSingleton::NotifyResult |
+ProcessSingleton::NotifyOtherProcessOrCreate() { |
ProcessSingleton::NotifyResult result = PROCESS_NONE; |
if (!Create()) { |
result = NotifyOtherProcess(); |
@@ -421,9 +351,7 @@ bool ProcessSingleton::Create() { |
static const wchar_t kMetroActivationEventName[] = |
L"Local\\ChromeProcessSingletonStartupMetroActivation!"; |
- remote_window_ = ::FindWindowEx(HWND_MESSAGE, NULL, |
- chrome::kMessageWindowClass, |
- user_data_dir_.value().c_str()); |
+ remote_window_ = chrome::FindRunningChromeWindow(user_data_dir_); |
if (!remote_window_ && !EscapeVirtualization(user_data_dir_)) { |
// Make sure we will be the one and only process creating the window. |
// We use a named Mutex since we are protecting against multi-process |
@@ -439,9 +367,7 @@ bool ProcessSingleton::Create() { |
// window at this time, but we must still check if someone created it |
// between the time where we looked for it above and the time the mutex |
// was given to us. |
- remote_window_ = ::FindWindowEx(HWND_MESSAGE, NULL, |
- chrome::kMessageWindowClass, |
- user_data_dir_.value().c_str()); |
+ remote_window_ = chrome::FindRunningChromeWindow(user_data_dir_); |
// In Win8+, a new Chrome process launched in Desktop mode may need to be |
@@ -490,9 +416,7 @@ bool ProcessSingleton::Create() { |
// Check if this singleton was successfully grabbed by another process |
// (hopefully Metro Chrome). Failing to do so, this process will grab |
// the singleton and launch in Desktop mode. |
- remote_window_ = ::FindWindowEx(HWND_MESSAGE, NULL, |
- chrome::kMessageWindowClass, |
- user_data_dir_.value().c_str()); |
+ remote_window_ = chrome::FindRunningChromeWindow(user_data_dir_); |
} |
} |