Loading services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java +8 −12 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -516,6 +517,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { mRollbackLifetimeDurationInMillis = DEFAULT_ROLLBACK_LIFETIME_DURATION_MILLIS; } Slog.d(TAG, "mRollbackLifetimeDurationInMillis=" + mRollbackLifetimeDurationInMillis); runExpiration(); } @AnyThread Loading Loading @@ -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) { Loading @@ -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(); Loading Loading @@ -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(); } /* Loading tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java +47 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading
services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java +8 −12 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -516,6 +517,7 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub { mRollbackLifetimeDurationInMillis = DEFAULT_ROLLBACK_LIFETIME_DURATION_MILLIS; } Slog.d(TAG, "mRollbackLifetimeDurationInMillis=" + mRollbackLifetimeDurationInMillis); runExpiration(); } @AnyThread Loading Loading @@ -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) { Loading @@ -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(); Loading Loading @@ -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(); } /* Loading
tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java +47 −0 Original line number Diff line number Diff line Loading @@ -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 Loading