1 /*
2  * Copyright (C) 2019 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.permission.cts;
18 
19 import static android.Manifest.permission.ACCESS_BACKGROUND_LOCATION;
20 import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
21 import static android.Manifest.permission.ACCESS_MEDIA_LOCATION;
22 import static android.Manifest.permission.READ_CALL_LOG;
23 import static android.Manifest.permission.READ_CONTACTS;
24 import static android.Manifest.permission.SYSTEM_ALERT_WINDOW;
25 import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_ROLE;
26 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
27 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT;
28 import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_WHEN_REQUESTED;
29 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
30 import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
31 import static android.permission.cts.PermissionUtils.clearAppState;
32 import static android.permission.cts.PermissionUtils.getAllPermissionFlags;
33 import static android.permission.cts.PermissionUtils.getPermissionFlags;
34 import static android.permission.cts.PermissionUtils.install;
35 import static android.permission.cts.PermissionUtils.isGranted;
36 import static android.permission.cts.PermissionUtils.setPermissionFlags;
37 import static android.permission.cts.PermissionUtils.uninstallApp;
38 
39 import static com.android.compatibility.common.util.SystemUtil.eventually;
40 
41 import static org.junit.Assert.assertEquals;
42 import static org.junit.Assert.assertFalse;
43 
44 import android.os.Build;
45 import android.platform.test.annotations.AppModeFull;
46 import android.platform.test.annotations.AsbSecurityTest;
47 import android.platform.test.annotations.PlatinumTest;
48 
49 import androidx.test.filters.SdkSuppress;
50 import androidx.test.runner.AndroidJUnit4;
51 
52 import org.junit.After;
53 import org.junit.Before;
54 import org.junit.Test;
55 import org.junit.runner.RunWith;
56 
57 /**
58  * Tests how permission flags behave.
59  */
60 @RunWith(AndroidJUnit4.class)
61 @AppModeFull(reason = "Cannot read permission flags of other app.")
62 @PlatinumTest
63 @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
64 public class PermissionFlagsTest {
65     /** The package name of most apps used in the test */
66     private static final String APP_PKG = "android.permission.cts.appthatrequestpermission";
67     private static final String APP_SYSTEM_ALERT_WINDOW_PKG =
68             "android.permission.cts.usesystemalertwindowpermission";
69 
70     private static final String TMP_DIR = "/data/local/tmp/cts-permission/";
71     private static final String APK_CONTACTS_15 =
72             TMP_DIR + "CtsAppThatRequestsContactsPermission15.apk";
73     private static final String APK_LOCATION_22 =
74             TMP_DIR + "CtsAppThatRequestsLocationPermission22.apk";
75     private static final String APK_LOCATION_28 =
76             TMP_DIR + "CtsAppThatRequestsLocationPermission28.apk";
77     private static final String APK_STORAGE_22 =
78             TMP_DIR + "CtsAppThatRequestsStoragePermission22.apk";
79     private static final String APK_SYSTEM_ALERT_WINDOW_23 =
80             TMP_DIR + "CtsAppThatRequestsSystemAlertWindow23.apk";
81 
82     @After
83     @Before
uninstallTestApp()84     public void uninstallTestApp() {
85         uninstallApp(APP_PKG);
86         uninstallApp(APP_SYSTEM_ALERT_WINDOW_PKG);
87     }
88 
89     @Test
implicitPermission()90     public void implicitPermission() {
91         install(APK_LOCATION_28);
92 
93         assertEquals(FLAG_PERMISSION_REVOKE_WHEN_REQUESTED,
94                 getPermissionFlags(APP_PKG, ACCESS_BACKGROUND_LOCATION));
95     }
96 
97     @Test
implicitPermissionPreM()98     public void implicitPermissionPreM() throws Exception {
99         install(APK_STORAGE_22);
100 
101         // Test ACCESS_MEDIA_LOCATION which is split from READ_EXTERNAL_STORAGE but won't get
102         // REVOKE_ON_UPGRADE, while it should still get REVIEW_REQUIRED when pre-M.
103         assertEquals(FLAG_PERMISSION_REVIEW_REQUIRED, getPermissionFlags(APP_PKG,
104                 ACCESS_MEDIA_LOCATION) & FLAG_PERMISSION_REVIEW_REQUIRED);
105     }
106 
107     @Test
regularPermission()108     public void regularPermission() {
109         install(APK_LOCATION_28);
110 
111         assertEquals(0, getPermissionFlags(APP_PKG, ACCESS_COARSE_LOCATION));
112     }
113 
114     @Test
regularPermissionPreM()115     public void regularPermissionPreM() {
116         install(APK_CONTACTS_15);
117 
118         assertEquals(FLAG_PERMISSION_REVIEW_REQUIRED,
119                 getPermissionFlags(APP_PKG, READ_CONTACTS) & FLAG_PERMISSION_REVIEW_REQUIRED);
120     }
121 
122     @Test
clearRegularPermissionPreM()123     public void clearRegularPermissionPreM() {
124         install(APK_CONTACTS_15);
125 
126         int defaultState = getPermissionFlags(APP_PKG, READ_CONTACTS);
127         setPermissionFlags(APP_PKG, READ_CONTACTS, FLAG_PERMISSION_REVIEW_REQUIRED, 0);
128         setPermissionFlags(APP_PKG, READ_CONTACTS,
129                 FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED,
130                 FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED);
131 
132         clearAppState(APP_PKG);
133 
134         eventually(() -> assertEquals(defaultState, getPermissionFlags(APP_PKG, READ_CONTACTS)));
135     }
136 
137     @Test
clearImplicitPermissionPreM()138     public void clearImplicitPermissionPreM() {
139         install(APK_CONTACTS_15);
140 
141         int defaultState = getPermissionFlags(APP_PKG, READ_CALL_LOG);
142         setPermissionFlags(APP_PKG, READ_CALL_LOG, FLAG_PERMISSION_REVIEW_REQUIRED, 0);
143         setPermissionFlags(APP_PKG, READ_CALL_LOG,
144                 FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED,
145                 FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED);
146 
147         clearAppState(APP_PKG);
148 
149         eventually(() -> assertEquals(defaultState, getPermissionFlags(APP_PKG, READ_CALL_LOG)));
150     }
151 
152     @Test
clearRegularPermission()153     public void clearRegularPermission() {
154         install(APK_LOCATION_28);
155 
156         int defaultState = getPermissionFlags(APP_PKG, ACCESS_COARSE_LOCATION);
157         setPermissionFlags(APP_PKG, ACCESS_COARSE_LOCATION,
158                 FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED,
159                 FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED);
160 
161         clearAppState(APP_PKG);
162 
163         eventually(() -> assertEquals(defaultState,
164                 getPermissionFlags(APP_PKG, ACCESS_COARSE_LOCATION)));
165     }
166 
167     @Test
clearImplicitPermission()168     public void clearImplicitPermission() {
169         install(APK_LOCATION_28);
170 
171         int defaultState = getPermissionFlags(APP_PKG, ACCESS_BACKGROUND_LOCATION);
172         setPermissionFlags(APP_PKG, ACCESS_BACKGROUND_LOCATION,
173                 FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED,
174                 FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED);
175 
176         clearAppState(APP_PKG);
177 
178         eventually(() -> assertEquals(defaultState,
179                 getPermissionFlags(APP_PKG, ACCESS_BACKGROUND_LOCATION)));
180     }
181 
182     @Test
reinstallPreM()183     public void reinstallPreM() {
184         install(APK_CONTACTS_15);
185         install(APK_CONTACTS_15);
186 
187         assertEquals(FLAG_PERMISSION_REVIEW_REQUIRED,
188                 getPermissionFlags(APP_PKG, READ_CONTACTS) & FLAG_PERMISSION_REVIEW_REQUIRED);
189     }
190 
191     @Test
reinstallDoesNotOverrideChangesPreM()192     public void reinstallDoesNotOverrideChangesPreM() {
193         install(APK_CONTACTS_15);
194 
195         setPermissionFlags(APP_PKG, READ_CONTACTS, FLAG_PERMISSION_REVIEW_REQUIRED, 0);
196         setPermissionFlags(APP_PKG, READ_CONTACTS,
197                 FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED,
198                 FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED);
199 
200         install(APK_CONTACTS_15);
201 
202         assertEquals(FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED,
203                 getPermissionFlags(APP_PKG, READ_CONTACTS) & (FLAG_PERMISSION_USER_SET
204                         | FLAG_PERMISSION_USER_FIXED | FLAG_PERMISSION_REVIEW_REQUIRED));
205     }
206 
207     @Test
reinstall()208     public void reinstall() {
209         install(APK_LOCATION_28);
210         install(APK_LOCATION_28);
211 
212         assertEquals(0, getPermissionFlags(APP_PKG, ACCESS_COARSE_LOCATION));
213         assertEquals(FLAG_PERMISSION_REVOKE_WHEN_REQUESTED,
214                 getPermissionFlags(APP_PKG, ACCESS_BACKGROUND_LOCATION));
215     }
216 
217     @Test
reinstallDoesNotOverrideChanges()218     public void reinstallDoesNotOverrideChanges() {
219         install(APK_LOCATION_28);
220 
221         setPermissionFlags(APP_PKG, ACCESS_COARSE_LOCATION,
222                 FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED,
223                 FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED);
224         setPermissionFlags(APP_PKG, ACCESS_BACKGROUND_LOCATION,
225                 FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED,
226                 FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED);
227 
228         install(APK_LOCATION_28);
229 
230         assertEquals(FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED,
231                 getPermissionFlags(APP_PKG, ACCESS_COARSE_LOCATION));
232 
233         assertEquals(FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_USER_FIXED
234                         | FLAG_PERMISSION_REVOKE_WHEN_REQUESTED,
235                 getPermissionFlags(APP_PKG, ACCESS_BACKGROUND_LOCATION));
236     }
237 
238     @Test
revokeOnUpgrade()239     public void revokeOnUpgrade() throws Exception {
240         install(APK_LOCATION_22);
241 
242         install(APK_LOCATION_28);
243 
244         assertFalse(isGranted(APP_PKG, ACCESS_COARSE_LOCATION));
245         assertFalse(isGranted(APP_PKG, ACCESS_BACKGROUND_LOCATION));
246         assertEquals(0,getPermissionFlags(APP_PKG, ACCESS_COARSE_LOCATION)
247                 & FLAG_PERMISSION_REVOKED_COMPAT);
248         assertEquals(0,getPermissionFlags(APP_PKG, ACCESS_BACKGROUND_LOCATION)
249                 & FLAG_PERMISSION_REVOKED_COMPAT);
250     }
251 
252     @AsbSecurityTest(cveBugId = 283006437)
253     @Test
nonRuntimePermissionFlagsPreservedAfterReinstall()254     public void nonRuntimePermissionFlagsPreservedAfterReinstall() throws Exception {
255         install(APK_SYSTEM_ALERT_WINDOW_23);
256 
257         int flags = FLAG_PERMISSION_USER_SET | FLAG_PERMISSION_GRANTED_BY_ROLE;
258         setPermissionFlags(APP_SYSTEM_ALERT_WINDOW_PKG, SYSTEM_ALERT_WINDOW, flags, flags);
259         assertEquals(flags, getAllPermissionFlags(APP_SYSTEM_ALERT_WINDOW_PKG, SYSTEM_ALERT_WINDOW)
260                 & flags);
261 
262         install(APK_SYSTEM_ALERT_WINDOW_23);
263 
264         assertEquals(flags, getAllPermissionFlags(APP_SYSTEM_ALERT_WINDOW_PKG, SYSTEM_ALERT_WINDOW)
265                 & flags);
266     }
267 }
268