1 /* 2 * Copyright (C) 2020 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 android.appsecurity.cts; 18 19 import com.android.tradefed.util.RunUtil; 20 import static android.appsecurity.cts.Utils.waitForBootCompleted; 21 22 import static org.hamcrest.CoreMatchers.is; 23 import static org.junit.Assert.assertEquals; 24 import static org.junit.Assume.assumeThat; 25 import static org.junit.Assume.assumeTrue; 26 27 import com.android.tradefed.device.DeviceNotAvailableException; 28 import com.android.tradefed.device.ITestDevice; 29 import com.android.tradefed.log.LogUtil; 30 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner; 31 32 import org.junit.After; 33 import org.junit.Before; 34 import org.junit.Test; 35 import org.junit.runner.RunWith; 36 37 import java.util.HashMap; 38 import java.util.Map; 39 40 /** 41 * Set of tests that verify app data isolation works. 42 */ 43 @RunWith(DeviceJUnit4ClassRunner.class) 44 public class AppDataIsolationTests extends BaseAppSecurityTest { 45 46 private static final String APPA_APK = "CtsAppDataIsolationAppA.apk"; 47 private static final String APP_SHARED_A_APK = "CtsAppDataIsolationAppSharedA.apk"; 48 private static final String APP_DIRECT_BOOT_A_APK = "CtsAppDataIsolationAppDirectBootA.apk"; 49 private static final String APP_API29_A_APK = "CtsAppDataIsolationAppApi29A.apk"; 50 private static final String APPA_PKG = "com.android.cts.appdataisolation.appa"; 51 private static final String APPA_CLASS = 52 "com.android.cts.appdataisolation.appa.AppATests"; 53 private static final String APPA_METHOD_CREATE_CE_DE_DATA = "testCreateCeDeAppData"; 54 private static final String APPA_METHOD_CHECK_CE_DATA_EXISTS = "testAppACeDataExists"; 55 private static final String APPA_METHOD_CHECK_CE_DATA_DOES_NOT_EXIST = 56 "testAppACeDataDoesNotExist"; 57 private static final String APPA_METHOD_CHECK_DE_DATA_EXISTS = "testAppADeDataExists"; 58 private static final String APPA_METHOD_CHECK_DE_DATA_DOES_NOT_EXIST = 59 "testAppADeDataDoesNotExist"; 60 private static final String APPA_METHOD_CHECK_CUR_PROFILE_ACCESSIBLE = 61 "testAppACurProfileDataAccessible"; 62 private static final String APPA_METHOD_CHECK_REF_PROFILE_ACCESSIBLE = 63 "testAppARefProfileDataAccessible"; 64 private static final String APPA_METHOD_UNLOCK_DEVICE_AND_VERIFY_CE_DE_EXTERNAL_EXIST = 65 "testAppAUnlockDeviceAndVerifyCeDeExternalDataExist"; 66 private static final String APPA_METHOD_CANNOT_ACCESS_APPB_DIR = "testCannotAccessAppBDataDir"; 67 68 private static final String APPA_METHOD_TEST_UNLOCK_DEVICE = 69 "testUnlockDevice"; 70 71 private static final String APPB_APK = "CtsAppDataIsolationAppB.apk"; 72 private static final String APP_SHARED_B_APK = "CtsAppDataIsolationAppSharedB.apk"; 73 private static final String APPB_PKG = "com.android.cts.appdataisolation.appb"; 74 private static final String APPB_CLASS = 75 "com.android.cts.appdataisolation.appb.AppBTests"; 76 private static final String APPB_METHOD_CAN_NOT_ACCESS_APPA_DIR = "testCanNotAccessAppADataDir"; 77 private static final String APPB_METHOD_CAN_ACCESS_APPA_DIR = "testCanAccessAppADataDir"; 78 79 private static final String APPA_METHOD_CREATE_EXTERNAL_DIRS = "testCreateExternalDirs"; 80 private static final String APPA_METHOD_TEST_ISOLATED_PROCESS = "testIsolatedProcess"; 81 private static final String APPA_METHOD_TEST_APP_ZYGOTE_ISOLATED_PROCESS = 82 "testAppZygoteIsolatedProcess"; 83 private static final String APPB_METHOD_CAN_NOT_ACCESS_APPA_EXTERNAL_DIRS = 84 "testCanNotAccessAppAExternalDirs"; 85 private static final String APPB_METHOD_CAN_ACCESS_APPA_EXTERNAL_DIRS = 86 "testCanAccessAppAExternalDirs"; 87 private static final String APPA_METHOD_CHECK_EXTERNAL_DIRS_DO_NOT_EXIST = 88 "testAppAExternalDirsDoNotExist"; 89 private static final String APPA_METHOD_CHECK_EXTERNAL_DIRS_DO_EXIST = 90 "testAppAExternalDirsDoExist"; 91 private static final String APPA_METHOD_CHECK_EXTERNAL_DIRS_UNAVAILABLE = 92 "testAppAExternalDirsUnavailable"; 93 private static final String APPA_METHOD_TEST_OTHER_USER_DIRS_NOT_PRESENT = 94 "testOtherUserDirsNotPresent"; 95 private static final String APPA_METHOD_TEST_OTHER_USER_DIRS_NOT_ACCESSIBLE = 96 "testOtherUserDirsNotAccessible"; 97 98 private int mOtherUser = -1; 99 100 @Before setUp()101 public void setUp() throws Exception { 102 Utils.prepareSingleUser(getDevice()); 103 getDevice().uninstallPackage(APPA_PKG); 104 getDevice().uninstallPackage(APPB_PKG); 105 } 106 107 @After tearDown()108 public void tearDown() throws Exception { 109 if (mOtherUser != -1) { 110 getDevice().removeUser(mOtherUser); 111 } 112 getDevice().uninstallPackage(APPA_PKG); 113 getDevice().uninstallPackage(APPB_PKG); 114 } 115 116 @Test testAppAbleToAccessItsDataAfterForceStop()117 public void testAppAbleToAccessItsDataAfterForceStop() throws Exception { 118 // Install AppA and verify no data stored 119 new InstallMultiple().addFile(APPA_APK).run(); 120 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_CE_DATA_DOES_NOT_EXIST); 121 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_DE_DATA_DOES_NOT_EXIST); 122 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_EXTERNAL_DIRS_DO_NOT_EXIST); 123 124 // Create data in CE, DE and external storage 125 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CREATE_CE_DE_DATA); 126 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CREATE_EXTERNAL_DIRS); 127 128 // Verify CE, DE and external storage contains data, cur profile is accessible and ref 129 // profile is not accessible 130 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_CE_DATA_EXISTS); 131 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_DE_DATA_EXISTS); 132 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_EXTERNAL_DIRS_DO_EXIST); 133 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_CUR_PROFILE_ACCESSIBLE); 134 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_REF_PROFILE_ACCESSIBLE); 135 136 // Force stop and verify CE, DE and external storage contains data, cur profile is 137 // accessible and ref profile is not accessible, to confirm it's binding back the same data 138 // directory, not binding to a wrong one / create a new one. 139 forceStopPackage(APPA_PKG); 140 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_CE_DATA_EXISTS); 141 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_DE_DATA_EXISTS); 142 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_EXTERNAL_DIRS_DO_EXIST); 143 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_CUR_PROFILE_ACCESSIBLE); 144 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_REF_PROFILE_ACCESSIBLE); 145 } 146 147 @Test testAppAbleToAccessItsDataAfterReboot()148 public void testAppAbleToAccessItsDataAfterReboot() throws Exception { 149 // Install AppA and verify no data stored 150 new InstallMultiple().addFile(APPA_APK).run(); 151 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_CE_DATA_DOES_NOT_EXIST); 152 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_DE_DATA_DOES_NOT_EXIST); 153 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_EXTERNAL_DIRS_DO_NOT_EXIST); 154 155 // Create data in CE, DE and external storage 156 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CREATE_CE_DE_DATA); 157 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CREATE_EXTERNAL_DIRS); 158 159 // Verify CE, DE and external storage contains data, cur profile is accessible and ref 160 // profile is not accessible 161 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_CE_DATA_EXISTS); 162 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_DE_DATA_EXISTS); 163 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_EXTERNAL_DIRS_DO_EXIST); 164 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_CUR_PROFILE_ACCESSIBLE); 165 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_REF_PROFILE_ACCESSIBLE); 166 167 // Reboot and verify CE, DE and external storage contains data, cur profile is accessible 168 // and ref profile is not accessible 169 reboot(); 170 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_CE_DATA_EXISTS); 171 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_DE_DATA_EXISTS); 172 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_EXTERNAL_DIRS_DO_EXIST); 173 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_CUR_PROFILE_ACCESSIBLE); 174 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_REF_PROFILE_ACCESSIBLE); 175 } 176 177 @Test testDirectBootModeWorks()178 public void testDirectBootModeWorks() throws Exception { 179 if (!"file".equals(getDevice().getProperty("ro.crypto.type"))) { 180 LogUtil.CLog.d("Device is NOT encrypted with file-based encryption. skipping test"); 181 return; 182 } 183 assumeTrue("Screen lock is not supported so skip direct boot test", 184 hasDeviceFeature("android.software.secure_lock_screen")); 185 // Install AppA and verify no data stored 186 new InstallMultiple().addFile(APP_DIRECT_BOOT_A_APK).run(); 187 new InstallMultiple().addFile(APPB_APK).run(); 188 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_CE_DATA_DOES_NOT_EXIST); 189 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_DE_DATA_DOES_NOT_EXIST); 190 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_EXTERNAL_DIRS_DO_NOT_EXIST); 191 192 // Create data in CE, DE and external storage 193 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CREATE_CE_DE_DATA); 194 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CREATE_EXTERNAL_DIRS); 195 196 // Verify CE, DE and external storage contains data, cur profile is accessible and ref 197 // profile is not accessible 198 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_CE_DATA_EXISTS); 199 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_DE_DATA_EXISTS); 200 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_EXTERNAL_DIRS_DO_EXIST); 201 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_CUR_PROFILE_ACCESSIBLE); 202 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_REF_PROFILE_ACCESSIBLE); 203 204 try { 205 // Setup screenlock 206 getDevice().executeShellCommand("locksettings set-disabled false"); 207 String response = getDevice().executeShellCommand("locksettings set-pin 1234"); 208 if (!response.contains("1234")) { 209 // This seems to fail occasionally. Try again once, then give up. 210 RunUtil.getDefault().sleep(500); 211 response = getDevice().executeShellCommand("locksettings set-pin 1234"); 212 assumeTrue("Test requires setting a pin, which failed: " + response, 213 response.contains("1234")); 214 } 215 216 // Give enough time for vold to update keys 217 RunUtil.getDefault().sleep(15000); 218 219 // Follow DirectBootHostTest, reboot system into known state with keys ejected 220 getDevice().rebootUntilOnline(); 221 waitForBootCompleted(getDevice()); 222 223 // Verify DE data is still readable and writeable, while CE and external data are not 224 // accessible 225 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_DE_DATA_EXISTS); 226 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_CE_DATA_DOES_NOT_EXIST); 227 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_EXTERNAL_DIRS_UNAVAILABLE); 228 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_CUR_PROFILE_ACCESSIBLE); 229 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_REF_PROFILE_ACCESSIBLE); 230 // Verify cannot access other apps data 231 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CANNOT_ACCESS_APPB_DIR); 232 233 // Unlock device and verify CE, DE and external data still exist, without killing the 234 // process, as test process usually will be killed after the test 235 runDeviceTests(APPA_PKG, APPA_CLASS, 236 APPA_METHOD_UNLOCK_DEVICE_AND_VERIFY_CE_DE_EXTERNAL_EXIST); 237 238 // Restart test app and verify CE, DE and external storage contains data, cur profile is 239 // accessible and ref profile is not accessible 240 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_CE_DATA_EXISTS); 241 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_DE_DATA_EXISTS); 242 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_EXTERNAL_DIRS_DO_EXIST); 243 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_CUR_PROFILE_ACCESSIBLE); 244 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_REF_PROFILE_ACCESSIBLE); 245 } finally { 246 try { 247 // Always try to unlock first, then clear screenlock setting 248 try { 249 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_TEST_UNLOCK_DEVICE); 250 } catch (Exception e) {} 251 getDevice().executeShellCommand("locksettings clear --old 1234"); 252 getDevice().executeShellCommand("locksettings set-disabled true"); 253 } finally { 254 // Get ourselves back into a known-good state 255 getDevice().rebootUntilOnline(); 256 getDevice().waitForDeviceAvailable(); 257 } 258 } 259 } 260 261 @Test testAppNotAbleToAccessItsDataAfterReinstall()262 public void testAppNotAbleToAccessItsDataAfterReinstall() throws Exception { 263 // Install AppA create CE DE data 264 new InstallMultiple().addFile(APPA_APK).run(); 265 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CREATE_CE_DE_DATA); 266 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CREATE_EXTERNAL_DIRS); 267 268 // Reinstall AppA 269 getDevice().uninstallPackage(APPA_PKG); 270 new InstallMultiple().addFile(APPA_APK).run(); 271 272 // Verify CE, DE and external data are removed 273 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_CE_DATA_DOES_NOT_EXIST); 274 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_DE_DATA_DOES_NOT_EXIST); 275 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CHECK_EXTERNAL_DIRS_DO_NOT_EXIST); 276 } 277 278 @Test testNormalProcessCannotAccessOtherAppDataDir()279 public void testNormalProcessCannotAccessOtherAppDataDir() throws Exception { 280 new InstallMultiple().addFile(APPA_APK).run(); 281 new InstallMultiple().addFile(APPB_APK).run(); 282 283 runDeviceTests(APPB_PKG, APPB_CLASS, APPB_METHOD_CAN_NOT_ACCESS_APPA_DIR); 284 } 285 286 @Test testSharedAppAbleToAccessOtherAppDataDir()287 public void testSharedAppAbleToAccessOtherAppDataDir() throws Exception { 288 new InstallMultiple().addFile(APP_SHARED_A_APK).run(); 289 new InstallMultiple().addFile(APP_SHARED_B_APK).run(); 290 291 runDeviceTests(APPB_PKG, APPB_CLASS, APPB_METHOD_CAN_ACCESS_APPA_DIR); 292 } 293 294 @Test testNormalProcessCannotAccessOtherAppExternalDataDir()295 public void testNormalProcessCannotAccessOtherAppExternalDataDir() throws Exception { 296 assumeThatFuseDataIsolationIsEnabled(getDevice()); 297 298 new InstallMultiple().addFile(APPA_APK).run(); 299 new InstallMultiple().addFile(APPB_APK).run(); 300 301 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CREATE_EXTERNAL_DIRS); 302 runDeviceTests(APPB_PKG, APPB_CLASS, APPB_METHOD_CAN_NOT_ACCESS_APPA_EXTERNAL_DIRS); 303 } 304 305 @Test testSharedAppAbleToAccessOtherAppExternalDataDir()306 public void testSharedAppAbleToAccessOtherAppExternalDataDir() throws Exception { 307 new InstallMultiple().addFile(APP_SHARED_A_APK).run(); 308 new InstallMultiple().addFile(APP_SHARED_B_APK).run(); 309 310 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_CREATE_EXTERNAL_DIRS); 311 runDeviceTests(APPB_PKG, APPB_CLASS, APPB_METHOD_CAN_ACCESS_APPA_EXTERNAL_DIRS); 312 } 313 314 @Test testIsolatedProcess()315 public void testIsolatedProcess() throws Exception { 316 new InstallMultiple().addFile(APPA_APK).run(); 317 new InstallMultiple().addFile(APPB_APK).run(); 318 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_TEST_ISOLATED_PROCESS); 319 } 320 321 @Test testAppZygoteIsolatedProcess()322 public void testAppZygoteIsolatedProcess() throws Exception { 323 new InstallMultiple().addFile(APPA_APK).run(); 324 new InstallMultiple().addFile(APPB_APK).run(); 325 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_TEST_APP_ZYGOTE_ISOLATED_PROCESS); 326 } 327 328 @Test testAppUnableToAccessOtherUserAppDataDir()329 public void testAppUnableToAccessOtherUserAppDataDir() throws Exception { 330 assumeCanCreateUser(); 331 mOtherUser = getDevice().createUser("other_user"); 332 333 // For targetSdk > 29, directories related to other users are not visible at all. 334 new InstallMultiple().addFile(APPA_APK).run(); 335 new InstallMultiple().addFile(APPB_APK).run(); 336 getDevice().startUser(mOtherUser, true /* wait */); 337 installExistingAppAsUser(APPB_PKG, mOtherUser); 338 339 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_TEST_OTHER_USER_DIRS_NOT_PRESENT, 340 makeOtherUserIdArgs(mOtherUser)); 341 } 342 343 @Test testAppUnableToAccessOtherUserAppDataDirApi29()344 public void testAppUnableToAccessOtherUserAppDataDirApi29() throws Exception { 345 assumeCanCreateUser(); 346 mOtherUser = getDevice().createUser("other_user"); 347 348 // For targetSdk <= 29, directories related to other users are visible but we cannot 349 // access anything within them. 350 new InstallMultiple().addFile(APP_API29_A_APK).run(); 351 new InstallMultiple().addFile(APPB_APK).run(); 352 getDevice().startUser(mOtherUser, true /* wait */); 353 installExistingAppAsUser(APPB_PKG, mOtherUser); 354 355 runDeviceTests(APPA_PKG, APPA_CLASS, APPA_METHOD_TEST_OTHER_USER_DIRS_NOT_ACCESSIBLE, 356 makeOtherUserIdArgs(mOtherUser)); 357 } 358 assumeCanCreateUser()359 private void assumeCanCreateUser() throws DeviceNotAvailableException { 360 assumeTrue("Test requires multi-user support", mSupportsMultiUser); 361 // If we're already at the user limit, e.g. when running the test in a secondary user, 362 // then we can't create another one. 363 int currentUserCount = getDevice().listUsers().size(); 364 assumeTrue("Test requires creating another user", 365 getDevice().getMaxNumberOfUsersSupported() > currentUserCount); 366 } 367 runDeviceTests(String pkgName, String testClassName, String testMethodName, Map<String, String> instrumentationArgs)368 private void runDeviceTests(String pkgName, String testClassName, String testMethodName, 369 Map<String, String> instrumentationArgs) throws DeviceNotAvailableException { 370 runDeviceTests(getDevice(), null, pkgName, testClassName, testMethodName, null, 371 10 * 60 * 1000L, 10 * 60 * 1000L, 0L, true, false, instrumentationArgs); 372 } 373 makeOtherUserIdArgs(int otherUser)374 private Map<String, String> makeOtherUserIdArgs(int otherUser) { 375 Map<String, String> args = new HashMap<>(); 376 args.put("other_user_id", Integer.toString(otherUser)); 377 return args; 378 } 379 forceStopPackage(String packageName)380 private void forceStopPackage(String packageName) throws Exception { 381 getDevice().executeShellCommand("am force-stop " + packageName); 382 } 383 reboot()384 private void reboot() throws Exception { 385 getDevice().reboot(); 386 waitForBootCompleted(getDevice()); 387 } 388 installExistingAppAsUser(String packageName, int userId)389 private void installExistingAppAsUser(String packageName, int userId) throws Exception { 390 final String installString = 391 "Package " + packageName + " installed for user: " + userId + "\n"; 392 assertEquals(installString, getDevice().executeShellCommand( 393 "cmd package install-existing --full" 394 + " --user " + Integer.toString(userId) 395 + " " + packageName)); 396 } 397 assumeThatFuseDataIsolationIsEnabled(ITestDevice device)398 private static void assumeThatFuseDataIsolationIsEnabled(ITestDevice device) 399 throws DeviceNotAvailableException { 400 assumeThat(device.executeShellCommand( 401 "getprop persist.sys.vold_app_data_isolation_enabled").trim(), 402 is("true")); 403 } 404 } 405