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

Commit 09155bc0 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: 8b07029f am: 4ff00a94

Change-Id: Idf2dbc533661fe273891468e1c7def7f657c2ab9
parents a6cd35c6 4ff00a94
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