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 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>
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{};
}

@@ -3144,14 +3152,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(
@@ -3193,36 +3194,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;
@@ -3234,8 +3216,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 =
@@ -3257,8 +3239,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 {
@@ -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
                if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus
                        && windowHandle->getInfo()->visible) {
            if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus &&
                windowHandle->getInfo()->visible) {
                newFocusedWindowHandle = windowHandle;
            }
            if (windowHandle == mLastHoverWindowHandle) {
@@ -3277,10 +3285,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
@@ -1055,6 +1055,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);