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