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

Commit f1563010 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Merge cherrypicks of [13232455, 13232456, 13232432, 13232495, 13232299,...

Merge cherrypicks of [13232455, 13232456, 13232432, 13232495, 13232299, 13232399, 13232951, 13232952, 13232953, 13232954, 13232955, 13232956, 13232957, 13232522, 13232433, 13232353, 13232400, 13232354, 13232699, 13232700, 13232701, 13232702] into rvc-qpr1-release

Change-Id: Ib418ded080791ab8610cd2623246270286a70f2e
parents 0c0a6550 2dfebdbf
Loading
Loading
Loading
Loading
+4 −0
Original line number Original line Diff line number Diff line
@@ -299,6 +299,10 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
        final ArraySet<File> unclaimedStages = newArraySet(
        final ArraySet<File> unclaimedStages = newArraySet(
                stagingDir.listFiles(sStageFilter));
                stagingDir.listFiles(sStageFilter));


        // We also need to clean up orphaned staging directory for staged sessions
        final File stagedSessionStagingDir = Environment.getDataStagingDirectory(volumeUuid);
        unclaimedStages.addAll(newArraySet(stagedSessionStagingDir.listFiles()));

        // Ignore stages claimed by active sessions
        // Ignore stages claimed by active sessions
        for (int i = 0; i < mSessions.size(); i++) {
        for (int i = 0; i < mSessions.size(); i++) {
            final PackageInstallerSession session = mSessions.valueAt(i);
            final PackageInstallerSession session = mSessions.valueAt(i);
+4 −0
Original line number Original line Diff line number Diff line
@@ -1581,6 +1581,10 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        destroyInternal();
        destroyInternal();
        // Dispatch message to remove session from PackageInstallerService.
        // Dispatch message to remove session from PackageInstallerService.
        dispatchSessionFinished(error, detailMessage, null);
        dispatchSessionFinished(error, detailMessage, null);
        // TODO(b/173194203): clean up staged session in destroyInternal() call instead
        if (isStaged() && stageDir != null) {
            cleanStageDir();
        }
    }
    }


    private void onStorageUnhealthy() {
    private void onStorageUnhealthy() {
+13 −0
Original line number Original line Diff line number Diff line
@@ -96,6 +96,19 @@ public class StagedInstallInternalTest {
        assertSessionReady(sessionId);
        assertSessionReady(sessionId);
    }
    }


    @Test
    public void testStagedInstallationShouldCleanUpOnValidationFailure() throws Exception {
        InstallUtils.commitExpectingFailure(AssertionError.class, "INSTALL_FAILED_INVALID_APK",
                Install.single(TestApp.AIncompleteSplit).setStaged());
    }

    @Test
    public void testStagedInstallationShouldCleanUpOnValidationFailureMultiPackage()
            throws Exception {
        InstallUtils.commitExpectingFailure(AssertionError.class, "INSTALL_FAILED_INVALID_APK",
                Install.multi(TestApp.AIncompleteSplit, TestApp.B1, TestApp.Apex1).setStaged());
    }

    private static void assertSessionReady(int sessionId) {
    private static void assertSessionReady(int sessionId) {
        assertSessionState(sessionId,
        assertSessionState(sessionId,
                (session) -> assertThat(session.isStagedSessionReady()).isTrue());
                (session) -> assertThat(session.isStagedSessionReady()).isTrue());
+51 −0
Original line number Original line Diff line number Diff line
@@ -21,6 +21,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertTrue;


import com.android.ddmlib.Log;
import com.android.ddmlib.Log;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
import com.android.tradefed.util.ProcessInfo;
import com.android.tradefed.util.ProcessInfo;
@@ -30,6 +31,10 @@ import org.junit.Before;
import org.junit.Test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runner.RunWith;


import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@RunWith(DeviceJUnit4ClassRunner.class)
@RunWith(DeviceJUnit4ClassRunner.class)
public class StagedInstallInternalTest extends BaseHostJUnit4Test {
public class StagedInstallInternalTest extends BaseHostJUnit4Test {


@@ -87,6 +92,52 @@ public class StagedInstallInternalTest extends BaseHostJUnit4Test {
        runPhase("testSystemServerRestartDoesNotAffectStagedSessions_Verify");
        runPhase("testSystemServerRestartDoesNotAffectStagedSessions_Verify");
    }
    }


    @Test
    public void testStagedInstallationShouldCleanUpOnValidationFailure() throws Exception {
        List<String> before = getStagingDirectories();
        runPhase("testStagedInstallationShouldCleanUpOnValidationFailure");
        List<String> after = getStagingDirectories();
        assertThat(after).isEqualTo(before);
    }

    @Test
    public void testStagedInstallationShouldCleanUpOnValidationFailureMultiPackage()
            throws Exception {
        List<String> before = getStagingDirectories();
        runPhase("testStagedInstallationShouldCleanUpOnValidationFailureMultiPackage");
        List<String> after = getStagingDirectories();
        assertThat(after).isEqualTo(before);
    }

    @Test
    public void testOrphanedStagingDirectoryGetsCleanedUpOnReboot() throws Exception {
        //create random directories in /data/app-staging folder
        getDevice().enableAdbRoot();
        getDevice().executeShellCommand("mkdir /data/app-staging/session_123");
        getDevice().executeShellCommand("mkdir /data/app-staging/random_name");
        getDevice().disableAdbRoot();

        assertThat(getStagingDirectories()).isNotEmpty();
        getDevice().reboot();
        assertThat(getStagingDirectories()).isEmpty();
    }

    private List<String> getStagingDirectories() throws DeviceNotAvailableException {
        String baseDir = "/data/app-staging";
        try {
            getDevice().enableAdbRoot();
            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;
        } finally {
            getDevice().disableAdbRoot();
        }
    }

    private void restartSystemServer() throws Exception {
    private void restartSystemServer() throws Exception {
        // Restart the system server
        // Restart the system server
        long oldStartTime = getDevice().getProcessByName("system_server").getStartTime();
        long oldStartTime = getDevice().getProcessByName("system_server").getStartTime();