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