InputReader: Clear the multi-touch state when the device is reset

This is a partial revert of Change-Id:
Ic59d9fcb4e13fe262c422825c2485185004b719b

That CL introduced a behavior where the multi-touch state was never
reset, assuming there was no way to forcefully sync the state with the
kernel. This leads to issues when there are overflows of the kernel
buffer, in which case events may be dropped. Dropped events can lead to
the touch state being out of sync, which can result in behaviors such as
stuck pointers.

To avoid this, we will start resetting the touch state again when the
device is reset, such as after a buffer overflow.

We will follow this with the long-term fix of using EVIOCGMTSLOTS to
sync the multi-touch state in b/291626046.

Bug: 301332406
Test: atest inputflinger_tests
Test: manual, see b/301332406#comment24
Change-Id: If3027840bfff52adce086b853adc7284adf3777d
diff --git a/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp b/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
index 2dd05f5..5a74a42 100644
--- a/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
@@ -35,12 +35,10 @@
 MultiTouchInputMapper::~MultiTouchInputMapper() {}
 
 std::list<NotifyArgs> MultiTouchInputMapper::reset(nsecs_t when) {
-    // The evdev multi-touch protocol does not allow userspace applications to query the initial or
-    // current state of the pointers at any time. This means if we clear our accumulated state when
-    // resetting the input mapper, there's no way to rebuild the full initial state of the pointers.
-    // We can only wait for updates to all the pointers and axes. Rather than clearing the state and
-    // rebuilding the state from scratch, we work around this kernel API limitation by never
-    // fully clearing any state specific to the multi-touch protocol.
+    // TODO(b/291626046): Sync the MT state with the kernel using EVIOCGMTSLOTS.
+    mMultiTouchMotionAccumulator.reset(getDeviceContext());
+    mPointerIdBits.clear();
+
     return TouchInputMapper::reset(when);
 }
 
diff --git a/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.cpp b/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.cpp
index b0fc903..d06514a 100644
--- a/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.cpp
+++ b/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.cpp
@@ -30,23 +30,29 @@
                                             size_t slotCount, bool usingSlotsProtocol) {
     mUsingSlotsProtocol = usingSlotsProtocol;
     mSlots = std::vector<Slot>(slotCount);
+    reset(deviceContext);
+}
 
-    mCurrentSlot = -1;
-    if (mUsingSlotsProtocol) {
-        // Query the driver for the current slot index and use it as the initial slot before we
-        // start reading events from the device.  It is possible that the current slot index will
-        // not be the same as it was when the first event was written into the evdev buffer, which
-        // means the input mapper could start out of sync with the initial state of the events in
-        // the evdev buffer. In the extremely unlikely case that this happens, the data from two
-        // slots will be confused until the next ABS_MT_SLOT event is received. This can cause the
-        // touch point to "jump", but at least there will be no stuck touches.
-        int32_t initialSlot;
-        if (const auto status = deviceContext.getAbsoluteAxisValue(ABS_MT_SLOT, &initialSlot);
-            status == OK) {
-            mCurrentSlot = initialSlot;
-        } else {
-            ALOGD("Could not retrieve current multi-touch slot index. status=%d", status);
-        }
+void MultiTouchMotionAccumulator::reset(const InputDeviceContext& deviceContext) {
+    resetSlots();
+
+    if (!mUsingSlotsProtocol) {
+        return;
+    }
+
+    // Query the driver for the current slot index and use it as the initial slot before we
+    // start reading events from the device.  It is possible that the current slot index will
+    // not be the same as it was when the first event was written into the evdev buffer, which
+    // means the input mapper could start out of sync with the initial state of the events in
+    // the evdev buffer. In the extremely unlikely case that this happens, the data from two
+    // slots will be confused until the next ABS_MT_SLOT event is received. This can cause the
+    // touch point to "jump", but at least there will be no stuck touches.
+    int32_t initialSlot;
+    if (const auto status = deviceContext.getAbsoluteAxisValue(ABS_MT_SLOT, &initialSlot);
+        status == OK) {
+        mCurrentSlot = initialSlot;
+    } else {
+        ALOGD("Could not retrieve current multi-touch slot index. status=%d", status);
     }
 }
 
diff --git a/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.h b/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.h
index 0e3e2bb..5b55e3d 100644
--- a/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.h
+++ b/services/inputflinger/reader/mapper/accumulator/MultiTouchMotionAccumulator.h
@@ -83,6 +83,7 @@
         LOG_ALWAYS_FATAL_IF(index < 0 || index >= mSlots.size(), "Invalid index: %zu", index);
         return mSlots[index];
     }
+    void reset(const InputDeviceContext& deviceContext);
 
 private:
     int32_t mCurrentSlot;