diff options
author | 2025-03-11 14:14:47 +0900 | |
---|---|---|
committer | 2025-03-12 11:50:47 +0900 | |
commit | c76ef2ceac32b3cf7436d72670953a186fc9debf (patch) | |
tree | 6680dc92325e4c9fa384769e4a6c1b0d7b066d76 | |
parent | 12bd0c83e0d837baacf5c0bb7d7060e1a63de103 (diff) |
Correctly dispose of input channels.
Previously, DragResizeInputListener did not dispose of input channels
when they were registered on a background thread and then
DragResizeInputListener was closed before the channels were populated on
the main thread. This change adds the necessary cleanup.
Flag: com.android.window.flags.enable_drag_resize_set_up_in_bg_thread
Bug: 401999837
Test: DragResizeInputListenerTest
Change-Id: I0c6f1e5e9de5df9ea5918fb9926e70e444842f77
2 files changed, 27 insertions, 7 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java index 7a4a834e9dc2..40737120f364 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java @@ -23,12 +23,12 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERL import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_CONSUMER; +import static com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE; import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_BOTTOM; import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_LEFT; import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_RIGHT; import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_TOP; -import static com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger; import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.isEdgeResizePermitted; import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.isEventFromTouchscreen; @@ -127,7 +127,9 @@ class DragResizeInputListener implements AutoCloseable { Supplier<SurfaceControl.Builder> surfaceControlBuilderSupplier, Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier, DisplayController displayController, - DesktopModeEventLogger desktopModeEventLogger) { + DesktopModeEventLogger desktopModeEventLogger, + InputChannel inputChannel, + InputChannel sinkInputChannel) { mContext = context; mWindowSession = windowSession; mBgExecutor = bgExecutor; @@ -154,9 +156,13 @@ class DragResizeInputListener implements AutoCloseable { final InputSetUpResult result = setUpInputChannels(mDisplayId, mWindowSession, mDecorationSurface, mClientToken, mSinkClientToken, mSurfaceControlBuilderSupplier, - mSurfaceControlTransactionSupplier); + mSurfaceControlTransactionSupplier, inputChannel, sinkInputChannel); mainExecutor.execute(() -> { if (mClosed) { + result.mInputChannel.dispose(); + result.mSinkInputChannel.dispose(); + mSurfaceControlTransactionSupplier.get().remove( + result.mInputSinkSurface).apply(); return; } mInputSinkSurface = result.mInputSinkSurface; @@ -208,7 +214,7 @@ class DragResizeInputListener implements AutoCloseable { new DefaultTaskResizeInputEventReceiverFactory(), taskInfo, handler, choreographer, displayId, decorationSurface, callback, surfaceControlBuilderSupplier, surfaceControlTransactionSupplier, - displayController, desktopModeEventLogger); + displayController, desktopModeEventLogger, new InputChannel(), new InputChannel()); } DragResizeInputListener( @@ -251,11 +257,11 @@ class DragResizeInputListener implements AutoCloseable { @NonNull IBinder clientToken, @NonNull IBinder sinkClientToken, @NonNull Supplier<SurfaceControl.Builder> surfaceControlBuilderSupplier, - @NonNull Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier) { + @NonNull Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier, + @NonNull InputChannel inputChannel, + @NonNull InputChannel sinkInputChannel) { Trace.beginSection("DragResizeInputListener#setUpInputChannels"); final InputTransferToken inputTransferToken = new InputTransferToken(); - final InputChannel inputChannel = new InputChannel(); - final InputChannel sinkInputChannel = new InputChannel(); try { windowSession.grantInputChannel( displayId, diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeInputListenerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeInputListenerTest.kt index 7341e098add5..e23d0ad55b04 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeInputListenerTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeInputListenerTest.kt @@ -63,6 +63,8 @@ class DragResizeInputListenerTest : ShellTestCase() { private val testBgExecutor = TestShellExecutor() private val mockWindowSession = mock<IWindowSession>() private val mockInputEventReceiver = mock<TaskResizeInputEventReceiver>() + private val inputChannel = mock<InputChannel>() + private val sinkInputChannel = mock<InputChannel>() @Test fun testGrantInputChannelOffMainThread() { @@ -143,6 +145,16 @@ class DragResizeInputListenerTest : ShellTestCase() { verify(mockWindowSession).remove(inputListener.mSinkClientToken) } + @Test + fun testClose_afterBgSetup_disposesOfInputChannels() { + val inputListener = create() + testBgExecutor.flushAll() + inputListener.close() + testMainExecutor.flushAll() + verify(inputChannel).dispose() + verify(sinkInputChannel).dispose() + } + private fun verifyNoInputChannelGrantRequests() { verify(mockWindowSession, never()) .grantInputChannel( @@ -178,6 +190,8 @@ class DragResizeInputListenerTest : ShellTestCase() { { StubTransaction() }, mock<DisplayController>(), mock<DesktopModeEventLogger>(), + inputChannel, + sinkInputChannel, ) private class TestInitializationCallback : Runnable { |