xref: /aosp_15_r20/frameworks/native/services/inputflinger/tests/UinputDevice.h (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright (C) 2020 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #pragma once
18*38e8c45fSAndroid Build Coastguard Worker 
19*38e8c45fSAndroid Build Coastguard Worker #include <android-base/unique_fd.h>
20*38e8c45fSAndroid Build Coastguard Worker #include <gtest/gtest.h>
21*38e8c45fSAndroid Build Coastguard Worker #include <inttypes.h>
22*38e8c45fSAndroid Build Coastguard Worker #include <linux/uinput.h>
23*38e8c45fSAndroid Build Coastguard Worker #include <log/log.h>
24*38e8c45fSAndroid Build Coastguard Worker #include <ui/Point.h>
25*38e8c45fSAndroid Build Coastguard Worker #include <ui/Rect.h>
26*38e8c45fSAndroid Build Coastguard Worker 
27*38e8c45fSAndroid Build Coastguard Worker #include <memory>
28*38e8c45fSAndroid Build Coastguard Worker 
29*38e8c45fSAndroid Build Coastguard Worker namespace android {
30*38e8c45fSAndroid Build Coastguard Worker 
31*38e8c45fSAndroid Build Coastguard Worker // This is the factory method that must be used to create a UinputDevice.
32*38e8c45fSAndroid Build Coastguard Worker template <class D, class... Ts>
createUinputDevice(Ts...args)33*38e8c45fSAndroid Build Coastguard Worker std::unique_ptr<D> createUinputDevice(Ts... args) {
34*38e8c45fSAndroid Build Coastguard Worker     // Using `new` to access non-public constructors.
35*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<D> dev(new D(args...));
36*38e8c45fSAndroid Build Coastguard Worker     EXPECT_NO_FATAL_FAILURE(dev->init());
37*38e8c45fSAndroid Build Coastguard Worker     return dev;
38*38e8c45fSAndroid Build Coastguard Worker }
39*38e8c45fSAndroid Build Coastguard Worker 
40*38e8c45fSAndroid Build Coastguard Worker // --- UinputDevice ---
41*38e8c45fSAndroid Build Coastguard Worker 
42*38e8c45fSAndroid Build Coastguard Worker class UinputDevice {
43*38e8c45fSAndroid Build Coastguard Worker public:
44*38e8c45fSAndroid Build Coastguard Worker     virtual ~UinputDevice();
45*38e8c45fSAndroid Build Coastguard Worker 
getName()46*38e8c45fSAndroid Build Coastguard Worker     inline const char* getName() const { return mName; }
47*38e8c45fSAndroid Build Coastguard Worker 
48*38e8c45fSAndroid Build Coastguard Worker     // Subclasses must either provide a public constructor or must be-friend the factory method.
49*38e8c45fSAndroid Build Coastguard Worker     template <class D, class... Ts>
50*38e8c45fSAndroid Build Coastguard Worker     friend std::unique_ptr<D> createUinputDevice(Ts... args);
51*38e8c45fSAndroid Build Coastguard Worker 
52*38e8c45fSAndroid Build Coastguard Worker protected:
53*38e8c45fSAndroid Build Coastguard Worker     const char* mName;
54*38e8c45fSAndroid Build Coastguard Worker     const int16_t mProductId;
55*38e8c45fSAndroid Build Coastguard Worker 
56*38e8c45fSAndroid Build Coastguard Worker     explicit UinputDevice(const char* name, int16_t productId);
57*38e8c45fSAndroid Build Coastguard Worker 
58*38e8c45fSAndroid Build Coastguard Worker     // Signals which types of events this device supports before it is created.
59*38e8c45fSAndroid Build Coastguard Worker     // This must be overridden by subclasses.
60*38e8c45fSAndroid Build Coastguard Worker     virtual void configureDevice(int fd, uinput_user_dev* device) = 0;
61*38e8c45fSAndroid Build Coastguard Worker 
62*38e8c45fSAndroid Build Coastguard Worker     void injectEvent(uint16_t type, uint16_t code, int32_t value);
63*38e8c45fSAndroid Build Coastguard Worker 
64*38e8c45fSAndroid Build Coastguard Worker private:
65*38e8c45fSAndroid Build Coastguard Worker     base::unique_fd mDeviceFd;
66*38e8c45fSAndroid Build Coastguard Worker 
67*38e8c45fSAndroid Build Coastguard Worker     // This is called once by the factory method createUinputDevice().
68*38e8c45fSAndroid Build Coastguard Worker     void init();
69*38e8c45fSAndroid Build Coastguard Worker };
70*38e8c45fSAndroid Build Coastguard Worker 
71*38e8c45fSAndroid Build Coastguard Worker // --- UinputKeyboard ---
72*38e8c45fSAndroid Build Coastguard Worker 
73*38e8c45fSAndroid Build Coastguard Worker class UinputKeyboard : public UinputDevice {
74*38e8c45fSAndroid Build Coastguard Worker public:
75*38e8c45fSAndroid Build Coastguard Worker     static constexpr const char* KEYBOARD_NAME = "Test Uinput Keyboard Device";
76*38e8c45fSAndroid Build Coastguard Worker     static constexpr int16_t PRODUCT_ID = 42;
77*38e8c45fSAndroid Build Coastguard Worker 
78*38e8c45fSAndroid Build Coastguard Worker     // Injects key press and sync.
79*38e8c45fSAndroid Build Coastguard Worker     void pressKey(int key);
80*38e8c45fSAndroid Build Coastguard Worker     // Injects key release and sync.
81*38e8c45fSAndroid Build Coastguard Worker     void releaseKey(int key);
82*38e8c45fSAndroid Build Coastguard Worker     // Injects 4 events: key press, sync, key release, and sync.
83*38e8c45fSAndroid Build Coastguard Worker     void pressAndReleaseKey(int key);
84*38e8c45fSAndroid Build Coastguard Worker 
85*38e8c45fSAndroid Build Coastguard Worker     template <class D, class... Ts>
86*38e8c45fSAndroid Build Coastguard Worker     friend std::unique_ptr<D> createUinputDevice(Ts... args);
87*38e8c45fSAndroid Build Coastguard Worker 
88*38e8c45fSAndroid Build Coastguard Worker protected:
89*38e8c45fSAndroid Build Coastguard Worker     explicit UinputKeyboard(const char* name, int16_t productId = PRODUCT_ID,
90*38e8c45fSAndroid Build Coastguard Worker                             std::initializer_list<int> keys = {});
91*38e8c45fSAndroid Build Coastguard Worker 
92*38e8c45fSAndroid Build Coastguard Worker     void configureDevice(int fd, uinput_user_dev* device) override;
93*38e8c45fSAndroid Build Coastguard Worker 
94*38e8c45fSAndroid Build Coastguard Worker private:
95*38e8c45fSAndroid Build Coastguard Worker     std::set<int> mKeys;
96*38e8c45fSAndroid Build Coastguard Worker };
97*38e8c45fSAndroid Build Coastguard Worker 
98*38e8c45fSAndroid Build Coastguard Worker // --- UinputHomeKey---
99*38e8c45fSAndroid Build Coastguard Worker 
100*38e8c45fSAndroid Build Coastguard Worker // A keyboard device that has a single HOME key.
101*38e8c45fSAndroid Build Coastguard Worker class UinputHomeKey : public UinputKeyboard {
102*38e8c45fSAndroid Build Coastguard Worker public:
103*38e8c45fSAndroid Build Coastguard Worker     static constexpr const char* DEVICE_NAME = "Test Uinput Home Key";
104*38e8c45fSAndroid Build Coastguard Worker     static constexpr int16_t PRODUCT_ID = 43;
105*38e8c45fSAndroid Build Coastguard Worker 
106*38e8c45fSAndroid Build Coastguard Worker     // Injects 4 events: key press, sync, key release, and sync.
107*38e8c45fSAndroid Build Coastguard Worker     void pressAndReleaseHomeKey();
108*38e8c45fSAndroid Build Coastguard Worker 
109*38e8c45fSAndroid Build Coastguard Worker     template <class D, class... Ts>
110*38e8c45fSAndroid Build Coastguard Worker     friend std::unique_ptr<D> createUinputDevice(Ts... args);
111*38e8c45fSAndroid Build Coastguard Worker 
112*38e8c45fSAndroid Build Coastguard Worker private:
113*38e8c45fSAndroid Build Coastguard Worker     explicit UinputHomeKey();
114*38e8c45fSAndroid Build Coastguard Worker };
115*38e8c45fSAndroid Build Coastguard Worker 
116*38e8c45fSAndroid Build Coastguard Worker // --- UinputSteamController ---
117*38e8c45fSAndroid Build Coastguard Worker 
118*38e8c45fSAndroid Build Coastguard Worker // A joystick device that sends a BTN_GEAR_DOWN / BTN_WHEEL key.
119*38e8c45fSAndroid Build Coastguard Worker class UinputSteamController : public UinputKeyboard {
120*38e8c45fSAndroid Build Coastguard Worker public:
121*38e8c45fSAndroid Build Coastguard Worker     static constexpr const char* DEVICE_NAME = "Test Uinput Steam Controller";
122*38e8c45fSAndroid Build Coastguard Worker     static constexpr int16_t PRODUCT_ID = 44;
123*38e8c45fSAndroid Build Coastguard Worker 
124*38e8c45fSAndroid Build Coastguard Worker     template <class D, class... Ts>
125*38e8c45fSAndroid Build Coastguard Worker     friend std::unique_ptr<D> createUinputDevice(Ts... args);
126*38e8c45fSAndroid Build Coastguard Worker 
127*38e8c45fSAndroid Build Coastguard Worker private:
128*38e8c45fSAndroid Build Coastguard Worker     explicit UinputSteamController();
129*38e8c45fSAndroid Build Coastguard Worker };
130*38e8c45fSAndroid Build Coastguard Worker 
131*38e8c45fSAndroid Build Coastguard Worker // --- UinputExternalStylus ---
132*38e8c45fSAndroid Build Coastguard Worker 
133*38e8c45fSAndroid Build Coastguard Worker // A stylus that reports button presses.
134*38e8c45fSAndroid Build Coastguard Worker class UinputExternalStylus : public UinputKeyboard {
135*38e8c45fSAndroid Build Coastguard Worker public:
136*38e8c45fSAndroid Build Coastguard Worker     static constexpr const char* DEVICE_NAME = "Test Uinput External Stylus";
137*38e8c45fSAndroid Build Coastguard Worker     static constexpr int16_t PRODUCT_ID = 45;
138*38e8c45fSAndroid Build Coastguard Worker 
139*38e8c45fSAndroid Build Coastguard Worker     template <class D, class... Ts>
140*38e8c45fSAndroid Build Coastguard Worker     friend std::unique_ptr<D> createUinputDevice(Ts... args);
141*38e8c45fSAndroid Build Coastguard Worker 
142*38e8c45fSAndroid Build Coastguard Worker private:
143*38e8c45fSAndroid Build Coastguard Worker     explicit UinputExternalStylus();
144*38e8c45fSAndroid Build Coastguard Worker };
145*38e8c45fSAndroid Build Coastguard Worker 
146*38e8c45fSAndroid Build Coastguard Worker // --- UinputExternalStylusWithPressure ---
147*38e8c45fSAndroid Build Coastguard Worker 
148*38e8c45fSAndroid Build Coastguard Worker // A stylus that reports button presses and pressure values.
149*38e8c45fSAndroid Build Coastguard Worker class UinputExternalStylusWithPressure : public UinputKeyboard {
150*38e8c45fSAndroid Build Coastguard Worker public:
151*38e8c45fSAndroid Build Coastguard Worker     static constexpr const char* DEVICE_NAME = "Test Uinput External Stylus With Pressure";
152*38e8c45fSAndroid Build Coastguard Worker     static constexpr int16_t PRODUCT_ID = 46;
153*38e8c45fSAndroid Build Coastguard Worker 
154*38e8c45fSAndroid Build Coastguard Worker     static constexpr int32_t RAW_PRESSURE_MIN = 0;
155*38e8c45fSAndroid Build Coastguard Worker     static constexpr int32_t RAW_PRESSURE_MAX = 255;
156*38e8c45fSAndroid Build Coastguard Worker 
157*38e8c45fSAndroid Build Coastguard Worker     void setPressure(int32_t pressure);
158*38e8c45fSAndroid Build Coastguard Worker 
159*38e8c45fSAndroid Build Coastguard Worker     template <class D, class... Ts>
160*38e8c45fSAndroid Build Coastguard Worker     friend std::unique_ptr<D> createUinputDevice(Ts... args);
161*38e8c45fSAndroid Build Coastguard Worker 
162*38e8c45fSAndroid Build Coastguard Worker private:
163*38e8c45fSAndroid Build Coastguard Worker     void configureDevice(int fd, uinput_user_dev* device) override;
164*38e8c45fSAndroid Build Coastguard Worker 
165*38e8c45fSAndroid Build Coastguard Worker     explicit UinputExternalStylusWithPressure();
166*38e8c45fSAndroid Build Coastguard Worker };
167*38e8c45fSAndroid Build Coastguard Worker 
168*38e8c45fSAndroid Build Coastguard Worker // --- UinputKeyboardWithUsage ---
169*38e8c45fSAndroid Build Coastguard Worker // A keyboard that supports EV_MSC MSC_SCAN through which it can report HID usage codes.
170*38e8c45fSAndroid Build Coastguard Worker 
171*38e8c45fSAndroid Build Coastguard Worker class UinputKeyboardWithHidUsage : public UinputKeyboard {
172*38e8c45fSAndroid Build Coastguard Worker public:
173*38e8c45fSAndroid Build Coastguard Worker     static constexpr const char* DEVICE_NAME = "Test Uinput Keyboard With Usage";
174*38e8c45fSAndroid Build Coastguard Worker     static constexpr int16_t PRODUCT_ID = 47;
175*38e8c45fSAndroid Build Coastguard Worker 
176*38e8c45fSAndroid Build Coastguard Worker     template <class D, class... Ts>
177*38e8c45fSAndroid Build Coastguard Worker     friend std::unique_ptr<D> createUinputDevice(Ts... args);
178*38e8c45fSAndroid Build Coastguard Worker 
179*38e8c45fSAndroid Build Coastguard Worker protected:
180*38e8c45fSAndroid Build Coastguard Worker     explicit UinputKeyboardWithHidUsage(std::initializer_list<int> keys);
181*38e8c45fSAndroid Build Coastguard Worker 
182*38e8c45fSAndroid Build Coastguard Worker     void configureDevice(int fd, uinput_user_dev* device) override;
183*38e8c45fSAndroid Build Coastguard Worker };
184*38e8c45fSAndroid Build Coastguard Worker 
185*38e8c45fSAndroid Build Coastguard Worker // --- UinputTouchScreen ---
186*38e8c45fSAndroid Build Coastguard Worker 
187*38e8c45fSAndroid Build Coastguard Worker // A multi-touch touchscreen device with specific size that also supports styluses.
188*38e8c45fSAndroid Build Coastguard Worker class UinputTouchScreen : public UinputKeyboard {
189*38e8c45fSAndroid Build Coastguard Worker public:
190*38e8c45fSAndroid Build Coastguard Worker     static constexpr const char* DEVICE_NAME = "Test Uinput Touch Screen";
191*38e8c45fSAndroid Build Coastguard Worker     static constexpr int16_t PRODUCT_ID = 48;
192*38e8c45fSAndroid Build Coastguard Worker 
193*38e8c45fSAndroid Build Coastguard Worker     static const int32_t RAW_TOUCH_MIN = 0;
194*38e8c45fSAndroid Build Coastguard Worker     static const int32_t RAW_TOUCH_MAX = 31;
195*38e8c45fSAndroid Build Coastguard Worker     static const int32_t RAW_ID_MIN = 0;
196*38e8c45fSAndroid Build Coastguard Worker     static const int32_t RAW_ID_MAX = 9;
197*38e8c45fSAndroid Build Coastguard Worker     static const int32_t RAW_SLOT_MIN = 0;
198*38e8c45fSAndroid Build Coastguard Worker     static const int32_t RAW_SLOT_MAX = 9;
199*38e8c45fSAndroid Build Coastguard Worker     static const int32_t RAW_PRESSURE_MIN = 0;
200*38e8c45fSAndroid Build Coastguard Worker     static const int32_t RAW_PRESSURE_MAX = 255;
201*38e8c45fSAndroid Build Coastguard Worker 
202*38e8c45fSAndroid Build Coastguard Worker     template <class D, class... Ts>
203*38e8c45fSAndroid Build Coastguard Worker     friend std::unique_ptr<D> createUinputDevice(Ts... args);
204*38e8c45fSAndroid Build Coastguard Worker 
205*38e8c45fSAndroid Build Coastguard Worker     void sendSlot(int32_t slot);
206*38e8c45fSAndroid Build Coastguard Worker     void sendTrackingId(int32_t trackingId);
207*38e8c45fSAndroid Build Coastguard Worker     void sendDown(const Point& point);
208*38e8c45fSAndroid Build Coastguard Worker     void sendMove(const Point& point);
209*38e8c45fSAndroid Build Coastguard Worker     void sendPressure(int32_t pressure);
210*38e8c45fSAndroid Build Coastguard Worker     void sendPointerUp();
211*38e8c45fSAndroid Build Coastguard Worker     void sendUp();
212*38e8c45fSAndroid Build Coastguard Worker     void sendToolType(int32_t toolType);
213*38e8c45fSAndroid Build Coastguard Worker     void sendSync();
214*38e8c45fSAndroid Build Coastguard Worker 
215*38e8c45fSAndroid Build Coastguard Worker     const Point getCenterPoint();
216*38e8c45fSAndroid Build Coastguard Worker 
217*38e8c45fSAndroid Build Coastguard Worker protected:
218*38e8c45fSAndroid Build Coastguard Worker     explicit UinputTouchScreen(const Rect& size, const std::string& physicalPort = "");
219*38e8c45fSAndroid Build Coastguard Worker 
220*38e8c45fSAndroid Build Coastguard Worker private:
221*38e8c45fSAndroid Build Coastguard Worker     void configureDevice(int fd, uinput_user_dev* device) override;
222*38e8c45fSAndroid Build Coastguard Worker     const Rect mSize;
223*38e8c45fSAndroid Build Coastguard Worker     const std::string mPhysicalPort;
224*38e8c45fSAndroid Build Coastguard Worker };
225*38e8c45fSAndroid Build Coastguard Worker 
226*38e8c45fSAndroid Build Coastguard Worker } // namespace android
227