From df23b34839123e62d9eb9da8a42f2cc41a925c71 Mon Sep 17 00:00:00 2001 From: Lucas Silva Date: Mon, 10 Apr 2023 15:38:45 -0400 Subject: Remove event listeners when touch session ends Currently, the event listeners may still run after the touch session has ended, which is causing NullPointerException to be thrown Was able to reproduce this by forcing dreams to switch while swiping up on the screen to bring up the bouncer. Bug: 275659024 Test: atest DreamOverlayTouchMonitorTest Change-Id: I2e47d16231e0f7297e4e7781325a6de9f8e8c948 --- .../dreams/touch/DreamOverlayTouchMonitor.java | 10 ++++++++- .../dreams/touch/DreamOverlayTouchMonitorTest.java | 24 ++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitor.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitor.java index 7f44463f1191..aca621bd9e55 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitor.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitor.java @@ -41,6 +41,7 @@ import com.google.common.util.concurrent.ListenableFuture; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.Set; import java.util.concurrent.Executor; import java.util.function.Consumer; @@ -195,7 +196,14 @@ public class DreamOverlayTouchMonitor { * Called by the monitor when this session is removed. */ private void onRemoved() { - mCallbacks.forEach(callback -> callback.onRemoved()); + mEventListeners.clear(); + mGestureListeners.clear(); + final Iterator iter = mCallbacks.iterator(); + while (iter.hasNext()) { + final Callback callback = iter.next(); + callback.onRemoved(); + iter.remove(); + } } @Override diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitorTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitorTest.java index 08427dab978b..21397d97b578 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitorTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/DreamOverlayTouchMonitorTest.java @@ -268,6 +268,30 @@ public class DreamOverlayTouchMonitorTest extends SysuiTestCase { verify(eventListener).onInputEvent(eq(event)); } + @Test + public void testInputEventPropagationAfterRemoval() { + final DreamTouchHandler touchHandler = Mockito.mock(DreamTouchHandler.class); + + final Environment environment = new Environment(Stream.of(touchHandler) + .collect(Collectors.toCollection(HashSet::new))); + + final InputEvent initialEvent = Mockito.mock(InputEvent.class); + environment.publishInputEvent(initialEvent); + + // Ensure session started + final DreamTouchHandler.TouchSession session = captureSession(touchHandler); + final InputChannelCompat.InputEventListener eventListener = + registerInputEventListener(session); + + session.pop(); + environment.executeAll(); + + final InputEvent event = Mockito.mock(InputEvent.class); + environment.publishInputEvent(event); + + verify(eventListener, never()).onInputEvent(eq(event)); + } + @Test public void testInputGesturePropagation() { final DreamTouchHandler touchHandler = Mockito.mock(DreamTouchHandler.class); -- cgit v1.2.3-59-g8ed1b