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