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

Commit 09cb30e3 authored by Arthur Hung's avatar Arthur Hung
Browse files

Fix WM input limitations on secondary displays (2/N)

For one DisplayContent contains one InputMonitor now.
Store InputWindowHandles divided by displayId.
setInputWIndow will be updated by displayId
instead of updating all windows from all displays.

Bug: 111363643
Test: atest WindowManagerSmokeTest ActivityManagerMultiDisplayTests
Test: atest libinput_tests inputflinger_tests
Change-Id: I336945abdd36a543207e15650264280b04253eef
parent f5a824e8
Loading
Loading
Loading
Loading
+106 −65
Original line number Original line Diff line number Diff line
@@ -515,9 +515,10 @@ void InputDispatcher::addRecentEventLocked(EventEntry* entry) {
sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId,
sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId,
        int32_t x, int32_t y) {
        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();
    const Vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
    size_t numWindows = windowHandles.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 = windowHandles.itemAt(i);
        const InputWindowInfo* windowInfo = windowHandle->getInfo();
        const InputWindowInfo* windowInfo = windowHandle->getInfo();
        if (windowInfo->displayId == displayId) {
        if (windowInfo->displayId == displayId) {
            int32_t flags = windowInfo->layoutParamsFlags;
            int32_t flags = windowInfo->layoutParamsFlags;
@@ -1247,9 +1248,10 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
        bool isTouchModal = false;
        bool isTouchModal = false;


        // Traverse windows from front to back to find touched window and outside targets.
        // Traverse windows from front to back to find touched window and outside targets.
        size_t numWindows = mWindowHandles.size();
        const Vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
        size_t numWindows = windowHandles.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 = windowHandles.itemAt(i);
            const InputWindowInfo* windowInfo = windowHandle->getInfo();
            const InputWindowInfo* windowInfo = windowHandle->getInfo();
            if (windowInfo->displayId != displayId) {
            if (windowInfo->displayId != displayId) {
                continue; // wrong display
                continue; // wrong display
@@ -1472,8 +1474,10 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
        sp<InputWindowHandle> foregroundWindowHandle =
        sp<InputWindowHandle> foregroundWindowHandle =
                mTempTouchState.getFirstForegroundWindowHandle();
                mTempTouchState.getFirstForegroundWindowHandle();
        if (foregroundWindowHandle->getInfo()->hasWallpaper) {
        if (foregroundWindowHandle->getInfo()->hasWallpaper) {
            for (size_t i = 0; i < mWindowHandles.size(); i++) {
            const Vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
                sp<InputWindowHandle> windowHandle = mWindowHandles.itemAt(i);
            size_t numWindows = windowHandles.size();
            for (size_t i = 0; i < numWindows; i++) {
                sp<InputWindowHandle> windowHandle = windowHandles.itemAt(i);
                const InputWindowInfo* info = windowHandle->getInfo();
                const InputWindowInfo* info = windowHandle->getInfo();
                if (info->displayId == displayId
                if (info->displayId == displayId
                        && windowHandle->getInfo()->layoutParamsType
                        && windowHandle->getInfo()->layoutParamsType
@@ -1658,9 +1662,10 @@ 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;
    int32_t displayId = windowHandle->getInfo()->displayId;
    size_t numWindows = mWindowHandles.size();
    const Vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
    size_t numWindows = windowHandles.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 = windowHandles.itemAt(i);
        if (otherHandle == windowHandle) {
        if (otherHandle == windowHandle) {
            break;
            break;
        }
        }
@@ -1678,10 +1683,11 @@ bool InputDispatcher::isWindowObscuredAtPointLocked(


bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
bool InputDispatcher::isWindowObscuredLocked(const sp<InputWindowHandle>& windowHandle) const {
    int32_t displayId = windowHandle->getInfo()->displayId;
    int32_t displayId = windowHandle->getInfo()->displayId;
    const Vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
    const InputWindowInfo* windowInfo = windowHandle->getInfo();
    const InputWindowInfo* windowInfo = windowHandle->getInfo();
    size_t numWindows = mWindowHandles.size();
    size_t numWindows = windowHandles.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 = windowHandles.itemAt(i);
        if (otherHandle == windowHandle) {
        if (otherHandle == windowHandle) {
            break;
            break;
        }
        }
@@ -2909,45 +2915,69 @@ void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* ent
    }
    }
}
}


Vector<sp<InputWindowHandle>> InputDispatcher::getWindowHandlesLocked(int32_t displayId) const {
    std::unordered_map<int32_t, Vector<sp<InputWindowHandle>>>::const_iterator it
        = mWindowHandlesByDisplay.find(displayId);
    if(it != mWindowHandlesByDisplay.end()) {
        return it->second;
    }

    // Return an empty one if nothing found.
    return Vector<sp<InputWindowHandle>>();
}

sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
        const sp<InputChannel>& inputChannel) const {
        const sp<InputChannel>& inputChannel) const {
    size_t numWindows = mWindowHandles.size();
    for (auto& it : mWindowHandlesByDisplay) {
        const Vector<sp<InputWindowHandle>> windowHandles = it.second;
        size_t numWindows = windowHandles.size();
        for (size_t i = 0; i < numWindows; i++) {
        for (size_t i = 0; i < numWindows; i++) {
        const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
            const sp<InputWindowHandle>& windowHandle = windowHandles.itemAt(i);
            if (windowHandle->getInputChannel() == inputChannel) {
            if (windowHandle->getInputChannel() == inputChannel) {
                return windowHandle;
                return windowHandle;
            }
            }
        }
        }
    }
    return nullptr;
    return nullptr;
}
}


bool InputDispatcher::hasWindowHandleLocked(
bool InputDispatcher::hasWindowHandleLocked(
        const sp<InputWindowHandle>& windowHandle) const {
        const sp<InputWindowHandle>& windowHandle, int32_t displayId) const {
    size_t numWindows = mWindowHandles.size();

    const Vector<sp<InputWindowHandle>> windowHandles = getWindowHandlesLocked(displayId);
    size_t numWindows = windowHandles.size();
    for (size_t i = 0; i < numWindows; i++) {
    for (size_t i = 0; i < numWindows; i++) {
        if (mWindowHandles.itemAt(i) == windowHandle) {
        if (windowHandles.itemAt(i) == windowHandle) {
            return true;
            return true;
        }
        }
    }
    }
    return false;
    return false;
}
}


void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles) {
void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle>>& inputWindowHandles,
        int displayId) {
#if DEBUG_FOCUS
#if DEBUG_FOCUS
    ALOGD("setInputWindows");
    ALOGD("setInputWindows");
#endif
#endif
    { // acquire lock
    { // acquire lock
        AutoMutex _l(mLock);
        AutoMutex _l(mLock);


        Vector<sp<InputWindowHandle> > oldWindowHandles = mWindowHandles;
        const Vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
        mWindowHandles = inputWindowHandles;
        Vector<sp<InputWindowHandle>> windowHandles = inputWindowHandles;
        // Insert or replace
        mWindowHandlesByDisplay[displayId] = windowHandles;


        sp<InputWindowHandle> newFocusedWindowHandle;
        // TODO(b/111361570): multi-display focus, one focus in all display in current.
        sp<InputWindowHandle> newFocusedWindowHandle = mFocusedWindowHandle;
        bool foundHoveredWindow = false;
        bool foundHoveredWindow = false;
        for (size_t i = 0; i < mWindowHandles.size(); i++) {

            const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
        if (windowHandles.isEmpty()) {
            // Remove all handles on a display if there are no windows left.
            mWindowHandlesByDisplay.erase(displayId);
        } else {
            for (size_t i = 0; i < windowHandles.size(); i++) {
                const sp<InputWindowHandle>& windowHandle = windowHandles.itemAt(i);
                if (!windowHandle->updateInfo() || windowHandle->getInputChannel() == nullptr) {
                if (!windowHandle->updateInfo() || windowHandle->getInputChannel() == nullptr) {
                mWindowHandles.removeAt(i--);
                    continue;
                    continue;
                }
                }
                if (windowHandle->getInfo()->hasFocus) {
                if (windowHandle->getInfo()->hasFocus) {
@@ -2957,11 +2987,13 @@ void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle> >& inpu
                    foundHoveredWindow = true;
                    foundHoveredWindow = true;
                }
                }
            }
            }
        }


        if (!foundHoveredWindow) {
        if (!foundHoveredWindow) {
            mLastHoverWindowHandle = nullptr;
            mLastHoverWindowHandle = nullptr;
        }
        }


        // TODO(b/111361570): multi-display focus, one focus in all display in current.
        if (mFocusedWindowHandle != newFocusedWindowHandle) {
        if (mFocusedWindowHandle != newFocusedWindowHandle) {
            if (mFocusedWindowHandle != nullptr) {
            if (mFocusedWindowHandle != nullptr) {
#if DEBUG_FOCUS
#if DEBUG_FOCUS
@@ -2985,11 +3017,12 @@ void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle> >& inpu
            mFocusedWindowHandle = newFocusedWindowHandle;
            mFocusedWindowHandle = newFocusedWindowHandle;
        }
        }


        for (size_t d = 0; d < mTouchStatesByDisplay.size(); d++) {
        ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
            TouchState& state = mTouchStatesByDisplay.editValueAt(d);
        if (stateIndex >= 0) {
            TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
            for (size_t i = 0; i < state.windows.size(); ) {
            for (size_t i = 0; i < state.windows.size(); ) {
                TouchedWindow& touchedWindow = state.windows.editItemAt(i);
                TouchedWindow& touchedWindow = state.windows.editItemAt(i);
                if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
                if (!hasWindowHandleLocked(touchedWindow.windowHandle, displayId)) {
#if DEBUG_FOCUS
#if DEBUG_FOCUS
                    ALOGD("Touched window was removed: %s",
                    ALOGD("Touched window was removed: %s",
                            touchedWindow.windowHandle->getName().c_str());
                            touchedWindow.windowHandle->getName().c_str());
@@ -3015,7 +3048,7 @@ void InputDispatcher::setInputWindows(const Vector<sp<InputWindowHandle> >& inpu
        // which might not happen until the next GC.
        // which might not happen until the next GC.
        for (size_t i = 0; i < oldWindowHandles.size(); i++) {
        for (size_t i = 0; i < oldWindowHandles.size(); i++) {
            const sp<InputWindowHandle>& oldWindowHandle = oldWindowHandles.itemAt(i);
            const sp<InputWindowHandle>& oldWindowHandle = oldWindowHandles.itemAt(i);
            if (!hasWindowHandleLocked(oldWindowHandle)) {
            if (!hasWindowHandleLocked(oldWindowHandle, displayId)) {
#if DEBUG_FOCUS
#if DEBUG_FOCUS
                ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
                ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
#endif
#endif
@@ -3266,10 +3299,14 @@ void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
        dump += INDENT "TouchStates: <no displays touched>\n";
        dump += INDENT "TouchStates: <no displays touched>\n";
    }
    }


    if (!mWindowHandles.isEmpty()) {
    if (!mWindowHandlesByDisplay.empty()) {
       for (auto& it : mWindowHandlesByDisplay) {
            const Vector<sp<InputWindowHandle>> windowHandles = it.second;
            dump += StringPrintf(INDENT "Display: %d\n", it.first);
            if (!windowHandles.isEmpty()) {
                dump += INDENT "Windows:\n";
                dump += INDENT "Windows:\n";
        for (size_t i = 0; i < mWindowHandles.size(); i++) {
                for (size_t i = 0; i < windowHandles.size(); i++) {
            const sp<InputWindowHandle>& windowHandle = mWindowHandles.itemAt(i);
                    const sp<InputWindowHandle>& windowHandle = windowHandles.itemAt(i);
                    const InputWindowInfo* windowInfo = windowHandle->getInfo();
                    const InputWindowInfo* windowInfo = windowHandle->getInfo();


                    dump += StringPrintf(INDENT2 "%zu: name='%s', displayId=%d, "
                    dump += StringPrintf(INDENT2 "%zu: name='%s', displayId=%d, "
@@ -3297,6 +3334,10 @@ void InputDispatcher::dumpDispatchStateLocked(std::string& dump) {
            } else {
            } else {
                dump += INDENT "Windows: <none>\n";
                dump += INDENT "Windows: <none>\n";
            }
            }
        }
    } else {
        dump += INDENT "Displays: <none>\n";
    }


    if (!mMonitoringChannels.isEmpty()) {
    if (!mMonitoringChannels.isEmpty()) {
        dump += INDENT "MonitoringChannels:\n";
        dump += INDENT "MonitoringChannels:\n";
+9 −5
Original line number Original line Diff line number Diff line
@@ -31,6 +31,7 @@
#include <stddef.h>
#include <stddef.h>
#include <unistd.h>
#include <unistd.h>
#include <limits.h>
#include <limits.h>
#include <unordered_map>


#include "InputWindow.h"
#include "InputWindow.h"
#include "InputApplication.h"
#include "InputApplication.h"
@@ -307,7 +308,8 @@ public:
     *
     *
     * This method may be called on any thread (usually by the input manager).
     * This method may be called on any thread (usually by the input manager).
     */
     */
    virtual void setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles) = 0;
    virtual void setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles,
            int displayId) = 0;


    /* Sets the focused application.
    /* Sets the focused application.
     *
     *
@@ -387,7 +389,8 @@ public:
            int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
            int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis,
            uint32_t policyFlags);
            uint32_t policyFlags);


    virtual void setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles);
    virtual void setInputWindows(const Vector<sp<InputWindowHandle> >& inputWindowHandles,
            int displayId);
    virtual void setFocusedApplication(const sp<InputApplicationHandle>& inputApplicationHandle);
    virtual void setFocusedApplication(const sp<InputApplicationHandle>& inputApplicationHandle);
    virtual void setInputDispatchMode(bool enabled, bool frozen);
    virtual void setInputDispatchMode(bool enabled, bool frozen);
    virtual void setInputFilterEnabled(bool enabled);
    virtual void setInputFilterEnabled(bool enabled);
@@ -956,10 +959,11 @@ private:
    bool mDispatchFrozen;
    bool mDispatchFrozen;
    bool mInputFilterEnabled;
    bool mInputFilterEnabled;


    Vector<sp<InputWindowHandle> > mWindowHandles;
    std::unordered_map<int32_t, Vector<sp<InputWindowHandle>>> mWindowHandlesByDisplay;

    // Get window handles by display, return an empty vector if not found.
    Vector<sp<InputWindowHandle>> getWindowHandlesLocked(int32_t displayId) const;
    sp<InputWindowHandle> getWindowHandleLocked(const sp<InputChannel>& inputChannel) const;
    sp<InputWindowHandle> getWindowHandleLocked(const sp<InputChannel>& inputChannel) const;
    bool hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const;
    bool hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle, int32_t displayId) const;


    // Focus tracking for keys, trackball, etc.
    // Focus tracking for keys, trackball, etc.
    sp<InputWindowHandle> mFocusedWindowHandle;
    sp<InputWindowHandle> mFocusedWindowHandle;