From 17d28ca3d76e943e30bdaafb98596cf35bb45087 Mon Sep 17 00:00:00 2001 From: Michael Wright Date: Thu, 31 Oct 2013 17:47:45 -0700 Subject: [PATCH] Check view and focus invariants after calling into app When we dispatch input events into the actual application, make sure the input invariants we rely on haven't changed. If they have, we drop the event and log why. Bug: 11399505 Change-Id: Id772e41ca41dc332bb02725ab486e3b10a73c220 --- core/java/android/view/ViewRootImpl.java | 37 +++++++++++++++++------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 637af6f54fd60..bc0d7e3c806be 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -3393,16 +3393,7 @@ public final class ViewRootImpl implements ViewParent, public final void deliver(QueuedInputEvent q) { if ((q.mFlags & QueuedInputEvent.FLAG_FINISHED) != 0) { forward(q); - } else if (mView == null || !mAdded) { - Slog.w(TAG, "Dropping event due to root view being removed: " + q.mEvent); - finish(q, false); - } else if (!mAttachInfo.mHasWindowFocus && - !q.mEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER) && - !isTerminalInputEvent(q.mEvent)) { - // If this is a focused event and the window doesn't currently have input focus, - // then drop this event. This could be an event that came back from the previous - // stage but the window has lost focus in the meantime. - Slog.w(TAG, "Dropping event due to no window focus: " + q.mEvent); + } else if (shouldDropInputEvent(q)) { finish(q, false); } else { apply(q, onProcess(q)); @@ -3461,6 +3452,22 @@ public final class ViewRootImpl implements ViewParent, } } + protected boolean shouldDropInputEvent(QueuedInputEvent q) { + if (mView == null || !mAdded) { + Slog.w(TAG, "Dropping event due to root view being removed: " + q.mEvent); + return true; + } else if (!mAttachInfo.mHasWindowFocus && + !q.mEvent.isFromSource(InputDevice.SOURCE_CLASS_POINTER) && + !isTerminalInputEvent(q.mEvent)) { + // If this is a focused event and the window doesn't currently have input focus, + // then drop this event. This could be an event that came back from the previous + // stage but the window has lost focus in the meantime. + Slog.w(TAG, "Dropping event due to no window focus: " + q.mEvent); + return true; + } + return false; + } + void dump(String prefix, PrintWriter writer) { if (mNext != null) { mNext.dump(prefix, writer); @@ -3846,6 +3853,10 @@ public final class ViewRootImpl implements ViewParent, return FINISH_HANDLED; } + if (shouldDropInputEvent(q)) { + return FINISH_NOT_HANDLED; + } + // If the Control modifier is held, try to interpret the key as a shortcut. if (event.getAction() == KeyEvent.ACTION_DOWN && event.isCtrlPressed() @@ -3854,12 +3865,18 @@ public final class ViewRootImpl implements ViewParent, if (mView.dispatchKeyShortcutEvent(event)) { return FINISH_HANDLED; } + if (shouldDropInputEvent(q)) { + return FINISH_NOT_HANDLED; + } } // Apply the fallback event policy. if (mFallbackEventHandler.dispatchKeyEvent(event)) { return FINISH_HANDLED; } + if (shouldDropInputEvent(q)) { + return FINISH_NOT_HANDLED; + } // Handle automatic focus changes. if (event.getAction() == KeyEvent.ACTION_DOWN) {