1 // Copyright (c) 2012 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.
5 #include "remoting/host/curtain_mode.h"
7 #include <X11/extensions/XInput.h>
9 #include "base/callback.h"
10 #include "base/single_thread_task_runner.h"
11 #include "remoting/base/logging.h"
12 #include "remoting/host/client_session_control.h"
16 class CurtainModeLinux
: public CurtainMode
{
20 // Overriden from CurtainMode.
21 bool Activate() override
;
24 // Returns true if the host is running under an Xvfb session.
27 DISALLOW_COPY_AND_ASSIGN(CurtainModeLinux
);
30 CurtainModeLinux::CurtainModeLinux() {
33 bool CurtainModeLinux::Activate() {
34 // We can't curtain the session in run-time in Linux.
35 // Either the session is running on Xvfb (i.e. always curtained), or it is
36 // attached to the physical console (i.e. impossible to curtain).
37 bool activated
= IsXvfbSession();
39 LOG(ERROR
) << "Curtain-mode is not supported when running on non-Xvfb "
46 bool CurtainModeLinux::IsXvfbSession() {
47 // Try to identify an Xvfb session. There's no way to query what X server we
48 // are running under, so we check for the Xvfb input devices.
49 // TODO(rmsousa): Find a similar way to determine that the *output* is secure.
50 Display
* display
= XOpenDisplay(nullptr);
51 int opcode
, event
, error
;
52 if (!XQueryExtension(display
, "XInputExtension", &opcode
, &event
, &error
)) {
53 // If XInput is not available, assume it is not an Xvfb session.
54 LOG(ERROR
) << "X Input extension not available: " << error
;
55 XCloseDisplay(display
);
60 bool found_xvfb_mouse
= false;
61 bool found_xvfb_keyboard
= false;
62 bool found_other_devices
= false;
63 devices
= XListInputDevices(display
, &num_devices
);
64 for (int i
= 0; i
< num_devices
; i
++) {
65 XDeviceInfo
* device_info
= &devices
[i
];
66 if (device_info
->use
== IsXExtensionPointer
) {
67 if (strcmp(device_info
->name
, "Xvfb mouse") == 0) {
68 found_xvfb_mouse
= true;
69 } else if (strcmp(device_info
->name
, "Virtual core XTEST pointer") != 0) {
70 found_other_devices
= true;
71 HOST_LOG
<< "Non Xvfb mouse found: " << device_info
->name
;
73 } else if (device_info
->use
== IsXExtensionKeyboard
) {
74 if (strcmp(device_info
->name
, "Xvfb keyboard") == 0) {
75 found_xvfb_keyboard
= true;
76 } else if (strcmp(device_info
->name
,
77 "Virtual core XTEST keyboard") != 0) {
78 found_other_devices
= true;
79 HOST_LOG
<< "Non Xvfb keyboard found: " << device_info
->name
;
81 } else if (device_info
->use
== IsXPointer
) {
82 if (strcmp(device_info
->name
, "Virtual core pointer") != 0) {
83 found_other_devices
= true;
84 HOST_LOG
<< "Non Xvfb mouse found: " << device_info
->name
;
86 } else if (device_info
->use
== IsXKeyboard
) {
87 if (strcmp(device_info
->name
, "Virtual core keyboard") != 0) {
88 found_other_devices
= true;
89 HOST_LOG
<< "Non Xvfb keyboard found: " << device_info
->name
;
92 found_other_devices
= true;
93 HOST_LOG
<< "Non Xvfb device found: " << device_info
->name
;
96 XFreeDeviceList(devices
);
97 XCloseDisplay(display
);
98 return found_xvfb_mouse
&& found_xvfb_keyboard
&& !found_other_devices
;
102 scoped_ptr
<CurtainMode
> CurtainMode::Create(
103 scoped_refptr
<base::SingleThreadTaskRunner
> caller_task_runner
,
104 scoped_refptr
<base::SingleThreadTaskRunner
> ui_task_runner
,
105 base::WeakPtr
<ClientSessionControl
> client_session_control
) {
106 return make_scoped_ptr(new CurtainModeLinux());
109 } // namespace remoting