diff options
| author | Jeff Brown <jeffbrown@google.com> | 2012-04-20 11:33:27 -0700 |
|---|---|---|
| committer | Jeff Brown <jeffbrown@google.com> | 2012-04-20 11:33:27 -0700 |
| commit | f44e39493c471b5e6a0807778c7a6439ea1b8adc (patch) | |
| tree | d07153558b48cf8ec07d752a0e527bf5679056e2 | |
| parent | 80a76276dc9440ffad30dc4c820eb7d65f4df368 (diff) | |
| download | frameworks_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.cpp | 18 | ||||
| -rw-r--r-- | services/input/InputDispatcher.h | 1 |
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; |
