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

Commit f187bb84 authored by Siarhei Vishniakou's avatar Siarhei Vishniakou Committed by android-build-merger
Browse files

Fix resampling logic for duplicate events.

am: 086a02a2

Change-Id: Idfbd41a7309e96bdd6caaa230a8a8124d1bbc4ba
parents ac18e8a9 086a02a2
Loading
Loading
Loading
Loading
+23 −8
Original line number Diff line number Diff line
@@ -370,14 +370,14 @@ private:
        int32_t idToIndex[MAX_POINTER_ID + 1];
        PointerCoords pointers[MAX_POINTERS];

        void initializeFrom(const InputMessage* msg) {
            eventTime = msg->body.motion.eventTime;
        void initializeFrom(const InputMessage& msg) {
            eventTime = msg.body.motion.eventTime;
            idBits.clear();
            for (uint32_t i = 0; i < msg->body.motion.pointerCount; i++) {
                uint32_t id = msg->body.motion.pointers[i].properties.id;
            for (uint32_t i = 0; i < msg.body.motion.pointerCount; i++) {
                uint32_t id = msg.body.motion.pointers[i].properties.id;
                idBits.markBit(id);
                idToIndex[id] = i;
                pointers[i].copyFrom(msg->body.motion.pointers[i].coords);
                pointers[i].copyFrom(msg.body.motion.pointers[i].coords);
            }
        }

@@ -402,7 +402,7 @@ private:
            lastResample.idBits.clear();
        }

        void addHistory(const InputMessage* msg) {
        void addHistory(const InputMessage& msg) {
            historyCurrent ^= 1;
            if (historySize < 2) {
                historySize += 1;
@@ -413,6 +413,21 @@ private:
        const History* getHistory(size_t index) const {
            return &history[(historyCurrent + index) & 1];
        }

        bool recentCoordinatesAreIdentical(uint32_t id) const {
            // Return true if the two most recently received "raw" coordinates are identical
            if (historySize < 2) {
                return false;
            }
            float currentX = getHistory(0)->getPointerById(id).getX();
            float currentY = getHistory(0)->getPointerById(id).getY();
            float previousX = getHistory(1)->getPointerById(id).getX();
            float previousY = getHistory(1)->getPointerById(id).getY();
            if (currentX == previousX && currentY == previousY) {
                return true;
            }
            return false;
        }
    };
    Vector<TouchState> mTouchStates;

@@ -432,8 +447,8 @@ private:
            Batch& batch, size_t count, uint32_t* outSeq, InputEvent** outEvent,
            int32_t* displayId);

    void updateTouchState(InputMessage* msg);
    void rewriteMessage(const TouchState& state, InputMessage* msg);
    void updateTouchState(InputMessage& msg);
    bool rewriteMessage(const TouchState& state, InputMessage& msg);
    void resampleTouchState(nsecs_t frameTime, MotionEvent* event,
            const InputMessage *next);

+39 −29
Original line number Diff line number Diff line
@@ -496,7 +496,7 @@ status_t InputConsumer::consume(InputEventFactoryInterface* factory,
            MotionEvent* motionEvent = factory->createMotionEvent();
            if (! motionEvent) return NO_MEMORY;

            updateTouchState(&mMsg);
            updateTouchState(mMsg);
            initializeMotionEvent(motionEvent, &mMsg);
            *outSeq = mMsg.body.motion.seq;
            *outEvent = motionEvent;
@@ -564,7 +564,7 @@ status_t InputConsumer::consumeSamples(InputEventFactoryInterface* factory,
    uint32_t chain = 0;
    for (size_t i = 0; i < count; i++) {
        InputMessage& msg = batch.samples.editItemAt(i);
        updateTouchState(&msg);
        updateTouchState(msg);
        if (i) {
            SeqChain seqChain;
            seqChain.seq = msg.body.motion.seq;
@@ -584,20 +584,19 @@ status_t InputConsumer::consumeSamples(InputEventFactoryInterface* factory,
    return OK;
}

void InputConsumer::updateTouchState(InputMessage* msg) {
void InputConsumer::updateTouchState(InputMessage& msg) {
    if (!mResampleTouch ||
            !(msg->body.motion.source & AINPUT_SOURCE_CLASS_POINTER)) {
            !(msg.body.motion.source & AINPUT_SOURCE_CLASS_POINTER)) {
        return;
    }

    int32_t deviceId = msg->body.motion.deviceId;
    int32_t source = msg->body.motion.source;
    nsecs_t eventTime = msg->body.motion.eventTime;
    int32_t deviceId = msg.body.motion.deviceId;
    int32_t source = msg.body.motion.source;

    // Update the touch state history to incorporate the new input message.
    // If the message is in the past relative to the most recently produced resampled
    // touch, then use the resampled time and coordinates instead.
    switch (msg->body.motion.action & AMOTION_EVENT_ACTION_MASK) {
    switch (msg.body.motion.action & AMOTION_EVENT_ACTION_MASK) {
    case AMOTION_EVENT_ACTION_DOWN: {
        ssize_t index = findTouchState(deviceId, source);
        if (index < 0) {
@@ -615,9 +614,8 @@ void InputConsumer::updateTouchState(InputMessage* msg) {
        if (index >= 0) {
            TouchState& touchState = mTouchStates.editItemAt(index);
            touchState.addHistory(msg);
            if (eventTime < touchState.lastResample.eventTime) {
                rewriteMessage(touchState, msg);
            } else {
            bool messageRewritten = rewriteMessage(touchState, msg);
            if (!messageRewritten) {
                touchState.lastResample.idBits.clear();
            }
        }
@@ -628,7 +626,7 @@ void InputConsumer::updateTouchState(InputMessage* msg) {
        ssize_t index = findTouchState(deviceId, source);
        if (index >= 0) {
            TouchState& touchState = mTouchStates.editItemAt(index);
            touchState.lastResample.idBits.clearBit(msg->body.motion.getActionId());
            touchState.lastResample.idBits.clearBit(msg.body.motion.getActionId());
            rewriteMessage(touchState, msg);
        }
        break;
@@ -639,7 +637,7 @@ void InputConsumer::updateTouchState(InputMessage* msg) {
        if (index >= 0) {
            TouchState& touchState = mTouchStates.editItemAt(index);
            rewriteMessage(touchState, msg);
            touchState.lastResample.idBits.clearBit(msg->body.motion.getActionId());
            touchState.lastResample.idBits.clearBit(msg.body.motion.getActionId());
        }
        break;
    }
@@ -666,24 +664,29 @@ void InputConsumer::updateTouchState(InputMessage* msg) {
    }
}

void InputConsumer::rewriteMessage(const TouchState& state, InputMessage* msg) {
    for (uint32_t i = 0; i < msg->body.motion.pointerCount; i++) {
        uint32_t id = msg->body.motion.pointers[i].properties.id;
bool InputConsumer::rewriteMessage(const TouchState& state, InputMessage& msg) {
    bool messageRewritten = false;
    nsecs_t eventTime = msg.body.motion.eventTime;
    for (uint32_t i = 0; i < msg.body.motion.pointerCount; i++) {
        uint32_t id = msg.body.motion.pointers[i].properties.id;
        if (state.lastResample.idBits.hasBit(id)) {
            PointerCoords& msgCoords = msg->body.motion.pointers[i].coords;
            PointerCoords& msgCoords = msg.body.motion.pointers[i].coords;
            const PointerCoords& resampleCoords = state.lastResample.getPointerById(id);
            if (eventTime < state.lastResample.eventTime ||
                    state.recentCoordinatesAreIdentical(id)) {
                msgCoords.setAxisValue(AMOTION_EVENT_AXIS_X, resampleCoords.getX());
                msgCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, resampleCoords.getY());
#if DEBUG_RESAMPLING
                ALOGD("[%d] - rewrite (%0.3f, %0.3f), old (%0.3f, %0.3f)", id,
                    resampleCoords.getAxisValue(AMOTION_EVENT_AXIS_X),
                    resampleCoords.getAxisValue(AMOTION_EVENT_AXIS_Y),
                    msgCoords.getAxisValue(AMOTION_EVENT_AXIS_X),
                    msgCoords.getAxisValue(AMOTION_EVENT_AXIS_Y));
                        resampleCoords.getX(), resampleCoords.getY(),
                        msgCoords.getX(), msgCoords.getY());
#endif
            msgCoords.setAxisValue(AMOTION_EVENT_AXIS_X, resampleCoords.getX());
            msgCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, resampleCoords.getY());
                messageRewritten = true;
            }
        }
    }
    return messageRewritten;
}

void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event,
    const InputMessage* next) {
@@ -710,6 +713,7 @@ void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event,
    }

    // Ensure that the current sample has all of the pointers that need to be reported.
    // Also ensure that the past two "real" touch events do not contain duplicate coordinates
    const History* current = touchState.getHistory(0);
    size_t pointerCount = event->getPointerCount();
    for (size_t i = 0; i < pointerCount; i++) {
@@ -717,6 +721,12 @@ void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event,
        if (!current->idBits.hasBit(id)) {
#if DEBUG_RESAMPLING
            ALOGD("Not resampled, missing id %d", id);
#endif
            return;
        }
        if (touchState.recentCoordinatesAreIdentical(id)) {
#if DEBUG_RESAMPLING
            ALOGD("Not resampled, past two historical events have duplicate coordinates");
#endif
            return;
        }
@@ -729,12 +739,12 @@ void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event,
    if (next) {
        // Interpolate between current sample and future sample.
        // So current->eventTime <= sampleTime <= future.eventTime.
        future.initializeFrom(next);
        future.initializeFrom(*next);
        other = &future;
        nsecs_t delta = future.eventTime - current->eventTime;
        if (delta < RESAMPLE_MIN_DELTA) {
#if DEBUG_RESAMPLING
            ALOGD("Not resampled, delta time is too small: %lld ns.", delta);
            ALOGD("Not resampled, delta time is too small: %" PRId64 " ns.", delta);
#endif
            return;
        }
@@ -746,12 +756,12 @@ void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event,
        nsecs_t delta = current->eventTime - other->eventTime;
        if (delta < RESAMPLE_MIN_DELTA) {
#if DEBUG_RESAMPLING
            ALOGD("Not resampled, delta time is too small: %lld ns.", delta);
            ALOGD("Not resampled, delta time is too small: %" PRId64 " ns.", delta);
#endif
            return;
        } else if (delta > RESAMPLE_MAX_DELTA) {
#if DEBUG_RESAMPLING
            ALOGD("Not resampled, delta time is too large: %lld ns.", delta);
            ALOGD("Not resampled, delta time is too large: %" PRId64 " ns.", delta);
#endif
            return;
        }
@@ -759,7 +769,7 @@ void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event,
        if (sampleTime > maxPredict) {
#if DEBUG_RESAMPLING
            ALOGD("Sample time is too far in the future, adjusting prediction "
                    "from %lld to %lld ns.",
                    "from %" PRId64 " to %" PRId64 " ns.",
                    sampleTime - current->eventTime, maxPredict - current->eventTime);
#endif
            sampleTime = maxPredict;