diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index 91155252d75bc..28c5e964fe275 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -2762,15 +2762,15 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { // do it now. return; } + mDestroyed = true; if (mCommitted) { - mDestroyed = true; if (!mStagingManager.abortCommittedSessionLocked(this)) { // Do not clean up the staged session from system. It is not safe yet. mCallback.onStagedSessionChanged(this); return; } - cleanStageDir(getChildSessionsLocked()); } + cleanStageDir(getChildSessionsLocked()); destroyInternal(); } dispatchSessionFinished(INSTALL_FAILED_ABORTED, "Session was abandoned", null); diff --git a/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java b/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java index 12f1750fb78cf..781723985ec56 100644 --- a/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java +++ b/tests/StagedInstallTest/app/src/com/android/tests/stagedinstallinternal/StagedInstallInternalTest.java @@ -119,6 +119,18 @@ public class StagedInstallInternalTest { assertSessionReady(sessionId); } + @Test + public void testAbandonStagedSessionShouldCleanUp() throws Exception { + int id1 = Install.single(TestApp.A1).setStaged().createSession(); + InstallUtils.getPackageInstaller().abandonSession(id1); + int id2 = Install.multi(TestApp.A1).setStaged().createSession(); + InstallUtils.getPackageInstaller().abandonSession(id2); + int id3 = Install.single(TestApp.A1).setStaged().commit(); + InstallUtils.getPackageInstaller().abandonSession(id3); + int id4 = Install.multi(TestApp.A1).setStaged().commit(); + InstallUtils.getPackageInstaller().abandonSession(id4); + } + private static void assertSessionReady(int sessionId) { assertSessionState(sessionId, (session) -> assertThat(session.isStagedSessionReady()).isTrue()); diff --git a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java index 792e29d93be23..d7b07967f9792 100644 --- a/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java +++ b/tests/StagedInstallTest/src/com/android/tests/stagedinstallinternal/host/StagedInstallInternalTest.java @@ -41,6 +41,9 @@ import org.junit.Test; import org.junit.runner.RunWith; import java.io.File; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; @RunWith(DeviceJUnit4ClassRunner.class) public class StagedInstallInternalTest extends BaseHostJUnit4Test { @@ -200,6 +203,28 @@ public class StagedInstallInternalTest extends BaseHostJUnit4Test { assertThat(sessionIds.length).isEqualTo(3); } + @Test + public void testAbandonStagedSessionShouldCleanUp() throws Exception { + List before = getStagingDirectories(); + runPhase("testAbandonStagedSessionShouldCleanUp"); + List after = getStagingDirectories(); + // The staging directories generated during the test should be deleted + assertThat(after).isEqualTo(before); + } + + private List getStagingDirectories() { + String baseDir = "/data/app-staging"; + try { + return getDevice().getFileEntry(baseDir).getChildren(false) + .stream().filter(entry -> entry.getName().matches("session_\\d+")) + .map(entry -> entry.getName()) + .collect(Collectors.toList()); + } catch (Exception e) { + // Return an empty list if any error + return Collections.EMPTY_LIST; + } + } + private void restartSystemServer() throws Exception { // Restart the system server ProcessInfo oldPs = getDevice().getProcessByName("system_server");