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