Home | History | Annotate | Download | only in virtual_touchpad
      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:
     44     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 
     56   EvdevInjector() {}
     57   ~EvdevInjector() { Close(); }
     58   void Close();
     59 
     60   int GetError() const { return error_; }
     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().
    113   inline void SetUInputForTesting(UInput* uinput) { uinput_ = uinput; }
    114   // Caller must not retain pointer longer than EvdevInjector.
    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