Loading services/inputflinger/InputDispatcher.cpp +78 −74 Original line number Diff line number Diff line Loading @@ -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{}; } Loading Loading @@ -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( Loading Loading @@ -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; Loading @@ -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 = Loading @@ -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 { Loading @@ -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) { Loading @@ -3277,10 +3285,6 @@ void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>& } } // Insert or replace mWindowHandlesByDisplay[displayId] = newHandles; } if (!foundHoveredWindow) { mLastHoverWindowHandle = nullptr; } Loading services/inputflinger/InputDispatcher.h +7 −0 Original line number Diff line number Diff line Loading @@ -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); Loading Loading
services/inputflinger/InputDispatcher.cpp +78 −74 Original line number Diff line number Diff line Loading @@ -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{}; } Loading Loading @@ -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( Loading Loading @@ -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; Loading @@ -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 = Loading @@ -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 { Loading @@ -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) { Loading @@ -3277,10 +3285,6 @@ void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>& } } // Insert or replace mWindowHandlesByDisplay[displayId] = newHandles; } if (!foundHoveredWindow) { mLastHoverWindowHandle = nullptr; } Loading
services/inputflinger/InputDispatcher.h +7 −0 Original line number Diff line number Diff line Loading @@ -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); Loading