xref: /aosp_15_r20/external/autotest/client/cros/graphics/graphics_uinput.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1# Lint as: python2, python3
2# Copyright 2020 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""
7Provides uinput utils for generating user input events.
8"""
9
10# Please limit the use of the uinput library to this file. Try not to spread
11# dependencies and abstract as much as possible to make switching to a different
12# input library in the future easier.
13import uinput
14
15
16# Don't create a device during build_packages or for tests that don't need it.
17uinput_device_keyboard = None
18uinput_device_touch = None
19uinput_device_mouse_rel = None
20
21# Don't add more events to this list than are used. For a complete list of
22# available events check python2.7/site-packages/uinput/ev.py.
23UINPUT_DEVICE_EVENTS_KEYBOARD = [
24    uinput.KEY_F4,
25    uinput.KEY_F11,
26    uinput.KEY_KPPLUS,
27    uinput.KEY_KPMINUS,
28    uinput.KEY_LEFTCTRL,
29    uinput.KEY_TAB,
30    uinput.KEY_UP,
31    uinput.KEY_DOWN,
32    uinput.KEY_LEFT,
33    uinput.KEY_RIGHT,
34    uinput.KEY_RIGHTSHIFT,
35    uinput.KEY_LEFTALT,
36    uinput.KEY_A,
37    uinput.KEY_M,
38    uinput.KEY_Q,
39    uinput.KEY_V
40]
41# TODO(ihf): Find an ABS sequence that actually works.
42UINPUT_DEVICE_EVENTS_TOUCH = [
43    uinput.BTN_TOUCH,
44    uinput.ABS_MT_SLOT,
45    uinput.ABS_MT_POSITION_X + (0, 2560, 0, 0),
46    uinput.ABS_MT_POSITION_Y + (0, 1700, 0, 0),
47    uinput.ABS_MT_TRACKING_ID + (0, 10, 0, 0),
48    uinput.BTN_TOUCH
49]
50UINPUT_DEVICE_EVENTS_MOUSE_REL = [
51    uinput.REL_X,
52    uinput.REL_Y,
53    uinput.BTN_MOUSE,
54    uinput.BTN_LEFT,
55    uinput.BTN_RIGHT
56]
57
58
59def get_device_keyboard():
60    """
61    Lazy initialize device and return it. We don't want to create a device
62    during build_packages or for tests that don't need it, hence init with None.
63    """
64    global uinput_device_keyboard
65    if uinput_device_keyboard is None:
66        uinput_device_keyboard = uinput.Device(UINPUT_DEVICE_EVENTS_KEYBOARD)
67    return uinput_device_keyboard
68
69
70def get_device_mouse_rel():
71    """
72    Lazy initialize device and return it. We don't want to create a device
73    during build_packages or for tests that don't need it, hence init with None.
74    """
75    global uinput_device_mouse_rel
76    if uinput_device_mouse_rel is None:
77        uinput_device_mouse_rel = uinput.Device(UINPUT_DEVICE_EVENTS_MOUSE_REL)
78    return uinput_device_mouse_rel
79
80
81def get_device_touch():
82    """
83    Lazy initialize device and return it. We don't want to create a device
84    during build_packages or for tests that don't need it, hence init with None.
85    """
86    global uinput_device_touch
87    if uinput_device_touch is None:
88        uinput_device_touch = uinput.Device(UINPUT_DEVICE_EVENTS_TOUCH)
89    return uinput_device_touch
90
91
92def translate_name(event_name):
93    """
94    Translates string |event_name| to uinput event.
95    """
96    return getattr(uinput, event_name)
97
98
99def emit(device, event_name, value, syn=True):
100    """
101    Wrapper for uinput.emit. Emits event with value.
102    Example: ('REL_X', 20), ('BTN_RIGHT', 1)
103    """
104    event = translate_name(event_name)
105    device.emit(event, value, syn)
106
107
108def emit_click(device, event_name, syn=True):
109    """
110    Wrapper for uinput.emit_click. Emits click event. Only KEY and BTN events
111    are accepted, otherwise ValueError is raised. Example: 'KEY_A'
112    """
113    event = translate_name(event_name)
114    device.emit_click(event, syn)
115
116
117def emit_combo(device, event_names, syn=True):
118    """
119    Wrapper for uinput.emit_combo. Emits sequence of events.
120    Example: ['KEY_LEFTCTRL', 'KEY_LEFTALT', 'KEY_F5']
121    """
122    events = [translate_name(en) for en in event_names]
123    device.emit_combo(events, syn)
124