• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2024 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.domain.usecase.v31
18 
19 import android.Manifest
20 import android.content.pm.ApplicationInfo
21 import android.content.pm.PackageInfo
22 import android.content.pm.PackageManager
23 import android.os.UserHandle
24 import androidx.annotation.VisibleForTesting
25 import com.android.modules.utils.build.SdkLevel
26 import com.android.permissioncontroller.permission.data.repository.v31.PermissionRepository
27 import com.android.permissioncontroller.permission.utils.PermissionMapping
28 import com.android.permissioncontroller.pm.data.repository.v31.PackageRepository
29 import com.android.permissioncontroller.user.data.repository.v31.UserRepository
30 
31 /** Returns a list of users which can be shown in the Settings surfaces. */
32 suspend fun List<Int>.filterUsersToShowInQuietMode(userRepository: UserRepository): List<Int> {
33     if (!SdkLevel.isAtLeastV()) {
34         return this
35     }
36     val usersQuietModeEnabledMap =
37         this.associateWith { userId -> userRepository.isQuietModeEnabled(userId) }
38     val usersShouldShowInQuietModeMap =
39         this.associateWith { userId -> userRepository.shouldShowInQuietMode(userId) }
40 
41     return filter {
42         val isQuietModeEnabled = checkNotNull(usersQuietModeEnabledMap[it])
43         val shouldShowInQuietMode = checkNotNull(usersShouldShowInQuietModeMap[it])
44         !isQuietModeEnabled || shouldShowInQuietMode
45     }
46 }
47 
48 /**
49  * Determines if an app's permission group is user-sensitive. if the permission group is not user
50  * sensitive then its only shown when user choose `Show system` option
51  */
isPermissionGroupUserSensitivenull52 suspend fun isPermissionGroupUserSensitive(
53     packageName: String,
54     permissionGroup: String,
55     userId: Int,
56     permissionRepository: PermissionRepository,
57     packageRepository: PackageRepository,
58 ): Boolean {
59     if (isTelecomPackage(packageName, permissionGroup)) {
60         return false
61     }
62     val userHandle = UserHandle.of(userId)
63     val packageInfo = packageRepository.getPackageInfo(packageName, userHandle) ?: return false
64     // if not a system app, the permission group must be user sensitive
65     if (packageInfo.applicationFlags and ApplicationInfo.FLAG_SYSTEM == 0) {
66         return true
67     }
68 
69     packageInfo.requestedPermissions.forEachIndexed { index, permissionName ->
70         if (PermissionMapping.getGroupOfPlatformPermission(permissionName) == permissionGroup) {
71             val permFlags =
72                 permissionRepository.getPermissionFlags(permissionName, packageName, userHandle)
73             val packageFlags = packageInfo.requestedPermissionsFlags[index]
74             val isPermissionGranted =
75                 packageFlags and PackageInfo.REQUESTED_PERMISSION_GRANTED != 0 &&
76                     permFlags and PackageManager.FLAG_PERMISSION_REVOKED_COMPAT == 0
77             if (isPermissionUserSensitive(isPermissionGranted, permFlags)) {
78                 return true
79             }
80         }
81     }
82     return false
83 }
84 
isPermissionUserSensitivenull85 private fun isPermissionUserSensitive(isPermissionGranted: Boolean, permissionFlags: Int): Boolean {
86     return if (isPermissionGranted) {
87         permissionFlags and PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED != 0
88     } else {
89         permissionFlags and PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED != 0
90     }
91 }
92 
93 @VisibleForTesting const val TELECOM_PACKAGE = "com.android.server.telecom"
94 
isTelecomPackagenull95 private fun isTelecomPackage(packageName: String, permissionGroup: String): Boolean {
96     return packageName == TELECOM_PACKAGE &&
97         (permissionGroup == Manifest.permission_group.CAMERA ||
98             permissionGroup == Manifest.permission_group.MICROPHONE)
99 }
100 
isLocationByPassEnablednull101 fun isLocationByPassEnabled(): Boolean = SdkLevel.isAtLeastV()
102