Roll src/third_party/WebKit f298044:aa8346d (svn 202628:202629)
[chromium-blink-merge.git] / components / browser_watcher / window_hang_monitor_win.h
blob4c515d70d915535a3dadb749afcc237994d0319f
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_
7 #include <windows.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 {
21 public:
22 // Represents a detected window event.
23 enum WindowEvent {
24 // The target process exited before the window was detected.
25 WINDOW_NOT_FOUND,
26 // The window failed to respond to a ping within the configured timeout.
27 WINDOW_HUNG,
28 // The window disappeared.
29 WINDOW_VANISHED,
32 // Called when a window event is detected. Called precisely zero or one
33 // time(s).
34 typedef base::Callback<void(WindowEvent)> WindowEventCallback;
36 // Initialize the monitor with |callback|. The callback is guaranteed
37 // to be called no more than once, and never after the WindowHangMonitor is
38 // destroyed. The monitor will be configured to issue pings according to
39 // |ping_interval|. A failure to respond within |timeout| will be interpreted
40 // as a hang.
41 WindowHangMonitor(base::TimeDelta ping_interval,
42 base::TimeDelta timeout,
43 const WindowEventCallback& callback);
44 ~WindowHangMonitor();
46 // Initializes the watcher to monitor a window named |window_name| and owned
47 // by |process|. May be invoked prior to the appearance of the window.
48 void Initialize(base::Process process, const base::string16& window_name);
50 private:
51 struct OutstandingPing {
52 WindowHangMonitor* monitor;
55 // Schedules a delayed task to poll for the appearance of the target window.
56 void ScheduleFindWindow();
58 // Checks for the appearance of the target window. If found, initiates the
59 // ping cycle. Otherwise, calls ScheduleFindWindow.
60 void PollForWindow();
62 static void CALLBACK
63 OnPongReceived(HWND window, UINT msg, ULONG_PTR data, LRESULT lresult);
65 // Sends a ping to |hwnd|. Issues a |WINDOW_VANISHED| callback if the
66 // operation fails. Schedules OnHangTimeout otherwise.
67 void SendPing(HWND hwnd);
69 // Runs after a |hang_timeout_| delay after sending a ping to |hwnd|. Checks
70 // whether a pong was received. Either issues a callback or schedules
71 // OnRetryTimeout.
72 void OnHangTimeout(HWND hwnd);
74 // Runs periodically at |ping_interval_| interval, as long as the window is
75 // still valid and not hung. Verifies that the target window still exists. If
76 // so, invokes SendPing. Otherwise, issues a |WINDOW_VANISHED| callback.
77 void OnRetryTimeout();
79 // Invoked when a window event is detected.
80 WindowEventCallback callback_;
82 // The name of the (message) window to monitor.
83 base::string16 window_name_;
85 // The target process in which the monitored window is expected to exist.
86 base::Process window_process_;
88 // The time the last message was sent.
89 base::Time last_ping_;
91 // The ping interval, must be larger than |hang_timeout_|.
92 base::TimeDelta ping_interval_;
94 // The time after which |window_| is assumed hung.
95 base::TimeDelta hang_timeout_;
97 // The timer used to schedule polls.
98 base::Timer timer_;
100 // Non-null when there is an outstanding ping.
101 // This is intentionally leaked when a hang is detected.
102 OutstandingPing* outstanding_ping_;
104 DISALLOW_COPY_AND_ASSIGN(WindowHangMonitor);
107 } // namespace browser_watcher
109 #endif // COMPONENTS_BROWSER_WATCHER_WINDOW_HANG_MONITOR_WIN_H_