summaryrefslogtreecommitdiffstats
path: root/services/input
diff options
context:
space:
mode:
authorChristopher Tate <ctate@google.com>2011-08-16 16:09:33 -0700
committerChristopher Tate <ctate@google.com>2011-08-16 16:09:33 -0700
commitd9be36c897680361da2daadba9bbc9da3c16329b (patch)
tree097fbf3074d35133c91c7a95890c6eb8deb37166 /services/input
parent154aa355f0ed0374a4b4db222419639ec1a385fe (diff)
downloadframeworks_base-d9be36c897680361da2daadba9bbc9da3c16329b.zip
frameworks_base-d9be36c897680361da2daadba9bbc9da3c16329b.tar.gz
frameworks_base-d9be36c897680361da2daadba9bbc9da3c16329b.tar.bz2
Don't crash if a drag recipient throws an uncaught exception
There turn out to be two distinct bugs leading to runtime restarts. The first, dating from at least Android 3.1, is that following certain kinds of app crashes we properly clean up the drag-state bookkeeping, but aren't prepared in the case of the drag-target timeout clock firing with a now- null drag state in effect. We now catch that edge condition and don't NPE (and note that there was already similar code around the separate timeout when an app is *starting* the drag process). The second bug is that some new-in-ICS code in the input channel management wasn't prepared for certain cases where the current touch window could have become unusable and its input channel torn down summarily in the case of the aforesaid app crash during drag. The code now makes sure that there really is an input channel that needs to be flushed / cancelled prior to attempting that operation. Fixes bug 5173534 Change-Id: Idaae158ecfb4b93456ab1425769b669962893c00
Diffstat (limited to 'services/input')
-rw-r--r--services/input/InputDispatcher.cpp20
1 files changed, 12 insertions, 8 deletions
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index 22372cf..542e46b 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -3193,10 +3193,12 @@ void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle> >& inpu
LOGD("Focus left window: %s",
mFocusedWindowHandle->name.string());
#endif
- CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
- "focus left window");
- synthesizeCancelationEventsForInputChannelLocked(
- mFocusedWindowHandle->inputChannel, options);
+ if (mFocusedWindowHandle->inputChannel != NULL) {
+ CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
+ "focus left window");
+ synthesizeCancelationEventsForInputChannelLocked(
+ mFocusedWindowHandle->inputChannel, options);
+ }
}
if (newFocusedWindowHandle != NULL) {
#if DEBUG_FOCUS
@@ -3213,10 +3215,12 @@ void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle> >& inpu
#if DEBUG_FOCUS
LOGD("Touched window was removed: %s", touchedWindow.windowHandle->name.string());
#endif
- CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
- "touched window was removed");
- synthesizeCancelationEventsForInputChannelLocked(
- touchedWindow.windowHandle->inputChannel, options);
+ if (touchedWindow.windowHandle->inputChannel != NULL) {
+ CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
+ "touched window was removed");
+ synthesizeCancelationEventsForInputChannelLocked(
+ touchedWindow.windowHandle->inputChannel, options);
+ }
mTouchState.windows.removeAt(i--);
}
}