Drop all dispatcher state when dispatcher is disabled.

This patch makes the dispatcher drop all of its state when it is
disabled (when the screen turns off).  This ensures that the dispatcher
does not get stuck thinking a pointer is still down if the screen
turned off while the user was touching the display (such as a fat touch
while hitting the power button).

Bug: 3098344
Change-Id: If50ef5804870aa1acd3179fd4b40e3cda58dd39d
diff --git a/include/ui/InputDispatcher.h b/include/ui/InputDispatcher.h
index b0b855e..5f77cba 100644
--- a/include/ui/InputDispatcher.h
+++ b/include/ui/InputDispatcher.h
@@ -1032,6 +1032,9 @@
     // Splitting motion events across windows.
     MotionEntry* splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds);
 
+    // Reset and drop everything the dispatcher is doing.
+    void resetAndDropEverythingLocked(const char* reason);
+
     // Dump state.
     void dumpDispatchStateLocked(String8& dump);
     void logDispatchStateLocked();
diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp
index fef8148..ae81d26 100644
--- a/libs/ui/InputDispatcher.cpp
+++ b/libs/ui/InputDispatcher.cpp
@@ -1302,6 +1302,9 @@
     }
 
 Unresponsive:
+    // Reset temporary touch state to ensure we release unnecessary references to input channels.
+    mTempTouchState.reset();
+
     nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
     updateDispatchStatisticsLocked(currentTime, entry,
             injectionResult, timeSpentWaitingForApplication);
@@ -2586,10 +2589,14 @@
         AutoMutex _l(mLock);
 
         if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
-            if (mDispatchFrozen && ! frozen) {
+            if (mDispatchFrozen && !frozen) {
                 resetANRTimeoutsLocked();
             }
 
+            if (mDispatchEnabled && !enabled) {
+                resetAndDropEverythingLocked("dispatcher is being disabled");
+            }
+
             mDispatchEnabled = enabled;
             mDispatchFrozen = frozen;
             changed = true;
@@ -2608,6 +2615,21 @@
     }
 }
 
+void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
+#if DEBUG_FOCUS
+    LOGD("Resetting and dropping all events (%s).", reason);
+#endif
+
+    synthesizeCancelationEventsForAllConnectionsLocked(InputState::CANCEL_ALL_EVENTS, reason);
+
+    resetKeyRepeatLocked();
+    releasePendingEventLocked();
+    drainInboundQueueLocked();
+    resetTargetsLocked();
+
+    mTouchState.reset();
+}
+
 void InputDispatcher::logDispatchStateLocked() {
     String8 dump;
     dumpDispatchStateLocked(dump);