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

Commit e8bdd33e authored by JW Wang's avatar JW Wang Committed by Automerger Merge Worker
Browse files

Run expiration when rollback lifetime is changed. DO NOT MERGE am: 9f8407b0...

Run expiration when rollback lifetime is changed. DO NOT MERGE am: 9f8407b0 am: 8121699d am: 72f8a2e2

Change-Id: Ibf5890497dafe8ce8cc5256e3b0022d4df6609d1
parents eb1168ad 72f8a2e2
Loading
Loading
Loading
Loading
+8 −12
Original line number Diff line number Diff line
@@ -137,6 +137,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
    private final Installer mInstaller;
    private final RollbackPackageHealthObserver mPackageHealthObserver;
    private final AppDataRollbackHelper mAppDataRollbackHelper;
    private final Runnable mRunExpiration = this::runExpiration;

    // The # of milli-seconds to sleep for each received ACTION_PACKAGE_ENABLE_ROLLBACK.
    // Used by #blockRollbackManager to test timeout in enabling rollbacks.
@@ -516,6 +517,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
            mRollbackLifetimeDurationInMillis = DEFAULT_ROLLBACK_LIFETIME_DURATION_MILLIS;
        }
        Slog.d(TAG, "mRollbackLifetimeDurationInMillis=" + mRollbackLifetimeDurationInMillis);
        runExpiration();
    }

    @AnyThread
@@ -644,6 +646,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
    // Schedules future expiration as appropriate.
    @WorkerThread
    private void runExpiration() {
        getHandler().removeCallbacks(mRunExpiration);

        Instant now = Instant.now();
        Instant oldest = null;
        synchronized (mLock) {
@@ -667,20 +671,12 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
        }

        if (oldest != null) {
            scheduleExpiration(now.until(oldest.plusMillis(mRollbackLifetimeDurationInMillis),
                        ChronoUnit.MILLIS));
            long delay = now.until(
                    oldest.plusMillis(mRollbackLifetimeDurationInMillis), ChronoUnit.MILLIS);
            getHandler().postDelayed(mRunExpiration, delay);
        }
    }

    /**
     * Schedules an expiration check to be run after the given duration in
     * milliseconds has gone by.
     */
    @AnyThread
    private void scheduleExpiration(long duration) {
        getHandler().postDelayed(() -> runExpiration(), duration);
    }

    @AnyThread
    private Handler getHandler() {
        return mHandlerThread.getThreadHandler();
@@ -1179,7 +1175,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
        // prepare to rollback if packages crashes too frequently.
        mPackageHealthObserver.startObservingHealth(rollback.getPackageNames(),
                mRollbackLifetimeDurationInMillis);
        scheduleExpiration(mRollbackLifetimeDurationInMillis);
        runExpiration();
    }

    /*
+47 −0
Original line number Diff line number Diff line
@@ -434,6 +434,53 @@ public class RollbackTest {
        }
    }

    /**
     * Test that available rollbacks should expire correctly when the property
     * {@link RollbackManager#PROPERTY_ROLLBACK_LIFETIME_MILLIS} is changed
     */
    @Test
    public void testRollbackExpiresWhenLifetimeChanges() throws Exception {
        long defaultExpirationTime = TimeUnit.HOURS.toMillis(48);
        RollbackManager rm = RollbackUtils.getRollbackManager();

        try {
            InstallUtils.adoptShellPermissionIdentity(
                    Manifest.permission.INSTALL_PACKAGES,
                    Manifest.permission.DELETE_PACKAGES,
                    Manifest.permission.TEST_MANAGE_ROLLBACKS,
                    Manifest.permission.WRITE_DEVICE_CONFIG);

            Uninstall.packages(TestApp.A);
            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(-1);
            Install.single(TestApp.A1).commit();
            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
            Install.single(TestApp.A2).setEnableRollback().commit();
            assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
            RollbackInfo rollback = waitForAvailableRollback(TestApp.A);
            assertThat(rollback).packagesContainsExactly(Rollback.from(TestApp.A2).to(TestApp.A1));

            // Change the lifetime to 0 which should expire rollbacks immediately
            DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK_BOOT,
                    RollbackManager.PROPERTY_ROLLBACK_LIFETIME_MILLIS,
                    Long.toString(0), false /* makeDefault*/);

            // Keep polling until device config changes has happened (which might take more than
            // 5 sec depending how busy system_server is) and rollbacks have expired
            for (int i = 0; i < 30; ++i) {
                if (hasRollbackInclude(rm.getAvailableRollbacks(), TestApp.A)) {
                    Thread.sleep(1000);
                }
            }
            rollback = getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TestApp.A);
            assertThat(rollback).isNull();
        } finally {
            DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK_BOOT,
                    RollbackManager.PROPERTY_ROLLBACK_LIFETIME_MILLIS,
                    Long.toString(defaultExpirationTime), false /* makeDefault*/);
            InstallUtils.dropShellPermissionIdentity();
        }
    }

    /**
     * Test that changing time on device does not affect the duration of time that we keep
     * rollback available