blob: d4b4e77e365c961adebaf2c89ce7c0ed844863c9 [file] [log] [blame]
Prabir Pradhane0105c92019-12-26 12:32:13 -08001/*
2 * Copyright (C) 2020 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
Prabir Pradhan48108662022-09-09 21:22:04 +000017#pragma once
Prabir Pradhane0105c92019-12-26 12:32:13 -080018
19#include <android-base/unique_fd.h>
20#include <gtest/gtest.h>
21#include <inttypes.h>
22#include <linux/uinput.h>
23#include <log/log.h>
Arthur Hungaab25622020-01-16 11:22:11 +080024#include <ui/Point.h>
25#include <ui/Rect.h>
Prabir Pradhane0105c92019-12-26 12:32:13 -080026
27#include <memory>
28
29namespace android {
30
31// This is the factory method that must be used to create a UinputDevice.
32template <class D, class... Ts>
33std::unique_ptr<D> createUinputDevice(Ts... args) {
34 // Using `new` to access non-public constructors.
Prabir Pradhanb7d434e2022-10-14 22:41:38 +000035 std::unique_ptr<D> dev(new D(args...));
Prabir Pradhane0105c92019-12-26 12:32:13 -080036 EXPECT_NO_FATAL_FAILURE(dev->init());
37 return dev;
38}
39
40// --- UinputDevice ---
41
42class UinputDevice {
43public:
44 virtual ~UinputDevice();
45
46 inline const char* getName() const { return mName; }
47
48 // Subclasses must either provide a public constructor or must be-friend the factory method.
49 template <class D, class... Ts>
50 friend std::unique_ptr<D> createUinputDevice(Ts... args);
51
52protected:
53 const char* mName;
Prabir Pradhanb7d434e2022-10-14 22:41:38 +000054 const int16_t mProductId;
Prabir Pradhane0105c92019-12-26 12:32:13 -080055
Prabir Pradhanb7d434e2022-10-14 22:41:38 +000056 explicit UinputDevice(const char* name, int16_t productId);
Prabir Pradhane0105c92019-12-26 12:32:13 -080057
58 // Signals which types of events this device supports before it is created.
59 // This must be overridden by subclasses.
60 virtual void configureDevice(int fd, uinput_user_dev* device) = 0;
61
62 void injectEvent(uint16_t type, uint16_t code, int32_t value);
63
64private:
65 base::unique_fd mDeviceFd;
66
67 // This is called once by the factory method createUinputDevice().
68 void init();
69};
70
71// --- UinputKeyboard ---
72
73class UinputKeyboard : public UinputDevice {
74public:
Prabir Pradhanb7d434e2022-10-14 22:41:38 +000075 static constexpr const char* KEYBOARD_NAME = "Test Uinput Keyboard Device";
76 static constexpr int16_t PRODUCT_ID = 42;
Prabir Pradhane0105c92019-12-26 12:32:13 -080077
78 // Injects key press and sync.
79 void pressKey(int key);
80 // Injects key release and sync.
81 void releaseKey(int key);
82 // Injects 4 events: key press, sync, key release, and sync.
83 void pressAndReleaseKey(int key);
84
85 template <class D, class... Ts>
86 friend std::unique_ptr<D> createUinputDevice(Ts... args);
87
88protected:
Prabir Pradhanb7d434e2022-10-14 22:41:38 +000089 explicit UinputKeyboard(const char* name, int16_t productId = PRODUCT_ID,
90 std::initializer_list<int> keys = {});
Prabir Pradhane0105c92019-12-26 12:32:13 -080091
Prabir Pradhane0105c92019-12-26 12:32:13 -080092 void configureDevice(int fd, uinput_user_dev* device) override;
93
Prabir Pradhan484d55a2022-10-14 23:17:16 +000094private:
Prabir Pradhane0105c92019-12-26 12:32:13 -080095 std::set<int> mKeys;
96};
97
98// --- UinputHomeKey---
99
100// A keyboard device that has a single HOME key.
101class UinputHomeKey : public UinputKeyboard {
102public:
Prabir Pradhanb7d434e2022-10-14 22:41:38 +0000103 static constexpr const char* DEVICE_NAME = "Test Uinput Home Key";
104 static constexpr int16_t PRODUCT_ID = 43;
105
Prabir Pradhane0105c92019-12-26 12:32:13 -0800106 // Injects 4 events: key press, sync, key release, and sync.
107 void pressAndReleaseHomeKey();
108
109 template <class D, class... Ts>
110 friend std::unique_ptr<D> createUinputDevice(Ts... args);
111
112private:
Prabir Pradhanb7d434e2022-10-14 22:41:38 +0000113 explicit UinputHomeKey();
Prabir Pradhane0105c92019-12-26 12:32:13 -0800114};
115
Prabir Pradhanb7d434e2022-10-14 22:41:38 +0000116// --- UinputSteamController ---
117
Siarhei Vishniakoua0d2b802020-05-13 14:00:31 -0700118// A joystick device that sends a BTN_GEAR_DOWN / BTN_WHEEL key.
119class UinputSteamController : public UinputKeyboard {
120public:
Prabir Pradhanb7d434e2022-10-14 22:41:38 +0000121 static constexpr const char* DEVICE_NAME = "Test Uinput Steam Controller";
122 static constexpr int16_t PRODUCT_ID = 44;
123
Siarhei Vishniakoua0d2b802020-05-13 14:00:31 -0700124 template <class D, class... Ts>
125 friend std::unique_ptr<D> createUinputDevice(Ts... args);
126
127private:
Prabir Pradhanb7d434e2022-10-14 22:41:38 +0000128 explicit UinputSteamController();
Siarhei Vishniakoua0d2b802020-05-13 14:00:31 -0700129};
130
Prabir Pradhanb7d434e2022-10-14 22:41:38 +0000131// --- UinputExternalStylus ---
132
Prabir Pradhane1a41a82022-10-14 18:06:50 +0000133// A stylus that reports button presses.
134class UinputExternalStylus : public UinputKeyboard {
135public:
Prabir Pradhanb7d434e2022-10-14 22:41:38 +0000136 static constexpr const char* DEVICE_NAME = "Test Uinput External Stylus";
137 static constexpr int16_t PRODUCT_ID = 45;
138
Prabir Pradhane1a41a82022-10-14 18:06:50 +0000139 template <class D, class... Ts>
140 friend std::unique_ptr<D> createUinputDevice(Ts... args);
141
142private:
Prabir Pradhanb7d434e2022-10-14 22:41:38 +0000143 explicit UinputExternalStylus();
Prabir Pradhane1a41a82022-10-14 18:06:50 +0000144};
145
Prabir Pradhan484d55a2022-10-14 23:17:16 +0000146// --- UinputExternalStylusWithPressure ---
147
148// A stylus that reports button presses and pressure values.
149class UinputExternalStylusWithPressure : public UinputKeyboard {
150public:
151 static constexpr const char* DEVICE_NAME = "Test Uinput External Stylus With Pressure";
152 static constexpr int16_t PRODUCT_ID = 46;
153
154 static constexpr int32_t RAW_PRESSURE_MIN = 0;
155 static constexpr int32_t RAW_PRESSURE_MAX = 255;
156
157 void setPressure(int32_t pressure);
158
159 template <class D, class... Ts>
160 friend std::unique_ptr<D> createUinputDevice(Ts... args);
161
162private:
163 void configureDevice(int fd, uinput_user_dev* device) override;
164
165 explicit UinputExternalStylusWithPressure();
166};
167
Prabir Pradhan37a819b2023-08-22 23:20:16 +0000168// --- UinputKeyboardWithUsage ---
169// A keyboard that supports EV_MSC MSC_SCAN through which it can report HID usage codes.
170
171class UinputKeyboardWithHidUsage : public UinputKeyboard {
172public:
173 static constexpr const char* DEVICE_NAME = "Test Uinput Keyboard With Usage";
174 static constexpr int16_t PRODUCT_ID = 47;
175
176 template <class D, class... Ts>
177 friend std::unique_ptr<D> createUinputDevice(Ts... args);
178
179protected:
180 explicit UinputKeyboardWithHidUsage(std::initializer_list<int> keys);
181
182 void configureDevice(int fd, uinput_user_dev* device) override;
183};
184
Arthur Hungaab25622020-01-16 11:22:11 +0800185// --- UinputTouchScreen ---
Prabir Pradhanb7d434e2022-10-14 22:41:38 +0000186
187// A multi-touch touchscreen device with specific size that also supports styluses.
Prabir Pradhan124ea442022-10-28 20:27:44 +0000188class UinputTouchScreen : public UinputKeyboard {
Arthur Hungaab25622020-01-16 11:22:11 +0800189public:
Prabir Pradhanb7d434e2022-10-14 22:41:38 +0000190 static constexpr const char* DEVICE_NAME = "Test Uinput Touch Screen";
Prabir Pradhan37a819b2023-08-22 23:20:16 +0000191 static constexpr int16_t PRODUCT_ID = 48;
Prabir Pradhanb7d434e2022-10-14 22:41:38 +0000192
Arthur Hungaab25622020-01-16 11:22:11 +0800193 static const int32_t RAW_TOUCH_MIN = 0;
194 static const int32_t RAW_TOUCH_MAX = 31;
195 static const int32_t RAW_ID_MIN = 0;
196 static const int32_t RAW_ID_MAX = 9;
197 static const int32_t RAW_SLOT_MIN = 0;
198 static const int32_t RAW_SLOT_MAX = 9;
199 static const int32_t RAW_PRESSURE_MIN = 0;
200 static const int32_t RAW_PRESSURE_MAX = 255;
201
202 template <class D, class... Ts>
203 friend std::unique_ptr<D> createUinputDevice(Ts... args);
204
205 void sendSlot(int32_t slot);
206 void sendTrackingId(int32_t trackingId);
207 void sendDown(const Point& point);
208 void sendMove(const Point& point);
Prabir Pradhanc09ec6d2023-08-14 22:31:43 +0000209 void sendPressure(int32_t pressure);
arthurhungcc7f9802020-04-30 17:55:40 +0800210 void sendPointerUp();
Arthur Hungaab25622020-01-16 11:22:11 +0800211 void sendUp();
212 void sendToolType(int32_t toolType);
Siarhei Vishniakoufd97e9d2022-01-04 16:59:04 -0800213 void sendSync();
Arthur Hungaab25622020-01-16 11:22:11 +0800214
215 const Point getCenterPoint();
216
217protected:
Arpit Singh440bf652023-08-09 09:23:43 +0000218 explicit UinputTouchScreen(const Rect& size, const std::string& physicalPort = "");
Arthur Hungaab25622020-01-16 11:22:11 +0800219
220private:
221 void configureDevice(int fd, uinput_user_dev* device) override;
222 const Rect mSize;
Arpit Singh440bf652023-08-09 09:23:43 +0000223 const std::string mPhysicalPort;
Arthur Hungaab25622020-01-16 11:22:11 +0800224};
225
Prabir Pradhane0105c92019-12-26 12:32:13 -0800226} // namespace android