1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 #ifndef COMPONENTS_BROWSER_WATCHER_WINDOW_HANG_MONITOR_WIN_H_
5 #define COMPONENTS_BROWSER_WATCHER_WINDOW_HANG_MONITOR_WIN_H_
9 #include "base/callback_forward.h"
10 #include "base/macros.h"
11 #include "base/process/process.h"
12 #include "base/strings/string16.h"
13 #include "base/time/time.h"
14 #include "base/timer/timer.h"
16 namespace browser_watcher
{
18 // Monitors a window for hanging by periodically sending it a WM_NULL message
19 // and timing the response.
20 class WindowHangMonitor
{
26 // Called when a hang is detected or when the window has gone away.
27 // Called precisely zero or one time(s).
28 typedef base::Callback
<void(WindowEvent
)> WindowEventCallback
;
30 // Initialize the monitor with an event callback.
31 explicit WindowHangMonitor(const WindowEventCallback
& callback
);
34 // Initializes the watcher to monitor the window answering to |window_name|.
35 // Returns true on success.
36 bool Initialize(const base::string16
& window_name
);
39 bool IsIdleForTesting() const { return !timer_
.IsRunning(); }
40 void SetPingIntervalForTesting(base::TimeDelta ping_interval
);
41 void SetHangTimeoutForTesting(base::TimeDelta hang_timeout
);
43 HWND
window() const { return window_
; }
44 const base::Process
& window_process() const { return window_process_
; }
47 struct OutstandingPing
{
48 WindowHangMonitor
* monitor
;
52 OnPongReceived(HWND window
, UINT msg
, ULONG_PTR data
, LRESULT lresult
);
54 // Checks that |window_| is still valid, and sends it a ping.
55 // Issues a |WINDOW_VANISHED| callback if the window's no longer valid.
56 // Schedules OnHangTimeout in case of success.
57 // Returns true on success, false if the window is no longer valid or other
61 // Runs after a |hang_timeout_| delay after sending a ping. Checks whether
62 // a pong was received. Either issues a callback or schedules OnRetryTimeout.
65 // Runs periodically at |ping_interval_| interval, as long as the window is
66 // still valid and not hung.
67 void OnRetryTimeout();
69 // Invoked on significant window events.
70 WindowEventCallback callback_
;
72 // The name of the (message) window to monitor.
73 base::string16 window_name_
;
75 // The monitored window handle.
78 // The process that owned |window_| when Initialize was called.
79 base::Process window_process_
;
81 // The time the last message was sent.
82 base::Time last_ping_
;
84 // The ping interval, must be larger than |hang_timeout_|.
85 base::TimeDelta ping_interval_
;
87 // The time after which |window_| is assumed hung.
88 base::TimeDelta hang_timeout_
;
90 // The timer used to schedule polls.
93 // Non-null when there is an outstanding ping.
94 // This is intentionally leaked when a hang is detected.
95 OutstandingPing
* outstanding_ping_
;
97 DISALLOW_COPY_AND_ASSIGN(WindowHangMonitor
);
100 } // namespace browser_watcher
102 #endif // COMPONENTS_BROWSER_WATCHER_WINDOW_HANG_MONITOR_WIN_H_