summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Brown <jeffbrown@google.com>2012-04-20 11:33:27 -0700
committerJeff Brown <jeffbrown@google.com>2012-04-20 11:33:27 -0700
commitf44e39493c471b5e6a0807778c7a6439ea1b8adc (patch)
treed07153558b48cf8ec07d752a0e527bf5679056e2
parent80a76276dc9440ffad30dc4c820eb7d65f4df368 (diff)
downloadframeworks_base-f44e39493c471b5e6a0807778c7a6439ea1b8adc.zip
frameworks_base-f44e39493c471b5e6a0807778c7a6439ea1b8adc.tar.gz
frameworks_base-f44e39493c471b5e6a0807778c7a6439ea1b8adc.tar.bz2
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
-rw-r--r--services/input/InputDispatcher.cpp18
-rw-r--r--services/input/InputDispatcher.h1
2 files changed, 16 insertions, 3 deletions
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 @@ void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout
// 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 @@ void InputDispatcher::TouchState::addOrUpdateWindow(const sp<InputWindowHandle>&
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 @@ private:
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;