• 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.permissioncontroller.permissionui.ui.handheld
18 
19 import android.Manifest.permission.ACCESS_COARSE_LOCATION
20 import android.content.Intent
21 import android.content.pm.PackageManager
22 import android.permission.cts.PermissionUtils.grantPermission
23 import android.permission.cts.PermissionUtils.install
24 import android.permission.cts.PermissionUtils.revokePermission
25 import android.permission.cts.PermissionUtils.uninstallApp
26 import android.util.Log
27 import androidx.test.ext.junit.runners.AndroidJUnit4
28 import androidx.test.uiautomator.By
29 import com.android.compatibility.common.util.SystemUtil.eventually
30 import com.android.compatibility.common.util.SystemUtil.getEventually
31 import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity
32 import com.android.compatibility.common.util.UiAutomatorUtils2.waitFindObjectOrNull
33 import com.android.permissioncontroller.permissionui.getUsageCountsFromUi
34 import com.android.permissioncontroller.permissionui.wakeUpScreen
35 import com.google.common.truth.Truth.assertThat
36 import org.junit.After
37 import org.junit.Before
38 import org.junit.Test
39 import org.junit.runner.RunWith
40 
41 /** Simple tests for {@link ManageStandardPermissionsFragment} */
42 @RunWith(AndroidJUnit4::class)
43 class ManageStandardPermissionsFragmentTest : BaseHandheldPermissionUiTest() {
44     @Before
setupnull45     fun setup() {
46         wakeUpScreen()
47 
48         runWithShellPermissionIdentity {
49             removePackageIfInstalled()
50             instrumentationContext.startActivity(
51                 Intent(Intent.ACTION_MANAGE_PERMISSIONS).apply {
52                     addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
53                 }
54             )
55         }
56     }
57 
58     @After
tearDownnull59     fun tearDown() {
60         uninstallApp(LOCATION_USER_PKG)
61         uninstallApp(ADDITIONAL_DEFINER_PKG)
62         uninstallApp(ADDITIONAL_USER_PKG)
63         uiDevice.pressBack()
64     }
65 
66     /**
67      * The test packages are not expected to be installed already, remove them if they are already
68      * installed (i.e. leftover from another test) when a test starts.
69      */
removePackageIfInstallednull70     private fun removePackageIfInstalled() {
71         val packageNames = listOf(LOCATION_USER_PKG, ADDITIONAL_DEFINER_PKG, ADDITIONAL_USER_PKG)
72         for (packageName in packageNames) {
73             try {
74                 val packageInfo =
75                     instrumentationContext.packageManager.getPackageInfo(packageName, 0)
76                 if (packageInfo != null) {
77                     Log.w(LOG_TAG, "package $packageName not expected to be installed.")
78                     uninstallApp(packageName)
79                     Thread.sleep(1000)
80                 }
81             } catch (e: PackageManager.NameNotFoundException) {
82                 // ignore
83             }
84         }
85     }
86 
87     /**
88      * Read the number of additional permissions from the Ui.
89      *
90      * @return number of additional permissions
91      */
getAdditionalPermissionCountnull92     private fun getAdditionalPermissionCount(): Int {
93         waitFindObjectOrNull(By.textContains(ADDITIONAL_PERMISSIONS_LABEL)) ?: return 0
94         // Sometimes the entire preference disappears while it's searching for the app count
95         // (during uninstalling). Hence also return the count as 0 if count doesn't exist
96         val additionalPermissionsSummary =
97             waitFindObjectOrNull(By.textContains(ADDITIONAL_PERMISSIONS_SUMMARY)) ?: return 0
98         val additionalPermissionsSummaryText = additionalPermissionsSummary.getText()
99 
100         // Matches a single number out of the summary line, i.e. "...3..." -> "3"
101         return getEventually {
102             Regex("^[^\\d]*(\\d+)[^\\d]*\$")
103                 .find(additionalPermissionsSummaryText)!!
104                 .groupValues[1]
105                 .toInt()
106         }
107     }
108 
109     @Test
groupSummaryGetsUpdatedWhenAppGetsInstallednull110     fun groupSummaryGetsUpdatedWhenAppGetsInstalled() {
111         val original = getUsageCountsFromUi(LOCATION_GROUP_LABEL)
112 
113         install(LOCATION_USER_APK)
114         eventually(
115             {
116                 val afterInstall = getUsageCountsFromUi(LOCATION_GROUP_LABEL)
117                 assertThat(afterInstall.granted).isEqualTo(original.granted)
118                 assertThat(afterInstall.total).isEqualTo(original.total + 1)
119             },
120             TIMEOUT
121         )
122     }
123 
124     @Test
groupSummaryGetsUpdatedWhenAppGetsUninstallednull125     fun groupSummaryGetsUpdatedWhenAppGetsUninstalled() {
126         val original = getUsageCountsFromUi(LOCATION_GROUP_LABEL)
127         install(LOCATION_USER_APK)
128         eventually(
129             { assertThat(getUsageCountsFromUi(LOCATION_GROUP_LABEL)).isNotEqualTo(original) },
130             TIMEOUT
131         )
132 
133         uninstallApp(LOCATION_USER_PKG)
134         eventually(
135             { assertThat(getUsageCountsFromUi(LOCATION_GROUP_LABEL)).isEqualTo(original) },
136             TIMEOUT
137         )
138     }
139 
140     @Test
groupSummaryGetsUpdatedWhenPermissionGetsGrantednull141     fun groupSummaryGetsUpdatedWhenPermissionGetsGranted() {
142         val original = getUsageCountsFromUi(LOCATION_GROUP_LABEL)
143 
144         install(LOCATION_USER_APK)
145         eventually(
146             {
147                 assertThat(getUsageCountsFromUi(LOCATION_GROUP_LABEL).total)
148                     .isEqualTo(original.total + 1)
149             },
150             TIMEOUT
151         )
152 
153         grantPermission(LOCATION_USER_PKG, ACCESS_COARSE_LOCATION)
154         eventually {
155             assertThat(getUsageCountsFromUi(LOCATION_GROUP_LABEL).granted)
156                 .isEqualTo(original.granted + 1)
157         }
158     }
159 
160     @Test
groupSummaryGetsUpdatedWhenPermissionGetsRevokednull161     fun groupSummaryGetsUpdatedWhenPermissionGetsRevoked() {
162         val original = getUsageCountsFromUi(LOCATION_GROUP_LABEL)
163 
164         install(LOCATION_USER_APK)
165         grantPermission(LOCATION_USER_PKG, ACCESS_COARSE_LOCATION)
166         eventually(
167             {
168                 assertThat(getUsageCountsFromUi(LOCATION_GROUP_LABEL).total)
169                     .isNotEqualTo(original.total)
170                 assertThat(getUsageCountsFromUi(LOCATION_GROUP_LABEL).granted)
171                     .isNotEqualTo(original.granted)
172             },
173             TIMEOUT
174         )
175 
176         revokePermission(LOCATION_USER_PKG, ACCESS_COARSE_LOCATION)
177         eventually {
178             assertThat(getUsageCountsFromUi(LOCATION_GROUP_LABEL).granted)
179                 .isEqualTo(original.granted)
180         }
181     }
182 
183     @Test
additionalPermissionSummaryGetUpdateWhenAppGetsInstallednull184     fun additionalPermissionSummaryGetUpdateWhenAppGetsInstalled() {
185         val additionalPermissionBefore = getAdditionalPermissionCount()
186 
187         install(ADDITIONAL_DEFINER_APK)
188         install(ADDITIONAL_USER_APK)
189         eventually(
190             {
191                 assertThat(getAdditionalPermissionCount()).isEqualTo(additionalPermissionBefore + 1)
192             },
193             TIMEOUT
194         )
195     }
196 
197     @Test
additionalPermissionSummaryGetUpdateWhenUserGetsUninstallednull198     fun additionalPermissionSummaryGetUpdateWhenUserGetsUninstalled() {
199         val additionalPermissionBefore = getAdditionalPermissionCount()
200 
201         install(ADDITIONAL_DEFINER_APK)
202         install(ADDITIONAL_USER_APK)
203         eventually(
204             { assertThat(getAdditionalPermissionCount()).isNotEqualTo(additionalPermissionBefore) },
205             TIMEOUT
206         )
207 
208         uninstallApp(ADDITIONAL_USER_PKG)
209         eventually(
210             { assertThat(getAdditionalPermissionCount()).isEqualTo(additionalPermissionBefore) },
211             TIMEOUT
212         )
213     }
214 
215     @Test
additionalPermissionSummaryGetUpdateWhenDefinerGetsUninstallednull216     fun additionalPermissionSummaryGetUpdateWhenDefinerGetsUninstalled() {
217         val additionalPermissionBefore = getAdditionalPermissionCount()
218 
219         install(ADDITIONAL_DEFINER_APK)
220         install(ADDITIONAL_USER_APK)
221         eventually(
222             { assertThat(getAdditionalPermissionCount()).isNotEqualTo(additionalPermissionBefore) },
223             TIMEOUT
224         )
225 
226         uninstallApp(ADDITIONAL_DEFINER_PKG)
227         eventually(
228             { assertThat(getAdditionalPermissionCount()).isEqualTo(additionalPermissionBefore) },
229             TIMEOUT
230         )
231     }
232 
233     companion object {
234         private val LOG_TAG = ManageStandardPermissionsFragmentTest::class.java.simpleName
235 
236         private const val LOCATION_USER_APK =
237             "/data/local/tmp/pc-permissionui/AppThatRequestsLocation.apk"
238         private const val ADDITIONAL_DEFINER_APK =
239             "/data/local/tmp/pc-permissionui/" + "PermissionUiDefineAdditionalPermissionApp.apk"
240         private const val ADDITIONAL_USER_APK =
241             "/data/local/tmp/pc-permissionui/" + "PermissionUiUseAdditionalPermissionApp.apk"
242         private const val LOCATION_USER_PKG = "android.permission.cts.appthatrequestpermission"
243         private const val ADDITIONAL_DEFINER_PKG =
244             "com.android.permissioncontroller.tests.appthatdefinespermission"
245         private const val ADDITIONAL_USER_PKG =
246             "com.android.permissioncontroller.tests.appthatrequestpermission"
247         private const val ADDITIONAL_PERMISSIONS_LABEL = "Additional permissions"
248         private const val ADDITIONAL_PERMISSIONS_SUMMARY = "more"
249         private const val LOCATION_GROUP_LABEL = "Location"
250 
251         // Package Added/Removed broadcast are pretty slow on cf devices, we may want to increase
252         // this in future if the test still fails.
253         private const val TIMEOUT = 30000L
254     }
255 }
256