• 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.permission.cts.PermissionUtils.grantPermission
22 import android.permission.cts.PermissionUtils.install
23 import android.permission.cts.PermissionUtils.revokePermission
24 import android.permission.cts.PermissionUtils.uninstallApp
25 import androidx.test.uiautomator.By
26 import androidx.test.ext.junit.runners.AndroidJUnit4
27 import com.android.compatibility.common.util.SystemUtil.eventually
28 import com.android.compatibility.common.util.SystemUtil.getEventually
29 import com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity
30 import com.android.compatibility.common.util.UiAutomatorUtils2.waitFindObjectOrNull
31 import com.android.permissioncontroller.permissionui.getUsageCountsFromUi
32 import com.android.permissioncontroller.permissionui.wakeUpScreen
33 import com.google.common.truth.Truth.assertThat
34 import org.junit.After
35 import org.junit.Before
36 import org.junit.Test
37 import org.junit.runner.RunWith
38 
39 /**
40  * Simple tests for {@link ManageStandardPermissionsFragment}
41  */
42 @RunWith(AndroidJUnit4::class)
43 class ManageStandardPermissionsFragmentTest : BaseHandheldPermissionUiTest() {
44     private val LOCATION_USER_APK =
45         "/data/local/tmp/permissioncontroller/tests/permissionui/AppThatRequestsLocation.apk"
46     private val ADDITIONAL_DEFINER_APK =
47         "/data/local/tmp/permissioncontroller/tests/permissionui/" +
48             "PermissionUiDefineAdditionalPermissionApp.apk"
49     private val ADDITIONAL_USER_APK =
50         "/data/local/tmp/permissioncontroller/tests/permissionui/" +
51             "PermissionUiUseAdditionalPermissionApp.apk"
52     private val LOCATION_USER_PKG = "android.permission.cts.appthatrequestpermission"
53     private val ADDITIONAL_DEFINER_PKG =
54         "com.android.permissioncontroller.tests.appthatdefinespermission"
55     private val ADDITIONAL_USER_PKG =
56         "com.android.permissioncontroller.tests.appthatrequestpermission"
57     private val ADDITIONAL_PERMISSIONS_LABEL = "Additional permissions"
58     private val ADDITIONAL_PERMISSIONS_SUMMARY = "more"
59 
60     private val locationGroupLabel = "Location"
61 
62     /**
63      * Read the number of additional permissions from the Ui.
64      *
65      * @return number of additional permissions
66      */
getAdditionalPermissionCountnull67     private fun getAdditionalPermissionCount(): Int {
68         waitFindObjectOrNull(By.textContains(ADDITIONAL_PERMISSIONS_LABEL)) ?: return 0
69         // Sometimes the entire preference disappears while it's searching for the app count
70         // (during uninstalling). Hence also return the count as 0 if count doesn't exist
71         val additionalPermissionsSummary = waitFindObjectOrNull(
72             By.textContains(ADDITIONAL_PERMISSIONS_SUMMARY)) ?: return 0
73         val additionalPermissionsSummaryText = additionalPermissionsSummary.getText()
74 
75         // Matches a single number out of the summary line, i.e. "...3..." -> "3"
76         return getEventually {
77             Regex("^[^\\d]*(\\d+)[^\\d]*\$")
78                 .find(additionalPermissionsSummaryText)!!.groupValues[1]
79                 .toInt()
80         }
81     }
82 
83     @Before
setupnull84     fun setup() {
85         wakeUpScreen()
86 
87         runWithShellPermissionIdentity {
88             instrumentationContext.startActivity(Intent(Intent.ACTION_MANAGE_PERMISSIONS).apply {
89                 addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
90             })
91         }
92 
93         reuninstallApp(LOCATION_USER_APK, LOCATION_USER_PKG)
94 
95         // Sleep before each test for 1 second for getUsageCountsFromUi to get the correct counts
96         Thread.sleep(1000)
97     }
98 
99     @Test
groupSummaryGetsUpdatedWhenAppGetsInstallednull100     fun groupSummaryGetsUpdatedWhenAppGetsInstalled() {
101         val original = getUsageCountsFromUi(locationGroupLabel)
102 
103         install(LOCATION_USER_APK)
104         eventually {
105             val afterInstall = getUsageCountsFromUi(locationGroupLabel)
106             assertThat(afterInstall.granted).isEqualTo(original.granted)
107             assertThat(afterInstall.total).isEqualTo(original.total + 1)
108         }
109     }
110 
111     @Test
groupSummaryGetsUpdatedWhenAppGetsUninstallednull112     fun groupSummaryGetsUpdatedWhenAppGetsUninstalled() {
113         reuninstallApp(LOCATION_USER_APK, LOCATION_USER_PKG)
114         val original = getUsageCountsFromUi(locationGroupLabel)
115 
116         install(LOCATION_USER_APK)
117         eventually {
118             assertThat(getUsageCountsFromUi(locationGroupLabel)).isNotEqualTo(original)
119         }
120 
121         uninstallApp(LOCATION_USER_PKG)
122         reuninstallApp(LOCATION_USER_APK, LOCATION_USER_PKG)
123         eventually {
124             assertThat(getUsageCountsFromUi(locationGroupLabel)).isEqualTo(original)
125         }
126     }
127 
128     @Test
groupSummaryGetsUpdatedWhenPermissionGetsGrantednull129     fun groupSummaryGetsUpdatedWhenPermissionGetsGranted() {
130         val original = getUsageCountsFromUi(locationGroupLabel)
131 
132         install(LOCATION_USER_APK)
133         eventually {
134             assertThat(getUsageCountsFromUi(locationGroupLabel).total)
135                 .isEqualTo(original.total + 1)
136         }
137 
138         grantPermission(LOCATION_USER_PKG, ACCESS_COARSE_LOCATION)
139         eventually {
140             assertThat(getUsageCountsFromUi(locationGroupLabel).granted)
141                 .isEqualTo(original.granted + 1)
142         }
143     }
144 
145     @Test
groupSummaryGetsUpdatedWhenPermissionGetsRevokednull146     fun groupSummaryGetsUpdatedWhenPermissionGetsRevoked() {
147         val original = getUsageCountsFromUi(locationGroupLabel)
148 
149         install(LOCATION_USER_APK)
150         grantPermission(LOCATION_USER_PKG, ACCESS_COARSE_LOCATION)
151         eventually {
152             assertThat(getUsageCountsFromUi(locationGroupLabel).total)
153                 .isNotEqualTo(original.total)
154             assertThat(getUsageCountsFromUi(locationGroupLabel).granted)
155                 .isNotEqualTo(original.granted)
156         }
157 
158         revokePermission(LOCATION_USER_PKG, ACCESS_COARSE_LOCATION)
159         eventually {
160             assertThat(getUsageCountsFromUi(locationGroupLabel).granted)
161                 .isEqualTo(original.granted)
162         }
163     }
164 
165     @Test
additionalPermissionSummaryGetUpdateWhenAppGetsInstallednull166     fun additionalPermissionSummaryGetUpdateWhenAppGetsInstalled() {
167         val additionalPermissionBefore = getAdditionalPermissionCount()
168 
169         install(ADDITIONAL_DEFINER_APK)
170         install(ADDITIONAL_USER_APK)
171         eventually {
172             assertThat(getAdditionalPermissionCount())
173                 .isEqualTo(additionalPermissionBefore + 1)
174         }
175     }
176 
177     @Test
additionalPermissionSummaryGetUpdateWhenUserGetsUninstallednull178     fun additionalPermissionSummaryGetUpdateWhenUserGetsUninstalled() {
179         val additionalPermissionBefore = getAdditionalPermissionCount()
180 
181         install(ADDITIONAL_DEFINER_APK)
182         install(ADDITIONAL_USER_APK)
183         eventually {
184             assertThat(getAdditionalPermissionCount())
185                 .isNotEqualTo(additionalPermissionBefore)
186         }
187 
188         uninstallApp(ADDITIONAL_USER_PKG)
189         eventually {
190             assertThat(getAdditionalPermissionCount()).isEqualTo(additionalPermissionBefore)
191         }
192     }
193 
194     @Test
additionalPermissionSummaryGetUpdateWhenDefinerGetsUninstallednull195     fun additionalPermissionSummaryGetUpdateWhenDefinerGetsUninstalled() {
196         val additionalPermissionBefore = getAdditionalPermissionCount()
197 
198         install(ADDITIONAL_DEFINER_APK)
199         install(ADDITIONAL_USER_APK)
200         eventually {
201             assertThat(getAdditionalPermissionCount())
202                 .isNotEqualTo(additionalPermissionBefore)
203         }
204 
205         uninstallApp(ADDITIONAL_DEFINER_PKG)
206         eventually {
207             assertThat(getAdditionalPermissionCount()).isEqualTo(additionalPermissionBefore)
208         }
209     }
210 
reuninstallAppnull211     fun reuninstallApp(apk: String, pkg: String) {
212         // b/275752754: sometimes this test is flaky because inside @After it didn't uninstall the
213         // packages correctly. This caused the permission manager screen to still show the package
214         // as requesting the permission and caused the original usage count to be incorrect.
215         // Installing/uninstalling the packages again to ensure the package is correctly uninstalled
216         install(apk)
217         uninstallApp(pkg)
218     }
219 
220     @After
tearDownnull221     fun tearDown() {
222         uninstallApp(LOCATION_USER_PKG)
223         uninstallApp(ADDITIONAL_DEFINER_PKG)
224         uninstallApp(ADDITIONAL_USER_PKG)
225 
226         uiDevice.pressBack()
227     }
228 }
229