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

Commit b3ad35c9 authored by Siarhei Vishniakou's avatar Siarhei Vishniakou
Browse files

Refactor setInputWindows

The logic for the actual window update is now factored out into a
separate function.
Otherwise, setInputWindows was too long and tough to reason about.
There should be no functional change in this CL.

Bug: none
Test: atest -a inputflinger_tests
Change-Id: I49c2eda5178de79de23f772ffc279249ca4402e8
parent 2307104b
Loading
Loading
Loading
Loading
+78 −74
Original line number Diff line number Diff line
@@ -236,9 +236,17 @@ static void dumpRegion(std::string& dump, const Region& region) {
    }
}

/**
 * Find the entry in std::unordered_map by key, and return it.
 * If the entry is not found, return a default constructed entry.
 *
 * Useful when the entries are vectors, since an empty vector will be returned
 * if the entry is not found.
 * Also useful when the entries are sp<>. If an entry is not found, nullptr is returned.
 */
template <typename T, typename U>
static T getValueByKey(std::unordered_map<U, T>& map, U key) {
    typename std::unordered_map<U, T>::const_iterator it = map.find(key);
static T getValueByKey(const std::unordered_map<U, T>& map, U key) {
    auto it = map.find(key);
    return it != map.end() ? it->second : T{};
}

@@ -3028,14 +3036,7 @@ void InputDispatcher::decrementPendingForegroundDispatches(EventEntry* entry) {

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

    // Return an empty one if nothing found.
    return std::vector<sp<InputWindowHandle>>();
    return getValueByKey(mWindowHandlesByDisplay, displayId);
}

sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
@@ -3077,36 +3078,17 @@ sp<InputChannel> InputDispatcher::getInputChannelLocked(const sp<IBinder>& token
    return mInputChannelsByToken.at(token);
}

/**
 * Called from InputManagerService, update window handle list by displayId that can receive input.
 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
 * If set an empty list, remove all handles from the specific display.
 * For focused handle, check if need to change and send a cancel event to previous one.
 * For removed handle, check if need to send a cancel event if already in touch.
 */
void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>& inputWindowHandles,
        int32_t displayId, const sp<ISetInputWindowsListener>& setInputWindowsListener) {
#if DEBUG_FOCUS
    ALOGD("setInputWindows displayId=%" PRId32, displayId);
#endif
    { // acquire lock
        std::scoped_lock _l(mLock);

        // Copy old handles for release if they are no longer present.
        const std::vector<sp<InputWindowHandle>> oldWindowHandles =
                getWindowHandlesLocked(displayId);

        sp<InputWindowHandle> newFocusedWindowHandle = nullptr;
        bool foundHoveredWindow = false;

void InputDispatcher::updateWindowHandlesForDisplayLocked(
        const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
    if (inputWindowHandles.empty()) {
        // Remove all handles on a display if there are no windows left.
        mWindowHandlesByDisplay.erase(displayId);
        } else {
        return;
    }

    // Since we compare the pointer of input window handles across window updates, we need
    // to make sure the handle object for the same window stays unchanged across updates.
            const std::vector<sp<InputWindowHandle>>& oldHandles =
                    mWindowHandlesByDisplay[displayId];
    const std::vector<sp<InputWindowHandle>>& oldHandles = getWindowHandlesLocked(displayId);
    std::unordered_map<sp<IBinder>, sp<InputWindowHandle>, IBinderHash> oldHandlesByTokens;
    for (const sp<InputWindowHandle>& handle : oldHandles) {
        oldHandlesByTokens[handle->getToken()] = handle;
@@ -3118,8 +3100,8 @@ void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>&
            // handle no longer valid
            continue;
        }
                const InputWindowInfo* info = handle->getInfo();

        const InputWindowInfo* info = handle->getInfo();
        if ((getInputChannelLocked(handle->getToken()) == nullptr &&
             info->portalToDisplayId == ADISPLAY_ID_NONE)) {
            const bool noInputChannel =
@@ -3141,8 +3123,7 @@ void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>&
        }

        if (oldHandlesByTokens.find(handle->getToken()) != oldHandlesByTokens.end()) {
                    const sp<InputWindowHandle> oldHandle =
                            oldHandlesByTokens.at(handle->getToken());
            const sp<InputWindowHandle> oldHandle = oldHandlesByTokens.at(handle->getToken());
            oldHandle->updateFrom(handle);
            newHandles.push_back(oldHandle);
        } else {
@@ -3150,10 +3131,37 @@ void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>&
        }
    }

            for (const sp<InputWindowHandle>& windowHandle : newHandles) {
    // Insert or replace
    mWindowHandlesByDisplay[displayId] = newHandles;
}

/**
 * Called from InputManagerService, update window handle list by displayId that can receive input.
 * A window handle contains information about InputChannel, Touch Region, Types, Focused,...
 * If set an empty list, remove all handles from the specific display.
 * For focused handle, check if need to change and send a cancel event to previous one.
 * For removed handle, check if need to send a cancel event if already in touch.
 */
void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>& inputWindowHandles,
        int32_t displayId, const sp<ISetInputWindowsListener>& setInputWindowsListener) {
#if DEBUG_FOCUS
    ALOGD("setInputWindows displayId=%" PRId32, displayId);
#endif
    { // acquire lock
        std::scoped_lock _l(mLock);

        // Copy old handles for release if they are no longer present.
        const std::vector<sp<InputWindowHandle>> oldWindowHandles =
                getWindowHandlesLocked(displayId);

        updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);

        sp<InputWindowHandle> newFocusedWindowHandle = nullptr;
        bool foundHoveredWindow = false;
        for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
            // Set newFocusedWindowHandle to the top most focused window instead of the last one
                if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus
                        && windowHandle->getInfo()->visible) {
            if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus &&
                windowHandle->getInfo()->visible) {
                newFocusedWindowHandle = windowHandle;
            }
            if (windowHandle == mLastHoverWindowHandle) {
@@ -3161,10 +3169,6 @@ void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>&
            }
        }

            // Insert or replace
            mWindowHandlesByDisplay[displayId] = newHandles;
        }

        if (!foundHoveredWindow) {
            mLastHoverWindowHandle = nullptr;
        }
+7 −0
Original line number Diff line number Diff line
@@ -1006,6 +1006,13 @@ private:
    sp<InputChannel> getInputChannelLocked(const sp<IBinder>& windowToken) const REQUIRES(mLock);
    bool hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const REQUIRES(mLock);

    /*
     * Validate and update InputWindowHandles for a given display.
     */
    void updateWindowHandlesForDisplayLocked(
            const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId)
            REQUIRES(mLock);

    // Focus tracking for keys, trackball, etc.
    std::unordered_map<int32_t, sp<InputWindowHandle>> mFocusedWindowHandlesByDisplay
            GUARDED_BY(mLock);