Loading include/input/Input.h +2 −0 Original line number Diff line number Diff line Loading @@ -515,6 +515,8 @@ struct PointerProperties { PointerProperties& operator=(const PointerProperties&) = default; }; std::ostream& operator<<(std::ostream& out, const PointerProperties& properties); // TODO(b/211379801) : Use a strong type from ftl/mixins.h instead using DeviceId = int32_t; Loading libs/input/Input.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -379,6 +379,11 @@ std::ostream& operator<<(std::ostream& out, const KeyEvent& event) { return out; } std::ostream& operator<<(std::ostream& out, const PointerProperties& properties) { out << "Pointer(id=" << properties.id << ", " << ftl::enum_string(properties.toolType) << ")"; return out; } // --- PointerCoords --- float PointerCoords::getAxisValue(int32_t axis) const { Loading services/inputflinger/dispatcher/InputDispatcher.cpp +45 −39 Original line number Diff line number Diff line Loading @@ -253,6 +253,14 @@ Result<void> validateInputEvent(const InputEvent& event) { } } std::bitset<MAX_POINTER_ID + 1> getPointerIds(const std::vector<PointerProperties>& pointers) { std::bitset<MAX_POINTER_ID + 1> pointerIds; for (const PointerProperties& pointer : pointers) { pointerIds.set(pointer.id); } return pointerIds; } std::string dumpRegion(const Region& region) { if (region.isEmpty()) { return "<empty>"; Loading Loading @@ -631,15 +639,15 @@ std::vector<TouchedWindow> getHoveringWindowsLocked(const TouchState* oldState, } // We should consider all hovering pointers here. But for now, just use the first one const int32_t pointerId = entry.pointerProperties[0].id; const PointerProperties& pointer = entry.pointerProperties[0]; std::set<sp<WindowInfoHandle>> oldWindows; if (oldState != nullptr) { oldWindows = oldState->getWindowsWithHoveringPointer(entry.deviceId, pointerId); oldWindows = oldState->getWindowsWithHoveringPointer(entry.deviceId, pointer.id); } std::set<sp<WindowInfoHandle>> newWindows = newTouchState.getWindowsWithHoveringPointer(entry.deviceId, pointerId); newTouchState.getWindowsWithHoveringPointer(entry.deviceId, pointer.id); // If the pointer is no longer in the new window set, send HOVER_EXIT. for (const sp<WindowInfoHandle>& oldWindow : oldWindows) { Loading Loading @@ -673,7 +681,7 @@ std::vector<TouchedWindow> getHoveringWindowsLocked(const TouchState* oldState, } touchedWindow.dispatchMode = InputTarget::DispatchMode::AS_IS; } touchedWindow.addHoveringPointer(entry.deviceId, pointerId); touchedWindow.addHoveringPointer(entry.deviceId, pointer); if (canReceiveForegroundTouches(*newWindow->getInfo())) { touchedWindow.targetFlags |= InputTarget::Flags::FOREGROUND; } Loading Loading @@ -2320,7 +2328,7 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( /* Case 1: New splittable pointer going down, or need target for hover or scroll. */ const auto [x, y] = resolveTouchedPosition(entry); const int32_t pointerIndex = MotionEvent::getActionIndex(action); const int32_t pointerId = entry.pointerProperties[pointerIndex].id; const PointerProperties& pointer = entry.pointerProperties[pointerIndex]; // Outside targets should be added upon first dispatched DOWN event. That means, this should // be a pointer that would generate ACTION_DOWN, *and* touch should not already be down. const bool isStylus = isPointerFromStylus(entry, pointerIndex); Loading @@ -2328,7 +2336,7 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( findTouchedWindowAtLocked(displayId, x, y, isStylus); if (isDown) { targets += findOutsideTargetsLocked(displayId, newTouchedWindowHandle, pointerId); targets += findOutsideTargetsLocked(displayId, newTouchedWindowHandle, pointer.id); } // Handle the case where we did not find a window. if (newTouchedWindowHandle == nullptr) { Loading Loading @@ -2386,7 +2394,7 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( if (isHoverAction) { // The "windowHandle" is the target of this hovering pointer. tempTouchState.addHoveringPointerToWindow(windowHandle, entry.deviceId, pointerId); tempTouchState.addHoveringPointerToWindow(windowHandle, entry.deviceId, pointer); } // Set target flags. Loading @@ -2409,12 +2417,10 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( // Update the temporary touch state. if (!isHoverAction) { std::bitset<MAX_POINTER_ID + 1> pointerIds; pointerIds.set(pointerId); const bool isDownOrPointerDown = maskedAction == AMOTION_EVENT_ACTION_DOWN || maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN; tempTouchState.addOrUpdateWindow(windowHandle, InputTarget::DispatchMode::AS_IS, targetFlags, entry.deviceId, pointerIds, targetFlags, entry.deviceId, {pointer}, isDownOrPointerDown ? std::make_optional(entry.eventTime) : std::nullopt); Loading @@ -2437,7 +2443,7 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( } tempTouchState.addOrUpdateWindow(wallpaper, InputTarget::DispatchMode::AS_IS, wallpaperFlags, entry.deviceId, pointerIds, wallpaperFlags, entry.deviceId, {pointer}, entry.eventTime); } } Loading @@ -2448,12 +2454,12 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( // make it pilfering. This will prevent other non-spy windows from getting this pointer, // which is a specific behaviour that we want. for (TouchedWindow& touchedWindow : tempTouchState.windows) { if (touchedWindow.hasTouchingPointer(entry.deviceId, pointerId) && if (touchedWindow.hasTouchingPointer(entry.deviceId, pointer.id) && touchedWindow.hasPilferingPointers(entry.deviceId)) { // This window is already pilfering some pointers, and this new pointer is also // going to it. Therefore, take over this pointer and don't give it to anyone // else. touchedWindow.addPilferingPointer(entry.deviceId, pointerId); touchedWindow.addPilferingPointer(entry.deviceId, pointer.id); } } Loading Loading @@ -2522,8 +2528,8 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( // Make a slippery exit from the old window. std::bitset<MAX_POINTER_ID + 1> pointerIds; const int32_t pointerId = entry.pointerProperties[0].id; pointerIds.set(pointerId); const PointerProperties& pointer = entry.pointerProperties[0]; pointerIds.set(pointer.id); const TouchedWindow& touchedWindow = tempTouchState.getTouchedWindow(oldTouchedWindowHandle); Loading Loading @@ -2553,13 +2559,13 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, InputTarget::DispatchMode::SLIPPERY_ENTER, targetFlags, entry.deviceId, pointerIds, targetFlags, entry.deviceId, {pointer}, entry.eventTime); // Check if the wallpaper window should deliver the corresponding event. slipWallpaperTouch(targetFlags, oldTouchedWindowHandle, newTouchedWindowHandle, tempTouchState, entry.deviceId, pointerId, targets); tempTouchState.removeTouchingPointerFromWindow(entry.deviceId, pointerId, tempTouchState, entry.deviceId, pointer, targets); tempTouchState.removeTouchingPointerFromWindow(entry.deviceId, pointer.id, oldTouchedWindowHandle); } } Loading @@ -2568,14 +2574,12 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( if (!isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN) { // If no split, we suppose all touched windows should receive pointer down. const int32_t pointerIndex = MotionEvent::getActionIndex(action); for (size_t i = 0; i < tempTouchState.windows.size(); i++) { TouchedWindow& touchedWindow = tempTouchState.windows[i]; std::vector<PointerProperties> touchingPointers{entry.pointerProperties[pointerIndex]}; for (TouchedWindow& touchedWindow : tempTouchState.windows) { // Ignore drag window for it should just track one pointer. if (mDragState && mDragState->dragWindow == touchedWindow.windowHandle) { continue; } std::bitset<MAX_POINTER_ID + 1> touchingPointers; touchingPointers.set(entry.pointerProperties[pointerIndex].id); touchedWindow.addTouchingPointers(entry.deviceId, touchingPointers); } } Loading Loading @@ -2646,13 +2650,13 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( // Output targets from the touch state. for (const TouchedWindow& touchedWindow : tempTouchState.windows) { std::bitset<MAX_POINTER_ID + 1> touchingPointers = std::vector<PointerProperties> touchingPointers = touchedWindow.getTouchingPointers(entry.deviceId); if (touchingPointers.none()) { if (touchingPointers.empty()) { continue; } addPointerWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.dispatchMode, touchedWindow.targetFlags, touchingPointers, touchedWindow.targetFlags, getPointerIds(touchingPointers), touchedWindow.getDownTimeInTarget(entry.deviceId), targets); } Loading Loading @@ -5481,7 +5485,7 @@ bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp< // Erase old window. ftl::Flags<InputTarget::Flags> oldTargetFlags = touchedWindow->targetFlags; std::bitset<MAX_POINTER_ID + 1> pointerIds = touchedWindow->getTouchingPointers(deviceId); std::vector<PointerProperties> pointers = touchedWindow->getTouchingPointers(deviceId); sp<WindowInfoHandle> fromWindowHandle = touchedWindow->windowHandle; state->removeWindowByToken(fromToken); Loading @@ -5493,17 +5497,17 @@ bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp< newTargetFlags |= InputTarget::Flags::FOREGROUND; } state->addOrUpdateWindow(toWindowHandle, InputTarget::DispatchMode::AS_IS, newTargetFlags, deviceId, pointerIds, downTimeInTarget); deviceId, pointers, downTimeInTarget); // Store the dragging window. if (isDragDrop) { if (pointerIds.count() != 1) { if (pointers.size() != 1) { ALOGW("The drag and drop cannot be started when there is no pointer or more than 1" " pointer on the window."); return false; } // Track the pointer id for drag window and generate the drag state. const size_t id = firstMarkedBit(pointerIds); const size_t id = pointers.begin()->id; mDragState = std::make_unique<DragState>(toWindowHandle, id); } Loading @@ -5520,7 +5524,7 @@ bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp< // Check if the wallpaper window should deliver the corresponding event. transferWallpaperTouch(oldTargetFlags, newTargetFlags, fromWindowHandle, toWindowHandle, *state, deviceId, pointerIds); *state, deviceId, pointers); } } // release lock Loading Loading @@ -5997,8 +6001,10 @@ status_t InputDispatcher::pilferPointersLocked(const sp<IBinder>& token) { "input channel stole pointer stream"); options.deviceId = deviceId; options.displayId = displayId; std::bitset<MAX_POINTER_ID + 1> pointerIds = window.getTouchingPointers(deviceId); std::vector<PointerProperties> pointers = window.getTouchingPointers(deviceId); std::bitset<MAX_POINTER_ID + 1> pointerIds = getPointerIds(pointers); options.pointerIds = pointerIds; std::string canceledWindows; for (const TouchedWindow& w : state.windows) { const std::shared_ptr<InputChannel> channel = Loading Loading @@ -6794,10 +6800,10 @@ void InputDispatcher::setMonitorDispatchingTimeoutForTest(std::chrono::nanosecon void InputDispatcher::slipWallpaperTouch(ftl::Flags<InputTarget::Flags> targetFlags, const sp<WindowInfoHandle>& oldWindowHandle, const sp<WindowInfoHandle>& newWindowHandle, TouchState& state, int32_t deviceId, int32_t pointerId, TouchState& state, int32_t deviceId, const PointerProperties& pointerProperties, std::vector<InputTarget>& targets) const { std::bitset<MAX_POINTER_ID + 1> pointerIds; pointerIds.set(pointerId); std::vector<PointerProperties> pointers{pointerProperties}; const bool oldHasWallpaper = oldWindowHandle->getInfo()->inputConfig.test( gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER); const bool newHasWallpaper = targetFlags.test(InputTarget::Flags::FOREGROUND) && Loading @@ -6814,16 +6820,16 @@ void InputDispatcher::slipWallpaperTouch(ftl::Flags<InputTarget::Flags> targetFl if (oldWallpaper != nullptr) { const TouchedWindow& oldTouchedWindow = state.getTouchedWindow(oldWallpaper); addPointerWindowTargetLocked(oldWallpaper, InputTarget::DispatchMode::SLIPPERY_EXIT, oldTouchedWindow.targetFlags, pointerIds, oldTouchedWindow.targetFlags, getPointerIds(pointers), oldTouchedWindow.getDownTimeInTarget(deviceId), targets); state.removeTouchingPointerFromWindow(deviceId, pointerId, oldWallpaper); state.removeTouchingPointerFromWindow(deviceId, pointerProperties.id, oldWallpaper); } if (newWallpaper != nullptr) { state.addOrUpdateWindow(newWallpaper, InputTarget::DispatchMode::SLIPPERY_ENTER, InputTarget::Flags::WINDOW_IS_OBSCURED | InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED, deviceId, pointerIds); deviceId, pointers); } } Loading @@ -6832,7 +6838,7 @@ void InputDispatcher::transferWallpaperTouch(ftl::Flags<InputTarget::Flags> oldT const sp<WindowInfoHandle> fromWindowHandle, const sp<WindowInfoHandle> toWindowHandle, TouchState& state, int32_t deviceId, std::bitset<MAX_POINTER_ID + 1> pointerIds) { const std::vector<PointerProperties>& pointers) { const bool oldHasWallpaper = oldTargetFlags.test(InputTarget::Flags::FOREGROUND) && fromWindowHandle->getInfo()->inputConfig.test( gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER); Loading Loading @@ -6861,7 +6867,7 @@ void InputDispatcher::transferWallpaperTouch(ftl::Flags<InputTarget::Flags> oldT wallpaperFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED | InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED; state.addOrUpdateWindow(newWallpaper, InputTarget::DispatchMode::AS_IS, wallpaperFlags, deviceId, pointerIds, downTimeInTarget); deviceId, pointers, downTimeInTarget); std::shared_ptr<Connection> wallpaperConnection = getConnectionLocked(newWallpaper->getToken()); if (wallpaperConnection != nullptr) { Loading services/inputflinger/dispatcher/InputDispatcher.h +3 −2 Original line number Diff line number Diff line Loading @@ -690,14 +690,15 @@ private: void slipWallpaperTouch(ftl::Flags<InputTarget::Flags> targetFlags, const sp<android::gui::WindowInfoHandle>& oldWindowHandle, const sp<android::gui::WindowInfoHandle>& newWindowHandle, TouchState& state, int32_t deviceId, int32_t pointerId, TouchState& state, int32_t deviceId, const PointerProperties& pointerProperties, std::vector<InputTarget>& targets) const REQUIRES(mLock); void transferWallpaperTouch(ftl::Flags<InputTarget::Flags> oldTargetFlags, ftl::Flags<InputTarget::Flags> newTargetFlags, const sp<android::gui::WindowInfoHandle> fromWindowHandle, const sp<android::gui::WindowInfoHandle> toWindowHandle, TouchState& state, int32_t deviceId, std::bitset<MAX_POINTER_ID + 1> pointerIds) REQUIRES(mLock); const std::vector<PointerProperties>& pointers) REQUIRES(mLock); sp<android::gui::WindowInfoHandle> findWallpaperWindowBelow( const sp<android::gui::WindowInfoHandle>& windowHandle) const REQUIRES(mLock); Loading services/inputflinger/dispatcher/TouchState.cpp +7 −7 Original line number Diff line number Diff line Loading @@ -73,9 +73,9 @@ void TouchState::clearWindowsWithoutPointers() { void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle, InputTarget::DispatchMode dispatchMode, ftl::Flags<InputTarget::Flags> targetFlags, DeviceId deviceId, std::bitset<MAX_POINTER_ID + 1> touchingPointerIds, const std::vector<PointerProperties>& touchingPointers, std::optional<nsecs_t> firstDownTimeInTarget) { if (touchingPointerIds.none()) { if (touchingPointers.empty()) { LOG(FATAL) << __func__ << "No pointers specified for " << windowHandle->getName(); return; } Loading @@ -91,7 +91,7 @@ void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle, // For cases like hover enter/exit or DISPATCH_AS_OUTSIDE a touch window might not have // downTime set initially. Need to update existing window when a pointer is down for the // window. touchedWindow.addTouchingPointers(deviceId, touchingPointerIds); touchedWindow.addTouchingPointers(deviceId, touchingPointers); if (firstDownTimeInTarget) { touchedWindow.trySetDownTimeInTarget(deviceId, *firstDownTimeInTarget); } Loading @@ -102,7 +102,7 @@ void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle, touchedWindow.windowHandle = windowHandle; touchedWindow.dispatchMode = dispatchMode; touchedWindow.targetFlags = targetFlags; touchedWindow.addTouchingPointers(deviceId, touchingPointerIds); touchedWindow.addTouchingPointers(deviceId, touchingPointers); if (firstDownTimeInTarget) { touchedWindow.trySetDownTimeInTarget(deviceId, *firstDownTimeInTarget); } Loading @@ -110,17 +110,17 @@ void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle, } void TouchState::addHoveringPointerToWindow(const sp<WindowInfoHandle>& windowHandle, DeviceId deviceId, int32_t hoveringPointerId) { DeviceId deviceId, const PointerProperties& pointer) { for (TouchedWindow& touchedWindow : windows) { if (touchedWindow.windowHandle == windowHandle) { touchedWindow.addHoveringPointer(deviceId, hoveringPointerId); touchedWindow.addHoveringPointer(deviceId, pointer); return; } } TouchedWindow touchedWindow; touchedWindow.windowHandle = windowHandle; touchedWindow.addHoveringPointer(deviceId, hoveringPointerId); touchedWindow.addHoveringPointer(deviceId, pointer); windows.push_back(touchedWindow); } Loading Loading
include/input/Input.h +2 −0 Original line number Diff line number Diff line Loading @@ -515,6 +515,8 @@ struct PointerProperties { PointerProperties& operator=(const PointerProperties&) = default; }; std::ostream& operator<<(std::ostream& out, const PointerProperties& properties); // TODO(b/211379801) : Use a strong type from ftl/mixins.h instead using DeviceId = int32_t; Loading
libs/input/Input.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -379,6 +379,11 @@ std::ostream& operator<<(std::ostream& out, const KeyEvent& event) { return out; } std::ostream& operator<<(std::ostream& out, const PointerProperties& properties) { out << "Pointer(id=" << properties.id << ", " << ftl::enum_string(properties.toolType) << ")"; return out; } // --- PointerCoords --- float PointerCoords::getAxisValue(int32_t axis) const { Loading
services/inputflinger/dispatcher/InputDispatcher.cpp +45 −39 Original line number Diff line number Diff line Loading @@ -253,6 +253,14 @@ Result<void> validateInputEvent(const InputEvent& event) { } } std::bitset<MAX_POINTER_ID + 1> getPointerIds(const std::vector<PointerProperties>& pointers) { std::bitset<MAX_POINTER_ID + 1> pointerIds; for (const PointerProperties& pointer : pointers) { pointerIds.set(pointer.id); } return pointerIds; } std::string dumpRegion(const Region& region) { if (region.isEmpty()) { return "<empty>"; Loading Loading @@ -631,15 +639,15 @@ std::vector<TouchedWindow> getHoveringWindowsLocked(const TouchState* oldState, } // We should consider all hovering pointers here. But for now, just use the first one const int32_t pointerId = entry.pointerProperties[0].id; const PointerProperties& pointer = entry.pointerProperties[0]; std::set<sp<WindowInfoHandle>> oldWindows; if (oldState != nullptr) { oldWindows = oldState->getWindowsWithHoveringPointer(entry.deviceId, pointerId); oldWindows = oldState->getWindowsWithHoveringPointer(entry.deviceId, pointer.id); } std::set<sp<WindowInfoHandle>> newWindows = newTouchState.getWindowsWithHoveringPointer(entry.deviceId, pointerId); newTouchState.getWindowsWithHoveringPointer(entry.deviceId, pointer.id); // If the pointer is no longer in the new window set, send HOVER_EXIT. for (const sp<WindowInfoHandle>& oldWindow : oldWindows) { Loading Loading @@ -673,7 +681,7 @@ std::vector<TouchedWindow> getHoveringWindowsLocked(const TouchState* oldState, } touchedWindow.dispatchMode = InputTarget::DispatchMode::AS_IS; } touchedWindow.addHoveringPointer(entry.deviceId, pointerId); touchedWindow.addHoveringPointer(entry.deviceId, pointer); if (canReceiveForegroundTouches(*newWindow->getInfo())) { touchedWindow.targetFlags |= InputTarget::Flags::FOREGROUND; } Loading Loading @@ -2320,7 +2328,7 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( /* Case 1: New splittable pointer going down, or need target for hover or scroll. */ const auto [x, y] = resolveTouchedPosition(entry); const int32_t pointerIndex = MotionEvent::getActionIndex(action); const int32_t pointerId = entry.pointerProperties[pointerIndex].id; const PointerProperties& pointer = entry.pointerProperties[pointerIndex]; // Outside targets should be added upon first dispatched DOWN event. That means, this should // be a pointer that would generate ACTION_DOWN, *and* touch should not already be down. const bool isStylus = isPointerFromStylus(entry, pointerIndex); Loading @@ -2328,7 +2336,7 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( findTouchedWindowAtLocked(displayId, x, y, isStylus); if (isDown) { targets += findOutsideTargetsLocked(displayId, newTouchedWindowHandle, pointerId); targets += findOutsideTargetsLocked(displayId, newTouchedWindowHandle, pointer.id); } // Handle the case where we did not find a window. if (newTouchedWindowHandle == nullptr) { Loading Loading @@ -2386,7 +2394,7 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( if (isHoverAction) { // The "windowHandle" is the target of this hovering pointer. tempTouchState.addHoveringPointerToWindow(windowHandle, entry.deviceId, pointerId); tempTouchState.addHoveringPointerToWindow(windowHandle, entry.deviceId, pointer); } // Set target flags. Loading @@ -2409,12 +2417,10 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( // Update the temporary touch state. if (!isHoverAction) { std::bitset<MAX_POINTER_ID + 1> pointerIds; pointerIds.set(pointerId); const bool isDownOrPointerDown = maskedAction == AMOTION_EVENT_ACTION_DOWN || maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN; tempTouchState.addOrUpdateWindow(windowHandle, InputTarget::DispatchMode::AS_IS, targetFlags, entry.deviceId, pointerIds, targetFlags, entry.deviceId, {pointer}, isDownOrPointerDown ? std::make_optional(entry.eventTime) : std::nullopt); Loading @@ -2437,7 +2443,7 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( } tempTouchState.addOrUpdateWindow(wallpaper, InputTarget::DispatchMode::AS_IS, wallpaperFlags, entry.deviceId, pointerIds, wallpaperFlags, entry.deviceId, {pointer}, entry.eventTime); } } Loading @@ -2448,12 +2454,12 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( // make it pilfering. This will prevent other non-spy windows from getting this pointer, // which is a specific behaviour that we want. for (TouchedWindow& touchedWindow : tempTouchState.windows) { if (touchedWindow.hasTouchingPointer(entry.deviceId, pointerId) && if (touchedWindow.hasTouchingPointer(entry.deviceId, pointer.id) && touchedWindow.hasPilferingPointers(entry.deviceId)) { // This window is already pilfering some pointers, and this new pointer is also // going to it. Therefore, take over this pointer and don't give it to anyone // else. touchedWindow.addPilferingPointer(entry.deviceId, pointerId); touchedWindow.addPilferingPointer(entry.deviceId, pointer.id); } } Loading Loading @@ -2522,8 +2528,8 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( // Make a slippery exit from the old window. std::bitset<MAX_POINTER_ID + 1> pointerIds; const int32_t pointerId = entry.pointerProperties[0].id; pointerIds.set(pointerId); const PointerProperties& pointer = entry.pointerProperties[0]; pointerIds.set(pointer.id); const TouchedWindow& touchedWindow = tempTouchState.getTouchedWindow(oldTouchedWindowHandle); Loading Loading @@ -2553,13 +2559,13 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( tempTouchState.addOrUpdateWindow(newTouchedWindowHandle, InputTarget::DispatchMode::SLIPPERY_ENTER, targetFlags, entry.deviceId, pointerIds, targetFlags, entry.deviceId, {pointer}, entry.eventTime); // Check if the wallpaper window should deliver the corresponding event. slipWallpaperTouch(targetFlags, oldTouchedWindowHandle, newTouchedWindowHandle, tempTouchState, entry.deviceId, pointerId, targets); tempTouchState.removeTouchingPointerFromWindow(entry.deviceId, pointerId, tempTouchState, entry.deviceId, pointer, targets); tempTouchState.removeTouchingPointerFromWindow(entry.deviceId, pointer.id, oldTouchedWindowHandle); } } Loading @@ -2568,14 +2574,12 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( if (!isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN) { // If no split, we suppose all touched windows should receive pointer down. const int32_t pointerIndex = MotionEvent::getActionIndex(action); for (size_t i = 0; i < tempTouchState.windows.size(); i++) { TouchedWindow& touchedWindow = tempTouchState.windows[i]; std::vector<PointerProperties> touchingPointers{entry.pointerProperties[pointerIndex]}; for (TouchedWindow& touchedWindow : tempTouchState.windows) { // Ignore drag window for it should just track one pointer. if (mDragState && mDragState->dragWindow == touchedWindow.windowHandle) { continue; } std::bitset<MAX_POINTER_ID + 1> touchingPointers; touchingPointers.set(entry.pointerProperties[pointerIndex].id); touchedWindow.addTouchingPointers(entry.deviceId, touchingPointers); } } Loading Loading @@ -2646,13 +2650,13 @@ std::vector<InputTarget> InputDispatcher::findTouchedWindowTargetsLocked( // Output targets from the touch state. for (const TouchedWindow& touchedWindow : tempTouchState.windows) { std::bitset<MAX_POINTER_ID + 1> touchingPointers = std::vector<PointerProperties> touchingPointers = touchedWindow.getTouchingPointers(entry.deviceId); if (touchingPointers.none()) { if (touchingPointers.empty()) { continue; } addPointerWindowTargetLocked(touchedWindow.windowHandle, touchedWindow.dispatchMode, touchedWindow.targetFlags, touchingPointers, touchedWindow.targetFlags, getPointerIds(touchingPointers), touchedWindow.getDownTimeInTarget(entry.deviceId), targets); } Loading Loading @@ -5481,7 +5485,7 @@ bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp< // Erase old window. ftl::Flags<InputTarget::Flags> oldTargetFlags = touchedWindow->targetFlags; std::bitset<MAX_POINTER_ID + 1> pointerIds = touchedWindow->getTouchingPointers(deviceId); std::vector<PointerProperties> pointers = touchedWindow->getTouchingPointers(deviceId); sp<WindowInfoHandle> fromWindowHandle = touchedWindow->windowHandle; state->removeWindowByToken(fromToken); Loading @@ -5493,17 +5497,17 @@ bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp< newTargetFlags |= InputTarget::Flags::FOREGROUND; } state->addOrUpdateWindow(toWindowHandle, InputTarget::DispatchMode::AS_IS, newTargetFlags, deviceId, pointerIds, downTimeInTarget); deviceId, pointers, downTimeInTarget); // Store the dragging window. if (isDragDrop) { if (pointerIds.count() != 1) { if (pointers.size() != 1) { ALOGW("The drag and drop cannot be started when there is no pointer or more than 1" " pointer on the window."); return false; } // Track the pointer id for drag window and generate the drag state. const size_t id = firstMarkedBit(pointerIds); const size_t id = pointers.begin()->id; mDragState = std::make_unique<DragState>(toWindowHandle, id); } Loading @@ -5520,7 +5524,7 @@ bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp< // Check if the wallpaper window should deliver the corresponding event. transferWallpaperTouch(oldTargetFlags, newTargetFlags, fromWindowHandle, toWindowHandle, *state, deviceId, pointerIds); *state, deviceId, pointers); } } // release lock Loading Loading @@ -5997,8 +6001,10 @@ status_t InputDispatcher::pilferPointersLocked(const sp<IBinder>& token) { "input channel stole pointer stream"); options.deviceId = deviceId; options.displayId = displayId; std::bitset<MAX_POINTER_ID + 1> pointerIds = window.getTouchingPointers(deviceId); std::vector<PointerProperties> pointers = window.getTouchingPointers(deviceId); std::bitset<MAX_POINTER_ID + 1> pointerIds = getPointerIds(pointers); options.pointerIds = pointerIds; std::string canceledWindows; for (const TouchedWindow& w : state.windows) { const std::shared_ptr<InputChannel> channel = Loading Loading @@ -6794,10 +6800,10 @@ void InputDispatcher::setMonitorDispatchingTimeoutForTest(std::chrono::nanosecon void InputDispatcher::slipWallpaperTouch(ftl::Flags<InputTarget::Flags> targetFlags, const sp<WindowInfoHandle>& oldWindowHandle, const sp<WindowInfoHandle>& newWindowHandle, TouchState& state, int32_t deviceId, int32_t pointerId, TouchState& state, int32_t deviceId, const PointerProperties& pointerProperties, std::vector<InputTarget>& targets) const { std::bitset<MAX_POINTER_ID + 1> pointerIds; pointerIds.set(pointerId); std::vector<PointerProperties> pointers{pointerProperties}; const bool oldHasWallpaper = oldWindowHandle->getInfo()->inputConfig.test( gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER); const bool newHasWallpaper = targetFlags.test(InputTarget::Flags::FOREGROUND) && Loading @@ -6814,16 +6820,16 @@ void InputDispatcher::slipWallpaperTouch(ftl::Flags<InputTarget::Flags> targetFl if (oldWallpaper != nullptr) { const TouchedWindow& oldTouchedWindow = state.getTouchedWindow(oldWallpaper); addPointerWindowTargetLocked(oldWallpaper, InputTarget::DispatchMode::SLIPPERY_EXIT, oldTouchedWindow.targetFlags, pointerIds, oldTouchedWindow.targetFlags, getPointerIds(pointers), oldTouchedWindow.getDownTimeInTarget(deviceId), targets); state.removeTouchingPointerFromWindow(deviceId, pointerId, oldWallpaper); state.removeTouchingPointerFromWindow(deviceId, pointerProperties.id, oldWallpaper); } if (newWallpaper != nullptr) { state.addOrUpdateWindow(newWallpaper, InputTarget::DispatchMode::SLIPPERY_ENTER, InputTarget::Flags::WINDOW_IS_OBSCURED | InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED, deviceId, pointerIds); deviceId, pointers); } } Loading @@ -6832,7 +6838,7 @@ void InputDispatcher::transferWallpaperTouch(ftl::Flags<InputTarget::Flags> oldT const sp<WindowInfoHandle> fromWindowHandle, const sp<WindowInfoHandle> toWindowHandle, TouchState& state, int32_t deviceId, std::bitset<MAX_POINTER_ID + 1> pointerIds) { const std::vector<PointerProperties>& pointers) { const bool oldHasWallpaper = oldTargetFlags.test(InputTarget::Flags::FOREGROUND) && fromWindowHandle->getInfo()->inputConfig.test( gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER); Loading Loading @@ -6861,7 +6867,7 @@ void InputDispatcher::transferWallpaperTouch(ftl::Flags<InputTarget::Flags> oldT wallpaperFlags |= InputTarget::Flags::WINDOW_IS_OBSCURED | InputTarget::Flags::WINDOW_IS_PARTIALLY_OBSCURED; state.addOrUpdateWindow(newWallpaper, InputTarget::DispatchMode::AS_IS, wallpaperFlags, deviceId, pointerIds, downTimeInTarget); deviceId, pointers, downTimeInTarget); std::shared_ptr<Connection> wallpaperConnection = getConnectionLocked(newWallpaper->getToken()); if (wallpaperConnection != nullptr) { Loading
services/inputflinger/dispatcher/InputDispatcher.h +3 −2 Original line number Diff line number Diff line Loading @@ -690,14 +690,15 @@ private: void slipWallpaperTouch(ftl::Flags<InputTarget::Flags> targetFlags, const sp<android::gui::WindowInfoHandle>& oldWindowHandle, const sp<android::gui::WindowInfoHandle>& newWindowHandle, TouchState& state, int32_t deviceId, int32_t pointerId, TouchState& state, int32_t deviceId, const PointerProperties& pointerProperties, std::vector<InputTarget>& targets) const REQUIRES(mLock); void transferWallpaperTouch(ftl::Flags<InputTarget::Flags> oldTargetFlags, ftl::Flags<InputTarget::Flags> newTargetFlags, const sp<android::gui::WindowInfoHandle> fromWindowHandle, const sp<android::gui::WindowInfoHandle> toWindowHandle, TouchState& state, int32_t deviceId, std::bitset<MAX_POINTER_ID + 1> pointerIds) REQUIRES(mLock); const std::vector<PointerProperties>& pointers) REQUIRES(mLock); sp<android::gui::WindowInfoHandle> findWallpaperWindowBelow( const sp<android::gui::WindowInfoHandle>& windowHandle) const REQUIRES(mLock); Loading
services/inputflinger/dispatcher/TouchState.cpp +7 −7 Original line number Diff line number Diff line Loading @@ -73,9 +73,9 @@ void TouchState::clearWindowsWithoutPointers() { void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle, InputTarget::DispatchMode dispatchMode, ftl::Flags<InputTarget::Flags> targetFlags, DeviceId deviceId, std::bitset<MAX_POINTER_ID + 1> touchingPointerIds, const std::vector<PointerProperties>& touchingPointers, std::optional<nsecs_t> firstDownTimeInTarget) { if (touchingPointerIds.none()) { if (touchingPointers.empty()) { LOG(FATAL) << __func__ << "No pointers specified for " << windowHandle->getName(); return; } Loading @@ -91,7 +91,7 @@ void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle, // For cases like hover enter/exit or DISPATCH_AS_OUTSIDE a touch window might not have // downTime set initially. Need to update existing window when a pointer is down for the // window. touchedWindow.addTouchingPointers(deviceId, touchingPointerIds); touchedWindow.addTouchingPointers(deviceId, touchingPointers); if (firstDownTimeInTarget) { touchedWindow.trySetDownTimeInTarget(deviceId, *firstDownTimeInTarget); } Loading @@ -102,7 +102,7 @@ void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle, touchedWindow.windowHandle = windowHandle; touchedWindow.dispatchMode = dispatchMode; touchedWindow.targetFlags = targetFlags; touchedWindow.addTouchingPointers(deviceId, touchingPointerIds); touchedWindow.addTouchingPointers(deviceId, touchingPointers); if (firstDownTimeInTarget) { touchedWindow.trySetDownTimeInTarget(deviceId, *firstDownTimeInTarget); } Loading @@ -110,17 +110,17 @@ void TouchState::addOrUpdateWindow(const sp<WindowInfoHandle>& windowHandle, } void TouchState::addHoveringPointerToWindow(const sp<WindowInfoHandle>& windowHandle, DeviceId deviceId, int32_t hoveringPointerId) { DeviceId deviceId, const PointerProperties& pointer) { for (TouchedWindow& touchedWindow : windows) { if (touchedWindow.windowHandle == windowHandle) { touchedWindow.addHoveringPointer(deviceId, hoveringPointerId); touchedWindow.addHoveringPointer(deviceId, pointer); return; } } TouchedWindow touchedWindow; touchedWindow.windowHandle = windowHandle; touchedWindow.addHoveringPointer(deviceId, hoveringPointerId); touchedWindow.addHoveringPointer(deviceId, pointer); windows.push_back(touchedWindow); } Loading