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

Commit d2500739 authored by Michael Wright's avatar Michael Wright Committed by Android Git Automerger
Browse files

am a329c83d: am 88a0765d: Merge "Add pipelining optimization to IME dispatching" into jb-mr2-dev

* commit 'a329c83d':
  Add pipelining optimization to IME dispatching
parents 29b89ace a329c83d
Loading
Loading
Loading
Loading
+104 −45
Original line number Original line Diff line number Diff line
@@ -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;


@@ -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;
@@ -646,6 +661,7 @@ public final class ViewRootImpl implements ViewParent,
                }
                }


                mPendingInputEventQueueLengthCounterName = "pq:" + attrs.getTitle();
                mPendingInputEventQueueLengthCounterName = "pq:" + attrs.getTitle();
                mCurrentInputEventQueueLengthCounterName = "cq:" + attrs.getTitle();
            }
            }
        }
        }
    }
    }
@@ -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) {
@@ -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) {
@@ -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) {
@@ -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,
@@ -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);
                }
            }
            }
        }
        }


@@ -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);
@@ -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 {
+6 −6
Original line number Original line Diff line number Diff line
@@ -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;
    }
    }


    /**
    /**
@@ -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;
    }
    }


    /**
    /**
@@ -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) {