diff options
Diffstat (limited to 'PermissionController/src/com/android/permissioncontroller/permission/data/AppPermGroupUiInfoLiveData.kt')
-rw-r--r-- | PermissionController/src/com/android/permissioncontroller/permission/data/AppPermGroupUiInfoLiveData.kt | 224 |
1 files changed, 126 insertions, 98 deletions
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/data/AppPermGroupUiInfoLiveData.kt b/PermissionController/src/com/android/permissioncontroller/permission/data/AppPermGroupUiInfoLiveData.kt index 7c69d6078..b17098a13 100644 --- a/PermissionController/src/com/android/permissioncontroller/permission/data/AppPermGroupUiInfoLiveData.kt +++ b/PermissionController/src/com/android/permissioncontroller/permission/data/AppPermGroupUiInfoLiveData.kt @@ -32,17 +32,17 @@ import com.android.permissioncontroller.permission.model.livedatatypes.LightPack import com.android.permissioncontroller.permission.model.livedatatypes.LightPermGroupInfo import com.android.permissioncontroller.permission.model.livedatatypes.LightPermInfo import com.android.permissioncontroller.permission.model.livedatatypes.PermState -import com.android.permissioncontroller.permission.utils.PermissionMapping.isPlatformPermissionGroup import com.android.permissioncontroller.permission.utils.LocationUtils +import com.android.permissioncontroller.permission.utils.PermissionMapping.isPlatformPermissionGroup import com.android.permissioncontroller.permission.utils.Utils import kotlinx.coroutines.Job /** * A LiveData representing UI properties of an App Permission Group: * <ul> - * <li>shouldShow</li> - * <li>isSystem</li> - * <li>isGranted</li> + * <li>shouldShow</li> + * <li>isSystem</li> + * <li>isGranted</li> * </ul> * * @param app The current application @@ -50,7 +50,8 @@ import kotlinx.coroutines.Job * @param permGroupName The name of the permission group whose permissions are observed * @param user The user of the package */ -class AppPermGroupUiInfoLiveData private constructor( +class AppPermGroupUiInfoLiveData +private constructor( private val app: Application, private val packageName: String, private val permGroupName: String, @@ -65,21 +66,19 @@ class AppPermGroupUiInfoLiveData private constructor( private val isHealth = Utils.isHealthPermissionGroup(permGroupName) init { - isSpecialLocation = LocationUtils.isLocationGroupAndProvider(app, - permGroupName, packageName) || - LocationUtils.isLocationGroupAndControllerExtraPackage(app, permGroupName, packageName) + isSpecialLocation = + LocationUtils.isLocationGroupAndProvider(app, permGroupName, packageName) || + LocationUtils.isLocationGroupAndControllerExtraPackage( + app, + permGroupName, + packageName + ) - addSource(packageInfoLiveData) { - update() - } + addSource(packageInfoLiveData) { update() } - addSource(permGroupLiveData) { - update() - } + addSource(permGroupLiveData) { update() } - addSource(permissionStateLiveData) { - update() - } + addSource(permissionStateLiveData) { update() } } override suspend fun loadDataAndPostValue(job: Job) { @@ -91,27 +90,36 @@ class AppPermGroupUiInfoLiveData private constructor( val permissionState = permissionStateLiveData.value if (packageInfo == null || permissionGroup == null || permissionState == null) { - if (packageInfoLiveData.isInitialized && permGroupLiveData.isInitialized && - permissionStateLiveData.isInitialized) { + if ( + packageInfoLiveData.isInitialized && + permGroupLiveData.isInitialized && + permissionStateLiveData.isInitialized + ) { invalidateSingle(Triple(packageName, permGroupName, user)) postValue(null) } return } - postValue(getAppPermGroupUiInfo(packageInfo, permissionGroup.groupInfo, - permissionGroup.permissionInfos, permissionState)) + postValue( + getAppPermGroupUiInfo( + packageInfo, + permissionGroup.groupInfo, + permissionGroup.permissionInfos, + permissionState + ) + ) } /** - * Determines if the UI should show a given package, if that package is a system app, and - * if it has granted permissions in this LiveData's permission group. + * Determines if the UI should show a given package, if that package is a system app, and if it + * has granted permissions in this LiveData's permission group. * * @param packageInfo The PackageInfo of the package we wish to examine * @param groupInfo The groupInfo of the permission group we wish to examine * @param allPermInfos All of the PermissionInfos in the permission group - * @param permissionState The flags and grant state for all permissions in the permission - * group that this package requests + * @param permissionState The flags and grant state for all permissions in the permission group + * that this package requests */ private fun getAppPermGroupUiInfo( packageInfo: LightPackageInfo, @@ -126,10 +134,11 @@ class AppPermGroupUiInfoLiveData private constructor( val requestedPermissionInfos = allPermInfos.filter { permissionState.containsKey(it.key) }.values - val shouldShow = packageInfo.enabled && - isGrantableAndNotLegacyPlatform(packageInfo, groupInfo, requestedPermissionInfos) && - (!isStorage || Utils.shouldShowStorage(packageInfo)) && - (!isHealth || Utils.shouldShowHealthPermission(packageInfo, groupInfo.name)) + val shouldShow = + packageInfo.enabled && + isGrantableAndNotLegacyPlatform(packageInfo, groupInfo, requestedPermissionInfos) && + (!isStorage || Utils.shouldShowStorage(packageInfo)) && + (!isHealth || Utils.shouldShowHealthPermission(packageInfo, groupInfo.name)) val isSystemApp = !isUserSensitive(permissionState) @@ -147,19 +156,17 @@ class AppPermGroupUiInfoLiveData private constructor( * * @param packageInfo The PackageInfo of the package we are examining * @param groupInfo The Permission Group Info of the permission group we are examining - * @param permissionInfos The LightPermInfos corresponding to the permissions in the - * permission group that this package requests - * + * @param permissionInfos The LightPermInfos corresponding to the permissions in the permission + * group that this package requests * @return True if the app permission group is grantable, and is not a legacy system permission, - * false otherwise. + * false otherwise. */ private fun isGrantableAndNotLegacyPlatform( packageInfo: LightPackageInfo, groupInfo: LightPermGroupInfo, permissionInfos: Collection<LightPermInfo> ): Boolean { - if (groupInfo.packageName == Utils.OS_PKG && - !isPlatformPermissionGroup(groupInfo.name)) { + if (groupInfo.packageName == Utils.OS_PKG && !isPlatformPermissionGroup(groupInfo.name)) { return false } @@ -167,8 +174,9 @@ class AppPermGroupUiInfoLiveData private constructor( var hasPreRuntime = false for (permissionInfo in permissionInfos) { - if (permissionInfo.protectionFlags and - PermissionInfo.PROTECTION_FLAG_RUNTIME_ONLY == 0) { + if ( + permissionInfo.protectionFlags and PermissionInfo.PROTECTION_FLAG_RUNTIME_ONLY == 0 + ) { hasPreRuntime = true } @@ -177,8 +185,9 @@ class AppPermGroupUiInfoLiveData private constructor( } } - val isGrantingAllowed = (!packageInfo.isInstantApp || hasInstantPerm) && - (packageInfo.targetSdkVersion >= Build.VERSION_CODES.M || hasPreRuntime) + val isGrantingAllowed = + (!packageInfo.isInstantApp || hasInstantPerm) && + (packageInfo.targetSdkVersion >= Build.VERSION_CODES.M || hasPreRuntime) if (!isGrantingAllowed) { return false } @@ -191,10 +200,9 @@ class AppPermGroupUiInfoLiveData private constructor( * then it is considered a system app, and hidden in the UI by default. * * @param permissionState The permission flags and grant state corresponding to the permissions - * in this group requested by a given app - * + * in this group requested by a given app * @return Whether or not this package requests a user sensitive permission in the given - * permission group + * permission group */ private fun isUserSensitive(permissionState: Map<String, PermState>): Boolean { if (!isPlatformPermissionGroup(permGroupName)) { @@ -204,10 +212,12 @@ class AppPermGroupUiInfoLiveData private constructor( for (permissionName in permissionState.keys) { val flags = permissionState[permissionName]?.permFlags ?: return true val granted = permissionState[permissionName]?.granted ?: return true - if ((granted && + if ( + (granted && flags and PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED != 0) || - (!granted && - flags and PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED != 0)) { + (!granted && + flags and PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED != 0) + ) { return true } } @@ -218,32 +228,30 @@ class AppPermGroupUiInfoLiveData private constructor( * Determines if the app permission group is user set * * @param permissionState The permission flags and grant state corresponding to the permissions - * in this group requested by a given app - * + * in this group requested by a given app * @return Whether or not any of the permissions in this group have been set or fixed by the - * user + * user */ private fun isUserSet(permissionState: Map<String, PermState>): Boolean { - val flagMask = PackageManager.FLAG_PERMISSION_USER_SET or - PackageManager.FLAG_PERMISSION_USER_FIXED + val flagMask = + PackageManager.FLAG_PERMISSION_USER_SET or PackageManager.FLAG_PERMISSION_USER_FIXED return permissionState.any { (it.value.permFlags and flagMask) != 0 } } /** - * Determines if this app permission group is granted, granted in foreground only, or denied. - * It is granted if it either requests no background permissions, and has at least one requested - * permission that is granted, or has granted at least one requested background permission. - * It is granted in foreground only if it has at least one non-background permission granted, - * and has denied all requested background permissions. It is denied if all requested - * permissions are denied. + * Determines if this app permission group is granted, granted in foreground only, or denied. It + * is granted if it either requests no background permissions, and has at least one requested + * permission that is granted, or has granted at least one requested background permission. It + * is granted in foreground only if it has at least one non-background permission granted, and + * has denied all requested background permissions. It is denied if all requested permissions + * are denied. * * @param permissionState The permission flags and grant state corresponding to the permissions - * in this group requested by a given app - * @param allPermInfos All of the permissionInfos in the permission group of this app - * permission group - * + * in this group requested by a given app + * @param allPermInfos All of the permissionInfos in the permission group of this app permission + * group * @return The int code corresponding to the app permission group state, either allowed, allowed - * in foreground only, or denied. + * in foreground only, or denied. */ private fun getGrantedIncludingBackground( permissionState: Map<String, PermState>, @@ -262,36 +270,46 @@ class AppPermGroupUiInfoLiveData private constructor( val permInfo = allPermInfos[permName] ?: continue permInfo.backgroundPermission?.let { backgroundPerm -> hasPermWithBackground = true - if (permissionState[backgroundPerm]?.granted == true && + if ( + permissionState[backgroundPerm]?.granted == true && (permissionState[backgroundPerm]!!.permFlags and - PackageManager.FLAG_PERMISSION_ONE_TIME == 0) && - specialLocationState != false) { + PackageManager.FLAG_PERMISSION_ONE_TIME == 0) && + specialLocationState != false + ) { return PermGrantState.PERMS_ALLOWED_ALWAYS } } - isUserFixed = isUserFixed || + isUserFixed = + isUserFixed || permState.permFlags and PackageManager.FLAG_PERMISSION_USER_FIXED != 0 } // isOneTime indicates whether all granted permissions in permission states are one-time // permissions - val isOneTime = permissionState.any { - it.value.permFlags and PackageManager.FLAG_PERMISSION_ONE_TIME != 0 } && + val isOneTime = + permissionState.any { + it.value.permFlags and PackageManager.FLAG_PERMISSION_ONE_TIME != 0 + } && !permissionState.any { it.value.permFlags and PackageManager.FLAG_PERMISSION_ONE_TIME == 0 && - it.value.granted } + it.value.granted + } val supportsRuntime = pkg.targetSdkVersion >= Build.VERSION_CODES.M - val anyAllowed = specialLocationState ?: permissionState.any { (_, state) -> - state.granted || (supportsRuntime && - (state.permFlags and PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) - } + val anyAllowed = + specialLocationState + ?: permissionState.any { (_, state) -> + state.granted || + (supportsRuntime && + (state.permFlags and PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != + 0) + } val onlySelectedPhotosGranted = permissionState.containsKey(READ_MEDIA_VISUAL_USER_SELECTED) && - permissionState.all { (permName, state) -> - (permName == READ_MEDIA_VISUAL_USER_SELECTED && state.granted) || - (permName != READ_MEDIA_VISUAL_USER_SELECTED && !state.granted) - } + permissionState.all { (permName, state) -> + (permName == READ_MEDIA_VISUAL_USER_SELECTED && state.granted) || + (permName != READ_MEDIA_VISUAL_USER_SELECTED && !state.granted) + } if (anyAllowed && (hasPermWithBackground || shouldShowAsForegroundGroup())) { return if (isOneTime) { PermGrantState.PERMS_ASK @@ -325,32 +343,38 @@ class AppPermGroupUiInfoLiveData private constructor( } // The permission of the extra location controller package is determined by the // status of the controller package itself. - if (LocationUtils.isLocationGroupAndControllerExtraPackage(userContext, - permGroupName, packageName)) { + if ( + LocationUtils.isLocationGroupAndControllerExtraPackage( + userContext, + permGroupName, + packageName + ) + ) { return LocationUtils.isExtraLocationControllerPackageEnabled(userContext) } return null } private fun isFullFilesAccessGranted(pkg: LightPackageInfo): Boolean { - val packageState = if (!FullStoragePermissionAppsLiveData.isStale) { - val fullStoragePackages = FullStoragePermissionAppsLiveData.value ?: return false - fullStoragePackages.find { - it.packageName == packageName && it.user == user - } ?: return false - } else { - val appOpsManager = Utils.getUserContext(app, UserHandle.getUserHandleForUid(pkg.uid)) - .getSystemService(AppOpsManager::class.java)!! - FullStoragePermissionAppsLiveData.getFullStorageStateForPackage( - appOpsManager, pkg) ?: return false - } + val packageState = + if (!FullStoragePermissionAppsLiveData.isStale) { + val fullStoragePackages = FullStoragePermissionAppsLiveData.value ?: return false + fullStoragePackages.find { it.packageName == packageName && it.user == user } + ?: return false + } else { + val appOpsManager = + Utils.getUserContext(app, UserHandle.getUserHandleForUid(pkg.uid)) + .getSystemService(AppOpsManager::class.java)!! + FullStoragePermissionAppsLiveData.getFullStorageStateForPackage(appOpsManager, pkg) + ?: return false + } return !packageState.isLegacy && packageState.isGranted } // TODO moltmann-team: Actually change mic/camera to be a foreground only permission private fun shouldShowAsForegroundGroup(): Boolean { return permGroupName.equals(Manifest.permission_group.CAMERA) || - permGroupName.equals(Manifest.permission_group.MICROPHONE) + permGroupName.equals(Manifest.permission_group.MICROPHONE) } override fun onLocationStateChange(enabled: Boolean) { @@ -375,15 +399,19 @@ class AppPermGroupUiInfoLiveData private constructor( /** * Repository for AppPermGroupUiInfoLiveDatas. - * <p> Key value is a triple of string package name, string permission group name, and UserHandle, - * value is its corresponding LiveData. + * + * <p> Key value is a triple of string package name, string permission group name, and + * UserHandle, value is its corresponding LiveData. */ - companion object : DataRepositoryForPackage<Triple<String, String, UserHandle>, - AppPermGroupUiInfoLiveData>() { - override fun newValue(key: Triple<String, String, UserHandle>): - AppPermGroupUiInfoLiveData { - return AppPermGroupUiInfoLiveData(PermissionControllerApplication.get(), - key.first, key.second, key.third) + companion object : + DataRepositoryForPackage<Triple<String, String, UserHandle>, AppPermGroupUiInfoLiveData>() { + override fun newValue(key: Triple<String, String, UserHandle>): AppPermGroupUiInfoLiveData { + return AppPermGroupUiInfoLiveData( + PermissionControllerApplication.get(), + key.first, + key.second, + key.third + ) } } } |