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

Commit 858845f7 authored by JW Wang's avatar JW Wang
Browse files

Support rollback for rebootless apex (2/n)

The code is already there. We just need to remove
the restriction to enable rollback support.

* Note only the RETAIN policy is supported for rebootless APEX.
* Note this CL breaks CtsInstallHostTestCases. We will fix it
  in the next CL.

Bug: 195517333
Test: atest StagedRollbackTest

Change-Id: Ib218186fe1448f1f316d2c3b895636efc657ee0c
parent d27824e1
Loading
Loading
Loading
Loading
+0 −5
Original line number Diff line number Diff line
@@ -651,11 +651,6 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
            if (params.isMultiPackage) {
                throw new IllegalArgumentException("A multi-session can't be set as APEX.");
            }
            if (!params.isStaged
                    && (params.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
                throw new IllegalArgumentException(
                    "Non-staged APEX session doesn't support INSTALL_ENABLE_ROLLBACK");
            }
            if (isCalledBySystemOrShell(callingUid) || mBypassNextAllowedApexUpdateCheck) {
                params.installFlags |= PackageManager.INSTALL_DISABLE_ALLOWED_APEX_UPDATE_CHECK;
            } else {
+5 −0
Original line number Diff line number Diff line
@@ -843,6 +843,11 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub implements Rollba
        final String packageName = newPackage.getPackageName();
        final int rollbackDataPolicy = computeRollbackDataPolicy(
                session.rollbackDataPolicy, newPackage.getRollbackDataPolicy());
        if (!session.isStaged() && (installFlags & PackageManager.INSTALL_APEX) != 0
                && rollbackDataPolicy != PackageManager.ROLLBACK_DATA_POLICY_RETAIN) {
            Slog.e(TAG, "Only RETAIN is supported for rebootless APEX: " + packageName);
            return false;
        }
        Slog.i(TAG, "Enabling rollback for install of " + packageName
                + ", session:" + session.sessionId
                + ", rollbackDataPolicy=" + rollbackDataPolicy);
+6 −2
Original line number Diff line number Diff line
@@ -31,7 +31,8 @@ android_test {
    test_config: "RollbackTest.xml",
    java_resources: [
        ":com.android.apex.apkrollback.test_v2",
        ":com.android.apex.apkrollback.test_v2Crashing"
        ":com.android.apex.apkrollback.test_v2Crashing",
        ":test.rebootless_apex_v2",
    ],
}

@@ -47,7 +48,10 @@ java_test_host {
    ],
    test_suites: ["general-tests"],
    test_config: "StagedRollbackTest.xml",
    data: [":com.android.apex.apkrollback.test_v1"],
    data: [
        ":com.android.apex.apkrollback.test_v1",
        ":test.rebootless_apex_v1",
    ],
}

java_test_host {
+27 −0
Original line number Diff line number Diff line
@@ -240,6 +240,33 @@ public class StagedRollbackTest {
        assertThat(rollback.getCommittedSessionId()).isNotEqualTo(-1);
    }

    @Test
    public void testRollbackRebootlessApex() throws Exception {
        final String packageName = "test.apex.rebootless";
        assertThat(InstallUtils.getInstalledVersion(packageName)).isEqualTo(1);

        // install
        TestApp apex1 = new TestApp("TestRebootlessApexV1", packageName, 1,
                /* isApex= */ true, "test.rebootless_apex_v1.apex");
        TestApp apex2 = new TestApp("TestRebootlessApexV2", packageName, 2,
                /* isApex= */ true, "test.rebootless_apex_v2.apex");
        Install.single(apex2).setEnableRollback(PackageManager.ROLLBACK_DATA_POLICY_RETAIN)
                .commit();

        // verify rollback
        assertThat(InstallUtils.getInstalledVersion(packageName)).isEqualTo(2);
        RollbackManager rm = RollbackUtils.getRollbackManager();
        RollbackInfo rollback = getUniqueRollbackInfoForPackage(
                rm.getAvailableRollbacks(), packageName);
        assertThat(rollback).isNotNull();
        assertThat(rollback).packagesContainsExactly(Rollback.from(apex2).to(apex1));
        assertThat(rollback).isNotStaged();

        // rollback
        RollbackUtils.rollback(rollback.getRollbackId());
        assertThat(InstallUtils.getInstalledVersion(packageName)).isEqualTo(1);
    }

    @Test
    public void hasMainlineModule() throws Exception {
        String pkgName = getModuleMetadataPackageName();
+14 −4
Original line number Diff line number Diff line
@@ -96,7 +96,9 @@ public class StagedRollbackTest extends BaseHostJUnit4Test {
        deleteFiles("/system/apex/" + APK_IN_APEX_TESTAPEX_NAME + "*.apex",
                "/data/apex/active/" + APK_IN_APEX_TESTAPEX_NAME + "*.apex",
                apexDataDirDeSys(APK_IN_APEX_TESTAPEX_NAME) + "*",
                apexDataDirCe(APK_IN_APEX_TESTAPEX_NAME, 0) + "*");
                apexDataDirCe(APK_IN_APEX_TESTAPEX_NAME, 0) + "*",
                "/system/apex/test.rebootless_apex_v*.apex",
                "/data/apex/active/test.apex.rebootless*.apex");
    }

    /**
@@ -160,7 +162,7 @@ public class StagedRollbackTest extends BaseHostJUnit4Test {
     */
    @Test
    public void testRollbackApexWithApkCrashing() throws Exception {
        pushTestApex();
        pushTestApex(APK_IN_APEX_TESTAPEX_NAME + "_v1.apex");

        // Install an apex with apk that crashes
        runPhase("testRollbackApexWithApkCrashing_Phase1_Install");
@@ -180,6 +182,15 @@ public class StagedRollbackTest extends BaseHostJUnit4Test {
        assertThat(mLogger).eventOccurred(ROLLBACK_SUCCESS, null, null, null);
    }

    /**
     * Tests rollback is supported correctly for rebootless apex
     */
    @Test
    public void testRollbackRebootlessApex() throws Exception {
        pushTestApex("test.rebootless_apex_v1.apex");
        runPhase("testRollbackRebootlessApex");
    }

    /**
     * Tests that packages are monitored across multiple reboots.
     */
@@ -204,9 +215,8 @@ public class StagedRollbackTest extends BaseHostJUnit4Test {
        runPhase("testWatchdogMonitorsAcrossReboots_Phase3_VerifyRollback");
    }

    private void pushTestApex() throws Exception {
    private void pushTestApex(String fileName) throws Exception {
        CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(getBuild());
        final String fileName = APK_IN_APEX_TESTAPEX_NAME + "_v1.apex";
        final File apex = buildHelper.getTestFile(fileName);
        try {
            getDevice().enableAdbRoot();