Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(359)

Unified Diff: components/browser_watcher/window_hang_monitor_win.cc

Issue 1543803005: Added an integration test for kasko hang reports (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Using components for integration test. Rewrote unittests Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/browser_watcher/window_hang_monitor_win.cc
diff --git a/components/browser_watcher/window_hang_monitor_win.cc b/components/browser_watcher/window_hang_monitor_win.cc
index 964a6f76f4620a56aa2d2d4a557d1bec65b63ec5..0613d5c7832a8482262b18b607bb01ed8d395482 100644
--- a/components/browser_watcher/window_hang_monitor_win.cc
+++ b/components/browser_watcher/window_hang_monitor_win.cc
@@ -4,22 +4,47 @@
#include "components/browser_watcher/window_hang_monitor_win.h"
#include "base/callback.h"
+#include "base/files/file_util.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
+#include "base/strings/string_piece.h"
+#include "base/strings/string_util.h"
#include "base/win/message_window.h"
namespace browser_watcher {
namespace {
-HWND FindNamedWindowForProcess(const base::string16 name, base::ProcessId pid) {
- HWND candidate = base::win::MessageWindow::FindWindow(name);
- if (candidate) {
+// Returns true if the class name for |window| equals |str|.
+bool WindowClassNameEqualsString(HWND window, base::StringPiece16 str) {
+ wchar_t class_name[MAX_PATH];
+ int str_length = ::GetClassName(window, class_name, MAX_PATH);
+ return str_length && str.compare(class_name) == 0;
+}
+
+// Returns true if the window text is an existing directory. Ensures that
+// |window| is the right Chrome message window to ping.
+bool WindowNameIsExistingDirectory(HWND window) {
Sigurður Ásgeirsson 2016/01/20 18:21:13 nice - I think this heuristic is fine. Maybe leave
Patrick Monette 2016/01/21 00:05:10 Done.
+ base::string16 window_name;
+ int str_length = ::GetWindowText(
+ window, base::WriteInto(&window_name, MAX_PATH), MAX_PATH);
+ window_name.resize(str_length);
+ return base::DirectoryExists(base::FilePath(window_name));
+}
+
+// Returns the Chrome message window handle for the specified |pid| or nullptr
+// if not found.
+HWND FindChromeMessageWindow(base::ProcessId pid) {
+ HWND candidate = ::FindWindowEx(HWND_MESSAGE, nullptr, nullptr, nullptr);
+ while (candidate) {
DWORD actual_process_id = 0;
::GetWindowThreadProcessId(candidate, &actual_process_id);
- if (actual_process_id == pid)
+ if (WindowClassNameEqualsString(candidate, L"Chrome_MessageWindow") &&
+ WindowNameIsExistingDirectory(candidate) && actual_process_id == pid) {
return candidate;
+ }
+ candidate = ::GetNextWindow(candidate, GW_HWNDNEXT);
}
return nullptr;
}
@@ -45,9 +70,7 @@ WindowHangMonitor::~WindowHangMonitor() {
}
}
-void WindowHangMonitor::Initialize(base::Process process,
- const base::string16& window_name) {
- window_name_ = window_name;
+void WindowHangMonitor::Initialize(base::Process process) {
window_process_ = process.Pass();
timer_.SetTaskRunner(base::MessageLoop::current()->task_runner());
@@ -69,7 +92,7 @@ void WindowHangMonitor::PollForWindow() {
return;
}
- HWND hwnd = FindNamedWindowForProcess(window_name_, window_process_.Pid());
+ HWND hwnd = FindChromeMessageWindow(window_process_.Pid());
if (hwnd) {
// Sends a ping and schedules a timeout task. Upon receiving a ping response
// further pings will be scheduled ad infinitum. Will signal any failure now
@@ -121,7 +144,6 @@ void WindowHangMonitor::SendPing(HWND hwnd) {
void WindowHangMonitor::OnHangTimeout(HWND hwnd) {
DCHECK(window_process_.IsValid());
-
if (outstanding_ping_) {
// The ping is still outstanding, the window is hung or has vanished.
// Orphan the outstanding ping. If the callback arrives late, it will
@@ -129,8 +151,7 @@ void WindowHangMonitor::OnHangTimeout(HWND hwnd) {
outstanding_ping_->monitor = NULL;
outstanding_ping_ = NULL;
- if (hwnd !=
- FindNamedWindowForProcess(window_name_, window_process_.Pid())) {
+ if (hwnd != FindChromeMessageWindow(window_process_.Pid())) {
// The window vanished.
callback_.Run(WINDOW_VANISHED);
} else {
@@ -147,6 +168,7 @@ void WindowHangMonitor::OnHangTimeout(HWND hwnd) {
void WindowHangMonitor::OnRetryTimeout() {
DCHECK(window_process_.IsValid());
+ DCHECK(window_process_.IsValid());
DCHECK(!outstanding_ping_);
// We can't simply hold onto the previously located HWND due to potential
// aliasing.
@@ -155,11 +177,12 @@ void WindowHangMonitor::OnRetryTimeout() {
// process.
// 2. The window handle might have been re-assigned to a different process
// at any point after we found it.
- HWND hwnd = FindNamedWindowForProcess(window_name_, window_process_.Pid());
- if (hwnd)
+ HWND hwnd = FindChromeMessageWindow(window_process_.Pid());
+ if (hwnd) {
SendPing(hwnd);
- else
+ } else {
callback_.Run(WINDOW_VANISHED);
+ }
}
} // namespace browser_watcher

Powered by Google App Engine
This is Rietveld 408576698