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

Commit 423346e7 authored by Arthur Hung's avatar Arthur Hung
Browse files

Pass source to dispatchBatchedInputEventPending (1/2)

The API requestUnbufferedDispatch allow View could receive the event in
unbuffered way. But doing processUnbufferedRequest in onInputEvent is
too late for the first event. Instead, we should pass the source of
the input event up to onBatchedInputEventPending, and then we can
use that to determine whether we could consume event immediately or not.

Bug: 149715123
Test: atest ViewUnbufferedTest
Change-Id: I4344a99de77d3758cc7d1df155394c89fa828f2e
parent 8888ec91
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ public class BatchedInputEventReceiver extends InputEventReceiver {
    }

    @Override
    public void onBatchedInputEventPending() {
    public void onBatchedInputEventPending(int source) {
        scheduleBatchedInput();
    }

+2 −8
Original line number Diff line number Diff line
@@ -147,8 +147,9 @@ public abstract class InputEventReceiver {
     * samples until the recipient calls {@link #consumeBatchedInputEvents} or
     * an event is received that ends the batch and causes it to be consumed
     * immediately (such as a pointer up event).
     * @param source The source of the batched event.
     */
    public void onBatchedInputEventPending() {
    public void onBatchedInputEventPending(int source) {
        consumeBatchedInputEvents(-1);
    }

@@ -219,13 +220,6 @@ public abstract class InputEventReceiver {
        onInputEvent(event);
    }

    // Called from native code.
    @SuppressWarnings("unused")
    @UnsupportedAppUsage
    private void dispatchBatchedInputEventPending() {
        onBatchedInputEventPending();
    }

    /**
     * Factory for InputEventReceiver
     */
+11 −21
Original line number Diff line number Diff line
@@ -504,7 +504,6 @@ public final class ViewRootImpl implements ViewParent,
    int mPendingInputEventCount;
    boolean mProcessInputEventsScheduled;
    boolean mUnbufferedInputDispatch;
    boolean mUnbufferedInputDispatchBySource;
    @InputSourceClass
    int mUnbufferedInputSource = SOURCE_CLASS_NONE;

@@ -1872,9 +1871,6 @@ public final class ViewRootImpl implements ViewParent,
            mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
            mChoreographer.postCallback(
                    Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
            if (!mUnbufferedInputDispatch && !mUnbufferedInputDispatchBySource) {
                scheduleConsumeBatchedInput();
            }
            notifyRendererOfFramePending();
            pokeDrawLockIfNeeded();
        }
@@ -8147,7 +8143,6 @@ public final class ViewRootImpl implements ViewParent,
        @Override
        public void onInputEvent(InputEvent event) {
            Trace.traceBegin(Trace.TRACE_TAG_VIEW, "processInputEventForCompatibility");
            processUnbufferedRequest(event);
            List<InputEvent> processedEvents;
            try {
                processedEvents =
@@ -8172,12 +8167,18 @@ public final class ViewRootImpl implements ViewParent,
        }

        @Override
        public void onBatchedInputEventPending() {
            if (mUnbufferedInputDispatch || mUnbufferedInputDispatchBySource) {
                super.onBatchedInputEventPending();
            } else {
                scheduleConsumeBatchedInput();
        public void onBatchedInputEventPending(int source) {
            final boolean unbuffered = mUnbufferedInputDispatch
                    || (source & mUnbufferedInputSource) != SOURCE_CLASS_NONE;
            if (unbuffered) {
                if (mConsumeBatchedInputScheduled) {
                    unscheduleConsumeBatchedInput();
                }
                // Consume event immediately if unbuffered input dispatch has been requested.
                consumeBatchedInputEvents(-1);
                return;
            }
            scheduleConsumeBatchedInput();
        }

        @Override
@@ -8190,17 +8191,6 @@ public final class ViewRootImpl implements ViewParent,
            unscheduleConsumeBatchedInput();
            super.dispose();
        }

        private void processUnbufferedRequest(InputEvent event) {
            if (!(event instanceof MotionEvent)) {
                return;
            }
            mUnbufferedInputDispatchBySource =
                    (event.getSource() & mUnbufferedInputSource) != SOURCE_CLASS_NONE;
            if (mUnbufferedInputDispatchBySource && mConsumeBatchedInputScheduled) {
                scheduleConsumeBatchedInputImmediately();
            }
        }
    }
    WindowInputEventReceiver mInputEventReceiver;

+33 −29
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@ static struct {

    jmethodID dispatchInputEvent;
    jmethodID onFocusEvent;
    jmethodID dispatchBatchedInputEventPending;
    jmethodID onBatchedInputEventPending;
} gInputEventReceiverClassInfo;


@@ -242,16 +242,21 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,

        status_t status = mInputConsumer.consume(&mInputEventFactory,
                consumeBatches, frameTime, &seq, &inputEvent);
        if (status) {
        if (status != OK && status != WOULD_BLOCK) {
            ALOGE("channel '%s' ~ Failed to consume input event.  status=%d",
                  getInputChannelName().c_str(), status);
            return status;
        }

        if (status == WOULD_BLOCK) {
                if (!skipCallbacks && !mBatchedInputEventPending
                        && mInputConsumer.hasPendingBatch()) {
            if (!skipCallbacks && !mBatchedInputEventPending && mInputConsumer.hasPendingBatch()) {
                // There is a pending batch.  Come back later.
                if (!receiverObj.get()) {
                    receiverObj.reset(jniGetReferent(env, mReceiverWeakGlobal));
                    if (!receiverObj.get()) {
                        ALOGW("channel '%s' ~ Receiver object was finalized "
                                    "without being disposed.", getInputChannelName().c_str());
                              "without being disposed.",
                              getInputChannelName().c_str());
                        return DEAD_OBJECT;
                    }
                }
@@ -261,8 +266,10 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,
                    ALOGD("channel '%s' ~ Dispatching batched input event pending notification.",
                          getInputChannelName().c_str());
                }

                env->CallVoidMethod(receiverObj.get(),
                            gInputEventReceiverClassInfo.dispatchBatchedInputEventPending);
                                    gInputEventReceiverClassInfo.onBatchedInputEventPending,
                                    mInputConsumer.getPendingBatchSource());
                if (env->ExceptionCheck()) {
                    ALOGE("Exception dispatching batched input events.");
                    mBatchedInputEventPending = false; // try again later
@@ -270,10 +277,6 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,
            }
            return OK;
        }
            ALOGE("channel '%s' ~ Failed to consume input event.  status=%d",
                    getInputChannelName().c_str(), status);
            return status;
        }
        assert(inputEvent);

        if (!skipCallbacks) {
@@ -441,8 +444,9 @@ int register_android_view_InputEventReceiver(JNIEnv* env) {
            "dispatchInputEvent", "(ILandroid/view/InputEvent;)V");
    gInputEventReceiverClassInfo.onFocusEvent =
            GetMethodIDOrDie(env, gInputEventReceiverClassInfo.clazz, "onFocusEvent", "(ZZ)V");
    gInputEventReceiverClassInfo.dispatchBatchedInputEventPending = GetMethodIDOrDie(env,
            gInputEventReceiverClassInfo.clazz, "dispatchBatchedInputEventPending", "()V");
    gInputEventReceiverClassInfo.onBatchedInputEventPending =
            GetMethodIDOrDie(env, gInputEventReceiverClassInfo.clazz, "onBatchedInputEventPending",
                             "(I)V");

    return res;
}