OSDN Git Service

Backport of ag/14170751 and ag/14170752.
authorJW Wang <wangchun@google.com>
Tue, 13 Apr 2021 08:15:51 +0000 (16:15 +0800)
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>
Thu, 1 Jul 2021 10:59:39 +0000 (10:59 +0000)
1. An available rollback shouldn't be deleted when its session expires.
2. Add a test to check we don't crash or delete a rollback when its
   session expires.

Bug: 181087240
Bug: 185132440
Test: atest StagedRollbackTest

Merged-In: I3c2b718905d2d7619d6f299ee5402fd858de030e
Merged-In: I1bd786b38e2df1f4bdc80d0d371d5d2d52e21e06
Change-Id: Id55f1bde0ee69a6f26bc8e109918fb26d1da4e3f
(cherry picked from commit 29d5f72db216eeae13cb7d395b2359544012ffce)

services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/StagedRollbackTest.java
tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java

index f075790..d5dbf6b 100644 (file)
@@ -554,8 +554,10 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
                     PackageInstaller.SessionInfo session = mContext.getPackageManager()
                             .getPackageInstaller().getSessionInfo(rollback.getStagedSessionId());
                     if (session == null || session.isStagedSessionFailed()) {
-                        iter.remove();
-                        rollback.delete(mAppDataRollbackHelper);
+                        if (rollback.isEnabling()) {
+                            iter.remove();
+                            rollback.delete(mAppDataRollbackHelper);
+                        }
                         continue;
                     }
 
index 00bd4cf..eaf9c7b 100644 (file)
@@ -482,6 +482,33 @@ public class StagedRollbackTest {
     }
 
     @Test
+    public void testExpireSession_Phase1_Install() throws Exception {
+        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(-1);
+        Install.single(TestApp.A1).commit();
+        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1);
+        Install.single(TestApp.A2).setEnableRollback().setStaged().commit();
+    }
+
+    @Test
+    public void testExpireSession_Phase2_VerifyInstall() throws Exception {
+        assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2);
+        RollbackManager rm = RollbackUtils.getRollbackManager();
+        RollbackInfo rollback = getUniqueRollbackInfoForPackage(
+                rm.getAvailableRollbacks(), TestApp.A);
+        assertThat(rollback).isNotNull();
+        assertThat(rollback).packagesContainsExactly(Rollback.from(TestApp.A2).to(TestApp.A1));
+        assertThat(rollback.isStaged()).isTrue();
+    }
+
+    @Test
+    public void testExpireSession_Phase3_VerifyRollback() throws Exception {
+        RollbackManager rm = RollbackUtils.getRollbackManager();
+        RollbackInfo rollback = getUniqueRollbackInfoForPackage(
+                rm.getAvailableRollbacks(), TestApp.A);
+        assertThat(rollback).isNotNull();
+    }
+
+    @Test
     public void hasMainlineModule() throws Exception {
         String pkgName = getModuleMetadataPackageName();
         boolean existed =  InstrumentationRegistry.getInstrumentation().getContext()
index 9169ef5..bebb991 100644 (file)
@@ -38,7 +38,9 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import java.io.File;
+import java.time.Instant;
 import java.util.Collections;
+import java.util.Date;
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
@@ -441,6 +443,27 @@ public class StagedRollbackTest extends BaseHostJUnit4Test {
         after.forEach(dir -> assertDirectoryIsEmpty(dir));
     }
 
+    /**
+     * Tests an available rollback shouldn't be deleted when its session expires.
+     */
+    @Test
+    public void testExpireSession() throws Exception {
+        runPhase("testExpireSession_Phase1_Install");
+        getDevice().reboot();
+        runPhase("testExpireSession_Phase2_VerifyInstall");
+
+        // Advance system clock by 7 days to expire the staged session
+        Instant t1 = Instant.ofEpochMilli(getDevice().getDeviceDate());
+        Instant t2 = t1.plusMillis(TimeUnit.DAYS.toMillis(7));
+        runAsRoot(() -> getDevice().setDate(Date.from(t2)));
+
+        // Somehow we need to wait for a while before reboot. Otherwise the change to the
+        // system clock will be reset after reboot.
+        Thread.sleep(3000);
+        getDevice().reboot();
+        runPhase("testExpireSession_Phase3_VerifyRollback");
+    }
+
     private void pushTestApex() throws Exception {
         CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(getBuild());
         final String fileName = APK_IN_APEX_TESTAPEX_NAME + "_v1.apex";
@@ -521,4 +544,18 @@ public class StagedRollbackTest extends BaseHostJUnit4Test {
             return false;
         }
     }
+
+    @FunctionalInterface
+    private interface ExceptionalRunnable {
+        void run() throws Exception;
+    }
+
+    private void runAsRoot(ExceptionalRunnable runnable) throws Exception {
+        try {
+            getDevice().enableAdbRoot();
+            runnable.run();
+        } finally {
+            getDevice().disableAdbRoot();
+        }
+    }
 }