TouchEvent (1/n): Adding TouchModeEvent to InputChannel

This CL detaches the touch mode state update from focus update. It does
that by introducing a new internal event (TouchModeEvent). This CL also
adds this event to InputChannel and related processing logic to
InputPublisher and InputConsumer. InputDispatcher will process two
different events now: FocusEvent when gaining/losing focus and
TouchModeEvent when entering/leaving touch mode.

Test: atest libinput_tests
Bug: 193718270
Change-Id: Ie4e5b6e8e798f12d7203127b4559fa40d38788de
diff --git a/include/input/Input.h b/include/input/Input.h
index b09ff48..a7d34e2 100644
--- a/include/input/Input.h
+++ b/include/input/Input.h
@@ -883,6 +883,25 @@
     float mX, mY;
 };
 
+/*
+ * Touch mode events.
+ */
+class TouchModeEvent : public InputEvent {
+public:
+    virtual ~TouchModeEvent() {}
+
+    virtual int32_t getType() const override { return AINPUT_EVENT_TYPE_TOUCH_MODE; }
+
+    inline bool isInTouchMode() const { return mIsInTouchMode; }
+
+    void initialize(int32_t id, bool isInTouchMode);
+
+    void initialize(const TouchModeEvent& from);
+
+protected:
+    bool mIsInTouchMode;
+};
+
 /**
  * Base class for verified events.
  * Do not create a VerifiedInputEvent explicitly.
@@ -947,6 +966,7 @@
     virtual FocusEvent* createFocusEvent() = 0;
     virtual CaptureEvent* createCaptureEvent() = 0;
     virtual DragEvent* createDragEvent() = 0;
+    virtual TouchModeEvent* createTouchModeEvent() = 0;
 };
 
 /*
@@ -963,6 +983,7 @@
     virtual FocusEvent* createFocusEvent() override { return &mFocusEvent; }
     virtual CaptureEvent* createCaptureEvent() override { return &mCaptureEvent; }
     virtual DragEvent* createDragEvent() override { return &mDragEvent; }
+    virtual TouchModeEvent* createTouchModeEvent() override { return &mTouchModeEvent; }
 
 private:
     KeyEvent mKeyEvent;
@@ -970,6 +991,7 @@
     FocusEvent mFocusEvent;
     CaptureEvent mCaptureEvent;
     DragEvent mDragEvent;
+    TouchModeEvent mTouchModeEvent;
 };
 
 /*
@@ -985,6 +1007,7 @@
     virtual FocusEvent* createFocusEvent() override;
     virtual CaptureEvent* createCaptureEvent() override;
     virtual DragEvent* createDragEvent() override;
+    virtual TouchModeEvent* createTouchModeEvent() override;
 
     void recycle(InputEvent* event);
 
@@ -996,6 +1019,7 @@
     std::queue<std::unique_ptr<FocusEvent>> mFocusEventPool;
     std::queue<std::unique_ptr<CaptureEvent>> mCaptureEventPool;
     std::queue<std::unique_ptr<DragEvent>> mDragEventPool;
+    std::queue<std::unique_ptr<TouchModeEvent>> mTouchModeEventPool;
 };
 
 } // namespace android
diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h
index 360dfbf..62cf67e 100644
--- a/include/input/InputTransport.h
+++ b/include/input/InputTransport.h
@@ -72,6 +72,7 @@
         CAPTURE,
         DRAG,
         TIMELINE,
+        TOUCH_MODE,
     };
 
     struct Header {
@@ -206,6 +207,15 @@
 
             inline size_t size() const { return sizeof(Timeline); }
         } timeline;
+
+        struct TouchMode {
+            int32_t eventId;
+            // The following 2 fields take up 4 bytes total
+            bool isInTouchMode;
+            uint8_t empty[3];
+
+            inline size_t size() const { return sizeof(TouchMode); }
+        } touchMode;
     } __attribute__((aligned(8))) body;
 
     bool isValid(size_t actualSize) const;
@@ -387,6 +397,15 @@
      */
     status_t publishDragEvent(uint32_t seq, int32_t eventId, float x, float y, bool isExiting);
 
+    /* Publishes a touch mode event to the input channel.
+     *
+     * Returns OK on success.
+     * Returns WOULD_BLOCK if the channel is full.
+     * Returns DEAD_OBJECT if the channel's peer has been closed.
+     * Other errors probably indicate that the channel is broken.
+     */
+    status_t publishTouchModeEvent(uint32_t seq, int32_t eventId, bool isInTouchMode);
+
     struct Finished {
         uint32_t seq;
         bool handled;
@@ -657,6 +676,7 @@
     static void initializeFocusEvent(FocusEvent* event, const InputMessage* msg);
     static void initializeCaptureEvent(CaptureEvent* event, const InputMessage* msg);
     static void initializeDragEvent(DragEvent* event, const InputMessage* msg);
+    static void initializeTouchModeEvent(TouchModeEvent* event, const InputMessage* msg);
     static void addSample(MotionEvent* event, const InputMessage* msg);
     static bool canAddSample(const Batch& batch, const InputMessage* msg);
     static ssize_t findSampleNoLaterThan(const Batch& batch, nsecs_t time);