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 android.permissionui.cts
18 
19 import android.Manifest.permission.ACCESS_BACKGROUND_LOCATION
20 import android.Manifest.permission.ACCESS_COARSE_LOCATION
21 import android.Manifest.permission.ACCESS_FINE_LOCATION
22 import androidx.test.filters.FlakyTest
23 import androidx.test.uiautomator.By
24 import com.android.modules.utils.build.SdkLevel
25 import org.junit.Assume.assumeFalse
26 import org.junit.Assume.assumeTrue
27 import org.junit.Before
28 import org.junit.Test
29 
30 @FlakyTest
31 class LocationAccuracyTest : BaseUsePermissionTest() {
32 
33     companion object {
34         private const val LOCATION_ACCURACY_PRECISE_RADIO_BUTTON =
35             "com.android.permissioncontroller:id/permission_location_accuracy_radio_fine"
36         private const val LOCATION_ACCURACY_COARSE_RADIO_BUTTON =
37             "com.android.permissioncontroller:id/permission_location_accuracy_radio_coarse"
38         private const val LOCATION_ACCURACY_PRECISE_ONLY_VIEW =
39             "com.android.permissioncontroller:id/permission_location_accuracy_fine_only"
40         private const val LOCATION_ACCURACY_COARSE_ONLY_VIEW =
41             "com.android.permissioncontroller:id/permission_location_accuracy_coarse_only"
42     }
43 
44     @Before
setupnull45     fun setup() {
46         assumeTrue("Location Accuracy is only available on S+", SdkLevel.isAtLeastS())
47         assumeFalse(isAutomotive)
48         assumeFalse(isTv)
49         assumeFalse(isWatch)
50     }
51 
52     @Test
testCoarsePermissionIsGrantednull53     fun testCoarsePermissionIsGranted() {
54         installPackage(APP_APK_PATH_31)
55 
56         assertAppHasPermission(ACCESS_FINE_LOCATION, false)
57         assertAppHasPermission(ACCESS_COARSE_LOCATION, false)
58         assertAppHasPermission(ACCESS_BACKGROUND_LOCATION, false)
59 
60         requestAppPermissionsAndAssertResult(
61             ACCESS_FINE_LOCATION to false,
62             ACCESS_COARSE_LOCATION to true
63         ) {
64             clickCoarseLocationRadioButton()
65             clickPreciseLocationRadioButton()
66             clickCoarseLocationRadioButton()
67             clickPermissionRequestAllowForegroundButton()
68         }
69     }
70 
71     @Test
testPrecisePermissionIsGrantednull72     fun testPrecisePermissionIsGranted() {
73         installPackage(APP_APK_PATH_31)
74 
75         assertAppHasPermission(ACCESS_FINE_LOCATION, false)
76         assertAppHasPermission(ACCESS_COARSE_LOCATION, false)
77         assertAppHasPermission(ACCESS_BACKGROUND_LOCATION, false)
78 
79         requestAppPermissionsAndAssertResult(
80             ACCESS_FINE_LOCATION to true,
81             ACCESS_COARSE_LOCATION to true
82         ) {
83             clickPreciseLocationRadioButton()
84             clickCoarseLocationRadioButton()
85             clickPreciseLocationRadioButton()
86             clickPermissionRequestAllowForegroundButton()
87         }
88     }
89 
90     @Test
testPermissionUpgradeFlownull91     fun testPermissionUpgradeFlow() {
92         installPackage(APP_APK_PATH_31)
93 
94         assertAppHasPermission(ACCESS_FINE_LOCATION, false)
95         assertAppHasPermission(ACCESS_COARSE_LOCATION, false)
96         assertAppHasPermission(ACCESS_BACKGROUND_LOCATION, false)
97 
98         requestAppPermissionsAndAssertResult(
99             ACCESS_FINE_LOCATION to false,
100             ACCESS_COARSE_LOCATION to true
101         ) {
102             clickCoarseLocationRadioButton()
103             clickPreciseLocationRadioButton()
104             clickCoarseLocationRadioButton()
105             clickPermissionRequestAllowForegroundButton()
106         }
107 
108         // now request again to change to precise location
109         requestAppPermissionsAndAssertResult(
110             ACCESS_FINE_LOCATION to true,
111             ACCESS_COARSE_LOCATION to true
112         ) {
113             clickPreciseLocationOnlyView()
114             clickPermissionRequestAllowForegroundButton()
115         }
116     }
117 
118     @Test
testCoarseRequestAndGrantnull119     fun testCoarseRequestAndGrant() {
120         installPackage(APP_APK_PATH_31)
121 
122         assertAppHasPermission(ACCESS_FINE_LOCATION, false)
123         assertAppHasPermission(ACCESS_COARSE_LOCATION, false)
124         assertAppHasPermission(ACCESS_BACKGROUND_LOCATION, false)
125 
126         requestAppPermissionsAndAssertResult(ACCESS_COARSE_LOCATION to true) {
127             clickCoarseLocationOnlyView()
128             clickPermissionRequestAllowForegroundButton()
129         }
130 
131         assertAppHasPermission(ACCESS_FINE_LOCATION, false)
132         assertAppHasPermission(ACCESS_BACKGROUND_LOCATION, false)
133     }
134 
135     @Test
testPreSAppsAutograntFineIfCoarseGrantednull136     fun testPreSAppsAutograntFineIfCoarseGranted() {
137         installPackage(APP_APK_PATH_30)
138         assertAppHasPermission(ACCESS_COARSE_LOCATION, false)
139         requestAppPermissionsAndAssertResult(ACCESS_COARSE_LOCATION to true) {
140             clickPermissionRequestAllowForegroundButton()
141         }
142         assertAppHasPermission(ACCESS_FINE_LOCATION, false)
143         requestAppPermissionsAndAssertResult(
144             ACCESS_FINE_LOCATION to true,
145             waitForWindowTransition = false
146         ) {}
147     }
148 
clickPreciseLocationRadioButtonnull149     private fun clickPreciseLocationRadioButton() {
150         click(By.res(LOCATION_ACCURACY_PRECISE_RADIO_BUTTON))
151     }
152 
clickCoarseLocationRadioButtonnull153     private fun clickCoarseLocationRadioButton() {
154         click(By.res(LOCATION_ACCURACY_COARSE_RADIO_BUTTON))
155     }
156 
clickPreciseLocationOnlyViewnull157     private fun clickPreciseLocationOnlyView() {
158         click(By.res(LOCATION_ACCURACY_PRECISE_ONLY_VIEW))
159     }
160 
clickCoarseLocationOnlyViewnull161     private fun clickCoarseLocationOnlyView() {
162         click(By.res(LOCATION_ACCURACY_COARSE_ONLY_VIEW))
163     }
164 }
165