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