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

Commit b38d8c6e authored by Chavi Weingarten's avatar Chavi Weingarten
Browse files

Revert "Handle different scale and offset for pointers in InputTarget."

This reverts commit 5d22a235.

Reason for revert: b/147371357

Change-Id: I1987192eba55424265a9910237a2df96c2336807
Bug: 147371357
parent 5d22a235
Loading
Loading
Loading
Loading
+48 −106
Original line number Original line Diff line number Diff line
@@ -256,67 +256,6 @@ static bool isStaleEvent(nsecs_t currentTime, const EventEntry& entry) {
    return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
    return currentTime - entry.eventTime >= STALE_EVENT_TIMEOUT;
}
}


static std::unique_ptr<DispatchEntry> createDispatchEntry(const InputTarget& inputTarget,
                                                          EventEntry* eventEntry,
                                                          int32_t inputTargetFlags) {
    if (inputTarget.useDefaultPointerInfo()) {
        const PointerInfo& pointerInfo = inputTarget.getDefaultPointerInfo();
        return std::make_unique<DispatchEntry>(eventEntry, // increments ref
                                               inputTargetFlags, pointerInfo.xOffset,
                                               pointerInfo.yOffset, inputTarget.globalScaleFactor,
                                               pointerInfo.windowXScale, pointerInfo.windowYScale);
    }

    ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
    const MotionEntry& motionEntry = static_cast<const MotionEntry&>(*eventEntry);

    PointerCoords pointerCoords[MAX_POINTERS];

    // Use the first pointer information to normalize all other pointers. This could be any pointer
    // as long as all other pointers are normalized to the same value and the final DispatchEntry
    // uses the offset and scale for the normalized pointer.
    const PointerInfo& firstPointerInfo =
            inputTarget.pointerInfos[inputTarget.pointerIds.firstMarkedBit()];

    // Iterate through all pointers in the event to normalize against the first.
    for (uint32_t pointerIndex = 0; pointerIndex < motionEntry.pointerCount; pointerIndex++) {
        const PointerProperties& pointerProperties = motionEntry.pointerProperties[pointerIndex];
        uint32_t pointerId = uint32_t(pointerProperties.id);
        const PointerInfo& currPointerInfo = inputTarget.pointerInfos[pointerId];

        // The scale factor is the ratio of the current pointers scale to the normalized scale.
        float scaleXDiff = currPointerInfo.windowXScale / firstPointerInfo.windowXScale;
        float scaleYDiff = currPointerInfo.windowYScale / firstPointerInfo.windowYScale;

        pointerCoords[pointerIndex].copyFrom(motionEntry.pointerCoords[pointerIndex]);
        // First apply the current pointers offset to set the window at 0,0
        pointerCoords[pointerIndex].applyOffset(currPointerInfo.xOffset, currPointerInfo.yOffset);
        // Next scale the coordinates.
        pointerCoords[pointerIndex].scale(1, scaleXDiff, scaleYDiff);
        // Lastly, offset the coordinates so they're in the normalized pointer's frame.
        pointerCoords[pointerIndex].applyOffset(-firstPointerInfo.xOffset,
                                                -firstPointerInfo.yOffset);
    }

    MotionEntry* combinedMotionEntry =
            new MotionEntry(motionEntry.sequenceNum, motionEntry.eventTime, motionEntry.deviceId,
                            motionEntry.source, motionEntry.displayId, motionEntry.policyFlags,
                            motionEntry.action, motionEntry.actionButton, motionEntry.flags,
                            motionEntry.metaState, motionEntry.buttonState,
                            motionEntry.classification, motionEntry.edgeFlags,
                            motionEntry.xPrecision, motionEntry.yPrecision,
                            motionEntry.xCursorPosition, motionEntry.yCursorPosition,
                            motionEntry.downTime, motionEntry.pointerCount,
                            motionEntry.pointerProperties, pointerCoords, 0 /* xOffset */,
                            0 /* yOffset */);

    return std::make_unique<DispatchEntry>(combinedMotionEntry, // increments ref
                                           inputTargetFlags, firstPointerInfo.xOffset,
                                           firstPointerInfo.yOffset, inputTarget.globalScaleFactor,
                                           firstPointerInfo.windowXScale,
                                           firstPointerInfo.windowYScale);
}

// --- InputDispatcherThread ---
// --- InputDispatcherThread ---


class InputDispatcher::InputDispatcherThread : public Thread {
class InputDispatcher::InputDispatcherThread : public Thread {
@@ -1172,7 +1111,7 @@ void InputDispatcher::dispatchEventLocked(nsecs_t currentTime, EventEntry* event
        sp<Connection> connection =
        sp<Connection> connection =
                getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
                getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
        if (connection != nullptr) {
        if (connection != nullptr) {
            prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
            prepareDispatchCycleLocked(currentTime, connection, eventEntry, &inputTarget);
        } else {
        } else {
            if (DEBUG_FOCUS) {
            if (DEBUG_FOCUS) {
                ALOGD("Dropping event delivery to target with channel '%s' because it "
                ALOGD("Dropping event delivery to target with channel '%s' because it "
@@ -1846,34 +1785,23 @@ Unresponsive:
void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
                                            int32_t targetFlags, BitSet32 pointerIds,
                                            int32_t targetFlags, BitSet32 pointerIds,
                                            std::vector<InputTarget>& inputTargets) {
                                            std::vector<InputTarget>& inputTargets) {
    std::vector<InputTarget>::iterator it =
            std::find_if(inputTargets.begin(), inputTargets.end(),
                         [&windowHandle](const InputTarget& inputTarget) {
                             return inputTarget.inputChannel->getConnectionToken() ==
                                     windowHandle->getToken();
                         });

    const InputWindowInfo* windowInfo = windowHandle->getInfo();

    if (it == inputTargets.end()) {
        InputTarget inputTarget;
    sp<InputChannel> inputChannel = getInputChannelLocked(windowHandle->getToken());
    sp<InputChannel> inputChannel = getInputChannelLocked(windowHandle->getToken());
    if (inputChannel == nullptr) {
    if (inputChannel == nullptr) {
        ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
        ALOGW("Window %s already unregistered input channel", windowHandle->getName().c_str());
        return;
        return;
    }
    }
        inputTarget.inputChannel = inputChannel;
        inputTarget.flags = targetFlags;
        inputTarget.globalScaleFactor = windowInfo->globalScaleFactor;
        inputTargets.push_back(inputTarget);
        it = inputTargets.end() - 1;
    }

    ALOG_ASSERT(it->flags == targetFlags);
    ALOG_ASSERT(it->globalScaleFactor == windowInfo->globalScaleFactor);


    it->addPointers(pointerIds, -windowInfo->frameLeft, -windowInfo->frameTop,
    const InputWindowInfo* windowInfo = windowHandle->getInfo();
                    windowInfo->windowXScale, windowInfo->windowYScale);
    InputTarget target;
    target.inputChannel = inputChannel;
    target.flags = targetFlags;
    target.xOffset = -windowInfo->frameLeft;
    target.yOffset = -windowInfo->frameTop;
    target.globalScaleFactor = windowInfo->globalScaleFactor;
    target.windowXScale = windowInfo->windowXScale;
    target.windowYScale = windowInfo->windowYScale;
    target.pointerIds = pointerIds;
    inputTargets.push_back(target);
}
}


void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
@@ -1896,7 +1824,10 @@ void InputDispatcher::addMonitoringTargetLocked(const Monitor& monitor, float xO
    InputTarget target;
    InputTarget target;
    target.inputChannel = monitor.inputChannel;
    target.inputChannel = monitor.inputChannel;
    target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
    target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
    target.setDefaultPointerInfo(xOffset, yOffset, 1 /* windowXScale */, 1 /* windowYScale */);
    target.xOffset = xOffset;
    target.yOffset = yOffset;
    target.pointerIds.clear();
    target.globalScaleFactor = 1.0f;
    inputTargets.push_back(target);
    inputTargets.push_back(target);
}
}


@@ -2114,7 +2045,7 @@ void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
                                                 const sp<Connection>& connection,
                                                 const sp<Connection>& connection,
                                                 EventEntry* eventEntry,
                                                 EventEntry* eventEntry,
                                                 const InputTarget& inputTarget) {
                                                 const InputTarget* inputTarget) {
    if (ATRACE_ENABLED()) {
    if (ATRACE_ENABLED()) {
        std::string message =
        std::string message =
                StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, sequenceNum=%" PRIu32 ")",
                StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, sequenceNum=%" PRIu32 ")",
@@ -2125,9 +2056,9 @@ void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
    ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
    ALOGD("channel '%s' ~ prepareDispatchCycle - flags=0x%08x, "
          "xOffset=%f, yOffset=%f, globalScaleFactor=%f, "
          "xOffset=%f, yOffset=%f, globalScaleFactor=%f, "
          "windowScaleFactor=(%f, %f), pointerIds=0x%x",
          "windowScaleFactor=(%f, %f), pointerIds=0x%x",
          connection->getInputChannelName().c_str(), inputTarget.flags, inputTarget.xOffset,
          connection->getInputChannelName().c_str(), inputTarget->flags, inputTarget->xOffset,
          inputTarget.yOffset, inputTarget.globalScaleFactor, inputTarget.windowXScale,
          inputTarget->yOffset, inputTarget->globalScaleFactor, inputTarget->windowXScale,
          inputTarget.windowYScale, inputTarget.pointerIds.value);
          inputTarget->windowYScale, inputTarget->pointerIds.value);
#endif
#endif


    // Skip this event if the connection status is not normal.
    // Skip this event if the connection status is not normal.
@@ -2141,13 +2072,13 @@ void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
    }
    }


    // Split a motion event if needed.
    // Split a motion event if needed.
    if (inputTarget.flags & InputTarget::FLAG_SPLIT) {
    if (inputTarget->flags & InputTarget::FLAG_SPLIT) {
        ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);
        ALOG_ASSERT(eventEntry->type == EventEntry::Type::MOTION);


        const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
        const MotionEntry& originalMotionEntry = static_cast<const MotionEntry&>(*eventEntry);
        if (inputTarget.pointerIds.count() != originalMotionEntry.pointerCount) {
        if (inputTarget->pointerIds.count() != originalMotionEntry.pointerCount) {
            MotionEntry* splitMotionEntry =
            MotionEntry* splitMotionEntry =
                    splitMotionEvent(originalMotionEntry, inputTarget.pointerIds);
                    splitMotionEvent(originalMotionEntry, inputTarget->pointerIds);
            if (!splitMotionEntry) {
            if (!splitMotionEntry) {
                return; // split event was dropped
                return; // split event was dropped
            }
            }
@@ -2169,7 +2100,7 @@ void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,
                                                   const sp<Connection>& connection,
                                                   const sp<Connection>& connection,
                                                   EventEntry* eventEntry,
                                                   EventEntry* eventEntry,
                                                   const InputTarget& inputTarget) {
                                                   const InputTarget* inputTarget) {
    if (ATRACE_ENABLED()) {
    if (ATRACE_ENABLED()) {
        std::string message =
        std::string message =
                StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, sequenceNum=%" PRIu32
                StringPrintf("enqueueDispatchEntriesLocked(inputChannel=%s, sequenceNum=%" PRIu32
@@ -2202,7 +2133,7 @@ void InputDispatcher::enqueueDispatchEntriesLocked(nsecs_t currentTime,


void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connection,
                                                 EventEntry* eventEntry,
                                                 EventEntry* eventEntry,
                                                 const InputTarget& inputTarget,
                                                 const InputTarget* inputTarget,
                                                 int32_t dispatchMode) {
                                                 int32_t dispatchMode) {
    if (ATRACE_ENABLED()) {
    if (ATRACE_ENABLED()) {
        std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
        std::string message = StringPrintf("enqueueDispatchEntry(inputChannel=%s, dispatchMode=%s)",
@@ -2210,7 +2141,7 @@ void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connectio
                                           dispatchModeToString(dispatchMode).c_str());
                                           dispatchModeToString(dispatchMode).c_str());
        ATRACE_NAME(message.c_str());
        ATRACE_NAME(message.c_str());
    }
    }
    int32_t inputTargetFlags = inputTarget.flags;
    int32_t inputTargetFlags = inputTarget->flags;
    if (!(inputTargetFlags & dispatchMode)) {
    if (!(inputTargetFlags & dispatchMode)) {
        return;
        return;
    }
    }
@@ -2218,8 +2149,11 @@ void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connectio


    // This is a new event.
    // This is a new event.
    // Enqueue a new dispatch entry onto the outbound queue for this connection.
    // Enqueue a new dispatch entry onto the outbound queue for this connection.
    std::unique_ptr<DispatchEntry> dispatchEntry =
    DispatchEntry* dispatchEntry =
            createDispatchEntry(inputTarget, eventEntry, inputTargetFlags);
            new DispatchEntry(eventEntry, // increments ref
                              inputTargetFlags, inputTarget->xOffset, inputTarget->yOffset,
                              inputTarget->globalScaleFactor, inputTarget->windowXScale,
                              inputTarget->windowYScale);


    // Apply target flags and update the connection's input state.
    // Apply target flags and update the connection's input state.
    switch (eventEntry->type) {
    switch (eventEntry->type) {
@@ -2234,6 +2168,7 @@ void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connectio
                ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
                ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: skipping inconsistent key event",
                      connection->getInputChannelName().c_str());
                      connection->getInputChannelName().c_str());
#endif
#endif
                delete dispatchEntry;
                return; // skip the inconsistent event
                return; // skip the inconsistent event
            }
            }
            break;
            break;
@@ -2280,11 +2215,12 @@ void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connectio
                      "event",
                      "event",
                      connection->getInputChannelName().c_str());
                      connection->getInputChannelName().c_str());
#endif
#endif
                delete dispatchEntry;
                return; // skip the inconsistent event
                return; // skip the inconsistent event
            }
            }


            dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
            dispatchPointerDownOutsideFocus(motionEntry.source, dispatchEntry->resolvedAction,
                                            inputTarget.inputChannel->getConnectionToken());
                                            inputTarget->inputChannel->getConnectionToken());


            break;
            break;
        }
        }
@@ -2302,7 +2238,7 @@ void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connectio
    }
    }


    // Enqueue the dispatch entry.
    // Enqueue the dispatch entry.
    connection->outboundQueue.push_back(dispatchEntry.release());
    connection->outboundQueue.push_back(dispatchEntry);
    traceOutboundQueueLength(connection);
    traceOutboundQueueLength(connection);
}
}


@@ -2675,15 +2611,21 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
                    getWindowHandleLocked(connection->inputChannel->getConnectionToken());
                    getWindowHandleLocked(connection->inputChannel->getConnectionToken());
            if (windowHandle != nullptr) {
            if (windowHandle != nullptr) {
                const InputWindowInfo* windowInfo = windowHandle->getInfo();
                const InputWindowInfo* windowInfo = windowHandle->getInfo();
                target.setDefaultPointerInfo(-windowInfo->frameLeft, -windowInfo->frameTop,
                target.xOffset = -windowInfo->frameLeft;
                                             windowInfo->windowXScale, windowInfo->windowYScale);
                target.yOffset = -windowInfo->frameTop;
                target.globalScaleFactor = windowInfo->globalScaleFactor;
                target.globalScaleFactor = windowInfo->globalScaleFactor;
                target.windowXScale = windowInfo->windowXScale;
                target.windowYScale = windowInfo->windowYScale;
            } else {
                target.xOffset = 0;
                target.yOffset = 0;
                target.globalScaleFactor = 1.0f;
            }
            }
            target.inputChannel = connection->inputChannel;
            target.inputChannel = connection->inputChannel;
            target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
            target.flags = InputTarget::FLAG_DISPATCH_AS_IS;


            enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
            enqueueDispatchEntryLocked(connection, cancelationEventEntry, // increments ref
                                       target, InputTarget::FLAG_DISPATCH_AS_IS);
                                       &target, InputTarget::FLAG_DISPATCH_AS_IS);


            cancelationEventEntry->release();
            cancelationEventEntry->release();
        }
        }
+3 −3
Original line number Original line Diff line number Diff line
@@ -378,13 +378,13 @@ private:
    // with the mutex held makes it easier to ensure that connection invariants are maintained.
    // with the mutex held makes it easier to ensure that connection invariants are maintained.
    // If needed, the methods post commands to run later once the critical bits are done.
    // If needed, the methods post commands to run later once the critical bits are done.
    void prepareDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
    void prepareDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
                                    EventEntry* eventEntry, const InputTarget& inputTarget)
                                    EventEntry* eventEntry, const InputTarget* inputTarget)
            REQUIRES(mLock);
            REQUIRES(mLock);
    void enqueueDispatchEntriesLocked(nsecs_t currentTime, const sp<Connection>& connection,
    void enqueueDispatchEntriesLocked(nsecs_t currentTime, const sp<Connection>& connection,
                                      EventEntry* eventEntry, const InputTarget& inputTarget)
                                      EventEntry* eventEntry, const InputTarget* inputTarget)
            REQUIRES(mLock);
            REQUIRES(mLock);
    void enqueueDispatchEntryLocked(const sp<Connection>& connection, EventEntry* eventEntry,
    void enqueueDispatchEntryLocked(const sp<Connection>& connection, EventEntry* eventEntry,
                                    const InputTarget& inputTarget, int32_t dispatchMode)
                                    const InputTarget* inputTarget, int32_t dispatchMode)
            REQUIRES(mLock);
            REQUIRES(mLock);
    void startDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection)
    void startDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection)
            REQUIRES(mLock);
            REQUIRES(mLock);
+0 −39
Original line number Original line Diff line number Diff line
@@ -42,43 +42,4 @@ std::string dispatchModeToString(int32_t dispatchMode) {
    return StringPrintf("%" PRId32, dispatchMode);
    return StringPrintf("%" PRId32, dispatchMode);
}
}


void InputTarget::addPointers(BitSet32 newPointerIds, float xOffset, float yOffset,
                              float windowXScale, float windowYScale) {
    // The pointerIds can be empty, but still a valid InputTarget. This can happen for Monitors
    // and non splittable windows since we will just use all the pointers from the input event.
    if (newPointerIds.isEmpty()) {
        setDefaultPointerInfo(xOffset, yOffset, windowXScale, windowYScale);
        return;
    }

    // Ensure that the new set of pointers doesn't overlap with the current set of pointers.
    ALOG_ASSERT((pointerIds & newPointerIds) == 0);

    pointerIds |= newPointerIds;
    while (!newPointerIds.isEmpty()) {
        int32_t pointerId = newPointerIds.clearFirstMarkedBit();
        pointerInfos[pointerId].xOffset = xOffset;
        pointerInfos[pointerId].yOffset = yOffset;
        pointerInfos[pointerId].windowXScale = windowXScale;
        pointerInfos[pointerId].windowYScale = windowYScale;
    }
}

void InputTarget::setDefaultPointerInfo(float xOffset, float yOffset, float windowXScale,
                                        float windowYScale) {
    pointerIds.clear();
    pointerInfos[0].xOffset = xOffset;
    pointerInfos[0].yOffset = yOffset;
    pointerInfos[0].windowXScale = windowXScale;
    pointerInfos[0].windowYScale = windowYScale;
}

bool InputTarget::useDefaultPointerInfo() const {
    return pointerIds.isEmpty();
}

const PointerInfo& InputTarget::getDefaultPointerInfo() const {
    return pointerInfos[0];
}

} // namespace android::inputdispatcher
} // namespace android::inputdispatcher
+8 −39
Original line number Original line Diff line number Diff line
@@ -23,22 +23,6 @@


namespace android::inputdispatcher {
namespace android::inputdispatcher {


/*
 * Information about each pointer for an InputTarget. This includes offset and scale so
 * all pointers can be normalized to a single offset and scale.
 */
struct PointerInfo {
    // The x and y offset to add to a MotionEvent as it is delivered.
    // (ignored for KeyEvents)
    float xOffset = 0.0f;
    float yOffset = 0.0f;

    // Scaling factor to apply to MotionEvent as it is delivered.
    // (ignored for KeyEvents)
    float windowXScale = 1.0f;
    float windowYScale = 1.0f;
};

/*
/*
 * An input target specifies how an input event is to be dispatched to a particular window
 * An input target specifies how an input event is to be dispatched to a particular window
 * including the window's input channel, control flags, a timeout, and an X / Y offset to
 * including the window's input channel, control flags, a timeout, and an X / Y offset to
@@ -111,35 +95,20 @@ struct InputTarget {
    // Flags for the input target.
    // Flags for the input target.
    int32_t flags = 0;
    int32_t flags = 0;


    // The x and y offset to add to a MotionEvent as it is delivered.
    // (ignored for KeyEvents)
    float xOffset = 0.0f;
    float yOffset = 0.0f;

    // Scaling factor to apply to MotionEvent as it is delivered.
    // Scaling factor to apply to MotionEvent as it is delivered.
    // (ignored for KeyEvents)
    // (ignored for KeyEvents)
    float globalScaleFactor = 1.0f;
    float globalScaleFactor = 1.0f;
    float windowXScale = 1.0f;
    float windowYScale = 1.0f;


    // The subset of pointer ids to include in motion events dispatched to this input target
    // The subset of pointer ids to include in motion events dispatched to this input target
    // if FLAG_SPLIT is set.
    // if FLAG_SPLIT is set.
    BitSet32 pointerIds;
    BitSet32 pointerIds{};
    // The data is stored by the pointerId. Use the marked bits in pointerIds to look up PointerInfo
    // per pointerId.
    PointerInfo pointerInfos[MAX_POINTERS];

    void addPointers(BitSet32 pointerIds, float xOffset, float yOffset, float windowXScale,
                     float windowYScale);
    void setDefaultPointerInfo(float xOffset, float yOffset, float windowXScale,
                               float windowYScale);

    /**
     * Returns whether the default pointer information should be used. This will be true when the
     * InputTarget doesn't have any bits set in the pointerIds bitset. This can happen for monitors
     * and non splittable windows since we want all pointers for the EventEntry to go to this
     * target.
     */
    bool useDefaultPointerInfo() const;

    /**
     * Returns the default PointerInfo object. This should be used when useDefaultPointerInfo is
     * true.
     */
    const PointerInfo& getDefaultPointerInfo() const;
};
};


std::string dispatchModeToString(int32_t dispatchMode);
std::string dispatchModeToString(int32_t dispatchMode);
+0 −103
Original line number Original line Diff line number Diff line
@@ -1439,107 +1439,4 @@ TEST_F(InputDispatcherMultiWindowSameTokenTests, SingleTouchDifferentScale) {
    consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_DOWN, {expectedPoint});
    consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_DOWN, {expectedPoint});
}
}


TEST_F(InputDispatcherMultiWindowSameTokenTests, MultipleTouchDifferentScale) {
    mWindow2->setWindowScale(0.5f, 0.5f);

    // Touch Window 1
    std::vector<PointF> touchedPoints = {PointF{10, 10}};
    std::vector<PointF> expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0])};

    NotifyMotionArgs motionArgs =
            generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
                               ADISPLAY_ID_DEFAULT, touchedPoints);
    mDispatcher->notifyMotion(&motionArgs);
    consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_DOWN, expectedPoints);

    // Touch Window 2
    int32_t actionPointerDown =
            AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
    touchedPoints.emplace_back(PointF{150, 150});
    expectedPoints.emplace_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));

    motionArgs = generateMotionArgs(actionPointerDown, AINPUT_SOURCE_TOUCHSCREEN,
                                    ADISPLAY_ID_DEFAULT, touchedPoints);
    mDispatcher->notifyMotion(&motionArgs);

    // Consuming from window1 since it's the window that has the InputReceiver
    consumeMotionEvent(mWindow1, actionPointerDown, expectedPoints);
}

TEST_F(InputDispatcherMultiWindowSameTokenTests, MultipleTouchMoveDifferentScale) {
    mWindow2->setWindowScale(0.5f, 0.5f);

    // Touch Window 1
    std::vector<PointF> touchedPoints = {PointF{10, 10}};
    std::vector<PointF> expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0])};

    NotifyMotionArgs motionArgs =
            generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
                               ADISPLAY_ID_DEFAULT, touchedPoints);
    mDispatcher->notifyMotion(&motionArgs);
    consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_DOWN, expectedPoints);

    // Touch Window 2
    int32_t actionPointerDown =
            AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
    touchedPoints.emplace_back(PointF{150, 150});
    expectedPoints.emplace_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));

    motionArgs = generateMotionArgs(actionPointerDown, AINPUT_SOURCE_TOUCHSCREEN,
                                    ADISPLAY_ID_DEFAULT, touchedPoints);
    mDispatcher->notifyMotion(&motionArgs);

    // Consuming from window1 since it's the window that has the InputReceiver
    consumeMotionEvent(mWindow1, actionPointerDown, expectedPoints);

    // Move both windows
    touchedPoints = {{20, 20}, {175, 175}};
    expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0]),
                      getPointInWindow(mWindow2->getInfo(), touchedPoints[1])};

    motionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN,
                                    ADISPLAY_ID_DEFAULT, touchedPoints);
    mDispatcher->notifyMotion(&motionArgs);

    consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_MOVE, expectedPoints);
}

TEST_F(InputDispatcherMultiWindowSameTokenTests, MultipleWindowsFirstTouchWithScale) {
    mWindow1->setWindowScale(0.5f, 0.5f);

    // Touch Window 1
    std::vector<PointF> touchedPoints = {PointF{10, 10}};
    std::vector<PointF> expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0])};

    NotifyMotionArgs motionArgs =
            generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
                               ADISPLAY_ID_DEFAULT, touchedPoints);
    mDispatcher->notifyMotion(&motionArgs);
    consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_DOWN, expectedPoints);

    // Touch Window 2
    int32_t actionPointerDown =
            AMOTION_EVENT_ACTION_POINTER_DOWN + (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
    touchedPoints.emplace_back(PointF{150, 150});
    expectedPoints.emplace_back(getPointInWindow(mWindow2->getInfo(), touchedPoints[1]));

    motionArgs = generateMotionArgs(actionPointerDown, AINPUT_SOURCE_TOUCHSCREEN,
                                    ADISPLAY_ID_DEFAULT, touchedPoints);
    mDispatcher->notifyMotion(&motionArgs);

    // Consuming from window1 since it's the window that has the InputReceiver
    consumeMotionEvent(mWindow1, actionPointerDown, expectedPoints);

    // Move both windows
    touchedPoints = {{20, 20}, {175, 175}};
    expectedPoints = {getPointInWindow(mWindow1->getInfo(), touchedPoints[0]),
                      getPointInWindow(mWindow2->getInfo(), touchedPoints[1])};

    motionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_MOVE, AINPUT_SOURCE_TOUCHSCREEN,
                                    ADISPLAY_ID_DEFAULT, touchedPoints);
    mDispatcher->notifyMotion(&motionArgs);

    consumeMotionEvent(mWindow1, AMOTION_EVENT_ACTION_MOVE, expectedPoints);
}

} // namespace android::inputdispatcher
} // namespace android::inputdispatcher