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

Commit 608292b5 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Fix window jumping when crossing a display boundary" into main

parents 9384f33a 8bbbd550
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -135,6 +135,7 @@ private:
        BitSet32 idBits;
        int32_t idToIndex[MAX_POINTER_ID + 1];
        PointerCoords pointers[MAX_POINTERS];
        int32_t displayId;

        void initializeFrom(const InputMessage& msg) {
            eventTime = msg.body.motion.eventTime;
@@ -145,6 +146,7 @@ private:
                idToIndex[id] = i;
                pointers[i].copyFrom(msg.body.motion.pointers[i].coords);
            }
            displayId = msg.body.motion.displayId;
        }

        void initializeFrom(const History& other) {
@@ -157,6 +159,7 @@ private:
                pointers[index].copyFrom(other.pointers[index]);
            }
            idBits = other.idBits; // final copy
            displayId = other.displayId;
        }

        const PointerCoords& getPointerById(uint32_t id) const { return pointers[idToIndex[id]]; }
+5 −0
Original line number Diff line number Diff line
@@ -260,6 +260,11 @@ private:
     * the batched MotionEvent that it received.
     */
    std::map<uint32_t, std::vector<uint32_t>> mBatchedSequenceNumbers;

    /**
     * Checks if a given input event is okay to be added to an existing batch or not.
     */
    bool isBatchableEvent(const InputMessage& message) const;
};

} // namespace android
+8 −1
Original line number Diff line number Diff line
@@ -658,6 +658,11 @@ void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event,
        }
    }

    if (current->displayId != other->displayId) {
        ALOGD_IF(debugResampling(), "Not resampled, the other is on a different display");
        return;
    }

    // Resample touch coordinates.
    History oldLastResample;
    oldLastResample.initializeFrom(touchState.lastResample);
@@ -840,9 +845,11 @@ bool InputConsumer::canAddSample(const Batch& batch, const InputMessage* msg) {
    const InputMessage& head = batch.samples[0];
    uint32_t pointerCount = msg->body.motion.pointerCount;
    if (head.body.motion.pointerCount != pointerCount ||
        head.body.motion.action != msg->body.motion.action) {
        head.body.motion.action != msg->body.motion.action ||
        head.body.motion.displayId != msg->body.motion.displayId) {
        return false;
    }

    for (size_t i = 0; i < pointerCount; i++) {
        if (head.body.motion.pointers[i].properties != msg->body.motion.pointers[i].properties) {
            return false;
+22 −4
Original line number Diff line number Diff line
@@ -348,10 +348,7 @@ void InputConsumerNoResampling::handleMessages(std::vector<InputMessage>&& messa
            const int32_t action = msg.body.motion.action;
            const DeviceId deviceId = msg.body.motion.deviceId;
            const int32_t source = msg.body.motion.source;
            const bool batchableEvent = (action == AMOTION_EVENT_ACTION_MOVE ||
                                         action == AMOTION_EVENT_ACTION_HOVER_MOVE) &&
                    (isFromSource(source, AINPUT_SOURCE_CLASS_POINTER) ||
                     isFromSource(source, AINPUT_SOURCE_CLASS_JOYSTICK));
            const bool batchableEvent = isBatchableEvent(msg);

            const bool canResample = (mResamplerCreator != nullptr) &&
                    (isFromSource(source, AINPUT_SOURCE_CLASS_POINTER));
@@ -624,4 +621,25 @@ std::string InputConsumerNoResampling::dump() const {
    return out;
}

bool InputConsumerNoResampling::isBatchableEvent(const InputMessage& message) const {
    const int32_t action = message.body.motion.action;
    const int32_t source = message.body.motion.source;
    const bool batchableEventTypeAndSource =
            (action == AMOTION_EVENT_ACTION_MOVE || action == AMOTION_EVENT_ACTION_HOVER_MOVE) &&
            (isFromSource(source, AINPUT_SOURCE_CLASS_POINTER) ||
             isFromSource(source, AINPUT_SOURCE_CLASS_JOYSTICK));
    if (!batchableEventTypeAndSource) {
        return false;
    }

    const DeviceId deviceId = message.body.motion.deviceId;
    const auto& it = mBatches.find(deviceId);
    // If there is no pending event from the device, it's okay to add the event to the batch.
    if (it == mBatches.end() || it->second.size() == 0) {
        return true;
    }
    // It's okay to add the event to the existing batch if it's on the same display.
    return it->second.front().body.motion.displayId == message.body.motion.displayId;
}

} // namespace android
+49 −1
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ struct InputEventEntry {
    std::chrono::nanoseconds eventTime{0};
    std::vector<Pointer> pointers{};
    int32_t action{-1};
    ui::LogicalDisplayId displayId = ui::LogicalDisplayId::DEFAULT;
};

} // namespace
@@ -137,7 +138,8 @@ InputMessage InputConsumerResamplingTest::nextPointerMessage(const InputEventEnt
                                                 .eventTime(entry.eventTime.count())
                                                 .deviceId(1)
                                                 .action(entry.action)
                                                 .downTime(0);
                                                 .downTime(0)
                                                 .displayId(entry.displayId);
    for (const Pointer& pointer : entry.pointers) {
        messageBuilder.pointer(pointer.asPointerBuilder());
    }
@@ -741,4 +743,50 @@ TEST_F(InputConsumerResamplingTest, TwoPointersAreResampledIndependently) {
                             AMOTION_EVENT_ACTION_MOVE}});
}

/**
 * Events should not be resampled when they are on different displays.
 */
TEST_F(InputConsumerResamplingTest, EventsOnDifferentDisplaysAreNotResampled) {
    // Send the initial ACTION_DOWN separately, so that the first consumed event will only return an
    // InputEvent with a single action.
    mClientTestChannel->enqueueMessage(nextPointerMessage(
            {0ms, {Pointer{.id = 0, .x = 10.0f, .y = 20.0f}}, AMOTION_EVENT_ACTION_DOWN}));

    invokeLooperCallback();
    assertReceivedMotionEvent({InputEventEntry{0ms,
                                               {Pointer{.id = 0, .x = 10.0f, .y = 20.0f}},
                                               AMOTION_EVENT_ACTION_DOWN}});

    // Two ACTION_MOVE events 10 ms apart that move in X direction and stay still in Y, but on
    // different displays
    mClientTestChannel->enqueueMessage(
            nextPointerMessage({10ms,
                                {Pointer{.id = 0, .x = 20.0f, .y = 30.0f}},
                                AMOTION_EVENT_ACTION_MOVE,
                                ui::LogicalDisplayId::DEFAULT}));
    mClientTestChannel->enqueueMessage(
            nextPointerMessage({20ms,
                                {Pointer{.id = 0, .x = 30.0f, .y = 30.0f}},
                                AMOTION_EVENT_ACTION_MOVE,
                                ui::LogicalDisplayId{1}}));

    invokeLooperCallback();
    mConsumer->consumeBatchedInputEvents(nanoseconds{20ms + RESAMPLE_LATENCY * 2}.count());

    // MotionEvent should not be resampled because the resample time falls exactly on the existing
    // event time.
    assertReceivedMotionEvent({InputEventEntry{10ms,
                                               {Pointer{.id = 0, .x = 20.0f, .y = 30.0f}},
                                               AMOTION_EVENT_ACTION_MOVE,
                                               ui::LogicalDisplayId::DEFAULT}});
    assertReceivedMotionEvent({InputEventEntry{20ms,
                                               {Pointer{.id = 0, .x = 30.0f, .y = 30.0f}},
                                               AMOTION_EVENT_ACTION_MOVE,
                                               ui::LogicalDisplayId{1}}});

    mClientTestChannel->assertFinishMessage(/*seq=*/1, /*handled=*/true);
    mClientTestChannel->assertFinishMessage(/*seq=*/2, /*handled=*/true);
    mClientTestChannel->assertFinishMessage(/*seq=*/3, /*handled=*/true);
}

} // namespace android
Loading