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