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
This commit is contained in:
Lucas Silva
2023-04-10 15:38:45 -04:00
parent 1be684590b
commit df23b34839
2 changed files with 33 additions and 1 deletions

View File

@@ -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<Callback> iter = mCallbacks.iterator();
while (iter.hasNext()) {
final Callback callback = iter.next();
callback.onRemoved();
iter.remove();
}
}
@Override

View File

@@ -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);