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