1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.cts_root.rollback.host.app; 18 19 import static com.android.cts.rollback.lib.RollbackInfoSubject.assertThat; 20 21 import static com.google.common.truth.Truth.assertThat; 22 23 import android.Manifest; 24 import android.content.Context; 25 import android.content.SharedPreferences; 26 import android.content.pm.PackageInstaller; 27 import android.content.pm.PackageManager; 28 import android.content.rollback.RollbackInfo; 29 import android.content.rollback.RollbackManager; 30 import android.os.storage.StorageManager; 31 import android.provider.DeviceConfig; 32 33 import androidx.test.platform.app.InstrumentationRegistry; 34 35 import com.android.cts.install.lib.Install; 36 import com.android.cts.install.lib.InstallUtils; 37 import com.android.cts.install.lib.TestApp; 38 import com.android.cts.rollback.lib.Rollback; 39 import com.android.cts.rollback.lib.RollbackUtils; 40 41 import org.junit.After; 42 import org.junit.Before; 43 import org.junit.Test; 44 import org.junit.runner.RunWith; 45 import org.junit.runners.JUnit4; 46 47 import java.util.concurrent.TimeUnit; 48 49 /** 50 * On-device helper test methods used for host-driven rollback tests. 51 */ 52 @RunWith(JUnit4.class) 53 public class HostTestHelper { 54 private static final String PROPERTY_WATCHDOG_TRIGGER_FAILURE_COUNT = 55 "watchdog_trigger_failure_count"; 56 57 @Before setup()58 public void setup() { 59 InstallUtils.adoptShellPermissionIdentity( 60 Manifest.permission.INSTALL_PACKAGES, 61 Manifest.permission.DELETE_PACKAGES, 62 Manifest.permission.TEST_MANAGE_ROLLBACKS, 63 Manifest.permission.FORCE_STOP_PACKAGES, 64 Manifest.permission.WRITE_DEVICE_CONFIG); 65 } 66 67 @After teardown()68 public void teardown() { 69 InstallUtils.dropShellPermissionIdentity(); 70 } 71 72 @Test cleanUp()73 public void cleanUp() { 74 // Remove all pending rollbacks 75 RollbackManager rm = RollbackUtils.getRollbackManager(); 76 rm.getAvailableRollbacks().stream().flatMap(info -> info.getPackages().stream()) 77 .map(info -> info.getPackageName()).forEach(rm::expireRollbackForPackage); 78 } 79 80 @Test testRollbackDataPolicy_Phase1_Install()81 public void testRollbackDataPolicy_Phase1_Install() throws Exception { 82 Install.multi(TestApp.A1, TestApp.B1, TestApp.C1).commit(); 83 // Write user data version = 1 84 InstallUtils.processUserData(TestApp.A); 85 InstallUtils.processUserData(TestApp.B); 86 InstallUtils.processUserData(TestApp.C); 87 88 Install a2 = Install.single(TestApp.A2).setStaged() 89 .setEnableRollback(PackageManager.ROLLBACK_DATA_POLICY_WIPE); 90 Install b2 = Install.single(TestApp.B2).setStaged() 91 .setEnableRollback(PackageManager.ROLLBACK_DATA_POLICY_RESTORE); 92 Install c2 = Install.single(TestApp.C2).setStaged() 93 .setEnableRollback(PackageManager.ROLLBACK_DATA_POLICY_RETAIN); 94 Install.multi(a2, b2, c2).setEnableRollback().setStaged().commit(); 95 } 96 97 @Test testRollbackDataPolicy_Phase2_Rollback()98 public void testRollbackDataPolicy_Phase2_Rollback() throws Exception { 99 assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2); 100 assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2); 101 // Write user data version = 2 102 InstallUtils.processUserData(TestApp.A); 103 InstallUtils.processUserData(TestApp.B); 104 InstallUtils.processUserData(TestApp.C); 105 106 RollbackInfo info = RollbackUtils.getAvailableRollback(TestApp.A); 107 RollbackUtils.rollback(info.getRollbackId()); 108 } 109 110 @Test testRollbackDataPolicy_Phase3_VerifyRollback()111 public void testRollbackDataPolicy_Phase3_VerifyRollback() throws Exception { 112 assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1); 113 assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(1); 114 assertThat(InstallUtils.getInstalledVersion(TestApp.C)).isEqualTo(1); 115 // Read user data version from userdata.txt 116 // A's user data version is -1 for user data is wiped. 117 // B's user data version is 1 for user data is restored. 118 // C's user data version is 2 for user data is retained. 119 assertThat(InstallUtils.getUserDataVersion(TestApp.A)).isEqualTo(-1); 120 assertThat(InstallUtils.getUserDataVersion(TestApp.B)).isEqualTo(1); 121 assertThat(InstallUtils.getUserDataVersion(TestApp.C)).isEqualTo(2); 122 } 123 124 @Test testRollbackApkDataDirectories_Phase1_InstallV1()125 public void testRollbackApkDataDirectories_Phase1_InstallV1() throws Exception { 126 Install.single(TestApp.A1).commit(); 127 } 128 129 @Test testRollbackApkDataDirectories_Phase2_InstallV2()130 public void testRollbackApkDataDirectories_Phase2_InstallV2() throws Exception { 131 Install.single(TestApp.A2).setStaged().setEnableRollback().commit(); 132 } 133 134 @Test testRollbackApkDataDirectories_Phase3_Rollback()135 public void testRollbackApkDataDirectories_Phase3_Rollback() throws Exception { 136 RollbackInfo available = RollbackUtils.getAvailableRollback(TestApp.A); 137 RollbackUtils.rollback(available.getRollbackId(), TestApp.A2); 138 } 139 140 @Test testExpireSession_Phase1_Install()141 public void testExpireSession_Phase1_Install() throws Exception { 142 Install.single(TestApp.A1).commit(); 143 int sessionId = Install.single(TestApp.A2).setEnableRollback().setStaged().commit(); 144 145 Context context = InstrumentationRegistry.getInstrumentation().getContext(); 146 SharedPreferences prefs = context.getSharedPreferences("test", 0); 147 prefs.edit().putInt("sessionId", sessionId).commit(); 148 } 149 150 @Test testExpireSession_Phase2_VerifyInstall()151 public void testExpireSession_Phase2_VerifyInstall() throws Exception { 152 assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2); 153 RollbackInfo rollback = RollbackUtils.getAvailableRollback(TestApp.A); 154 assertThat(rollback).isNotNull(); 155 } 156 157 @Test testExpireSession_Phase3_VerifyRollback()158 public void testExpireSession_Phase3_VerifyRollback() throws Exception { 159 RollbackInfo rollback = RollbackUtils.getAvailableRollback(TestApp.A); 160 assertThat(rollback).isNotNull(); 161 162 // Check the session is expired 163 Context context = InstrumentationRegistry.getInstrumentation().getContext(); 164 SharedPreferences prefs = context.getSharedPreferences("test", 0); 165 int sessionId = prefs.getInt("sessionId", -1); 166 PackageInstaller.SessionInfo info = InstallUtils.getStagedSessionInfo(sessionId); 167 assertThat(info).isNull(); 168 } 169 170 @Test testRollbackApexDataDirectories_Phase1_Install()171 public void testRollbackApexDataDirectories_Phase1_Install() throws Exception { 172 Install.single(TestApp.Apex2).setStaged().setEnableRollback().commit(); 173 } 174 175 @Test testBadApkOnly_Phase1_Install()176 public void testBadApkOnly_Phase1_Install() throws Exception { 177 Install.single(TestApp.A1).commit(); 178 Install.single(TestApp.ACrashing2).setEnableRollback().setStaged().commit(); 179 } 180 181 @Test testBadApkOnly_Phase2_VerifyInstall()182 public void testBadApkOnly_Phase2_VerifyInstall() throws Exception { 183 assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2); 184 185 RollbackInfo rollback = RollbackUtils.getAvailableRollback(TestApp.A); 186 assertThat(rollback).isNotNull(); 187 assertThat(rollback).packagesContainsExactly(Rollback.from(TestApp.A2).to(TestApp.A1)); 188 assertThat(rollback.isStaged()).isTrue(); 189 190 DeviceConfig.setProperty(DeviceConfig.NAMESPACE_ROLLBACK, 191 PROPERTY_WATCHDOG_TRIGGER_FAILURE_COUNT, 192 Integer.toString(5), false); 193 RollbackUtils.sendCrashBroadcast(TestApp.A, 4); 194 // Sleep for a while to make sure we don't trigger rollback 195 Thread.sleep(TimeUnit.SECONDS.toMillis(30)); 196 } 197 198 @Test testBadApkOnly_Phase3_VerifyRollback()199 public void testBadApkOnly_Phase3_VerifyRollback() throws Exception { 200 assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1); 201 202 RollbackInfo rollback = RollbackUtils.getCommittedRollback(TestApp.A); 203 assertThat(rollback).isNotNull(); 204 assertThat(rollback).packagesContainsExactly(Rollback.from(TestApp.A2).to(TestApp.A1)); 205 assertThat(rollback).causePackagesContainsExactly(TestApp.ACrashing2); 206 assertThat(rollback).isStaged(); 207 assertThat(rollback.getCommittedSessionId()).isNotEqualTo(-1); 208 } 209 210 @Test testNativeWatchdogTriggersRollback_Phase1_Install()211 public void testNativeWatchdogTriggersRollback_Phase1_Install() throws Exception { 212 Install.single(TestApp.A1).commit(); 213 Install.single(TestApp.A2).setEnableRollback().setStaged().commit(); 214 } 215 216 @Test testNativeWatchdogTriggersRollback_Phase2_VerifyInstall()217 public void testNativeWatchdogTriggersRollback_Phase2_VerifyInstall() throws Exception { 218 assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2); 219 RollbackInfo rollback = RollbackUtils.getAvailableRollback(TestApp.A); 220 assertThat(rollback).isNotNull(); 221 } 222 223 @Test testNativeWatchdogTriggersRollback_Phase3_VerifyRollback()224 public void testNativeWatchdogTriggersRollback_Phase3_VerifyRollback() throws Exception { 225 assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1); 226 RollbackInfo rollback = RollbackUtils.getCommittedRollback(TestApp.A); 227 assertThat(rollback).isNotNull(); 228 } 229 230 @Test testNativeWatchdogTriggersRollbackForAll_Phase1_Install()231 public void testNativeWatchdogTriggersRollbackForAll_Phase1_Install() throws Exception { 232 Install.single(TestApp.A1).commit(); 233 Install.single(TestApp.B1).commit(); 234 Install.single(TestApp.A2).setEnableRollback().setStaged().commit(); 235 Install.single(TestApp.B2).setEnableRollback().setStaged().commit(); 236 } 237 238 @Test testNativeWatchdogTriggersRollbackForAll_Phase2_VerifyInstall()239 public void testNativeWatchdogTriggersRollbackForAll_Phase2_VerifyInstall() throws Exception { 240 assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(2); 241 assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(2); 242 RollbackInfo rollbackA = RollbackUtils.getAvailableRollback(TestApp.A); 243 RollbackInfo rollbackB = RollbackUtils.getAvailableRollback(TestApp.B); 244 assertThat(rollbackA).isNotNull(); 245 assertThat(rollbackB).isNotNull(); 246 assertThat(rollbackA.getRollbackId()).isNotEqualTo(rollbackB.getRollbackId()); 247 } 248 249 @Test testNativeWatchdogTriggersRollbackForAll_Phase3_VerifyRollback()250 public void testNativeWatchdogTriggersRollbackForAll_Phase3_VerifyRollback() throws Exception { 251 assertThat(InstallUtils.getInstalledVersion(TestApp.A)).isEqualTo(1); 252 assertThat(InstallUtils.getInstalledVersion(TestApp.B)).isEqualTo(1); 253 RollbackInfo rollbackA = RollbackUtils.getCommittedRollback(TestApp.A); 254 RollbackInfo rollbackB = RollbackUtils.getCommittedRollback(TestApp.B); 255 assertThat(rollbackA).isNotNull(); 256 assertThat(rollbackB).isNotNull(); 257 assertThat(rollbackA.getRollbackId()).isNotEqualTo(rollbackB.getRollbackId()); 258 } 259 260 @Test isCheckpointSupported()261 public void isCheckpointSupported() { 262 Context context = InstrumentationRegistry.getInstrumentation().getContext(); 263 StorageManager sm = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE); 264 assertThat(sm.isCheckpointSupported()).isTrue(); 265 } 266 } 267