1 #ifndef ANDROID_DVR_EVDEV_INJECTOR_H 2 #define ANDROID_DVR_EVDEV_INJECTOR_H 3 4 #include <android-base/unique_fd.h> 5 #include <linux/uinput.h> 6 #include <utils/String8.h> 7 8 #include <cstdint> 9 #include <memory> 10 #include <unordered_set> 11 12 namespace android { 13 namespace dvr { 14 15 // Simulated evdev input device. 16 // 17 class EvdevInjector { 18 public: 19 // EvdevInjector-specific error codes are negative integers; other non-zero 20 // values returned from public routines are |errno| codes from underlying I/O. 21 // EvdevInjector maintains a 'sticky' error state, similar to |errno|, so that 22 // a caller can perform a sequence of operations and check for errors at the 23 // end using |GetError()|. In general, the first such error will be recorded 24 // and will suppress effects of further device operations until |ResetError()| 25 // is called. 26 // 27 enum : int { 28 ERROR_DEVICE_NAME = -1, // Invalid device name. 29 ERROR_PROPERTY_RANGE = -2, // |INPUT_PROP_*| code out of range. 30 ERROR_KEY_RANGE = -3, // |KEY_*|/|BTN_*| code out of range. 31 ERROR_ABS_RANGE = -4, // |ABS_*| code out of range. 32 ERROR_SEQUENCING = -5, // Configure/Send out of order. 33 ERROR_REL_RANGE = -6, // |REL_*| code out of range. 34 }; 35 36 // Key event |value| is not defined in <linux/input.h>. 37 enum : int32_t { KEY_RELEASE = 0, KEY_PRESS = 1, KEY_REPEAT = 2 }; 38 39 // UInput provides a shim to intercept /dev/uinput operations 40 // just above the system call level, for testing. 41 // 42 class UInput { 43 public: UInput()44 UInput() {} ~UInput()45 virtual ~UInput() {} 46 virtual int Open(); 47 virtual int Close(); 48 virtual int Write(const void* buf, size_t count); 49 virtual int IoctlVoid(int request); 50 virtual int IoctlSetInt(int request, int value); 51 52 private: 53 base::unique_fd fd_; 54 }; 55 EvdevInjector()56 EvdevInjector() {} ~EvdevInjector()57 ~EvdevInjector() { Close(); } 58 void Close(); 59 GetError()60 int GetError() const { return error_; } ResetError()61 void ResetError() { error_ = 0; } 62 63 // Configuration must be performed before sending any events. 64 // |ConfigureBegin()| must be called first, and |ConfigureEnd()| last, 65 // with zero or more other |Configure...()| calls in between in any order. 66 67 // Configure the basic evdev device properties; must be called first. 68 int ConfigureBegin(const char* device_name, int16_t bustype, int16_t vendor, 69 int16_t product, int16_t version); 70 71 // Configure an optional input device property. 72 // @param property One of the |INPUT_PROP_*| constants from <linux/input.h>. 73 int ConfigureInputProperty(int property); 74 75 // Configure an input key. 76 // @param key One of the |KEY_*| or |BTN_*| constants from <linux/input.h>. 77 int ConfigureKey(uint16_t key); 78 79 // Configure an absolute axis. 80 // @param abs_type One of the |KEY_*| or |BTN_*| constants from 81 // <linux/input.h>. 82 int ConfigureAbs(uint16_t abs_type, int32_t min, int32_t max, int32_t fuzz, 83 int32_t flat); 84 85 // Configure the number of multitouch slots. 86 int ConfigureAbsSlots(int slots); 87 88 // Configure multitouch coordinate range. 89 int ConfigureMultiTouchXY(int32_t x0, int32_t y0, int32_t x1, int32_t y1); 90 91 // Configure a relative axis. 92 // @param rel_type One of the |REL_*| constants from <linux/input.h>. 93 int ConfigureRel(uint16_t rel_type); 94 95 // Complete configuration and create the input device. 96 int ConfigureEnd(); 97 98 // Send various events. 99 // 100 int Send(uint16_t type, uint16_t code, int32_t value); 101 int SendSynReport(); 102 int SendKey(uint16_t code, int32_t value); 103 int SendAbs(uint16_t code, int32_t value); 104 int SendRel(uint16_t code, int32_t value); 105 int SendMultiTouchSlot(int32_t slot); 106 int SendMultiTouchXY(int32_t slot, int32_t id, int32_t x, int32_t y); 107 int SendMultiTouchLift(int32_t slot); 108 109 void dumpInternal(String8& result); 110 111 protected: 112 // Must be called only between construction and ConfigureBegin(). SetUInputForTesting(UInput * uinput)113 inline void SetUInputForTesting(UInput* uinput) { uinput_ = uinput; } 114 // Caller must not retain pointer longer than EvdevInjector. GetUiDevForTesting()115 inline const uinput_user_dev* GetUiDevForTesting() const { return &uidev_; } 116 117 private: 118 // Phase to enforce that configuration is complete before events are sent. 119 enum class State { NEW, CONFIGURING, READY, CLOSED }; 120 121 // Sets |error_| if it is not already set; returns |code|. 122 int Error(int code); 123 124 // Returns a nonzero error if the injector is not in the required |state|. 125 int RequireState(State state); 126 127 // Configures an event type if necessary. 128 // @param type One of the |EV_*| constants from <linux/input.h>. 129 int EnableEventType(uint16_t type); 130 131 // Active pointer to owned or testing UInput. 132 UInput* uinput_ = nullptr; 133 std::unique_ptr<UInput> owned_uinput_; 134 135 State state_ = State::NEW; 136 int error_ = 0; 137 uinput_user_dev uidev_; 138 std::unordered_set<uint16_t> enabled_event_types_; 139 int32_t latest_slot_ = -1; 140 141 EvdevInjector(const EvdevInjector&) = delete; 142 void operator=(const EvdevInjector&) = delete; 143 }; 144 145 } // namespace dvr 146 } // namespace android 147 148 #endif // ANDROID_DVR_EVDEV_INJECTOR_H 149