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 
21 namespace android {
22 
23 enum class UinputAction {
24     RELEASE = 0,
25     PRESS = 1,
26     MOVE = 2,
27     CANCEL = 3,
28 };
29 
30 class VirtualInputDevice {
31 public:
32     VirtualInputDevice(android::base::unique_fd fd);
33     virtual ~VirtualInputDevice();
34 
35 protected:
36     const android::base::unique_fd mFd;
37     bool writeInputEvent(uint16_t type, uint16_t code, int32_t value,
38                          std::chrono::nanoseconds eventTime);
39     bool writeEvKeyEvent(int32_t androidCode, int32_t androidAction,
40                          const std::map<int, int>& evKeyCodeMapping,
41                          const std::map<int, UinputAction>& actionMapping,
42                          std::chrono::nanoseconds eventTime);
43 };
44 
45 class VirtualKeyboard : public VirtualInputDevice {
46 public:
47     static const std::map<int, int> KEY_CODE_MAPPING;
48     // Expose to share with VirtualDpad.
49     static const std::map<int, UinputAction> KEY_ACTION_MAPPING;
50     VirtualKeyboard(android::base::unique_fd fd);
51     virtual ~VirtualKeyboard() override;
52     bool writeKeyEvent(int32_t androidKeyCode, int32_t androidAction,
53                        std::chrono::nanoseconds eventTime);
54 };
55 
56 class VirtualDpad : public VirtualInputDevice {
57 public:
58     static const std::map<int, int> DPAD_KEY_CODE_MAPPING;
59     VirtualDpad(android::base::unique_fd fd);
60     virtual ~VirtualDpad() override;
61     bool writeDpadKeyEvent(int32_t androidKeyCode, int32_t androidAction,
62                            std::chrono::nanoseconds eventTime);
63 };
64 
65 class VirtualMouse : public VirtualInputDevice {
66 public:
67     // Expose to share with VirtualStylus.
68     static const std::map<int, UinputAction> BUTTON_ACTION_MAPPING;
69     VirtualMouse(android::base::unique_fd fd);
70     virtual ~VirtualMouse() override;
71     bool writeButtonEvent(int32_t androidButtonCode, int32_t androidAction,
72                           std::chrono::nanoseconds eventTime);
73     // TODO(b/259554911): changing float parameters to int32_t.
74     bool writeRelativeEvent(float relativeX, float relativeY, std::chrono::nanoseconds eventTime);
75     bool writeScrollEvent(float xAxisMovement, float yAxisMovement,
76                           std::chrono::nanoseconds eventTime);
77 
78 private:
79     static const std::map<int, int> BUTTON_CODE_MAPPING;
80 };
81 
82 class VirtualTouchscreen : public VirtualInputDevice {
83 public:
84     // Expose to share with VirtualStylus.
85     static const std::map<int, UinputAction> TOUCH_ACTION_MAPPING;
86     VirtualTouchscreen(android::base::unique_fd fd);
87     virtual ~VirtualTouchscreen() override;
88     // TODO(b/259554911): changing float parameters to int32_t.
89     bool writeTouchEvent(int32_t pointerId, int32_t toolType, int32_t action, float locationX,
90                          float locationY, float pressure, float majorAxisSize,
91                          std::chrono::nanoseconds eventTime);
92 
93 private:
94     static const std::map<int, int> TOOL_TYPE_MAPPING;
95     /* The set of active touch pointers on this device.
96      * We only allow pointer id to go up to MAX_POINTERS because the maximum slots of virtual
97      * touchscreen is set up with MAX_POINTERS. Note that in other cases Android allows pointer id
98      * to go up to MAX_POINTERS_ID.
99      */
100     std::bitset<MAX_POINTERS> mActivePointers{};
101     bool isValidPointerId(int32_t pointerId, UinputAction uinputAction);
102     bool handleTouchDown(int32_t pointerId, std::chrono::nanoseconds eventTime);
103     bool handleTouchUp(int32_t pointerId, std::chrono::nanoseconds eventTime);
104 };
105 
106 class VirtualStylus : public VirtualInputDevice {
107 public:
108     VirtualStylus(android::base::unique_fd fd);
109     ~VirtualStylus() override;
110     bool writeMotionEvent(int32_t toolType, int32_t action, int32_t locationX, int32_t locationY,
111                           int32_t pressure, int32_t tiltX, int32_t tiltY,
112                           std::chrono::nanoseconds eventTime);
113     bool writeButtonEvent(int32_t androidButtonCode, int32_t androidAction,
114                           std::chrono::nanoseconds eventTime);
115 
116 private:
117     static const std::map<int, int> TOOL_TYPE_MAPPING;
118     static const std::map<int, int> BUTTON_CODE_MAPPING;
119     // True if the stylus is touching or hovering on the screen.
120     bool mIsStylusDown;
121     bool handleStylusDown(uint16_t tool, std::chrono::nanoseconds eventTime);
122     bool handleStylusUp(uint16_t tool, std::chrono::nanoseconds eventTime);
123 };
124 
125 } // namespace android
126