Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 884e68ee authored by Adrian Roos's avatar Adrian Roos
Browse files

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
parent 2fbb619b
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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
+2 −1
Original line number Diff line number Diff line
@@ -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();
        }
    }

+12 −0
Original line number Diff line number Diff line
@@ -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();
    }
}
+11 −0
Original line number Diff line number Diff line
@@ -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);