Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d9be36c8 authored by Christopher Tate's avatar Christopher Tate
Browse files

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
parent 154aa355
Loading
Loading
Loading
Loading
+12 −8
Original line number Diff line number Diff line
@@ -3193,11 +3193,13 @@ void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle> >& inpu
                LOGD("Focus left window: %s",
                        mFocusedWindowHandle->name.string());
#endif
                if (mFocusedWindowHandle->inputChannel != NULL) {
                    CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
                            "focus left window");
                    synthesizeCancelationEventsForInputChannelLocked(
                            mFocusedWindowHandle->inputChannel, options);
                }
            }
            if (newFocusedWindowHandle != NULL) {
#if DEBUG_FOCUS
                LOGD("Focus entered window: %s",
@@ -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
                if (touchedWindow.windowHandle->inputChannel != NULL) {
                    CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
                            "touched window was removed");
                    synthesizeCancelationEventsForInputChannelLocked(
                            touchedWindow.windowHandle->inputChannel, options);
                }
                mTouchState.windows.removeAt(i--);
            }
        }
+4 −2
Original line number Diff line number Diff line
@@ -6573,9 +6573,11 @@ public class WindowManagerService extends IWindowManager.Stub
                    }
                    synchronized (mWindowMap) {
                        // !!! TODO: ANR the drag-receiving app
                        if (mDragState != null) {
                            mDragState.mDragResult = false;
                            mDragState.endDragLw();
                        }
                    }
                    break;
                }