• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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.sdksandbox.cts.host;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 import static com.google.common.truth.Truth.assertWithMessage;
21 
22 import static org.junit.Assume.assumeTrue;
23 
24 import android.app.sdksandbox.hosttestutils.AdoptableStorageUtils;
25 import android.app.sdksandbox.hosttestutils.SdkSandboxDeviceSupportedHostRule;
26 import android.app.sdksandbox.hosttestutils.SecondaryUserUtils;
27 import android.platform.test.annotations.LargeTest;
28 
29 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
30 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
31 import com.android.tradefed.testtype.junit4.DeviceTestRunOptions;
32 
33 import org.junit.After;
34 import org.junit.Before;
35 import org.junit.Rule;
36 import org.junit.Test;
37 import org.junit.runner.RunWith;
38 
39 @RunWith(DeviceJUnit4ClassRunner.class)
40 public class SdkSandboxDataIsolationHostTest extends BaseHostJUnit4Test {
41 
42     @Rule(order = 0)
43     public final SdkSandboxDeviceSupportedHostRule deviceSupportRule =
44             new SdkSandboxDeviceSupportedHostRule(this);
45 
46     private static final String APP_PACKAGE = "com.android.sdksandbox.cts.app";
47     private static final String APP_APK = "CtsSdkSandboxHostTestApp.apk";
48     private static final String APP_TEST_CLASS = APP_PACKAGE + ".SdkSandboxDataIsolationTestApp";
49 
50     private static final String APP_2_PACKAGE = "com.android.sdksandbox.cts.app2";
51     private static final String APP_2_APK = "CtsSdkSandboxHostTestApp2.apk";
52 
53     private final SecondaryUserUtils mUserUtils = new SecondaryUserUtils(this);
54     private final AdoptableStorageUtils mAdoptableUtils = new AdoptableStorageUtils(this);
55 
56     /**
57      * Runs the given phase of a test by calling into the device. Throws an exception if the test
58      * phase fails.
59      *
60      * <p>For example, <code>runPhase("testExample");</code>
61      */
runPhase(String phase)62     private void runPhase(String phase) throws Exception {
63         assertThat(runDeviceTests(APP_PACKAGE, APP_TEST_CLASS, phase)).isTrue();
64     }
65 
runPhase( String phase, String instrumentationArgKey, String instrumentationArgValue)66     private void runPhase(
67             String phase, String instrumentationArgKey, String instrumentationArgValue)
68             throws Exception {
69         runDeviceTests(
70                 new DeviceTestRunOptions(APP_PACKAGE)
71                         .setDevice(getDevice())
72                         .setTestClassName(APP_TEST_CLASS)
73                         .setTestMethodName(phase)
74                         .addInstrumentationArg(instrumentationArgKey, instrumentationArgValue));
75     }
76 
77     @Before
setUp()78     public void setUp() throws Exception {
79         // These tests run on system user
80         uninstallPackage(APP_PACKAGE);
81         uninstallPackage(APP_2_PACKAGE);
82     }
83 
84     @After
tearDown()85     public void tearDown() throws Exception {
86         mUserUtils.removeSecondaryUserIfNecessary();
87         uninstallPackage(APP_PACKAGE);
88         uninstallPackage(APP_2_PACKAGE);
89     }
90 
91     @Test
testAppCannotAccessAnySandboxDirectories()92     public void testAppCannotAccessAnySandboxDirectories() throws Exception {
93         installPackage(APP_APK);
94         installPackage(APP_2_APK);
95 
96         runPhase("testAppCannotAccessAnySandboxDirectories");
97     }
98 
99     /** Test whether an SDK can access its provided data directories after data isolation. */
100     @Test
testSdkSandboxDataIsolation_SandboxCanAccessItsDirectory()101     public void testSdkSandboxDataIsolation_SandboxCanAccessItsDirectory() throws Exception {
102         installPackage(APP_APK);
103         runPhase("testSdkSandboxDataIsolation_SandboxCanAccessItsDirectory");
104     }
105 
106     /**
107      * Test whether an SDK can detect if an app is installed by the error obtained from accessing
108      * other sandbox app directories. ENOENT error should occur regardless of whether the app exists
109      * or not.
110      */
111     @Test
testSdkSandboxDataIsolation_CannotVerifyAppExistence()112     public void testSdkSandboxDataIsolation_CannotVerifyAppExistence() throws Exception {
113         installPackage(APP_APK);
114         installPackage(APP_2_APK);
115 
116         runPhase("testSdkSandboxDataIsolation_CannotVerifyAppExistence");
117     }
118 
119     /**
120      * Test whether an SDK can detect if an app is installed by the error obtained from accessing
121      * other sandbox user directories. Permission errors should show up regardless of whether the
122      * app exists, when trying to access other user data.
123      */
124     @Test
125     @LargeTest // Creates user
testSdkSandboxDataIsolation_CannotVerifyOtherUserAppExistence()126     public void testSdkSandboxDataIsolation_CannotVerifyOtherUserAppExistence() throws Exception {
127         assumeTrue(getDevice().isMultiUserSupported());
128 
129         installPackage(APP_APK);
130 
131         int userId = mUserUtils.createAndStartSecondaryUser();
132         installPackageAsUser(APP_2_APK, true, userId);
133 
134         runPhase(
135                 "testSdkSandboxDataIsolation_CannotVerifyOtherUserAppExistence",
136                 "sandbox_isolation_user_id",
137                 Integer.toString(userId));
138     }
139 
140     /**
141      * Test whether an SDK can verify an app's existence by checking other volumes, after data
142      * isolation has occurred.
143      */
144     @Test
145     @LargeTest // Creates volume
testSdkSandboxDataIsolation_CannotVerifyAcrossVolumes()146     public void testSdkSandboxDataIsolation_CannotVerifyAcrossVolumes() throws Exception {
147         assumeTrue(mAdoptableUtils.isAdoptableStorageSupported());
148         mAdoptableUtils.enableVirtualDisk();
149         installPackage(APP_APK);
150         installPackage(APP_2_APK);
151 
152         try {
153             final String uuid = mAdoptableUtils.createNewVolume();
154 
155             // Move second package to the newly created volume
156             String result =
157                     getDevice()
158                             .executeShellCommand("pm move-package " + APP_2_PACKAGE + " " + uuid);
159             assertWithMessage("Command failed: pm move-package").that(result).startsWith("Success");
160 
161             runPhase(
162                     "testSdkSandboxDataIsolation_CannotVerifyAcrossVolumes",
163                     "sandbox_isolation_uuid",
164                     uuid);
165         } finally {
166             mAdoptableUtils.cleanUpVolume();
167         }
168     }
169 }
170