Skip to content

Commit 24a00a9

Browse files
author
Arpit Singh
committed
[15/n Dispatcher refactor] Remove TouchState from setInputWindows
In this CL we remove direct access to touchState internals from setInputWindows method. Bug: 367661487 Bug: 245989146 Test: atest inputflinger_tests Flag: EXEMPT refactor Change-Id: Ibdd09f429e2f6d7c365a2b9bd295df21c193910a
1 parent b9e6e59 commit 24a00a9

2 files changed

Lines changed: 121 additions & 67 deletions

File tree

services/inputflinger/dispatcher/InputDispatcher.cpp

Lines changed: 99 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -5453,72 +5453,38 @@ void InputDispatcher::setInputWindowsLocked(
54535453
onFocusChangedLocked(*changes, traceContext.getTracker(), removedFocusedWindowHandle);
54545454
}
54555455

5456-
if (const auto& it = mTouchStates.mTouchStatesByDisplay.find(displayId);
5457-
it != mTouchStates.mTouchStatesByDisplay.end()) {
5458-
TouchState& state = it->second;
5459-
for (size_t i = 0; i < state.windows.size();) {
5460-
TouchedWindow& touchedWindow = state.windows[i];
5461-
if (mWindowInfos.isWindowPresent(touchedWindow.windowHandle)) {
5462-
i++;
5463-
continue;
5464-
}
5465-
LOG(INFO) << "Touched window was removed: " << touchedWindow.windowHandle->getName()
5466-
<< " in display %" << displayId;
5467-
CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
5468-
"touched window was removed", traceContext.getTracker());
5469-
synthesizeCancelationEventsForWindowLocked(touchedWindow.windowHandle, options);
5470-
// Since we are about to drop the touch, cancel the events for the wallpaper as
5471-
// well.
5472-
if (touchedWindow.targetFlags.test(InputTarget::Flags::FOREGROUND) &&
5473-
touchedWindow.windowHandle->getInfo()->inputConfig.test(
5474-
gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
5475-
for (const DeviceId deviceId : touchedWindow.getTouchingDeviceIds()) {
5476-
if (const auto& ww = state.getWallpaperWindow(deviceId); ww != nullptr) {
5477-
options.deviceId = deviceId;
5478-
synthesizeCancelationEventsForWindowLocked(ww, options);
5479-
}
5480-
}
5481-
}
5482-
state.windows.erase(state.windows.begin() + i);
5483-
}
5484-
5485-
// If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We
5486-
// could just clear the state here.
5487-
if (mDragState && mDragState->dragWindow->getInfo()->displayId == displayId &&
5488-
std::find(windowHandles.begin(), windowHandles.end(), mDragState->dragWindow) ==
5489-
windowHandles.end()) {
5490-
ALOGI("Drag window went away: %s", mDragState->dragWindow->getName().c_str());
5491-
sendDropWindowCommandLocked(nullptr, 0, 0);
5492-
mDragState.reset();
5456+
CancelationOptions pointerCancellationOptions(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
5457+
"touched window was removed",
5458+
traceContext.getTracker());
5459+
CancelationOptions hoverCancellationOptions(CancelationOptions::Mode::CANCEL_HOVER_EVENTS,
5460+
"WindowInfo changed", traceContext.getTracker());
5461+
const std::list<DispatcherTouchState::CancellationArgs> cancellations =
5462+
mTouchStates.updateFromWindowInfo(displayId, mWindowInfos);
5463+
for (const auto& cancellationArgs : cancellations) {
5464+
switch (cancellationArgs.mode) {
5465+
case CancelationOptions::Mode::CANCEL_POINTER_EVENTS:
5466+
pointerCancellationOptions.deviceId = cancellationArgs.deviceId;
5467+
synthesizeCancelationEventsForWindowLocked(cancellationArgs.windowHandle,
5468+
pointerCancellationOptions);
5469+
break;
5470+
case CancelationOptions::Mode::CANCEL_HOVER_EVENTS:
5471+
hoverCancellationOptions.deviceId = cancellationArgs.deviceId;
5472+
synthesizeCancelationEventsForWindowLocked(cancellationArgs.windowHandle,
5473+
hoverCancellationOptions);
5474+
break;
5475+
default:
5476+
LOG_ALWAYS_FATAL("Unexpected cancellation Mode");
54935477
}
54945478
}
54955479

5496-
// Check if the hovering should stop because the window is no longer eligible to receive it
5497-
// (for example, if the touchable region changed)
5498-
if (const auto& it = mTouchStates.mTouchStatesByDisplay.find(displayId);
5499-
it != mTouchStates.mTouchStatesByDisplay.end()) {
5500-
TouchState& state = it->second;
5501-
for (TouchedWindow& touchedWindow : state.windows) {
5502-
std::vector<DeviceId> erasedDevices = touchedWindow.eraseHoveringPointersIf(
5503-
[this, displayId, &touchedWindow](const PointerProperties& properties, float x,
5504-
float y) REQUIRES(mLock) {
5505-
const bool isStylus = properties.toolType == ToolType::STYLUS;
5506-
const ui::Transform displayTransform =
5507-
mWindowInfos.getDisplayTransform(displayId);
5508-
const bool stillAcceptsTouch =
5509-
windowAcceptsTouchAt(*touchedWindow.windowHandle->getInfo(),
5510-
displayId, x, y, isStylus, displayTransform);
5511-
return !stillAcceptsTouch;
5512-
});
5513-
5514-
for (DeviceId deviceId : erasedDevices) {
5515-
CancelationOptions options(CancelationOptions::Mode::CANCEL_HOVER_EVENTS,
5516-
"WindowInfo changed",
5517-
traceContext.getTracker());
5518-
options.deviceId = deviceId;
5519-
synthesizeCancelationEventsForWindowLocked(touchedWindow.windowHandle, options);
5520-
}
5521-
}
5480+
// If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. We
5481+
// could just clear the state here.
5482+
if (mDragState && mDragState->dragWindow->getInfo()->displayId == displayId &&
5483+
std::find(windowHandles.begin(), windowHandles.end(), mDragState->dragWindow) ==
5484+
windowHandles.end()) {
5485+
ALOGI("Drag window went away: %s", mDragState->dragWindow->getName().c_str());
5486+
sendDropWindowCommandLocked(nullptr, 0, 0);
5487+
mDragState.reset();
55225488
}
55235489

55245490
// Release information for windows that are no longer present.
@@ -5535,6 +5501,76 @@ void InputDispatcher::setInputWindowsLocked(
55355501
}
55365502
}
55375503

5504+
std::list<InputDispatcher::DispatcherTouchState::CancellationArgs>
5505+
InputDispatcher::DispatcherTouchState::updateFromWindowInfo(
5506+
ui::LogicalDisplayId displayId, const DispatcherWindowInfo& windowInfos) {
5507+
std::list<CancellationArgs> cancellations;
5508+
if (const auto& it = mTouchStatesByDisplay.find(displayId); it != mTouchStatesByDisplay.end()) {
5509+
TouchState& state = it->second;
5510+
cancellations = eraseRemovedWindowsFromWindowInfo(state, displayId, windowInfos);
5511+
cancellations.splice(cancellations.end(),
5512+
updateHoveringStateFromWindowInfo(state, displayId, windowInfos));
5513+
}
5514+
return cancellations;
5515+
}
5516+
5517+
std::list<InputDispatcher::DispatcherTouchState::CancellationArgs>
5518+
InputDispatcher::DispatcherTouchState::eraseRemovedWindowsFromWindowInfo(
5519+
TouchState& state, ui::LogicalDisplayId displayId,
5520+
const DispatcherWindowInfo& windowInfos) {
5521+
std::list<CancellationArgs> cancellations;
5522+
for (auto it = state.windows.begin(); it != state.windows.end();) {
5523+
TouchedWindow& touchedWindow = *it;
5524+
if (windowInfos.isWindowPresent(touchedWindow.windowHandle)) {
5525+
it++;
5526+
continue;
5527+
}
5528+
LOG(INFO) << "Touched window was removed: " << touchedWindow.windowHandle->getName()
5529+
<< " in display %" << displayId;
5530+
cancellations.emplace_back(touchedWindow.windowHandle,
5531+
CancelationOptions::Mode::CANCEL_POINTER_EVENTS, std::nullopt);
5532+
// Since we are about to drop the touch, cancel the events for the wallpaper as well.
5533+
if (touchedWindow.targetFlags.test(InputTarget::Flags::FOREGROUND) &&
5534+
touchedWindow.windowHandle->getInfo()->inputConfig.test(
5535+
gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER)) {
5536+
for (const DeviceId deviceId : touchedWindow.getTouchingDeviceIds()) {
5537+
if (const auto& ww = state.getWallpaperWindow(deviceId); ww != nullptr) {
5538+
cancellations.emplace_back(ww, CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
5539+
deviceId);
5540+
}
5541+
}
5542+
}
5543+
it = state.windows.erase(it);
5544+
}
5545+
return cancellations;
5546+
}
5547+
5548+
std::list<InputDispatcher::DispatcherTouchState::CancellationArgs>
5549+
InputDispatcher::DispatcherTouchState::updateHoveringStateFromWindowInfo(
5550+
TouchState& state, ui::LogicalDisplayId displayId,
5551+
const DispatcherWindowInfo& windowInfos) {
5552+
std::list<CancellationArgs> cancellations;
5553+
// Check if the hovering should stop because the window is no longer eligible to receive it
5554+
// (for example, if the touchable region changed)
5555+
ui::Transform displayTransform = windowInfos.getDisplayTransform(displayId);
5556+
for (TouchedWindow& touchedWindow : state.windows) {
5557+
std::vector<DeviceId> erasedDevices = touchedWindow.eraseHoveringPointersIf(
5558+
[&](const PointerProperties& properties, float x, float y) {
5559+
const bool isStylus = properties.toolType == ToolType::STYLUS;
5560+
const bool stillAcceptsTouch =
5561+
windowAcceptsTouchAt(*touchedWindow.windowHandle->getInfo(), displayId,
5562+
x, y, isStylus, displayTransform);
5563+
return !stillAcceptsTouch;
5564+
});
5565+
5566+
for (DeviceId deviceId : erasedDevices) {
5567+
cancellations.emplace_back(touchedWindow.windowHandle,
5568+
CancelationOptions::Mode::CANCEL_HOVER_EVENTS, deviceId);
5569+
}
5570+
}
5571+
return cancellations;
5572+
}
5573+
55385574
void InputDispatcher::setFocusedApplication(
55395575
ui::LogicalDisplayId displayId,
55405576
const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {

services/inputflinger/dispatcher/InputDispatcher.h

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,12 @@ class InputDispatcher : public android::InputDispatcherInterface {
352352

353353
class DispatcherTouchState {
354354
public:
355+
struct CancellationArgs {
356+
const sp<gui::WindowInfoHandle> windowHandle;
357+
CancelationOptions::Mode mode;
358+
std::optional<DeviceId> deviceId;
359+
};
360+
355361
static void addPointerWindowTarget(const sp<android::gui::WindowInfoHandle>& windowHandle,
356362
InputTarget::DispatchMode dispatchMode,
357363
ftl::Flags<InputTarget::Flags> targetFlags,
@@ -380,18 +386,30 @@ class InputDispatcher : public android::InputDispatcherInterface {
380386

381387
std::string dump() const;
382388

389+
// Updates the touchState for display from WindowInfo,
390+
// return vector of CancellationArgs for every cancelled touch
391+
std::list<CancellationArgs> updateFromWindowInfo(ui::LogicalDisplayId displayId,
392+
const DispatcherWindowInfo& windowInfos);
393+
383394
void removeAllPointersForDevice(DeviceId deviceId);
384395

385396
void clear();
386397

387398
std::unordered_map<ui::LogicalDisplayId, TouchState> mTouchStatesByDisplay;
388399

389400
private:
401+
static std::list<CancellationArgs> eraseRemovedWindowsFromWindowInfo(
402+
TouchState& state, ui::LogicalDisplayId displayId,
403+
const DispatcherWindowInfo& windowInfos);
404+
405+
static std::list<CancellationArgs> updateHoveringStateFromWindowInfo(
406+
TouchState& state, ui::LogicalDisplayId displayId,
407+
const DispatcherWindowInfo& windowInfos);
408+
390409
static std::vector<InputTarget> findOutsideTargets(
391-
ui::LogicalDisplayId displayId,
392-
const sp<android::gui::WindowInfoHandle>& touchedWindow, int32_t pointerId,
393-
const ConnectionManager& connections, const DispatcherWindowInfo& windowInfos,
394-
std::function<void()> dump);
410+
ui::LogicalDisplayId displayId, const sp<gui::WindowInfoHandle>& touchedWindow,
411+
int32_t pointerId, const ConnectionManager& connections,
412+
const DispatcherWindowInfo& windowInfos, std::function<void()> dump);
395413

396414
/**
397415
* Slip the wallpaper touch if necessary.

0 commit comments

Comments
 (0)