diff options
Diffstat (limited to 'services/inputflinger/dispatcher/InputDispatcher.cpp')
-rw-r--r-- | services/inputflinger/dispatcher/InputDispatcher.cpp | 77 |
1 files changed, 49 insertions, 28 deletions
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp index 5e9427ad87..5c47be9be0 100644 --- a/services/inputflinger/dispatcher/InputDispatcher.cpp +++ b/services/inputflinger/dispatcher/InputDispatcher.cpp @@ -2195,10 +2195,7 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked( // Update the temporary touch state. BitSet32 pointerIds; - if (isSplit) { - uint32_t pointerId = entry.pointerProperties[pointerIndex].id; - pointerIds.markBit(pointerId); - } + pointerIds.markBit(entry.pointerProperties[pointerIndex].id); tempTouchState.addOrUpdateWindow(windowHandle, targetFlags, pointerIds); } @@ -2275,12 +2272,24 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked( } BitSet32 pointerIds; - if (isSplit) { - pointerIds.markBit(entry.pointerProperties[0].id); - } + pointerIds.markBit(entry.pointerProperties[0].id); tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, targetFlags, pointerIds); } } + + // Update the pointerIds for non-splittable when it received pointer down. + if (!isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN) { + // If no split, we suppose all touched windows should receive pointer down. + const int32_t pointerIndex = getMotionEventActionPointerIndex(action); + for (size_t i = 0; i < tempTouchState.windows.size(); i++) { + TouchedWindow& touchedWindow = tempTouchState.windows[i]; + // Ignore drag window for it should just track one pointer. + if (mDragState && mDragState->dragWindow == touchedWindow.windowHandle) { + continue; + } + touchedWindow.pointerIds.markBit(entry.pointerProperties[pointerIndex].id); + } + } } // Update dispatching for hover enter and exit. @@ -2389,13 +2398,15 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked( if (info->displayId == displayId && windowHandle->getInfo()->inputConfig.test( WindowInfo::InputConfig::IS_WALLPAPER)) { + BitSet32 pointerIds; + pointerIds.markBit(entry.pointerProperties[0].id); tempTouchState .addOrUpdateWindow(windowHandle, InputTarget::FLAG_WINDOW_IS_OBSCURED | InputTarget:: FLAG_WINDOW_IS_PARTIALLY_OBSCURED | InputTarget::FLAG_DISPATCH_AS_IS, - BitSet32(0)); + pointerIds); } } } @@ -2453,21 +2464,17 @@ Failed: } } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) { // One pointer went up. - if (isSplit) { - int32_t pointerIndex = getMotionEventActionPointerIndex(action); - uint32_t pointerId = entry.pointerProperties[pointerIndex].id; - - for (size_t i = 0; i < tempTouchState.windows.size();) { - TouchedWindow& touchedWindow = tempTouchState.windows[i]; - if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) { - touchedWindow.pointerIds.clearBit(pointerId); - if (touchedWindow.pointerIds.isEmpty()) { - tempTouchState.windows.erase(tempTouchState.windows.begin() + i); - continue; - } - } - i += 1; + int32_t pointerIndex = getMotionEventActionPointerIndex(action); + uint32_t pointerId = entry.pointerProperties[pointerIndex].id; + + for (size_t i = 0; i < tempTouchState.windows.size();) { + TouchedWindow& touchedWindow = tempTouchState.windows[i]; + touchedWindow.pointerIds.clearBit(pointerId); + if (touchedWindow.pointerIds.isEmpty()) { + tempTouchState.windows.erase(tempTouchState.windows.begin() + i); + continue; } + i += 1; } } @@ -4470,6 +4477,14 @@ void InputDispatcher::transformMotionEntryForInjectionLocked( if (it == mDisplayInfos.end()) return; const auto& transformToDisplay = it->second.transform.inverse() * injectedTransform; + if (entry.xCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION && + entry.yCursorPosition != AMOTION_EVENT_INVALID_CURSOR_POSITION) { + const vec2 cursor = + MotionEvent::calculateTransformedXY(entry.source, transformToDisplay, + {entry.xCursorPosition, entry.yCursorPosition}); + entry.xCursorPosition = cursor.x; + entry.yCursorPosition = cursor.y; + } for (uint32_t i = 0; i < entry.pointerCount; i++) { entry.pointerCoords[i] = MotionEvent::calculateTransformedCoords(entry.source, transformToDisplay, @@ -5079,14 +5094,13 @@ bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp< // Store the dragging window. if (isDragDrop) { - if (pointerIds.count() > 1) { - ALOGW("The drag and drop cannot be started when there is more than 1 pointer on the" - " window."); + if (pointerIds.count() != 1) { + ALOGW("The drag and drop cannot be started when there is no pointer or more than 1" + " pointer on the window."); return false; } - // If the window didn't not support split or the source is mouse, the pointerIds count - // would be 0, so we have to track the pointer 0. - const int32_t id = pointerIds.count() == 0 ? 0 : pointerIds.firstMarkedBit(); + // Track the pointer id for drag window and generate the drag state. + const int32_t id = pointerIds.firstMarkedBit(); mDragState = std::make_unique<DragState>(toWindowHandle, id); } @@ -6322,6 +6336,13 @@ void InputDispatcher::onWindowInfosChanged(const std::vector<WindowInfo>& window { // acquire lock std::scoped_lock _l(mLock); + + // Ensure that we have an entry created for all existing displays so that if a displayId has + // no windows, we can tell that the windows were removed from the display. + for (const auto& [displayId, _] : mWindowHandlesByDisplay) { + handlesPerDisplay[displayId]; + } + mDisplayInfos.clear(); for (const auto& displayInfo : displayInfos) { mDisplayInfos.emplace(displayInfo.displayId, displayInfo); |