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

Commit fbf5ac72 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Refactor setInputWindows"

parents 25f4a8a1 b3ad35c9
Loading
Loading
Loading
Loading
+78 −74
Original line number Original line Diff line number Diff line
@@ -253,9 +253,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>
template <typename T, typename U>
static T getValueByKey(std::unordered_map<U, T>& map, U key) {
static T getValueByKey(const std::unordered_map<U, T>& map, U key) {
    typename std::unordered_map<U, T>::const_iterator it = map.find(key);
    auto it = map.find(key);
    return it != map.end() ? it->second : T{};
    return it != map.end() ? it->second : T{};
}
}


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


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

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


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


/**
void InputDispatcher::updateWindowHandlesForDisplayLocked(
 * Called from InputManagerService, update window handle list by displayId that can receive input.
        const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
 * 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;

    if (inputWindowHandles.empty()) {
    if (inputWindowHandles.empty()) {
        // Remove all handles on a display if there are no windows left.
        // Remove all handles on a display if there are no windows left.
        mWindowHandlesByDisplay.erase(displayId);
        mWindowHandlesByDisplay.erase(displayId);
        } else {
        return;
    }

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


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


        if (oldHandlesByTokens.find(handle->getToken()) != oldHandlesByTokens.end()) {
        if (oldHandlesByTokens.find(handle->getToken()) != oldHandlesByTokens.end()) {
                    const sp<InputWindowHandle> oldHandle =
            const sp<InputWindowHandle> oldHandle = oldHandlesByTokens.at(handle->getToken());
                            oldHandlesByTokens.at(handle->getToken());
            oldHandle->updateFrom(handle);
            oldHandle->updateFrom(handle);
            newHandles.push_back(oldHandle);
            newHandles.push_back(oldHandle);
        } else {
        } else {
@@ -3266,10 +3247,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
            // Set newFocusedWindowHandle to the top most focused window instead of the last one
                if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus
            if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus &&
                        && windowHandle->getInfo()->visible) {
                windowHandle->getInfo()->visible) {
                newFocusedWindowHandle = windowHandle;
                newFocusedWindowHandle = windowHandle;
            }
            }
            if (windowHandle == mLastHoverWindowHandle) {
            if (windowHandle == mLastHoverWindowHandle) {
@@ -3277,10 +3285,6 @@ void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>&
            }
            }
        }
        }


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

        if (!foundHoveredWindow) {
        if (!foundHoveredWindow) {
            mLastHoverWindowHandle = nullptr;
            mLastHoverWindowHandle = nullptr;
        }
        }
+7 −0
Original line number Original line Diff line number Diff line
@@ -1055,6 +1055,13 @@ private:
    sp<InputChannel> getInputChannelLocked(const sp<IBinder>& windowToken) const REQUIRES(mLock);
    sp<InputChannel> getInputChannelLocked(const sp<IBinder>& windowToken) const REQUIRES(mLock);
    bool hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) 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.
    // Focus tracking for keys, trackball, etc.
    std::unordered_map<int32_t, sp<InputWindowHandle>> mFocusedWindowHandlesByDisplay
    std::unordered_map<int32_t, sp<InputWindowHandle>> mFocusedWindowHandlesByDisplay
            GUARDED_BY(mLock);
            GUARDED_BY(mLock);