diff options
Diffstat (limited to 'core/java/android/view/ViewRootImpl.java')
-rw-r--r-- | core/java/android/view/ViewRootImpl.java | 110 |
1 files changed, 99 insertions, 11 deletions
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 9461068..bc0d7e3 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -77,8 +77,10 @@ import com.android.internal.policy.PolicyManager; import com.android.internal.view.BaseSurfaceHolder; import com.android.internal.view.RootViewSurfaceTaker; +import java.io.FileDescriptor; import java.io.IOException; import java.io.OutputStream; +import java.io.PrintWriter; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.HashSet; @@ -3391,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)); @@ -3458,6 +3451,28 @@ public final class ViewRootImpl implements ViewParent, finishInputEvent(q); } } + + 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); + } + } } /** @@ -3595,6 +3610,16 @@ public final class ViewRootImpl implements ViewParent, mQueueLength -= 1; Trace.traceCounter(Trace.TRACE_TAG_INPUT, mTraceCounter, mQueueLength); } + + @Override + void dump(String prefix, PrintWriter writer) { + writer.print(prefix); + writer.print(getClass().getName()); + writer.print(": mQueueLength="); + writer.println(mQueueLength); + + super.dump(prefix, writer); + } } /** @@ -3828,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() @@ -3836,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) { @@ -5201,6 +5236,53 @@ public final class ViewRootImpl implements ViewParent, mView.debug(); } + public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { + String innerPrefix = prefix + " "; + writer.print(prefix); writer.println("ViewRoot:"); + writer.print(innerPrefix); writer.print("mAdded="); writer.print(mAdded); + writer.print(" mRemoved="); writer.println(mRemoved); + writer.print(innerPrefix); writer.print("mConsumeBatchedInputScheduled="); + writer.println(mConsumeBatchedInputScheduled); + writer.print(innerPrefix); writer.print("mPendingInputEventCount="); + writer.println(mPendingInputEventCount); + writer.print(innerPrefix); writer.print("mProcessInputEventsScheduled="); + writer.println(mProcessInputEventsScheduled); + writer.print(innerPrefix); writer.print("mTraversalScheduled="); + writer.print(mTraversalScheduled); + if (mTraversalScheduled) { + writer.print(" (barrier="); writer.print(mTraversalBarrier); writer.println(")"); + } else { + writer.println(); + } + mFirstInputStage.dump(innerPrefix, writer); + + mChoreographer.dump(prefix, writer); + + writer.print(prefix); writer.println("View Hierarchy:"); + dumpViewHierarchy(innerPrefix, writer, mView); + } + + private void dumpViewHierarchy(String prefix, PrintWriter writer, View view) { + writer.print(prefix); + if (view == null) { + writer.println("null"); + return; + } + writer.println(view.toString()); + if (!(view instanceof ViewGroup)) { + return; + } + ViewGroup grp = (ViewGroup)view; + final int N = grp.getChildCount(); + if (N <= 0) { + return; + } + prefix = prefix + " "; + for (int i=0; i<N; i++) { + dumpViewHierarchy(prefix, writer, grp.getChildAt(i)); + } + } + public void dumpGfxInfo(int[] info) { info[0] = info[1] = 0; if (mView != null) { @@ -5570,7 +5652,13 @@ public final class ViewRootImpl implements ViewParent, if (mConsumeBatchedInputScheduled) { mConsumeBatchedInputScheduled = false; if (mInputEventReceiver != null) { - mInputEventReceiver.consumeBatchedInputEvents(frameTimeNanos); + if (mInputEventReceiver.consumeBatchedInputEvents(frameTimeNanos)) { + // If we consumed a batch here, we want to go ahead and schedule the + // consumption of batched input events on the next frame. Otherwise, we would + // wait until we have more input events pending and might get starved by other + // things occurring in the process. + scheduleConsumeBatchedInput(); + } } doProcessInputEvents(); } |