diff options
author | Christopher Tate <ctate@google.com> | 2011-08-16 16:09:33 -0700 |
---|---|---|
committer | Christopher Tate <ctate@google.com> | 2011-08-16 16:09:33 -0700 |
commit | d9be36c897680361da2daadba9bbc9da3c16329b (patch) | |
tree | 097fbf3074d35133c91c7a95890c6eb8deb37166 /services/input | |
parent | 154aa355f0ed0374a4b4db222419639ec1a385fe (diff) | |
download | frameworks_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.cpp | 20 |
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--); } } |