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.scopedstorage.cts.host;
18 
19 import static org.junit.Assert.assertTrue;
20 
21 import android.platform.test.annotations.AppModeFull;
22 
23 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
24 
25 import org.junit.After;
26 import org.junit.Before;
27 import org.junit.Test;
28 import org.junit.runner.RunWith;
29 
30 /**
31  * Runs the core ScopedStorageTest tests.
32  */
33 @RunWith(DeviceJUnit4ClassRunner.class)
34 @AppModeFull
35 public class ScopedStorageCoreHostTest extends BaseHostTestCase {
36     private boolean mIsExternalStorageSetup = false;
37 
38     /**
39      * Runs the given phase of ScopedStorageTest by calling into the device.
40      * Throws an exception if the test phase fails.
41      */
runDeviceTest(String phase)42     void runDeviceTest(String phase) throws Exception {
43         assertTrue(runDeviceTests("android.scopedstorage.cts",
44                 "android.scopedstorage.cts.ScopedStorageTest", phase));
45 
46     }
47 
setupExternalStorage()48     private void setupExternalStorage() throws Exception {
49         if (!mIsExternalStorageSetup) {
50             runDeviceTest("setupExternalStorage");
51             mIsExternalStorageSetup = true;
52         }
53     }
54 
55     @Before
setup()56     public void setup() throws Exception {
57         setupExternalStorage();
58         executeShellCommand("mkdir /sdcard/Android/data/com.android.shell -m 2770");
59         executeShellCommand("mkdir /sdcard/Android/data/com.android.shell/files -m 2770");
60     }
61 
62     @Before
revokeStoragePermissions()63     public void revokeStoragePermissions() throws Exception {
64         revokePermissions(
65                 "android.permission.WRITE_EXTERNAL_STORAGE",
66                 "android.permission.READ_EXTERNAL_STORAGE",
67                 "android.permission.READ_MEDIA_AUDIO",
68                 "android.permission.READ_MEDIA_VIDEO",
69                 "android.permission.READ_MEDIA_IMAGES");
70     }
71 
72     @After
tearDown()73     public void tearDown() throws Exception {
74         executeShellCommand("rm -r /sdcard/Android/data/com.android.shell");
75     }
76 
77     @Test
testManageExternalStorageCanCreateFilesAnywhere()78     public void testManageExternalStorageCanCreateFilesAnywhere() throws Exception {
79         allowAppOps("android:manage_external_storage");
80         try {
81             runDeviceTest("testManageExternalStorageCanCreateFilesAnywhere");
82         } finally {
83             denyAppOps("android:manage_external_storage");
84         }
85     }
86 
87     @Test
testManageExternalStorageReaddir()88     public void testManageExternalStorageReaddir() throws Exception {
89         allowAppOps("android:manage_external_storage");
90         try {
91             runDeviceTest("testManageExternalStorageReaddir");
92         } finally {
93             denyAppOps("android:manage_external_storage");
94         }
95     }
96 
97     @Test
testAccess_file()98     public void testAccess_file() throws Exception {
99         grantPermissions("android.permission.READ_EXTERNAL_STORAGE");
100         grantPermissions("android.permission.READ_MEDIA_IMAGES");
101         try {
102             runDeviceTest("testAccess_file");
103         } finally {
104             revokePermissions("android.permission.READ_EXTERNAL_STORAGE");
105             revokePermissions("android.permission.READ_MEDIA_IMAGES");
106         }
107     }
108 
109     @Test
testAccess_MediaFile()110     public void testAccess_MediaFile() throws Exception {
111         grantPermissions("android.permission.READ_MEDIA_IMAGES");
112         grantPermissions("android.permission.READ_MEDIA_AUDIO");
113         grantPermissions("android.permission.READ_MEDIA_VIDEO");
114         try {
115             runDeviceTest("testAccess_MediaFile");
116         } finally {
117             revokePermissions("android.permission.READ_MEDIA_IMAGES");
118             revokePermissions("android.permission.READ_MEDIA_AUDIO");
119             revokePermissions("android.permission.READ_MEDIA_VIDEO");
120         }
121     }
122 
123     @Test
testAccess_OnlyAudioFile()124     public void testAccess_OnlyAudioFile() throws Exception {
125         grantPermissions("android.permission.READ_MEDIA_AUDIO");
126         try {
127             runDeviceTest("testAccess_OnlyAudioFile");
128         } finally {
129             revokePermissions("android.permission.READ_MEDIA_AUDIO");
130         }
131     }
132 
133     @Test
testAccess_OnlyVideoFile()134     public void testAccess_OnlyVideoFile() throws Exception {
135         grantPermissions("android.permission.READ_MEDIA_VIDEO");
136         try {
137             runDeviceTest("testAccess_OnlyVideoFile");
138         } finally {
139             revokePermissions("android.permission.READ_MEDIA_VIDEO");
140         }
141     }
142 
143     @Test
testAccess_OnlyImageFile()144     public void testAccess_OnlyImageFile() throws Exception {
145         grantPermissions("android.permission.READ_MEDIA_IMAGES");
146         try {
147             runDeviceTest("testAccess_OnlyImageFile");
148         } finally {
149             revokePermissions("android.permission.READ_MEDIA_IMAGES");
150         }
151     }
152 
153     @Test
testAccess_MediaFileLegacy()154     public void testAccess_MediaFileLegacy() throws Exception {
155         runDeviceTest("testAccess_MediaFileLegacy");
156     }
157 
158     @Test
testAccess_MediaFileWithRES()159     public void testAccess_MediaFileWithRES() throws Exception {
160         grantPermissions("android.permission.READ_EXTERNAL_STORAGE");
161         try {
162             runDeviceTest("testAccess_MediaFileWithRES");
163         } finally {
164             revokePermissions("android.permission.READ_EXTERNAL_STORAGE");
165         }
166     }
167 
168     @Test
testAccess_directory()169     public void testAccess_directory() throws Exception {
170         grantPermissions("android.permission.READ_EXTERNAL_STORAGE",
171                 "android.permission.WRITE_EXTERNAL_STORAGE");
172         try {
173             runDeviceTest("testAccess_directory");
174         } finally {
175             revokePermissions("android.permission.READ_EXTERNAL_STORAGE",
176                     "android.permission.WRITE_EXTERNAL_STORAGE");
177         }
178     }
179 
grantPermissions(String... perms)180     private void grantPermissions(String... perms) throws Exception {
181         int currentUserId = getCurrentUserId();
182         for (String perm : perms) {
183             executeShellCommand("pm grant --user %d android.scopedstorage.cts %s",
184                     currentUserId, perm);
185         }
186     }
187 
revokePermissions(String... perms)188     private void revokePermissions(String... perms) throws Exception {
189         int currentUserId = getCurrentUserId();
190         for (String perm : perms) {
191             executeShellCommand("pm revoke --user %d android.scopedstorage.cts %s",
192                     currentUserId, perm);
193         }
194     }
195 
allowAppOps(String... ops)196     private void allowAppOps(String... ops) throws Exception {
197         for (String op : ops) {
198             executeShellCommand("cmd appops set --uid android.scopedstorage.cts %s allow", op);
199         }
200     }
201 
denyAppOps(String... ops)202     private void denyAppOps(String... ops) throws Exception {
203         for (String op : ops) {
204             executeShellCommand("cmd appops set --uid android.scopedstorage.cts %s deny", op);
205         }
206     }
207 }
208