WindowProcessController: Fix potential memory leak

Fixes an issue where the WindowProcessController may leak after process
death due to still having listeners registered.

Now unregisters all listeners when the process record gets removed.

Fixes: 273149525
Test: atest WindowProcessControllerTests WindowProcessControllerMapTests
Change-Id: I44323f280ed7aa641ab41c4e62a354a4525a4268
This commit is contained in:
Adrian Roos
2023-03-14 11:03:47 +00:00
parent 2fbb619b53
commit 884e68eefb
4 changed files with 32 additions and 1 deletions

View File

@@ -1340,6 +1340,13 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
unregisterDisplayAreaConfigurationListener();
}
/**
* Destroys the WindwoProcessController, after the process has been removed.
*/
void destroy() {
unregisterConfigurationListeners();
}
/**
* Check if activity configuration override for the activity process needs an update and perform
* if needed. By default we try to override the process configuration to match the top activity

View File

@@ -19,8 +19,8 @@ package com.android.server.wm;
import android.util.ArraySet;
import android.util.SparseArray;
import java.util.Map;
import java.util.HashMap;
import java.util.Map;
final class WindowProcessControllerMap {
@@ -67,6 +67,7 @@ final class WindowProcessControllerMap {
mPidMap.remove(pid);
// remove process from mUidMap
removeProcessFromUidMap(proc);
proc.destroy();
}
}

View File

@@ -22,6 +22,8 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;
@@ -129,4 +131,14 @@ public class WindowProcessControllerMapTests extends WindowTestsBase {
assertEquals(uid2processes.size(), 1);
assertEquals(mProcessMap.getProcess(FAKE_PID1), pid1uid2);
}
@Test
public void testRemove_callsDestroy() {
var proc = spy(pid1uid1);
mProcessMap.put(FAKE_PID1, proc);
mProcessMap.remove(FAKE_PID1);
verify(proc).destroy();
}
}

View File

@@ -157,6 +157,17 @@ public class WindowProcessControllerTests extends WindowTestsBase {
assertEquals(displayBounds, mWpc.getConfiguration().windowConfiguration.getBounds());
}
@Test
public void testDestroy_unregistersDisplayAreaListener() {
final TestDisplayContent testDisplayContent1 = createTestDisplayContentInContainer();
final DisplayArea imeContainer1 = testDisplayContent1.getImeContainer();
mWpc.registerDisplayAreaConfigurationListener(imeContainer1);
mWpc.destroy();
assertNull(mWpc.getDisplayArea());
}
@Test
public void testSetRunningRecentsAnimation() {
mWpc.setRunningRecentsAnimation(true);