Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0a3f4b80 authored by Bryce Lee's avatar Bryce Lee
Browse files

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
parent 032f978c
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -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;
    }
+26 −0
Original line number Diff line number Diff line
@@ -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);