Loading core/java/android/view/ViewRootImpl.java +104 −45 Original line number Original line Diff line number Diff line Loading @@ -107,6 +107,7 @@ public final class ViewRootImpl implements ViewParent, private static final boolean DEBUG_IMF = false || LOCAL_LOGV; private static final boolean DEBUG_IMF = false || LOCAL_LOGV; private static final boolean DEBUG_CONFIGURATION = false || LOCAL_LOGV; private static final boolean DEBUG_CONFIGURATION = false || LOCAL_LOGV; private static final boolean DEBUG_FPS = false; private static final boolean DEBUG_FPS = false; private static final boolean DEBUG_INPUT_PROCESSING = false || LOCAL_LOGV; private static final boolean USE_RENDER_THREAD = false; private static final boolean USE_RENDER_THREAD = false; Loading Loading @@ -231,24 +232,38 @@ public final class ViewRootImpl implements ViewParent, int mClientWindowLayoutFlags; int mClientWindowLayoutFlags; boolean mLastOverscanRequested; boolean mLastOverscanRequested; /** @hide */ /** Event was not handled and is finished. * @hide */ public static final int EVENT_NOT_HANDLED = 0; public static final int EVENT_NOT_HANDLED = 0; /** @hide */ /** Event was handled and is finished. * @hide */ public static final int EVENT_HANDLED = 1; public static final int EVENT_HANDLED = 1; /** @hide */ /** Event is waiting on the IME. public static final int EVENT_IN_PROGRESS = 2; * @hide */ public static final int EVENT_PENDING_IME = 2; /** Event requires post-IME dispatch. * @hide */ public static final int EVENT_POST_IME = 3; // Pool of queued input events. // Pool of queued input events. private static final int MAX_QUEUED_INPUT_EVENT_POOL_SIZE = 10; private static final int MAX_QUEUED_INPUT_EVENT_POOL_SIZE = 10; private QueuedInputEvent mQueuedInputEventPool; private QueuedInputEvent mQueuedInputEventPool; private int mQueuedInputEventPoolSize; private int mQueuedInputEventPoolSize; // Input event queue. /* Input event queue. QueuedInputEvent mFirstPendingInputEvent; * Pending input events are input events waiting to be handled by the application. Current * input events are input events which are being handled but are waiting on some action by the * IME, even if they themselves may not need to be handled by the IME. */ QueuedInputEvent mPendingInputEventHead; QueuedInputEvent mPendingInputEventTail; int mPendingInputEventCount; int mPendingInputEventCount; QueuedInputEvent mCurrentInputEvent; QueuedInputEvent mCurrentInputEventHead; QueuedInputEvent mCurrentInputEventTail; int mCurrentInputEventCount; boolean mProcessInputEventsScheduled; boolean mProcessInputEventsScheduled; String mPendingInputEventQueueLengthCounterName = "pq"; String mPendingInputEventQueueLengthCounterName = "pq"; String mCurrentInputEventQueueLengthCounterName = "cq"; boolean mWindowAttributesChanged = false; boolean mWindowAttributesChanged = false; int mWindowAttributesChangesFlag = 0; int mWindowAttributesChangesFlag = 0; Loading Loading @@ -646,6 +661,7 @@ public final class ViewRootImpl implements ViewParent, } } mPendingInputEventQueueLengthCounterName = "pq:" + attrs.getTitle(); mPendingInputEventQueueLengthCounterName = "pq:" + attrs.getTitle(); mCurrentInputEventQueueLengthCounterName = "cq:" + attrs.getTitle(); } } } } } } Loading Loading @@ -3438,17 +3454,13 @@ public final class ViewRootImpl implements ViewParent, if (DEBUG_IMF) if (DEBUG_IMF) Log.v(TAG, "Sending trackball event to IME: seq=" Log.v(TAG, "Sending trackball event to IME: seq=" + seq + " event=" + event); + seq + " event=" + event); int result = imm.dispatchTrackballEvent(mView.getContext(), seq, event, return imm.dispatchTrackballEvent(mView.getContext(), seq, event, mInputMethodCallback); mInputMethodCallback); if (result != EVENT_NOT_HANDLED) { return result; } } } } } } } // Not dispatching to IME, continue with post IME actions. return EVENT_POST_IME; return deliverTrackballEventPostIme(q); } } private int deliverTrackballEventPostIme(QueuedInputEvent q) { private int deliverTrackballEventPostIme(QueuedInputEvent q) { Loading Loading @@ -3596,17 +3608,13 @@ public final class ViewRootImpl implements ViewParent, if (DEBUG_IMF) if (DEBUG_IMF) Log.v(TAG, "Sending generic motion event to IME: seq=" Log.v(TAG, "Sending generic motion event to IME: seq=" + seq + " event=" + event); + seq + " event=" + event); int result = imm.dispatchGenericMotionEvent(mView.getContext(), seq, event, return imm.dispatchGenericMotionEvent(mView.getContext(), seq, event, mInputMethodCallback); mInputMethodCallback); if (result != EVENT_NOT_HANDLED) { return result; } } } } } } } // Not dispatching to IME, continue with post IME actions. return EVENT_POST_IME; return deliverGenericMotionEventPostIme(q); } } private int deliverGenericMotionEventPostIme(QueuedInputEvent q) { private int deliverGenericMotionEventPostIme(QueuedInputEvent q) { Loading Loading @@ -3811,17 +3819,13 @@ public final class ViewRootImpl implements ViewParent, final int seq = event.getSequenceNumber(); final int seq = event.getSequenceNumber(); if (DEBUG_IMF) Log.v(TAG, "Sending key event to IME: seq=" if (DEBUG_IMF) Log.v(TAG, "Sending key event to IME: seq=" + seq + " event=" + event); + seq + " event=" + event); int result = imm.dispatchKeyEvent(mView.getContext(), seq, event, return imm.dispatchKeyEvent(mView.getContext(), seq, event, mInputMethodCallback); mInputMethodCallback); if (result != EVENT_NOT_HANDLED) { return result; } } } } } } } // Not dispatching to IME, continue with post IME actions. return EVENT_POST_IME; return deliverKeyEventPostIme(q); } } private int deliverKeyEventPostIme(QueuedInputEvent q) { private int deliverKeyEventPostIme(QueuedInputEvent q) { Loading Loading @@ -4422,14 +4426,13 @@ public final class ViewRootImpl implements ViewParent, // in response to touch events and we want to ensure that the injected keys // in response to touch events and we want to ensure that the injected keys // are processed in the order they were received and we cannot trust that // are processed in the order they were received and we cannot trust that // the time stamp of injected events are monotonic. // the time stamp of injected events are monotonic. QueuedInputEvent last = mFirstPendingInputEvent; QueuedInputEvent last = mPendingInputEventTail; if (last == null) { if (last == null) { mFirstPendingInputEvent = q; mPendingInputEventHead = q; mPendingInputEventTail = q; } else { } else { while (last.mNext != null) { last = last.mNext; } last.mNext = q; last.mNext = q; mPendingInputEventTail = q; } } mPendingInputEventCount += 1; mPendingInputEventCount += 1; Trace.traceCounter(Trace.TRACE_TAG_INPUT, mPendingInputEventQueueLengthCounterName, Trace.traceCounter(Trace.TRACE_TAG_INPUT, mPendingInputEventQueueLengthCounterName, Loading @@ -4452,19 +4455,44 @@ public final class ViewRootImpl implements ViewParent, } } void doProcessInputEvents() { void doProcessInputEvents() { while (mCurrentInputEvent == null && mFirstPendingInputEvent != null) { // Handle all of the available pending input events. Currently this will immediately QueuedInputEvent q = mFirstPendingInputEvent; // process all of the events it can until it encounters one that must go through the IME. mFirstPendingInputEvent = q.mNext; // After that it will continue adding events to the current input queue but will wait for a // response from the IME, regardless of whether that particular event needs it or not, in // order to guarantee ordering consistency. This could be slightly improved by only // queueing events whose source has previously encountered something that needs to be // handled by the IME, and otherwise handling them immediately since we only need to // guarantee ordering within a given source. while (mPendingInputEventHead != null) { QueuedInputEvent q = mPendingInputEventHead; mPendingInputEventHead = q.mNext; if (mPendingInputEventHead == null) { mPendingInputEventTail = null; } q.mNext = null; q.mNext = null; mCurrentInputEvent = q; mPendingInputEventCount -= 1; mPendingInputEventCount -= 1; Trace.traceCounter(Trace.TRACE_TAG_INPUT, mPendingInputEventQueueLengthCounterName, Trace.traceCounter(Trace.TRACE_TAG_INPUT, mPendingInputEventQueueLengthCounterName, mPendingInputEventCount); mPendingInputEventCount); final int result = deliverInputEvent(q); int result = deliverInputEvent(q); if (result != EVENT_IN_PROGRESS) { finishCurrentInputEvent(result == EVENT_HANDLED); if (result == EVENT_HANDLED || result == EVENT_NOT_HANDLED) { finishInputEvent(q, result == EVENT_HANDLED); } else if (result == EVENT_PENDING_IME) { enqueueCurrentInputEvent(q); } else { q.mFlags |= QueuedInputEvent.FLAG_DELIVER_POST_IME; // If the IME decided not to handle this event, and we have no events already being // handled by the IME, go ahead and handle this one and then continue to the next // input event. Otherwise, queue it up and handle it after whatever in front of it // in the queue has been handled. if (mCurrentInputEventHead == null) { result = deliverInputEventPostIme(q); finishInputEvent(q, result == EVENT_HANDLED); } else { enqueueCurrentInputEvent(q); } } } } } Loading @@ -4476,9 +4504,36 @@ public final class ViewRootImpl implements ViewParent, } } } } private void enqueueCurrentInputEvent(QueuedInputEvent q) { if (mCurrentInputEventHead == null) { mCurrentInputEventHead = q; mCurrentInputEventTail = q; } else { mCurrentInputEventTail.mNext = q; mCurrentInputEventTail = q; } mCurrentInputEventCount += 1; Trace.traceCounter(Trace.TRACE_TAG_INPUT, mCurrentInputEventQueueLengthCounterName, mCurrentInputEventCount); } private QueuedInputEvent dequeueCurrentInputEvent() { QueuedInputEvent q = mCurrentInputEventHead; mCurrentInputEventHead = q.mNext; if (mCurrentInputEventHead == null) { mCurrentInputEventTail = null; } q.mNext = null; mCurrentInputEventCount -= 1; Trace.traceCounter(Trace.TRACE_TAG_INPUT, mCurrentInputEventQueueLengthCounterName, mCurrentInputEventCount); return q; } void handleImeFinishedEvent(int seq, boolean handled) { void handleImeFinishedEvent(int seq, boolean handled) { final QueuedInputEvent q = mCurrentInputEvent; QueuedInputEvent q = mCurrentInputEventHead; if (q != null && q.mEvent.getSequenceNumber() == seq) { if (q != null && q.mEvent.getSequenceNumber() == seq) { dequeueCurrentInputEvent(); if (DEBUG_IMF) { if (DEBUG_IMF) { Log.v(TAG, "IME finished event: seq=" + seq Log.v(TAG, "IME finished event: seq=" + seq + " handled=" + handled + " event=" + q); + " handled=" + handled + " event=" + q); Loading @@ -4497,22 +4552,26 @@ public final class ViewRootImpl implements ViewParent, } } } } } } finishCurrentInputEvent(handled); // Immediately start processing the next input event. finishInputEvent(q, handled); doProcessInputEvents(); // Flush all of the input events that are no longer waiting on the IME while (mCurrentInputEventHead != null && (mCurrentInputEventHead.mFlags & QueuedInputEvent.FLAG_DELIVER_POST_IME) != 0) { q = dequeueCurrentInputEvent(); final int result = deliverInputEventPostIme(q); finishInputEvent(q, result == EVENT_HANDLED); } } else { } else { if (DEBUG_IMF) { if (DEBUG_IMF) { Log.v(TAG, "IME finished event: seq=" + seq Log.v(TAG, "IME finished event: seq=" + seq + " handled=" + handled + ", event not found!"); + " handled=" + handled + ", event not found!"); } } } } } private void finishCurrentInputEvent(boolean handled) { } final QueuedInputEvent q = mCurrentInputEvent; mCurrentInputEvent = null; private void finishInputEvent(QueuedInputEvent q, boolean handled) { if (q.mReceiver != null) { if (q.mReceiver != null) { q.mReceiver.finishInputEvent(q.mEvent, handled); q.mReceiver.finishInputEvent(q.mEvent, handled); } else { } else { Loading core/java/android/view/inputmethod/InputMethodManager.java +6 −6 Original line number Original line Diff line number Diff line Loading @@ -1577,13 +1577,13 @@ public final class InputMethodManager { final long startTime = SystemClock.uptimeMillis(); final long startTime = SystemClock.uptimeMillis(); enqueuePendingEventLocked(startTime, seq, mCurId, callback); enqueuePendingEventLocked(startTime, seq, mCurId, callback); mCurMethod.dispatchKeyEvent(seq, key, mInputMethodCallback); mCurMethod.dispatchKeyEvent(seq, key, mInputMethodCallback); return ViewRootImpl.EVENT_IN_PROGRESS; return ViewRootImpl.EVENT_PENDING_IME; } catch (RemoteException e) { } catch (RemoteException e) { Log.w(TAG, "IME died: " + mCurId + " dropping: " + key, e); Log.w(TAG, "IME died: " + mCurId + " dropping: " + key, e); } } } } } } return ViewRootImpl.EVENT_NOT_HANDLED; return ViewRootImpl.EVENT_POST_IME; } } /** /** Loading @@ -1600,13 +1600,13 @@ public final class InputMethodManager { final long startTime = SystemClock.uptimeMillis(); final long startTime = SystemClock.uptimeMillis(); enqueuePendingEventLocked(startTime, seq, mCurId, callback); enqueuePendingEventLocked(startTime, seq, mCurId, callback); mCurMethod.dispatchTrackballEvent(seq, motion, mInputMethodCallback); mCurMethod.dispatchTrackballEvent(seq, motion, mInputMethodCallback); return ViewRootImpl.EVENT_IN_PROGRESS; return ViewRootImpl.EVENT_PENDING_IME; } catch (RemoteException e) { } catch (RemoteException e) { Log.w(TAG, "IME died: " + mCurId + " dropping trackball: " + motion, e); Log.w(TAG, "IME died: " + mCurId + " dropping trackball: " + motion, e); } } } } } } return ViewRootImpl.EVENT_NOT_HANDLED; return ViewRootImpl.EVENT_POST_IME; } } /** /** Loading @@ -1623,13 +1623,13 @@ public final class InputMethodManager { final long startTime = SystemClock.uptimeMillis(); final long startTime = SystemClock.uptimeMillis(); enqueuePendingEventLocked(startTime, seq, mCurId, callback); enqueuePendingEventLocked(startTime, seq, mCurId, callback); mCurMethod.dispatchGenericMotionEvent(seq, motion, mInputMethodCallback); mCurMethod.dispatchGenericMotionEvent(seq, motion, mInputMethodCallback); return ViewRootImpl.EVENT_IN_PROGRESS; return ViewRootImpl.EVENT_PENDING_IME; } catch (RemoteException e) { } catch (RemoteException e) { Log.w(TAG, "IME died: " + mCurId + " dropping generic motion: " + motion, e); Log.w(TAG, "IME died: " + mCurId + " dropping generic motion: " + motion, e); } } } } } } return ViewRootImpl.EVENT_NOT_HANDLED; return ViewRootImpl.EVENT_POST_IME; } } void finishedEvent(int seq, boolean handled) { void finishedEvent(int seq, boolean handled) { Loading Loading
core/java/android/view/ViewRootImpl.java +104 −45 Original line number Original line Diff line number Diff line Loading @@ -107,6 +107,7 @@ public final class ViewRootImpl implements ViewParent, private static final boolean DEBUG_IMF = false || LOCAL_LOGV; private static final boolean DEBUG_IMF = false || LOCAL_LOGV; private static final boolean DEBUG_CONFIGURATION = false || LOCAL_LOGV; private static final boolean DEBUG_CONFIGURATION = false || LOCAL_LOGV; private static final boolean DEBUG_FPS = false; private static final boolean DEBUG_FPS = false; private static final boolean DEBUG_INPUT_PROCESSING = false || LOCAL_LOGV; private static final boolean USE_RENDER_THREAD = false; private static final boolean USE_RENDER_THREAD = false; Loading Loading @@ -231,24 +232,38 @@ public final class ViewRootImpl implements ViewParent, int mClientWindowLayoutFlags; int mClientWindowLayoutFlags; boolean mLastOverscanRequested; boolean mLastOverscanRequested; /** @hide */ /** Event was not handled and is finished. * @hide */ public static final int EVENT_NOT_HANDLED = 0; public static final int EVENT_NOT_HANDLED = 0; /** @hide */ /** Event was handled and is finished. * @hide */ public static final int EVENT_HANDLED = 1; public static final int EVENT_HANDLED = 1; /** @hide */ /** Event is waiting on the IME. public static final int EVENT_IN_PROGRESS = 2; * @hide */ public static final int EVENT_PENDING_IME = 2; /** Event requires post-IME dispatch. * @hide */ public static final int EVENT_POST_IME = 3; // Pool of queued input events. // Pool of queued input events. private static final int MAX_QUEUED_INPUT_EVENT_POOL_SIZE = 10; private static final int MAX_QUEUED_INPUT_EVENT_POOL_SIZE = 10; private QueuedInputEvent mQueuedInputEventPool; private QueuedInputEvent mQueuedInputEventPool; private int mQueuedInputEventPoolSize; private int mQueuedInputEventPoolSize; // Input event queue. /* Input event queue. QueuedInputEvent mFirstPendingInputEvent; * Pending input events are input events waiting to be handled by the application. Current * input events are input events which are being handled but are waiting on some action by the * IME, even if they themselves may not need to be handled by the IME. */ QueuedInputEvent mPendingInputEventHead; QueuedInputEvent mPendingInputEventTail; int mPendingInputEventCount; int mPendingInputEventCount; QueuedInputEvent mCurrentInputEvent; QueuedInputEvent mCurrentInputEventHead; QueuedInputEvent mCurrentInputEventTail; int mCurrentInputEventCount; boolean mProcessInputEventsScheduled; boolean mProcessInputEventsScheduled; String mPendingInputEventQueueLengthCounterName = "pq"; String mPendingInputEventQueueLengthCounterName = "pq"; String mCurrentInputEventQueueLengthCounterName = "cq"; boolean mWindowAttributesChanged = false; boolean mWindowAttributesChanged = false; int mWindowAttributesChangesFlag = 0; int mWindowAttributesChangesFlag = 0; Loading Loading @@ -646,6 +661,7 @@ public final class ViewRootImpl implements ViewParent, } } mPendingInputEventQueueLengthCounterName = "pq:" + attrs.getTitle(); mPendingInputEventQueueLengthCounterName = "pq:" + attrs.getTitle(); mCurrentInputEventQueueLengthCounterName = "cq:" + attrs.getTitle(); } } } } } } Loading Loading @@ -3438,17 +3454,13 @@ public final class ViewRootImpl implements ViewParent, if (DEBUG_IMF) if (DEBUG_IMF) Log.v(TAG, "Sending trackball event to IME: seq=" Log.v(TAG, "Sending trackball event to IME: seq=" + seq + " event=" + event); + seq + " event=" + event); int result = imm.dispatchTrackballEvent(mView.getContext(), seq, event, return imm.dispatchTrackballEvent(mView.getContext(), seq, event, mInputMethodCallback); mInputMethodCallback); if (result != EVENT_NOT_HANDLED) { return result; } } } } } } } // Not dispatching to IME, continue with post IME actions. return EVENT_POST_IME; return deliverTrackballEventPostIme(q); } } private int deliverTrackballEventPostIme(QueuedInputEvent q) { private int deliverTrackballEventPostIme(QueuedInputEvent q) { Loading Loading @@ -3596,17 +3608,13 @@ public final class ViewRootImpl implements ViewParent, if (DEBUG_IMF) if (DEBUG_IMF) Log.v(TAG, "Sending generic motion event to IME: seq=" Log.v(TAG, "Sending generic motion event to IME: seq=" + seq + " event=" + event); + seq + " event=" + event); int result = imm.dispatchGenericMotionEvent(mView.getContext(), seq, event, return imm.dispatchGenericMotionEvent(mView.getContext(), seq, event, mInputMethodCallback); mInputMethodCallback); if (result != EVENT_NOT_HANDLED) { return result; } } } } } } } // Not dispatching to IME, continue with post IME actions. return EVENT_POST_IME; return deliverGenericMotionEventPostIme(q); } } private int deliverGenericMotionEventPostIme(QueuedInputEvent q) { private int deliverGenericMotionEventPostIme(QueuedInputEvent q) { Loading Loading @@ -3811,17 +3819,13 @@ public final class ViewRootImpl implements ViewParent, final int seq = event.getSequenceNumber(); final int seq = event.getSequenceNumber(); if (DEBUG_IMF) Log.v(TAG, "Sending key event to IME: seq=" if (DEBUG_IMF) Log.v(TAG, "Sending key event to IME: seq=" + seq + " event=" + event); + seq + " event=" + event); int result = imm.dispatchKeyEvent(mView.getContext(), seq, event, return imm.dispatchKeyEvent(mView.getContext(), seq, event, mInputMethodCallback); mInputMethodCallback); if (result != EVENT_NOT_HANDLED) { return result; } } } } } } } // Not dispatching to IME, continue with post IME actions. return EVENT_POST_IME; return deliverKeyEventPostIme(q); } } private int deliverKeyEventPostIme(QueuedInputEvent q) { private int deliverKeyEventPostIme(QueuedInputEvent q) { Loading Loading @@ -4422,14 +4426,13 @@ public final class ViewRootImpl implements ViewParent, // in response to touch events and we want to ensure that the injected keys // in response to touch events and we want to ensure that the injected keys // are processed in the order they were received and we cannot trust that // are processed in the order they were received and we cannot trust that // the time stamp of injected events are monotonic. // the time stamp of injected events are monotonic. QueuedInputEvent last = mFirstPendingInputEvent; QueuedInputEvent last = mPendingInputEventTail; if (last == null) { if (last == null) { mFirstPendingInputEvent = q; mPendingInputEventHead = q; mPendingInputEventTail = q; } else { } else { while (last.mNext != null) { last = last.mNext; } last.mNext = q; last.mNext = q; mPendingInputEventTail = q; } } mPendingInputEventCount += 1; mPendingInputEventCount += 1; Trace.traceCounter(Trace.TRACE_TAG_INPUT, mPendingInputEventQueueLengthCounterName, Trace.traceCounter(Trace.TRACE_TAG_INPUT, mPendingInputEventQueueLengthCounterName, Loading @@ -4452,19 +4455,44 @@ public final class ViewRootImpl implements ViewParent, } } void doProcessInputEvents() { void doProcessInputEvents() { while (mCurrentInputEvent == null && mFirstPendingInputEvent != null) { // Handle all of the available pending input events. Currently this will immediately QueuedInputEvent q = mFirstPendingInputEvent; // process all of the events it can until it encounters one that must go through the IME. mFirstPendingInputEvent = q.mNext; // After that it will continue adding events to the current input queue but will wait for a // response from the IME, regardless of whether that particular event needs it or not, in // order to guarantee ordering consistency. This could be slightly improved by only // queueing events whose source has previously encountered something that needs to be // handled by the IME, and otherwise handling them immediately since we only need to // guarantee ordering within a given source. while (mPendingInputEventHead != null) { QueuedInputEvent q = mPendingInputEventHead; mPendingInputEventHead = q.mNext; if (mPendingInputEventHead == null) { mPendingInputEventTail = null; } q.mNext = null; q.mNext = null; mCurrentInputEvent = q; mPendingInputEventCount -= 1; mPendingInputEventCount -= 1; Trace.traceCounter(Trace.TRACE_TAG_INPUT, mPendingInputEventQueueLengthCounterName, Trace.traceCounter(Trace.TRACE_TAG_INPUT, mPendingInputEventQueueLengthCounterName, mPendingInputEventCount); mPendingInputEventCount); final int result = deliverInputEvent(q); int result = deliverInputEvent(q); if (result != EVENT_IN_PROGRESS) { finishCurrentInputEvent(result == EVENT_HANDLED); if (result == EVENT_HANDLED || result == EVENT_NOT_HANDLED) { finishInputEvent(q, result == EVENT_HANDLED); } else if (result == EVENT_PENDING_IME) { enqueueCurrentInputEvent(q); } else { q.mFlags |= QueuedInputEvent.FLAG_DELIVER_POST_IME; // If the IME decided not to handle this event, and we have no events already being // handled by the IME, go ahead and handle this one and then continue to the next // input event. Otherwise, queue it up and handle it after whatever in front of it // in the queue has been handled. if (mCurrentInputEventHead == null) { result = deliverInputEventPostIme(q); finishInputEvent(q, result == EVENT_HANDLED); } else { enqueueCurrentInputEvent(q); } } } } } Loading @@ -4476,9 +4504,36 @@ public final class ViewRootImpl implements ViewParent, } } } } private void enqueueCurrentInputEvent(QueuedInputEvent q) { if (mCurrentInputEventHead == null) { mCurrentInputEventHead = q; mCurrentInputEventTail = q; } else { mCurrentInputEventTail.mNext = q; mCurrentInputEventTail = q; } mCurrentInputEventCount += 1; Trace.traceCounter(Trace.TRACE_TAG_INPUT, mCurrentInputEventQueueLengthCounterName, mCurrentInputEventCount); } private QueuedInputEvent dequeueCurrentInputEvent() { QueuedInputEvent q = mCurrentInputEventHead; mCurrentInputEventHead = q.mNext; if (mCurrentInputEventHead == null) { mCurrentInputEventTail = null; } q.mNext = null; mCurrentInputEventCount -= 1; Trace.traceCounter(Trace.TRACE_TAG_INPUT, mCurrentInputEventQueueLengthCounterName, mCurrentInputEventCount); return q; } void handleImeFinishedEvent(int seq, boolean handled) { void handleImeFinishedEvent(int seq, boolean handled) { final QueuedInputEvent q = mCurrentInputEvent; QueuedInputEvent q = mCurrentInputEventHead; if (q != null && q.mEvent.getSequenceNumber() == seq) { if (q != null && q.mEvent.getSequenceNumber() == seq) { dequeueCurrentInputEvent(); if (DEBUG_IMF) { if (DEBUG_IMF) { Log.v(TAG, "IME finished event: seq=" + seq Log.v(TAG, "IME finished event: seq=" + seq + " handled=" + handled + " event=" + q); + " handled=" + handled + " event=" + q); Loading @@ -4497,22 +4552,26 @@ public final class ViewRootImpl implements ViewParent, } } } } } } finishCurrentInputEvent(handled); // Immediately start processing the next input event. finishInputEvent(q, handled); doProcessInputEvents(); // Flush all of the input events that are no longer waiting on the IME while (mCurrentInputEventHead != null && (mCurrentInputEventHead.mFlags & QueuedInputEvent.FLAG_DELIVER_POST_IME) != 0) { q = dequeueCurrentInputEvent(); final int result = deliverInputEventPostIme(q); finishInputEvent(q, result == EVENT_HANDLED); } } else { } else { if (DEBUG_IMF) { if (DEBUG_IMF) { Log.v(TAG, "IME finished event: seq=" + seq Log.v(TAG, "IME finished event: seq=" + seq + " handled=" + handled + ", event not found!"); + " handled=" + handled + ", event not found!"); } } } } } private void finishCurrentInputEvent(boolean handled) { } final QueuedInputEvent q = mCurrentInputEvent; mCurrentInputEvent = null; private void finishInputEvent(QueuedInputEvent q, boolean handled) { if (q.mReceiver != null) { if (q.mReceiver != null) { q.mReceiver.finishInputEvent(q.mEvent, handled); q.mReceiver.finishInputEvent(q.mEvent, handled); } else { } else { Loading
core/java/android/view/inputmethod/InputMethodManager.java +6 −6 Original line number Original line Diff line number Diff line Loading @@ -1577,13 +1577,13 @@ public final class InputMethodManager { final long startTime = SystemClock.uptimeMillis(); final long startTime = SystemClock.uptimeMillis(); enqueuePendingEventLocked(startTime, seq, mCurId, callback); enqueuePendingEventLocked(startTime, seq, mCurId, callback); mCurMethod.dispatchKeyEvent(seq, key, mInputMethodCallback); mCurMethod.dispatchKeyEvent(seq, key, mInputMethodCallback); return ViewRootImpl.EVENT_IN_PROGRESS; return ViewRootImpl.EVENT_PENDING_IME; } catch (RemoteException e) { } catch (RemoteException e) { Log.w(TAG, "IME died: " + mCurId + " dropping: " + key, e); Log.w(TAG, "IME died: " + mCurId + " dropping: " + key, e); } } } } } } return ViewRootImpl.EVENT_NOT_HANDLED; return ViewRootImpl.EVENT_POST_IME; } } /** /** Loading @@ -1600,13 +1600,13 @@ public final class InputMethodManager { final long startTime = SystemClock.uptimeMillis(); final long startTime = SystemClock.uptimeMillis(); enqueuePendingEventLocked(startTime, seq, mCurId, callback); enqueuePendingEventLocked(startTime, seq, mCurId, callback); mCurMethod.dispatchTrackballEvent(seq, motion, mInputMethodCallback); mCurMethod.dispatchTrackballEvent(seq, motion, mInputMethodCallback); return ViewRootImpl.EVENT_IN_PROGRESS; return ViewRootImpl.EVENT_PENDING_IME; } catch (RemoteException e) { } catch (RemoteException e) { Log.w(TAG, "IME died: " + mCurId + " dropping trackball: " + motion, e); Log.w(TAG, "IME died: " + mCurId + " dropping trackball: " + motion, e); } } } } } } return ViewRootImpl.EVENT_NOT_HANDLED; return ViewRootImpl.EVENT_POST_IME; } } /** /** Loading @@ -1623,13 +1623,13 @@ public final class InputMethodManager { final long startTime = SystemClock.uptimeMillis(); final long startTime = SystemClock.uptimeMillis(); enqueuePendingEventLocked(startTime, seq, mCurId, callback); enqueuePendingEventLocked(startTime, seq, mCurId, callback); mCurMethod.dispatchGenericMotionEvent(seq, motion, mInputMethodCallback); mCurMethod.dispatchGenericMotionEvent(seq, motion, mInputMethodCallback); return ViewRootImpl.EVENT_IN_PROGRESS; return ViewRootImpl.EVENT_PENDING_IME; } catch (RemoteException e) { } catch (RemoteException e) { Log.w(TAG, "IME died: " + mCurId + " dropping generic motion: " + motion, e); Log.w(TAG, "IME died: " + mCurId + " dropping generic motion: " + motion, e); } } } } } } return ViewRootImpl.EVENT_NOT_HANDLED; return ViewRootImpl.EVENT_POST_IME; } } void finishedEvent(int seq, boolean handled) { void finishedEvent(int seq, boolean handled) { Loading