• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 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.permission.ui.model.grantPermissions
18 
19 import android.Manifest.permission.ACCESS_COARSE_LOCATION
20 import android.Manifest.permission.ACCESS_FINE_LOCATION
21 import android.os.Build
22 import com.android.permissioncontroller.permission.model.livedatatypes.LightAppPermGroup
23 import com.android.permissioncontroller.permission.ui.model.DenyButton
24 import com.android.permissioncontroller.permission.ui.model.Prompt
25 import com.android.permissioncontroller.permission.utils.KotlinUtils
26 
27 /**
28  * The Location Grant behavior is the same as the Background group behavior, up until S. After S,
29  * the fine and coarse location permissions were allowed to be granted separately, and this created
30  * a new set of grant dialogs.
31  */
32 object LocationGrantBehavior : GrantBehavior() {
getPromptnull33     override fun getPrompt(
34         group: LightAppPermGroup,
35         requestedPerms: Set<String>,
36         isSystemTriggeredPrompt: Boolean
37     ): Prompt {
38         val backgroundPrompt = BackgroundGrantBehavior.getPrompt(group, requestedPerms)
39         val requestsBackground = requestedPerms.any { it in group.backgroundPermNames }
40         val coarseGranted = group.permissions[ACCESS_COARSE_LOCATION]?.isGranted == true
41         return if (!supportsLocationAccuracy(group) || requestsBackground) {
42             backgroundPrompt
43         } else if (requestedPerms.contains(ACCESS_FINE_LOCATION)) {
44             if (coarseGranted) {
45                 Prompt.LOCATION_FINE_UPGRADE
46             } else if (isFineLocationHighlighted(group)) {
47                 Prompt.LOCATION_TWO_BUTTON_FINE_HIGHLIGHT
48             } else {
49                 Prompt.LOCATION_TWO_BUTTON_COARSE_HIGHLIGHT
50             }
51         } else if (requestedPerms.contains(ACCESS_COARSE_LOCATION) && !coarseGranted) {
52             Prompt.LOCATION_COARSE_ONLY
53         } else {
54             backgroundPrompt
55         }
56     }
57 
getDenyButtonnull58     override fun getDenyButton(
59         group: LightAppPermGroup,
60         requestedPerms: Set<String>,
61         prompt: Prompt
62     ): DenyButton {
63         return BackgroundGrantBehavior.getDenyButton(group, requestedPerms, prompt)
64     }
65 
isGroupFullyGrantednull66     override fun isGroupFullyGranted(
67         group: LightAppPermGroup,
68         requestedPerms: Set<String>
69     ): Boolean {
70         val requestsBackground = requestedPerms.any { it in group.backgroundPermNames }
71         if (!supportsLocationAccuracy(group) || requestsBackground) {
72             return BackgroundGrantBehavior.isGroupFullyGranted(group, requestedPerms)
73         }
74         return isForegroundFullyGranted(group, requestedPerms)
75     }
76 
isForegroundFullyGrantednull77     override fun isForegroundFullyGranted(
78         group: LightAppPermGroup,
79         requestedPerms: Set<String>
80     ): Boolean {
81         if (!supportsLocationAccuracy(group)) {
82             return BackgroundGrantBehavior.isForegroundFullyGranted(group, requestedPerms)
83         }
84 
85         if (requestedPerms.contains(ACCESS_FINE_LOCATION)) {
86             return group.permissions[ACCESS_FINE_LOCATION]?.isGranted == true
87         }
88 
89         return group.foreground.allowFullGroupGrant
90     }
91 
isPermissionFixednull92     override fun isPermissionFixed(group: LightAppPermGroup, perm: String): Boolean {
93         if (!supportsLocationAccuracy(group) || perm != ACCESS_COARSE_LOCATION) {
94             return BackgroundGrantBehavior.isPermissionFixed(group, perm)
95         }
96 
97         // If the location group is user fixed but ACCESS_COARSE_LOCATION is not, then
98         // ACCESS_FINE_LOCATION must be user fixed. In this case ACCESS_COARSE_LOCATION
99         // is still grantable.
100         return group.foreground.isUserFixed && group.permissions[perm]?.isUserFixed == true
101     }
102 
supportsLocationAccuracynull103     private fun supportsLocationAccuracy(group: LightAppPermGroup): Boolean {
104         return KotlinUtils.isLocationAccuracyEnabled() &&
105             group.packageInfo.targetSdkVersion >= Build.VERSION_CODES.S
106     }
107 
isFineLocationHighlightednull108     private fun isFineLocationHighlighted(group: LightAppPermGroup): Boolean {
109         // Steps to decide location accuracy default state
110         // 1. If none of the FINE and COARSE isSelectedLocationAccuracy
111         //    flags is set, then use default precision from device config.
112         // 2. Otherwise set to whichever isSelectedLocationAccuracy is true.
113         val coarseLocationPerm = group.allPermissions[ACCESS_COARSE_LOCATION]
114         val fineLocationPerm = group.allPermissions[ACCESS_FINE_LOCATION]
115         return if (
116             coarseLocationPerm?.isSelectedLocationAccuracy == false &&
117                 fineLocationPerm?.isSelectedLocationAccuracy == false
118         ) {
119             // default location precision is true, indicates FINE
120             return true
121         } else {
122             fineLocationPerm?.isSelectedLocationAccuracy == true
123         }
124     }
125 }
126