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

Commit a5d0d2c7 authored by Bryce Lee's avatar Bryce Lee
Browse files

Clear active sessions when stopping touch monitoring.

It is currently possible to stop TouchMonitor even if there are active
touch sessions. This is needed when there is a lifecycle change and
touch handling must be disabled. While the sessions are currently
notified and cleaned up, TouchMonitor fails to clear the active session
references. Therefore, future touch events are sent to essentially
empty shells of past sessions.

This changelist addresses this issue by clearing the list of active
sessions after each has been notified.

Fixes: 348656793
Test: atest TouchMonitorTest#testSessionResetOnLifecycle
Flag: EXEMPT bugfix
Change-Id: If8abd912abdd177932c94fdd84f5e27ac0a53bf3
parent d9227e90
Loading
Loading
Loading
Loading
+9 −6
Original line number Diff line number Diff line
@@ -323,12 +323,15 @@ public class TouchMonitor {

        // 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.
        mMainExecutor.execute(() -> mActiveTouchSessions.forEach(touchSession -> {
        mMainExecutor.execute(() -> {
            mActiveTouchSessions.forEach(touchSession -> {
                while (touchSession != null) {
                    touchSession.onRemoved();
                    touchSession = touchSession.getPredecessor();
                }
        }));
            });
            mActiveTouchSessions.clear();
        });

        mCurrentInputSession.dispose();
        mCurrentInputSession = null;
+34 −1
Original line number Diff line number Diff line
@@ -211,6 +211,40 @@ public class TouchMonitorTest extends SysuiTestCase {
        }
    }

    @Test
    public void testSessionResetOnLifecycle() {
        final TouchHandler touchHandler = createTouchHandler();
        final Rect touchArea = new Rect(4, 4, 8 , 8);

        doAnswer(invocation -> {
            final Region region = (Region) invocation.getArguments()[1];
            region.set(touchArea);
            return null;
        }).when(touchHandler).getTouchInitiationRegion(any(), any(), any());

        final Environment environment = new Environment(Stream.of(touchHandler)
                .collect(Collectors.toCollection(HashSet::new)), mKosmos);

        // Ensure touch outside specified region is not delivered.
        final MotionEvent initialEvent = Mockito.mock(MotionEvent.class);

        // Make sure touch inside region causes session start.
        when(initialEvent.getX()).thenReturn(5.0f);
        when(initialEvent.getY()).thenReturn(5.0f);
        environment.publishInputEvent(initialEvent);
        verify(touchHandler).onSessionStart(any());

        Mockito.clearInvocations(touchHandler);

        // Reset lifecycle, forcing monitoring to be reset
        environment.updateLifecycle(Lifecycle.State.STARTED);
        environment.updateLifecycle(Lifecycle.State.RESUMED);
        environment.executeAll();

        environment.publishInputEvent(initialEvent);
        verify(touchHandler).onSessionStart(any());
    }

    @Test
    @EnableFlags(Flags.FLAG_AMBIENT_TOUCH_MONITOR_LISTEN_TO_DISPLAY_CHANGES)
    public void testConfigurationListenerUpdatesBounds() {
@@ -332,7 +366,6 @@ public class TouchMonitorTest extends SysuiTestCase {
        }
    }


    @Test
    public void testNoActiveSessionWhenHandlerDisabled() {
        final TouchHandler touchHandler = Mockito.mock(TouchHandler.class);