- add sources.
[platform/framework/web/crosswalk.git] / src / remoting / host / curtain_mode_linux.cc
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.
4
5 #include "remoting/host/curtain_mode.h"
6
7 #include <X11/extensions/XInput.h>
8
9 #include "base/callback.h"
10 #include "base/logging.h"
11 #include "base/single_thread_task_runner.h"
12 #include "remoting/host/client_session_control.h"
13
14 namespace remoting {
15
16 class CurtainModeLinux : public CurtainMode {
17  public:
18   CurtainModeLinux();
19
20   // Overriden from CurtainMode.
21   virtual bool Activate() OVERRIDE;
22
23  private:
24   // Returns true if the host is running under an Xvfb session.
25   bool IsXvfbSession();
26
27   DISALLOW_COPY_AND_ASSIGN(CurtainModeLinux);
28 };
29
30 CurtainModeLinux::CurtainModeLinux() {
31 }
32
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();
38   if (!activated) {
39     LOG(ERROR) << "Curtain-mode is not supported when running on non-Xvfb "
40                   "X server";
41   }
42
43   return activated;
44 }
45
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(NULL);
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);
56     return false;
57   }
58   int num_devices;
59   XDeviceInfo* devices;
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         LOG(INFO) << "Non Xvfb mouse found: " << device_info->name;
72       }
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         LOG(INFO) << "Non Xvfb keyboard found: " << device_info->name;
80       }
81     } else if (device_info->use == IsXPointer) {
82       if (strcmp(device_info->name, "Virtual core pointer") != 0) {
83         found_other_devices = true;
84         LOG(INFO) << "Non Xvfb mouse found: " << device_info->name;
85       }
86     } else if (device_info->use == IsXKeyboard) {
87       if (strcmp(device_info->name, "Virtual core keyboard") != 0) {
88         found_other_devices = true;
89         LOG(INFO) << "Non Xvfb keyboard found: " << device_info->name;
90       }
91     } else {
92       found_other_devices = true;
93       LOG(INFO) << "Non Xvfb device found: " << device_info->name;
94     }
95   }
96   XFreeDeviceList(devices);
97   XCloseDisplay(display);
98   return found_xvfb_mouse && found_xvfb_keyboard && !found_other_devices;
99 }
100
101 // static
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 scoped_ptr<CurtainMode>(new CurtainModeLinux());
107 }
108
109 }  // namespace remoting