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