xref: /aosp_15_r20/frameworks/native/include/input/VirtualInputDevice.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1 /*
2  * Copyright 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <android-base/unique_fd.h>
20 #include <input/Input.h>
21 #include <map>
22 
23 namespace android {
24 
25 enum class DeviceType {
26     KEYBOARD,
27     MOUSE,
28     TOUCHSCREEN,
29     DPAD,
30     STYLUS,
31     ROTARY_ENCODER,
32 };
33 
34 android::base::unique_fd openUinput(const char* readableName, int32_t vendorId, int32_t productId,
35                                     const char* phys, DeviceType deviceType, int32_t screenHeight,
36                                     int32_t screenWidth);
37 
38 enum class UinputAction {
39     RELEASE = 0,
40     PRESS = 1,
41     MOVE = 2,
42     CANCEL = 3,
43     ftl_last = CANCEL,
44 };
45 
46 class VirtualInputDevice {
47 public:
48     VirtualInputDevice(android::base::unique_fd fd);
49     virtual ~VirtualInputDevice();
50 
51 protected:
52     const android::base::unique_fd mFd;
53     bool writeInputEvent(uint16_t type, uint16_t code, int32_t value,
54                          std::chrono::nanoseconds eventTime);
55     bool writeEvKeyEvent(int32_t androidCode, int32_t androidAction,
56                          const std::map<int, int>& evKeyCodeMapping,
57                          const std::map<int, UinputAction>& actionMapping,
58                          std::chrono::nanoseconds eventTime);
59 };
60 
61 class VirtualKeyboard : public VirtualInputDevice {
62 public:
63     static const std::map<int, int> KEY_CODE_MAPPING;
64     // Expose to share with VirtualDpad.
65     static const std::map<int, UinputAction> KEY_ACTION_MAPPING;
66     VirtualKeyboard(android::base::unique_fd fd);
67     virtual ~VirtualKeyboard() override;
68     bool writeKeyEvent(int32_t androidKeyCode, int32_t androidAction,
69                        std::chrono::nanoseconds eventTime);
70 };
71 
72 class VirtualDpad : public VirtualInputDevice {
73 public:
74     static const std::map<int, int> DPAD_KEY_CODE_MAPPING;
75     VirtualDpad(android::base::unique_fd fd);
76     virtual ~VirtualDpad() override;
77     bool writeDpadKeyEvent(int32_t androidKeyCode, int32_t androidAction,
78                            std::chrono::nanoseconds eventTime);
79 };
80 
81 class VirtualMouse : public VirtualInputDevice {
82 public:
83     // Expose to share with VirtualStylus.
84     static const std::map<int, UinputAction> BUTTON_ACTION_MAPPING;
85     VirtualMouse(android::base::unique_fd fd);
86     virtual ~VirtualMouse() override;
87     bool writeButtonEvent(int32_t androidButtonCode, int32_t androidAction,
88                           std::chrono::nanoseconds eventTime);
89     // TODO(b/259554911): changing float parameters to int32_t.
90     bool writeRelativeEvent(float relativeX, float relativeY, std::chrono::nanoseconds eventTime);
91     bool writeScrollEvent(float xAxisMovement, float yAxisMovement,
92                           std::chrono::nanoseconds eventTime);
93 
94 private:
95     static const std::map<int, int> BUTTON_CODE_MAPPING;
96     int32_t mAccumulatedHighResScrollX;
97     int32_t mAccumulatedHighResScrollY;
98 };
99 
100 class VirtualTouchscreen : public VirtualInputDevice {
101 public:
102     // Expose to share with VirtualStylus.
103     static const std::map<int, UinputAction> TOUCH_ACTION_MAPPING;
104     VirtualTouchscreen(android::base::unique_fd fd);
105     virtual ~VirtualTouchscreen() override;
106     // TODO(b/259554911): changing float parameters to int32_t.
107     bool writeTouchEvent(int32_t pointerId, int32_t toolType, int32_t action, float locationX,
108                          float locationY, float pressure, float majorAxisSize,
109                          std::chrono::nanoseconds eventTime);
110 
111 private:
112     static const std::map<int, int> TOOL_TYPE_MAPPING;
113     /* The set of active touch pointers on this device.
114      * We only allow pointer id to go up to MAX_POINTERS because the maximum slots of virtual
115      * touchscreen is set up with MAX_POINTERS. Note that in other cases Android allows pointer id
116      * to go up to MAX_POINTERS_ID.
117      */
118     std::bitset<MAX_POINTERS> mActivePointers{};
119     bool isValidPointerId(int32_t pointerId, UinputAction uinputAction);
120     bool handleTouchDown(int32_t pointerId, std::chrono::nanoseconds eventTime);
121     bool handleTouchUp(int32_t pointerId, std::chrono::nanoseconds eventTime);
122 };
123 
124 class VirtualStylus : public VirtualInputDevice {
125 public:
126     VirtualStylus(android::base::unique_fd fd);
127     ~VirtualStylus() override;
128     bool writeMotionEvent(int32_t toolType, int32_t action, int32_t locationX, int32_t locationY,
129                           int32_t pressure, int32_t tiltX, int32_t tiltY,
130                           std::chrono::nanoseconds eventTime);
131     bool writeButtonEvent(int32_t androidButtonCode, int32_t androidAction,
132                           std::chrono::nanoseconds eventTime);
133 
134 private:
135     static const std::map<int, int> TOOL_TYPE_MAPPING;
136     static const std::map<int, int> BUTTON_CODE_MAPPING;
137     // True if the stylus is touching or hovering on the screen.
138     bool mIsStylusDown;
139     bool handleStylusDown(uint16_t tool, std::chrono::nanoseconds eventTime);
140     bool handleStylusUp(uint16_t tool, std::chrono::nanoseconds eventTime);
141 };
142 
143 class VirtualRotaryEncoder : public VirtualInputDevice {
144 public:
145     VirtualRotaryEncoder(android::base::unique_fd fd);
146     virtual ~VirtualRotaryEncoder() override;
147     bool writeScrollEvent(float scrollAmount, std::chrono::nanoseconds eventTime);
148 
149 private:
150     int32_t mAccumulatedHighResScrollAmount;
151 };
152 
153 } // namespace android
154