blob: 905bcd86c45a62eff987d326ba7ec5b0365fa688 [file] [log] [blame]
// Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef WINDOW_MANAGER_CHROME_WATCHDOG_H_
#define WINDOW_MANAGER_CHROME_WATCHDOG_H_
#include <set>
#include <sys/types.h>
#include <gtest/gtest_prod.h> // for FRIEND_TEST() macro
#include "base/memory/scoped_ptr.h"
#include "base/time.h"
#include "window_manager/event_consumer.h"
#include "window_manager/x11/x_types.h"
namespace window_manager {
class EventConsumerRegistrar;
class WindowManager;
class Window;
// ChromeWatchdog sends _NET_WM_PING client messages to Chrome windows and
// kills them if they don't respond soon enough.
class ChromeWatchdog : public EventConsumer {
public:
explicit ChromeWatchdog(WindowManager* wm);
virtual ~ChromeWatchdog();
// Begin EventConsumer implementation.
virtual bool IsInputWindow(XWindow xid) { return false; }
virtual void HandleScreenResize() {}
virtual void HandleLoggedInStateChange() {}
virtual bool HandleWindowMapRequest(Window* win) { return false; }
virtual void HandleWindowMap(Window* win);
virtual void HandleWindowUnmap(Window* win);
virtual void HandleWindowPixmapFetch(Window* win) {}
virtual void HandleWindowConfigureRequest(Window* win,
const Rect& requested_bounds) {}
virtual void HandleButtonPress(XWindow xid,
const Point& relative_pos,
const Point& absolute_pos,
int button,
XTime timestamp) {}
virtual void HandleButtonRelease(XWindow xid,
const Point& relative_pos,
const Point& absolute_pos,
int button,
XTime timestamp) {}
virtual void HandlePointerEnter(XWindow xid,
const Point& relative_pos,
const Point& absolute_pos,
XTime timestamp) {}
virtual void HandlePointerLeave(XWindow xid,
const Point& relative_pos,
const Point& absolute_pos,
XTime timestamp) {}
virtual void HandlePointerMotion(XWindow xid,
const Point& relative_pos,
const Point& absolute_pos,
XTime timestamp) {}
virtual void HandleChromeMessage(const WmIpc::Message& msg) {}
virtual void HandleClientMessage(XWindow xid,
XAtom message_type,
const long data[5]);
virtual void HandleWindowPropertyChange(XWindow xid, XAtom xatom) {}
virtual void OwnDestroyedWindow(DestroyedWindow* destroyed_win, XWindow xid) {
NOTREACHED();
}
// End EventConsumer implementation.
// Send a _NET_WM_PING client message event to a Chrome window. If
// there's an outstanding ping, we abort it first.
bool SendPingToChrome(XTime timestamp, int timeout_ms);
private:
FRIEND_TEST(ChromeWatchdogTest, Basic);
bool is_pid_valid(pid_t pid) const { return pid > 1; }
bool has_outstanding_ping() const { return pinged_chrome_xid_ != 0; }
// If we have an outstanding timeout, abort it. We cancel the timeout
// and clear the related fields.
void AbortTimeout();
// Handle the timeout firing, meaning that Chrome didn't respond to our
// ping in time.
void HandleTimeout();
WindowManager* wm_; // not owned
// Our machine's hostname.
std::string local_hostname_;
scoped_ptr<EventConsumerRegistrar> registrar_;
// IDs of all currently-mapped Chrome windows that we can ping (i.e. ones
// that support the _NET_WM_PING protocol, and were created by clients
// that are running on the local machine and have supplied their PIDs).
std::set<XWindow> usable_chrome_xids_;
// The Chrome window to which an outstanding ping has been sent, or 0 if
// we're not currently waiting for a reply.
XWindow pinged_chrome_xid_;
// X timestamp in the last ping that we sent. We expect to receive this in
// the reply.
XTime ping_timestamp_;
// Time at which we sent the last ping (used for metrics).
base::TimeTicks monotonic_time_from_last_ping_;
// ID of the timeout that will run HandleTimeout(), or
// EventLoop::kUnsetTimeoutId if no timeout is currently registered.
int timeout_id_;
// PID of the last process that we killed, or -1 if we've never killed a
// process. Used for testing.
pid_t last_killed_pid_;
DISALLOW_COPY_AND_ASSIGN(ChromeWatchdog);
};
} // namespace window_manager
#endif // WINDOW_MANAGER_CHROME_WATCHDOG_H_