Ensure TouchSessions are always removed.

Gesture events normally drive TouchSession cleanup with up/cancel
events triggering the removal of any active sessions. However, it
is possible for the touch monitor to be stopped before this point.
This changelist ensure that the sessions are properly cleaned up
when monitoring stops before the expected touch events.

Test: atest DreamOverlayTouchMonitorTest#testOnRemovedCallbackOnStopMonitor
Fixes: 245441667
Change-Id: Id6817e726058b0a2738cbb7c163d2efa5eb3875e
This commit is contained in:
Bryce Lee
2023-01-19 16:15:00 -08:00
parent 032f978c38
commit 0a3f4b80e5
2 changed files with 35 additions and 0 deletions

View File

@@ -226,6 +226,15 @@ public class DreamOverlayTouchMonitor {
return;
}
// When we stop monitoring touches, we must ensure that all active touch sessions and
// descendants informed of the removal so any cleanup for active tracking can proceed.
mExecutor.execute(() -> mActiveTouchSessions.forEach(touchSession -> {
while (touchSession != null) {
touchSession.onRemoved();
touchSession = touchSession.getPredecessor();
}
}));
mCurrentInputSession.dispose();
mCurrentInputSession = null;
}

View File

@@ -424,6 +424,32 @@ public class DreamOverlayTouchMonitorTest extends SysuiTestCase {
verify(gestureListener2).onDown(eq(followupEvent));
}
@Test
public void testOnRemovedCallbackOnStopMonitoring() {
final DreamTouchHandler touchHandler = Mockito.mock(DreamTouchHandler.class);
final DreamTouchHandler.TouchSession.Callback callback =
Mockito.mock(DreamTouchHandler.TouchSession.Callback.class);
final Environment environment = new Environment(Stream.of(touchHandler)
.collect(Collectors.toCollection(HashSet::new)));
final InputEvent initialEvent = Mockito.mock(InputEvent.class);
environment.publishInputEvent(initialEvent);
final DreamTouchHandler.TouchSession session = captureSession(touchHandler);
session.registerCallback(callback);
environment.executeAll();
environment.updateLifecycle(observerOwnerPair -> {
observerOwnerPair.first.onPause(observerOwnerPair.second);
});
environment.executeAll();
verify(callback).onRemoved();
}
public GestureDetector.OnGestureListener registerGestureListener(DreamTouchHandler handler) {
final GestureDetector.OnGestureListener gestureListener = Mockito.mock(
GestureDetector.OnGestureListener.class);