When ANR happens, only remove ANR'd window.

The system bar uses input event injection to inject BACK keys
into the application.  If the receiving application ANRs, we
used to clear the touch state unconditionally.  Doing so would
prevent the system bar from receiving the ACTION_UP event so
the back button would continue to appear pressed until pressed
again.

Now we are more careful to only remove the specific ANR'd
window from the touch state.  Other windows should continue
to receive touch events as usual.

Change-Id: If86bfc323e2c7aed82ca1334bc67da649953168f
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index da3548f..dad4ef4 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -970,14 +970,17 @@
         // Give up.
         mInputTargetWaitTimeoutExpired = true;
 
-        // Release the touch targets.
-        mTouchState.reset();
-
         // Input state will not be realistic.  Mark it out of sync.
         if (inputChannel.get()) {
             ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
             if (connectionIndex >= 0) {
                 sp<Connection> connection = mConnectionsByFd.valueAt(connectionIndex);
+                sp<InputWindowHandle> windowHandle = connection->inputWindowHandle;
+
+                if (windowHandle != NULL) {
+                    mTouchState.removeWindow(windowHandle);
+                }
+
                 if (connection->status == Connection::STATUS_NORMAL) {
                     CancelationOptions options(CancelationOptions::CANCEL_ALL_EVENTS,
                             "application not responding");
@@ -4146,6 +4149,15 @@
     touchedWindow.pointerIds = pointerIds;
 }
 
+void InputDispatcher::TouchState::removeWindow(const sp<InputWindowHandle>& windowHandle) {
+    for (size_t i = 0; i < windows.size(); i++) {
+        if (windows.itemAt(i).windowHandle == windowHandle) {
+            windows.removeAt(i);
+            return;
+        }
+    }
+}
+
 void InputDispatcher::TouchState::filterNonAsIsTouchWindows() {
     for (size_t i = 0 ; i < windows.size(); ) {
         TouchedWindow& window = windows.editItemAt(i);
diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h
index 91f7554..07ca9d5 100644
--- a/services/input/InputDispatcher.h
+++ b/services/input/InputDispatcher.h
@@ -926,6 +926,7 @@
         void copyFrom(const TouchState& other);
         void addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle,
                 int32_t targetFlags, BitSet32 pointerIds);
+        void removeWindow(const sp<InputWindowHandle>& windowHandle);
         void filterNonAsIsTouchWindows();
         sp<InputWindowHandle> getFirstForegroundWindowHandle() const;
         bool isSlippery() const;