From 03512570f7f936dd4937729cd1eb98b47578a366 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Wed, 25 May 2022 21:45:04 +0800 Subject: [PATCH] Fix death recipient leakage of WindowTokenClient When WindowContext#finalize is called on client side, it will call WindowTokenClient#detachFromWindowContainerIfNeeded to notify system server to remove the listener. But unregisterWindowContainerListener didn't unlink its death recipient, that causes the objects are never actual released both on client and server side. Bug: 233784911 Test: atest WindowContextListenerControllerTests# \ testRegisterWindowContextListener Change-Id: I0e203d07e485c4577f669f512123757fd2dea058 --- .../android/server/wm/WindowContextListenerController.java | 3 +++ .../server/wm/WindowContextListenerControllerTests.java | 7 ++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/wm/WindowContextListenerController.java b/services/core/java/com/android/server/wm/WindowContextListenerController.java index 912fdb2e32af9..43dc9c8ff5d60 100644 --- a/services/core/java/com/android/server/wm/WindowContextListenerController.java +++ b/services/core/java/com/android/server/wm/WindowContextListenerController.java @@ -116,6 +116,9 @@ class WindowContextListenerController { return; } listener.unregister(); + if (listener.mDeathRecipient != null) { + listener.mDeathRecipient.unlinkToDeath(); + } } void dispatchPendingConfigurationIfNeeded(int displayId) { diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java index 646647fcc4ca9..1685673327951 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowContextListenerControllerTests.java @@ -24,6 +24,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG; import static android.window.WindowProvider.KEY_IS_WINDOW_PROVIDER_SERVICE; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.google.common.truth.Truth.assertThat; @@ -86,7 +87,7 @@ public class WindowContextListenerControllerTests extends WindowTestsBase { assertEquals(1, mController.mListeners.size()); - final IBinder clientToken = new Binder(); + final IBinder clientToken = mock(IBinder.class); mController.registerWindowContainerListener(clientToken, mContainer, -1, TYPE_APPLICATION_OVERLAY, null /* options */); @@ -103,6 +104,10 @@ public class WindowContextListenerControllerTests extends WindowTestsBase { WindowContextListenerController.WindowContextListenerImpl listener = mController.mListeners.get(mClientToken); assertEquals(container, listener.getWindowContainer()); + + mController.unregisterWindowContainerListener(clientToken); + assertFalse(mController.mListeners.containsKey(clientToken)); + verify(clientToken).unlinkToDeath(any(), anyInt()); } @UseTestDisplay