Clean up staging directories of abandoned sessions (4/n)

Now ag/12369403 prevents a staged session from being a child of a
non-staged session which however discloses a bug where the staging
directory is not correctly cleaned up when a non-committed staged
session is abandoned.

This CL fixes that and adds a test to check staging directories are
correctly deleted when abandoning both committed and non-committed
sessions.

Bug: 163976510
Test: atest StagedInstallTest StagedInstallInternalTest
Change-Id: I5d0eed9c5cc71c29a12e61471b2f870140899087
This commit is contained in:
JW Wang
2020-08-14 10:13:12 +08:00
parent 348096df83
commit ec050f6ad4
3 changed files with 39 additions and 2 deletions

View File

@@ -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);

View File

@@ -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());

View File

@@ -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<String> before = getStagingDirectories();
runPhase("testAbandonStagedSessionShouldCleanUp");
List<String> after = getStagingDirectories();
// The staging directories generated during the test should be deleted
assertThat(after).isEqualTo(before);
}
private List<String> 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");