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

Commit 83d616a9 authored by Jeff Brown's avatar Jeff Brown
Browse files

Make input system aware of multiple displays.

The input system needs to know about the window that has
focus, even if it is on a secondary display.  So now we
send it the list of all windows and indicate which display
they are on.  We filter the list of windows as necessary
when delivering touch events.

To keep things simple, monitor input channels and input
filters are not supported except on the main display.
We also do not pass the display id to applications; it is
only used inside the input system for now.

Properly scale touch coordinates based on the viewport.
This will be needed to ensure that touch works on external
display as well as when the internal display is being used
to simulate a different resolution.

Change-Id: I1815579a52fcc852c519b5391fc7ab8767c2dc59
parent 7a8cce3d
Loading
Loading
Loading
Loading
+9 −0
Original line number Original line Diff line number Diff line
@@ -48,6 +48,15 @@ enum {
    AMOTION_EVENT_FLAG_TAINTED = 0x80000000,
    AMOTION_EVENT_FLAG_TAINTED = 0x80000000,
};
};


enum {
    /* Used when a motion event is not associated with any display.
     * Typically used for non-pointer events. */
    ADISPLAY_ID_NONE = -1,

    /* The default display id. */
    ADISPLAY_ID_DEFAULT = 0,
};

enum {
enum {
    /*
    /*
     * Indicates that an input device has switches.
     * Indicates that an input device has switches.
+90 −39
Original line number Original line Diff line number Diff line
@@ -166,6 +166,10 @@ static bool validateMotionEvent(int32_t action, size_t pointerCount,
    return true;
    return true;
}
}


static bool isMainDisplay(int32_t displayId) {
    return displayId == ADISPLAY_ID_DEFAULT || displayId == ADISPLAY_ID_NONE;
}

static void dumpRegion(String8& dump, const SkRegion& region) {
static void dumpRegion(String8& dump, const SkRegion& region) {
    if (region.isEmpty()) {
    if (region.isEmpty()) {
        dump.append("<empty>");
        dump.append("<empty>");
@@ -423,11 +427,12 @@ bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
                && (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
                && (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER)
                && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY
                && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY
                && mInputTargetWaitApplicationHandle != NULL) {
                && mInputTargetWaitApplicationHandle != NULL) {
            int32_t displayId = motionEntry->displayId;
            int32_t x = int32_t(motionEntry->pointerCoords[0].
            int32_t x = int32_t(motionEntry->pointerCoords[0].
                    getAxisValue(AMOTION_EVENT_AXIS_X));
                    getAxisValue(AMOTION_EVENT_AXIS_X));
            int32_t y = int32_t(motionEntry->pointerCoords[0].
            int32_t y = int32_t(motionEntry->pointerCoords[0].
                    getAxisValue(AMOTION_EVENT_AXIS_Y));
                    getAxisValue(AMOTION_EVENT_AXIS_Y));
            sp<InputWindowHandle> touchedWindowHandle = findTouchedWindowAtLocked(x, y);
            sp<InputWindowHandle> touchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y);
            if (touchedWindowHandle != NULL
            if (touchedWindowHandle != NULL
                    && touchedWindowHandle->inputApplicationHandle
                    && touchedWindowHandle->inputApplicationHandle
                            != mInputTargetWaitApplicationHandle) {
                            != mInputTargetWaitApplicationHandle) {
@@ -444,12 +449,14 @@ bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
    return needWake;
    return needWake;
}
}


sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t x, int32_t y) {
sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId,
        int32_t x, int32_t y) {
    // Traverse windows from front to back to find touched window.
    // Traverse windows from front to back to find touched window.
    size_t numWindows = mWindowHandles.size();
    size_t numWindows = mWindowHandles.size();
    for (size_t i = 0; i < numWindows; i++) {
    for (size_t i = 0; i < numWindows; i++) {
        sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
        sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
        const InputWindowInfo* windowInfo = windowHandle->getInfo();
        const InputWindowInfo* windowInfo = windowHandle->getInfo();
        if (windowInfo->displayId == displayId) {
            int32_t flags = windowInfo->layoutParamsFlags;
            int32_t flags = windowInfo->layoutParamsFlags;


            if (windowInfo->visible) {
            if (windowInfo->visible) {
@@ -468,6 +475,7 @@ sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t x, int3
                return NULL;
                return NULL;
            }
            }
        }
        }
    }
    return NULL;
    return NULL;
}
}


@@ -826,7 +834,10 @@ bool InputDispatcher::dispatchMotionLocked(
        return true;
        return true;
    }
    }


    // TODO: support sending secondary display events to input monitors
    if (isMainDisplay(entry->displayId)) {
        addMonitoringTargetsLocked(inputTargets);
        addMonitoringTargetsLocked(inputTargets);
    }


    // Dispatch the motion.
    // Dispatch the motion.
    if (conflictingPointerActions) {
    if (conflictingPointerActions) {
@@ -1117,6 +1128,7 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
    //
    //
    bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
    bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;


    int32_t displayId = entry->displayId;
    int32_t action = entry->action;
    int32_t action = entry->action;
    int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
    int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;


@@ -1126,9 +1138,10 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
    sp<InputWindowHandle> newHoverWindowHandle;
    sp<InputWindowHandle> newHoverWindowHandle;


    bool isSplit = mTouchState.split;
    bool isSplit = mTouchState.split;
    bool switchedDevice = mTouchState.deviceId >= 0
    bool switchedDevice = mTouchState.deviceId >= 0 && mTouchState.displayId >= 0
            && (mTouchState.deviceId != entry->deviceId
            && (mTouchState.deviceId != entry->deviceId
                    || mTouchState.source != entry->source);
                    || mTouchState.source != entry->source
                    || mTouchState.displayId != displayId);
    bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
    bool isHoverAction = (maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
            || maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
            || maskedAction == AMOTION_EVENT_ACTION_HOVER_ENTER
            || maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
            || maskedAction == AMOTION_EVENT_ACTION_HOVER_EXIT);
@@ -1152,6 +1165,7 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
        mTempTouchState.down = down;
        mTempTouchState.down = down;
        mTempTouchState.deviceId = entry->deviceId;
        mTempTouchState.deviceId = entry->deviceId;
        mTempTouchState.source = entry->source;
        mTempTouchState.source = entry->source;
        mTempTouchState.displayId = displayId;
        isSplit = false;
        isSplit = false;
    } else {
    } else {
        mTempTouchState.copyFrom(mTouchState);
        mTempTouchState.copyFrom(mTouchState);
@@ -1174,8 +1188,11 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
        for (size_t i = 0; i < numWindows; i++) {
        for (size_t i = 0; i < numWindows; i++) {
            sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
            sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
            const InputWindowInfo* windowInfo = windowHandle->getInfo();
            const InputWindowInfo* windowInfo = windowHandle->getInfo();
            int32_t flags = windowInfo->layoutParamsFlags;
            if (windowInfo->displayId != displayId) {
                continue; // wrong display
            }


            int32_t flags = windowInfo->layoutParamsFlags;
            if (flags & InputWindowInfo::FLAG_SYSTEM_ERROR) {
            if (flags & InputWindowInfo::FLAG_SYSTEM_ERROR) {
                if (topErrorWindowHandle == NULL) {
                if (topErrorWindowHandle == NULL) {
                    topErrorWindowHandle = windowHandle;
                    topErrorWindowHandle = windowHandle;
@@ -1300,7 +1317,8 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,


            sp<InputWindowHandle> oldTouchedWindowHandle =
            sp<InputWindowHandle> oldTouchedWindowHandle =
                    mTempTouchState.getFirstForegroundWindowHandle();
                    mTempTouchState.getFirstForegroundWindowHandle();
            sp<InputWindowHandle> newTouchedWindowHandle = findTouchedWindowAtLocked(x, y);
            sp<InputWindowHandle> newTouchedWindowHandle =
                    findTouchedWindowAtLocked(displayId, x, y);
            if (oldTouchedWindowHandle != newTouchedWindowHandle
            if (oldTouchedWindowHandle != newTouchedWindowHandle
                    && newTouchedWindowHandle != NULL) {
                    && newTouchedWindowHandle != NULL) {
#if DEBUG_FOCUS
#if DEBUG_FOCUS
@@ -1438,7 +1456,9 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
        if (foregroundWindowHandle->getInfo()->hasWallpaper) {
        if (foregroundWindowHandle->getInfo()->hasWallpaper) {
            for (size_t i = 0; i < mWindowHandles.size(); i++) {
            for (size_t i = 0; i < mWindowHandles.size(); i++) {
                sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
                sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
                if (windowHandle->getInfo()->layoutParamsType
                const InputWindowInfo* info = windowHandle->getInfo();
                if (info->displayId == displayId
                        && windowHandle->getInfo()->layoutParamsType
                                == InputWindowInfo::TYPE_WALLPAPER) {
                                == InputWindowInfo::TYPE_WALLPAPER) {
                    mTempTouchState.addOrUpdateWindow(windowHandle,
                    mTempTouchState.addOrUpdateWindow(windowHandle,
                            InputTarget::FLAG_WINDOW_IS_OBSCURED
                            InputTarget::FLAG_WINDOW_IS_OBSCURED
@@ -1495,6 +1515,7 @@ Failed:
                        || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
                        || maskedAction == AMOTION_EVENT_ACTION_HOVER_MOVE) {
                    mTouchState.deviceId = entry->deviceId;
                    mTouchState.deviceId = entry->deviceId;
                    mTouchState.source = entry->source;
                    mTouchState.source = entry->source;
                    mTouchState.displayId = displayId;
                }
                }
            } else if (maskedAction == AMOTION_EVENT_ACTION_UP
            } else if (maskedAction == AMOTION_EVENT_ACTION_UP
                    || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
                    || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
@@ -1610,6 +1631,7 @@ bool InputDispatcher::checkInjectionPermission(const sp<InputWindowHandle>& wind


bool InputDispatcher::isWindowObscuredAtPointLocked(
bool InputDispatcher::isWindowObscuredAtPointLocked(
        const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
        const sp<InputWindowHandle>& windowHandle, int32_t x, int32_t y) const {
    int32_t displayId = windowHandle->getInfo()->displayId;
    size_t numWindows = mWindowHandles.size();
    size_t numWindows = mWindowHandles.size();
    for (size_t i = 0; i < numWindows; i++) {
    for (size_t i = 0; i < numWindows; i++) {
        sp<InputWindowHandle> otherHandle = mWindowHandles.itemAt(i);
        sp<InputWindowHandle> otherHandle = mWindowHandles.itemAt(i);
@@ -1618,7 +1640,8 @@ bool InputDispatcher::isWindowObscuredAtPointLocked(
        }
        }


        const InputWindowInfo* otherInfo = otherHandle->getInfo();
        const InputWindowInfo* otherInfo = otherHandle->getInfo();
        if (otherInfo->visible && ! otherInfo->isTrustedOverlay()
        if (otherInfo->displayId == displayId
                && otherInfo->visible && !otherInfo->isTrustedOverlay()
                && otherInfo->frameContainsPoint(x, y)) {
                && otherInfo->frameContainsPoint(x, y)) {
            return true;
            return true;
        }
        }
@@ -1845,7 +1868,7 @@ void InputDispatcher::enqueueDispatchEntryLocked(
        }
        }
        if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
        if (dispatchEntry->resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE
                && !connection->inputState.isHovering(
                && !connection->inputState.isHovering(
                        motionEntry->deviceId, motionEntry->source)) {
                        motionEntry->deviceId, motionEntry->source, motionEntry->displayId)) {
#if DEBUG_DISPATCH_CYCLE
#if DEBUG_DISPATCH_CYCLE
        ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter event",
        ALOGD("channel '%s' ~ enqueueDispatchEntryLocked: filling in missing hover enter event",
                connection->getInputChannelName());
                connection->getInputChannelName());
@@ -2271,6 +2294,7 @@ InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet
            originalMotionEntry->xPrecision,
            originalMotionEntry->xPrecision,
            originalMotionEntry->yPrecision,
            originalMotionEntry->yPrecision,
            originalMotionEntry->downTime,
            originalMotionEntry->downTime,
            originalMotionEntry->displayId,
            splitPointerCount, splitPointerProperties, splitPointerCoords);
            splitPointerCount, splitPointerProperties, splitPointerCoords);


    if (originalMotionEntry->injectionState) {
    if (originalMotionEntry->injectionState) {
@@ -2351,7 +2375,7 @@ void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
    { // acquire lock
    { // acquire lock
        mLock.lock();
        mLock.lock();


        if (mInputFilterEnabled) {
        if (shouldSendKeyToInputFilterLocked(args)) {
            mLock.unlock();
            mLock.unlock();


            policyFlags |= POLICY_FLAG_FILTERED;
            policyFlags |= POLICY_FLAG_FILTERED;
@@ -2377,6 +2401,10 @@ void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
    }
    }
}
}


bool InputDispatcher::shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args) {
    return mInputFilterEnabled;
}

void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
#if DEBUG_INBOUND_EVENT_DETAILS
#if DEBUG_INBOUND_EVENT_DETAILS
    ALOGD("notifyMotion - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
    ALOGD("notifyMotion - eventTime=%lld, deviceId=%d, source=0x%x, policyFlags=0x%x, "
@@ -2415,7 +2443,7 @@ void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
    { // acquire lock
    { // acquire lock
        mLock.lock();
        mLock.lock();


        if (mInputFilterEnabled) {
        if (shouldSendMotionToInputFilterLocked(args)) {
            mLock.unlock();
            mLock.unlock();


            MotionEvent event;
            MotionEvent event;
@@ -2438,6 +2466,7 @@ void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
                args->deviceId, args->source, policyFlags,
                args->deviceId, args->source, policyFlags,
                args->action, args->flags, args->metaState, args->buttonState,
                args->action, args->flags, args->metaState, args->buttonState,
                args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime,
                args->edgeFlags, args->xPrecision, args->yPrecision, args->downTime,
                args->displayId,
                args->pointerCount, args->pointerProperties, args->pointerCoords);
                args->pointerCount, args->pointerProperties, args->pointerCoords);


        needWake = enqueueInboundEventLocked(newEntry);
        needWake = enqueueInboundEventLocked(newEntry);
@@ -2449,6 +2478,11 @@ void InputDispatcher::notifyMotion(const NotifyMotionArgs* args) {
    }
    }
}
}


bool InputDispatcher::shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args) {
    // TODO: support sending secondary display events to input filter
    return mInputFilterEnabled && isMainDisplay(args->displayId);
}

void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
void InputDispatcher::notifySwitch(const NotifySwitchArgs* args) {
#if DEBUG_INBOUND_EVENT_DETAILS
#if DEBUG_INBOUND_EVENT_DETAILS
    ALOGD("notifySwitch - eventTime=%lld, policyFlags=0x%x, switchCode=%d, switchValue=%d",
    ALOGD("notifySwitch - eventTime=%lld, policyFlags=0x%x, switchCode=%d, switchValue=%d",
@@ -2532,6 +2566,7 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event,


    case AINPUT_EVENT_TYPE_MOTION: {
    case AINPUT_EVENT_TYPE_MOTION: {
        const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
        const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
        int32_t displayId = ADISPLAY_ID_DEFAULT;
        int32_t action = motionEvent->getAction();
        int32_t action = motionEvent->getAction();
        size_t pointerCount = motionEvent->getPointerCount();
        size_t pointerCount = motionEvent->getPointerCount();
        const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
        const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
@@ -2553,8 +2588,8 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
                motionEvent->getMetaState(), motionEvent->getButtonState(),
                motionEvent->getMetaState(), motionEvent->getButtonState(),
                motionEvent->getEdgeFlags(),
                motionEvent->getEdgeFlags(),
                motionEvent->getXPrecision(), motionEvent->getYPrecision(),
                motionEvent->getXPrecision(), motionEvent->getYPrecision(),
                motionEvent->getDownTime(), uint32_t(pointerCount),
                motionEvent->getDownTime(), displayId,
                pointerProperties, samplePointerCoords);
                uint32_t(pointerCount), pointerProperties, samplePointerCoords);
        lastInjectedEntry = firstInjectedEntry;
        lastInjectedEntry = firstInjectedEntry;
        for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
        for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
            sampleEventTimes += 1;
            sampleEventTimes += 1;
@@ -2565,8 +2600,8 @@ int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
                    motionEvent->getMetaState(), motionEvent->getButtonState(),
                    motionEvent->getMetaState(), motionEvent->getButtonState(),
                    motionEvent->getEdgeFlags(),
                    motionEvent->getEdgeFlags(),
                    motionEvent->getXPrecision(), motionEvent->getYPrecision(),
                    motionEvent->getXPrecision(), motionEvent->getYPrecision(),
                    motionEvent->getDownTime(), uint32_t(pointerCount),
                    motionEvent->getDownTime(), displayId,
                    pointerProperties, samplePointerCoords);
                    uint32_t(pointerCount), pointerProperties, samplePointerCoords);
            lastInjectedEntry->next = nextInjectedEntry;
            lastInjectedEntry->next = nextInjectedEntry;
            lastInjectedEntry = nextInjectedEntry;
            lastInjectedEntry = nextInjectedEntry;
        }
        }
@@ -2939,6 +2974,12 @@ bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
#endif
#endif
            return true;
            return true;
        }
        }
        if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
#if DEBUG_FOCUS
            ALOGD("Cannot transfer focus because windows are on different displays.");
#endif
            return false;
        }


        bool found = false;
        bool found = false;
        for (size_t i = 0; i < mTouchState.windows.size(); i++) {
        for (size_t i = 0; i < mTouchState.windows.size(); i++) {
@@ -3040,6 +3081,7 @@ void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
    dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
    dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
    dump.appendFormat(INDENT "TouchDeviceId: %d\n", mTouchState.deviceId);
    dump.appendFormat(INDENT "TouchDeviceId: %d\n", mTouchState.deviceId);
    dump.appendFormat(INDENT "TouchSource: 0x%08x\n", mTouchState.source);
    dump.appendFormat(INDENT "TouchSource: 0x%08x\n", mTouchState.source);
    dump.appendFormat(INDENT "TouchDisplayId: %d\n", mTouchState.displayId);
    if (!mTouchState.windows.isEmpty()) {
    if (!mTouchState.windows.isEmpty()) {
        dump.append(INDENT "TouchedWindows:\n");
        dump.append(INDENT "TouchedWindows:\n");
        for (size_t i = 0; i < mTouchState.windows.size(); i++) {
        for (size_t i = 0; i < mTouchState.windows.size(); i++) {
@@ -3059,11 +3101,12 @@ void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
            const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
            const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
            const InputWindowInfo* windowInfo = windowHandle->getInfo();
            const InputWindowInfo* windowInfo = windowHandle->getInfo();


            dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
            dump.appendFormat(INDENT2 "%d: name='%s', displayId=%d, "
                    "paused=%s, hasFocus=%s, hasWallpaper=%s, "
                    "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
                    "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
                    "frame=[%d,%d][%d,%d], scale=%f, "
                    "frame=[%d,%d][%d,%d], scale=%f, "
                    "touchableRegion=",
                    "touchableRegion=",
                    i, windowInfo->name.string(),
                    i, windowInfo->name.string(), windowInfo->displayId,
                    toString(windowInfo->paused),
                    toString(windowInfo->paused),
                    toString(windowInfo->hasFocus),
                    toString(windowInfo->hasFocus),
                    toString(windowInfo->hasWallpaper),
                    toString(windowInfo->hasWallpaper),
@@ -3802,14 +3845,14 @@ InputDispatcher::MotionEntry::MotionEntry(nsecs_t eventTime,
        int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
        int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
        int32_t metaState, int32_t buttonState,
        int32_t metaState, int32_t buttonState,
        int32_t edgeFlags, float xPrecision, float yPrecision,
        int32_t edgeFlags, float xPrecision, float yPrecision,
        nsecs_t downTime, uint32_t pointerCount,
        nsecs_t downTime, int32_t displayId, uint32_t pointerCount,
        const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) :
        const PointerProperties* pointerProperties, const PointerCoords* pointerCoords) :
        EventEntry(TYPE_MOTION, eventTime, policyFlags),
        EventEntry(TYPE_MOTION, eventTime, policyFlags),
        eventTime(eventTime),
        eventTime(eventTime),
        deviceId(deviceId), source(source), action(action), flags(flags),
        deviceId(deviceId), source(source), action(action), flags(flags),
        metaState(metaState), buttonState(buttonState), edgeFlags(edgeFlags),
        metaState(metaState), buttonState(buttonState), edgeFlags(edgeFlags),
        xPrecision(xPrecision), yPrecision(yPrecision),
        xPrecision(xPrecision), yPrecision(yPrecision),
        downTime(downTime), pointerCount(pointerCount) {
        downTime(downTime), displayId(displayId), pointerCount(pointerCount) {
    for (uint32_t i = 0; i < pointerCount; i++) {
    for (uint32_t i = 0; i < pointerCount; i++) {
        this->pointerProperties[i].copyFrom(pointerProperties[i]);
        this->pointerProperties[i].copyFrom(pointerProperties[i]);
        this->pointerCoords[i].copyFrom(pointerCoords[i]);
        this->pointerCoords[i].copyFrom(pointerCoords[i]);
@@ -3820,8 +3863,8 @@ InputDispatcher::MotionEntry::~MotionEntry() {
}
}


void InputDispatcher::MotionEntry::appendDescription(String8& msg) const {
void InputDispatcher::MotionEntry::appendDescription(String8& msg) const {
    msg.appendFormat("MotionEvent(action=%d, deviceId=%d, source=0x%08x)",
    msg.appendFormat("MotionEvent(action=%d, deviceId=%d, source=0x%08x, displayId=%d)",
            action, deviceId, source);
            action, deviceId, source, displayId);
}
}




@@ -3864,11 +3907,13 @@ bool InputDispatcher::InputState::isNeutral() const {
    return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
    return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
}
}


bool InputDispatcher::InputState::isHovering(int32_t deviceId, uint32_t source) const {
bool InputDispatcher::InputState::isHovering(int32_t deviceId, uint32_t source,
        int32_t displayId) const {
    for (size_t i = 0; i < mMotionMementos.size(); i++) {
    for (size_t i = 0; i < mMotionMementos.size(); i++) {
        const MotionMemento& memento = mMotionMementos.itemAt(i);
        const MotionMemento& memento = mMotionMementos.itemAt(i);
        if (memento.deviceId == deviceId
        if (memento.deviceId == deviceId
                && memento.source == source
                && memento.source == source
                && memento.displayId == displayId
                && memento.hovering) {
                && memento.hovering) {
            return true;
            return true;
        }
        }
@@ -4025,6 +4070,7 @@ ssize_t InputDispatcher::InputState::findMotionMemento(const MotionEntry* entry,
        const MotionMemento& memento = mMotionMementos.itemAt(i);
        const MotionMemento& memento = mMotionMementos.itemAt(i);
        if (memento.deviceId == entry->deviceId
        if (memento.deviceId == entry->deviceId
                && memento.source == entry->source
                && memento.source == entry->source
                && memento.displayId == entry->displayId
                && memento.hovering == hovering) {
                && memento.hovering == hovering) {
            return i;
            return i;
        }
        }
@@ -4055,6 +4101,7 @@ void InputDispatcher::InputState::addMotionMemento(const MotionEntry* entry,
    memento.xPrecision = entry->xPrecision;
    memento.xPrecision = entry->xPrecision;
    memento.yPrecision = entry->yPrecision;
    memento.yPrecision = entry->yPrecision;
    memento.downTime = entry->downTime;
    memento.downTime = entry->downTime;
    memento.displayId = entry->displayId;
    memento.setPointers(entry);
    memento.setPointers(entry);
    memento.hovering = hovering;
    memento.hovering = hovering;
    memento.policyFlags = entry->policyFlags;
    memento.policyFlags = entry->policyFlags;
@@ -4090,6 +4137,7 @@ void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTim
                            : AMOTION_EVENT_ACTION_CANCEL,
                            : AMOTION_EVENT_ACTION_CANCEL,
                    memento.flags, 0, 0, 0,
                    memento.flags, 0, 0, 0,
                    memento.xPrecision, memento.yPrecision, memento.downTime,
                    memento.xPrecision, memento.yPrecision, memento.downTime,
                    memento.displayId,
                    memento.pointerCount, memento.pointerProperties, memento.pointerCoords));
                    memento.pointerCount, memento.pointerProperties, memento.pointerCoords));
        }
        }
    }
    }
@@ -4108,7 +4156,8 @@ void InputDispatcher::InputState::copyPointerStateTo(InputState& other) const {
            for (size_t j = 0; j < other.mMotionMementos.size(); ) {
            for (size_t j = 0; j < other.mMotionMementos.size(); ) {
                const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
                const MotionMemento& otherMemento = other.mMotionMementos.itemAt(j);
                if (memento.deviceId == otherMemento.deviceId
                if (memento.deviceId == otherMemento.deviceId
                        && memento.source == otherMemento.source) {
                        && memento.source == otherMemento.source
                        && memento.displayId == otherMemento.displayId) {
                    other.mMotionMementos.removeAt(j);
                    other.mMotionMementos.removeAt(j);
                } else {
                } else {
                    j += 1;
                    j += 1;
@@ -4240,7 +4289,7 @@ InputDispatcher::CommandEntry::~CommandEntry() {
// --- InputDispatcher::TouchState ---
// --- InputDispatcher::TouchState ---


InputDispatcher::TouchState::TouchState() :
InputDispatcher::TouchState::TouchState() :
    down(false), split(false), deviceId(-1), source(0) {
    down(false), split(false), deviceId(-1), source(0), displayId(-1) {
}
}


InputDispatcher::TouchState::~TouchState() {
InputDispatcher::TouchState::~TouchState() {
@@ -4251,6 +4300,7 @@ void InputDispatcher::TouchState::reset() {
    split = false;
    split = false;
    deviceId = -1;
    deviceId = -1;
    source = 0;
    source = 0;
    displayId = -1;
    windows.clear();
    windows.clear();
}
}


@@ -4259,6 +4309,7 @@ void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
    split = other.split;
    split = other.split;
    deviceId = other.deviceId;
    deviceId = other.deviceId;
    source = other.source;
    source = other.source;
    displayId = other.displayId;
    windows = other.windows;
    windows = other.windows;
}
}


+13 −5
Original line number Original line Diff line number Diff line
@@ -511,15 +511,17 @@ private:
        float xPrecision;
        float xPrecision;
        float yPrecision;
        float yPrecision;
        nsecs_t downTime;
        nsecs_t downTime;
        int32_t displayId;
        uint32_t pointerCount;
        uint32_t pointerCount;
        PointerProperties pointerProperties[MAX_POINTERS];
        PointerProperties pointerProperties[MAX_POINTERS];
        PointerCoords pointerCoords[MAX_POINTERS];
        PointerCoords pointerCoords[MAX_POINTERS];


        MotionEntry(nsecs_t eventTime,
        MotionEntry(nsecs_t eventTime,
                int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
                int32_t deviceId, uint32_t source, uint32_t policyFlags,
                int32_t flags, int32_t metaState, int32_t buttonState, int32_t edgeFlags,
                int32_t action, int32_t flags,
                int32_t metaState, int32_t buttonState, int32_t edgeFlags,
                float xPrecision, float yPrecision,
                float xPrecision, float yPrecision,
                nsecs_t downTime, uint32_t pointerCount,
                nsecs_t downTime, int32_t displayId, uint32_t pointerCount,
                const PointerProperties* pointerProperties, const PointerCoords* pointerCoords);
                const PointerProperties* pointerProperties, const PointerCoords* pointerCoords);
        virtual void appendDescription(String8& msg) const;
        virtual void appendDescription(String8& msg) const;


@@ -696,7 +698,7 @@ private:


        // Returns true if the specified source is known to have received a hover enter
        // Returns true if the specified source is known to have received a hover enter
        // motion event.
        // motion event.
        bool isHovering(int32_t deviceId, uint32_t source) const;
        bool isHovering(int32_t deviceId, uint32_t source, int32_t displayId) const;


        // Records tracking information for a key event that has just been published.
        // Records tracking information for a key event that has just been published.
        // Returns true if the event should be delivered, false if it is inconsistent
        // Returns true if the event should be delivered, false if it is inconsistent
@@ -752,6 +754,7 @@ private:
            float xPrecision;
            float xPrecision;
            float yPrecision;
            float yPrecision;
            nsecs_t downTime;
            nsecs_t downTime;
            int32_t displayId;
            uint32_t pointerCount;
            uint32_t pointerCount;
            PointerProperties pointerProperties[MAX_POINTERS];
            PointerProperties pointerProperties[MAX_POINTERS];
            PointerCoords pointerCoords[MAX_POINTERS];
            PointerCoords pointerCoords[MAX_POINTERS];
@@ -867,7 +870,7 @@ private:
    // to transfer focus to a new application.
    // to transfer focus to a new application.
    EventEntry* mNextUnblockedEvent;
    EventEntry* mNextUnblockedEvent;


    sp<InputWindowHandle> findTouchedWindowAtLocked(int32_t x, int32_t y);
    sp<InputWindowHandle> findTouchedWindowAtLocked(int32_t displayId, int32_t x, int32_t y);


    // All registered connections mapped by channel file descriptor.
    // All registered connections mapped by channel file descriptor.
    KeyedVector<int, sp<Connection> > mConnectionsByFd;
    KeyedVector<int, sp<Connection> > mConnectionsByFd;
@@ -899,6 +902,10 @@ private:
    bool runCommandsLockedInterruptible();
    bool runCommandsLockedInterruptible();
    CommandEntry* postCommandLocked(Command command);
    CommandEntry* postCommandLocked(Command command);


    // Input filter processing.
    bool shouldSendKeyToInputFilterLocked(const NotifyKeyArgs* args);
    bool shouldSendMotionToInputFilterLocked(const NotifyMotionArgs* args);

    // Inbound event processing.
    // Inbound event processing.
    void drainInboundQueueLocked();
    void drainInboundQueueLocked();
    void releasePendingEventLocked();
    void releasePendingEventLocked();
@@ -928,6 +935,7 @@ private:
        bool split;
        bool split;
        int32_t deviceId; // id of the device that is currently down, others are rejected
        int32_t deviceId; // id of the device that is currently down, others are rejected
        uint32_t source;  // source of the device that is current down, others are rejected
        uint32_t source;  // source of the device that is current down, others are rejected
        int32_t displayId; // id to the display that currently has a touch, others are rejected
        Vector<TouchedWindow> windows;
        Vector<TouchedWindow> windows;


        TouchState();
        TouchState();
+4 −3
Original line number Original line Diff line number Diff line
@@ -69,12 +69,12 @@ void NotifyKeyArgs::notify(const sp<InputListenerInterface>& listener) const {
NotifyMotionArgs::NotifyMotionArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source,
NotifyMotionArgs::NotifyMotionArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source,
        uint32_t policyFlags,
        uint32_t policyFlags,
        int32_t action, int32_t flags, int32_t metaState, int32_t buttonState,
        int32_t action, int32_t flags, int32_t metaState, int32_t buttonState,
        int32_t edgeFlags, uint32_t pointerCount,
        int32_t edgeFlags, int32_t displayId, uint32_t pointerCount,
        const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
        const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
        float xPrecision, float yPrecision, nsecs_t downTime) :
        float xPrecision, float yPrecision, nsecs_t downTime) :
        eventTime(eventTime), deviceId(deviceId), source(source), policyFlags(policyFlags),
        eventTime(eventTime), deviceId(deviceId), source(source), policyFlags(policyFlags),
        action(action), flags(flags), metaState(metaState), buttonState(buttonState),
        action(action), flags(flags), metaState(metaState), buttonState(buttonState),
        edgeFlags(edgeFlags), pointerCount(pointerCount),
        edgeFlags(edgeFlags), displayId(displayId), pointerCount(pointerCount),
        xPrecision(xPrecision), yPrecision(yPrecision), downTime(downTime) {
        xPrecision(xPrecision), yPrecision(yPrecision), downTime(downTime) {
    for (uint32_t i = 0; i < pointerCount; i++) {
    for (uint32_t i = 0; i < pointerCount; i++) {
        this->pointerProperties[i].copyFrom(pointerProperties[i]);
        this->pointerProperties[i].copyFrom(pointerProperties[i]);
@@ -87,7 +87,8 @@ NotifyMotionArgs::NotifyMotionArgs(const NotifyMotionArgs& other) :
        policyFlags(other.policyFlags),
        policyFlags(other.policyFlags),
        action(other.action), flags(other.flags),
        action(other.action), flags(other.flags),
        metaState(other.metaState), buttonState(other.buttonState),
        metaState(other.metaState), buttonState(other.buttonState),
        edgeFlags(other.edgeFlags), pointerCount(other.pointerCount),
        edgeFlags(other.edgeFlags), displayId(other.displayId),
        pointerCount(other.pointerCount),
        xPrecision(other.xPrecision), yPrecision(other.yPrecision), downTime(other.downTime) {
        xPrecision(other.xPrecision), yPrecision(other.yPrecision), downTime(other.downTime) {
    for (uint32_t i = 0; i < pointerCount; i++) {
    for (uint32_t i = 0; i < pointerCount; i++) {
        pointerProperties[i].copyFrom(other.pointerProperties[i]);
        pointerProperties[i].copyFrom(other.pointerProperties[i]);
+2 −1
Original line number Original line Diff line number Diff line
@@ -88,6 +88,7 @@ struct NotifyMotionArgs : public NotifyArgs {
    int32_t metaState;
    int32_t metaState;
    int32_t buttonState;
    int32_t buttonState;
    int32_t edgeFlags;
    int32_t edgeFlags;
    int32_t displayId;
    uint32_t pointerCount;
    uint32_t pointerCount;
    PointerProperties pointerProperties[MAX_POINTERS];
    PointerProperties pointerProperties[MAX_POINTERS];
    PointerCoords pointerCoords[MAX_POINTERS];
    PointerCoords pointerCoords[MAX_POINTERS];
@@ -99,7 +100,7 @@ struct NotifyMotionArgs : public NotifyArgs {


    NotifyMotionArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source, uint32_t policyFlags,
    NotifyMotionArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source, uint32_t policyFlags,
            int32_t action, int32_t flags, int32_t metaState, int32_t buttonState,
            int32_t action, int32_t flags, int32_t metaState, int32_t buttonState,
            int32_t edgeFlags, uint32_t pointerCount,
            int32_t edgeFlags, int32_t displayId, uint32_t pointerCount,
            const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
            const PointerProperties* pointerProperties, const PointerCoords* pointerCoords,
            float xPrecision, float yPrecision, nsecs_t downTime);
            float xPrecision, float yPrecision, nsecs_t downTime);


Loading