summaryrefslogtreecommitdiffstats
path: root/remoting/host/curtain_mode_linux.cc
diff options
context:
space:
mode:
Diffstat (limited to 'remoting/host/curtain_mode_linux.cc')
-rw-r--r--remoting/host/curtain_mode_linux.cc89
1 files changed, 84 insertions, 5 deletions
diff --git a/remoting/host/curtain_mode_linux.cc b/remoting/host/curtain_mode_linux.cc
index 5c3f269..61a3d97 100644
--- a/remoting/host/curtain_mode_linux.cc
+++ b/remoting/host/curtain_mode_linux.cc
@@ -4,28 +4,107 @@
#include "remoting/host/curtain_mode.h"
+#include <X11/extensions/XInput.h>
+
+#include "base/callback.h"
#include "base/logging.h"
namespace remoting {
class CurtainModeLinux : public CurtainMode {
public:
- CurtainModeLinux() {}
+ CurtainModeLinux(const base::Closure& on_session_activate,
+ const base::Closure& on_error);
+
// Overriden from CurtainMode.
- virtual void SetActivated(bool activated) OVERRIDE {
- NOTIMPLEMENTED();
- }
+ virtual void SetActivated(bool activated) OVERRIDE;
private:
+ // Returns true if the host is running under an Xvfb session.
+ bool IsXvfbSession();
+
+ base::Closure on_session_activate_;
+ base::Closure on_error_;
+
DISALLOW_COPY_AND_ASSIGN(CurtainModeLinux);
};
+CurtainModeLinux::CurtainModeLinux(const base::Closure& on_session_activate,
+ const base::Closure& on_error)
+ : on_session_activate_(on_session_activate),
+ on_error_(on_error) {
+}
+
+bool CurtainModeLinux::IsXvfbSession() {
+ // Try to identify an Xvfb session. There's no way to query what X server we
+ // are running under, so we check for the Xvfb input devices.
+ // TODO(rmsousa): Find a similar way to determine that the *output* is secure.
+ Display* display = XOpenDisplay(NULL);
+ int opcode, event, error;
+ if (!XQueryExtension(display, "XInputExtension", &opcode, &event, &error)) {
+ // If XInput is not available, assume it is not an Xvfb session.
+ LOG(ERROR) << "X Input extension not available: " << error;
+ XCloseDisplay(display);
+ return false;
+ }
+ int num_devices;
+ XDeviceInfo* devices;
+ bool found_xvfb_mouse = false;
+ bool found_xvfb_keyboard = false;
+ bool found_other_devices = false;
+ devices = XListInputDevices(display, &num_devices);
+ for (int i = 0; i < num_devices; i++) {
+ XDeviceInfo* device_info = &devices[i];
+ if (device_info->use == IsXExtensionPointer) {
+ if (strcmp(device_info->name, "Xvfb mouse") == 0) {
+ found_xvfb_mouse = true;
+ } else if (strcmp(device_info->name, "Virtual core XTEST pointer") != 0) {
+ found_other_devices = true;
+ LOG(INFO) << "Non Xvfb mouse found: " << device_info->name;
+ }
+ } else if (device_info->use == IsXExtensionKeyboard) {
+ if (strcmp(device_info->name, "Xvfb keyboard") == 0) {
+ found_xvfb_keyboard = true;
+ } else if (strcmp(device_info->name,
+ "Virtual core XTEST keyboard") != 0) {
+ found_other_devices = true;
+ LOG(INFO) << "Non Xvfb keyboard found: " << device_info->name;
+ }
+ } else if (device_info->use == IsXPointer) {
+ if (strcmp(device_info->name, "Virtual core pointer") != 0) {
+ found_other_devices = true;
+ LOG(INFO) << "Non Xvfb mouse found: " << device_info->name;
+ }
+ } else if (device_info->use == IsXKeyboard) {
+ if (strcmp(device_info->name, "Virtual core keyboard") != 0) {
+ found_other_devices = true;
+ LOG(INFO) << "Non Xvfb keyboard found: " << device_info->name;
+ }
+ } else {
+ found_other_devices = true;
+ LOG(INFO) << "Non Xvfb device found: " << device_info->name;
+ }
+ }
+ XFreeDeviceList(devices);
+ XCloseDisplay(display);
+ return found_xvfb_mouse && found_xvfb_keyboard && !found_other_devices;
+}
+
+void CurtainModeLinux::SetActivated(bool activated) {
+ // We can't curtain the session in run-time in Linux.
+ // Either the session is running on Xvfb (i.e. always curtained), or it is
+ // attached to the physical console (i.e. impossible to curtain).
+ if (activated && !IsXvfbSession()) {
+ on_error_.Run();
+ }
+}
+
// static
scoped_ptr<CurtainMode> CurtainMode::Create(
const base::Closure& on_session_activate,
const base::Closure& on_error) {
return scoped_ptr<CurtainMode>(
- new CurtainModeLinux());
+ new CurtainModeLinux(on_session_activate, on_error));
}
} // namespace remoting