Loading src/com/android/permissioncontroller/permission/data/AppPermGroupLiveData.kt +52 −1 Original line number Diff line number Diff line Loading @@ -17,10 +17,14 @@ package com.android.permissioncontroller.permission.data import android.app.Application import android.content.pm.PackageManager import android.content.pm.PermissionInfo import android.os.Build import android.os.UserHandle import android.permission.PermissionManager import android.util.Log import com.android.permissioncontroller.permission.model.livedatatypes.LightAppPermGroup import com.android.permissioncontroller.permission.model.livedatatypes.LightPackageInfo import com.android.permissioncontroller.permission.model.livedatatypes.LightPermission import com.android.permissioncontroller.permission.utils.LocationUtils import com.android.permissioncontroller.permission.utils.SoftRestrictedPermissionPolicy Loading @@ -42,6 +46,8 @@ class AppPermGroupLiveData( private val user: UserHandle ) : SmartUpdateMediatorLiveData<LightAppPermGroup>() { val LOG_TAG = this::class.java.simpleName private val permStateLiveData = PermStateRepository.getPermStateLiveData(app, packageName, permGroupName, user) private val permGroupLiveData = PermGroupRepository.getPermGroupLiveData(app, permGroupName) Loading Loading @@ -125,7 +131,52 @@ class AppPermGroupLiveData( specialLocationGrant = LocationUtils.isExtraLocationControllerPackageEnabled( userContext) } val hasInstallToRuntimeSplit = hasInstallToRuntimeSplit(packageInfo, permissionMap) value = LightAppPermGroup(packageInfo, permGroup.groupInfo, permissionMap, specialLocationGrant) hasInstallToRuntimeSplit, specialLocationGrant) } /** * Check if permission group contains a runtime permission that split from an installed * permission and the split happened in an Android version higher than app's targetSdk. * * @return `true` if there is such permission, `false` otherwise */ private fun hasInstallToRuntimeSplit( packageInfo: LightPackageInfo, permissionMap: Map<String, LightPermission> ): Boolean { val permissionManager = app.getSystemService(PermissionManager::class.java) ?: return false for (spi in permissionManager.splitPermissions) { val splitPerm = spi.splitPermission val pi = try { app.packageManager.getPermissionInfo(splitPerm, 0) } catch (e: PackageManager.NameNotFoundException) { Log.w(LOG_TAG, "No such permission: $splitPerm", e) continue } // Skip if split permission is not "install" permission. if (pi.protection != PermissionInfo.PROTECTION_NORMAL) { continue } val newPerms = spi.newPermissions for (permName in newPerms) { val newPerm = permissionMap[permName]?.permInfo ?: continue // Skip if new permission is not "runtime" permission. if (newPerm.protection != PermissionInfo.PROTECTION_DANGEROUS) { continue } if (packageInfo.targetSdkVersion < spi.targetSdk) { return true } } } return false } } No newline at end of file src/com/android/permissioncontroller/permission/model/livedatatypes/LightAppPermGroup.kt +23 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.permissioncontroller.permission.model.livedatatypes import android.os.Build import android.os.UserHandle /** Loading @@ -25,6 +26,8 @@ import android.os.UserHandle * @param packageInfo Information about the package * @param permGroupInfo Information about the permission group * @param permissions The permissions in the permission group that the package requests * @param hasInstallToRuntimeSplit If this group contains a permission that was previously an * install permission, but is currently a runtime permission * @param specialLocationGrant If this package is the location provider, or the extra location * package, then the grant state of the group is not determined by the grant state of individual * permissions, but by other system properties Loading @@ -33,10 +36,11 @@ data class LightAppPermGroup( val packageInfo: LightPackageInfo, val permGroupInfo: LightPermGroupInfo, val permissions: Map<String, LightPermission>, val hasInstallToRuntimeSplit: Boolean, val specialLocationGrant: Boolean? ) { constructor(pI: LightPackageInfo, pGI: LightPermGroupInfo, perms: Map<String, LightPermission>): this(pI, pGI, perms, null) this(pI, pGI, perms, false, null) /** * The current userHandle of this AppPermGroup. */ Loading @@ -48,6 +52,14 @@ data class LightAppPermGroup( */ val backgroundPermNames = permissions.mapNotNull { it.value.backgroundPermission } /** * The names of all foreground permissions in the permission group which are requested by the * package. */ val foregroundPermNames = permissions.mapNotNull { if (!backgroundPermNames.contains(it.key)) it.key else null } /** * Whether or not this App Permission Group has a permission which has a background mode */ Loading Loading @@ -106,6 +118,16 @@ data class LightAppPermGroup( backgroundPermNames.contains(it.key) && it.value.isGrantedIncludingAppOp } val isForegroundGrantedByDefault = permissions.any { !backgroundPermNames.contains(it.key) && it.value.isGrantedByDefault } val isBackgroundGrantedByDefault = permissions.any { backgroundPermNames.contains(it.key) && it.value.isGrantedByDefault } val supportsRuntimePerms = packageInfo.targetSdkVersion >= Build.VERSION_CODES.M /** * Whether this App Permission Group's permissions are fixed by the user */ Loading src/com/android/permissioncontroller/permission/model/livedatatypes/LightPermission.kt +2 −0 Original line number Diff line number Diff line Loading @@ -64,4 +64,6 @@ data class LightPermission( /** Whether this permission is a runtime only permission */ val isRuntimeOnly = permInfo.protectionFlags and PermissionInfo.PROTECTION_FLAG_RUNTIME_ONLY != 0 /** Whether this permission is granted by default */ val isGrantedByDefault = flags and PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT != 0 } No newline at end of file src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionViewModel.kt +67 −89 Original line number Diff line number Diff line Loading @@ -35,7 +35,6 @@ import com.android.permissioncontroller.PermissionControllerStatsLog.APP_PERMISS import com.android.permissioncontroller.R import com.android.permissioncontroller.permission.data.AppPermGroupLiveData import com.android.permissioncontroller.permission.data.SmartUpdateMediatorLiveData import com.android.permissioncontroller.permission.model.AppPermissionGroup import com.android.permissioncontroller.permission.model.livedatatypes.LightAppPermGroup import com.android.permissioncontroller.permission.utils.KotlinUtils import com.android.permissioncontroller.permission.utils.LocationUtils Loading Loading @@ -101,7 +100,6 @@ class AppPermissionViewModel( } private var hasConfirmedRevoke = false private var appPermissionGroup: AppPermissionGroup? = null private var lightAppPermGroup: LightAppPermGroup? = null /** Loading Loading @@ -147,13 +145,6 @@ class AppPermissionViewModel( } override fun update() { appPermissionGroup = AppPermissionGroup.create(app, packageName, permGroupName, user, false) if (appPermissionGroup == null) { value = null return } val group = appPermGroupLiveData.value ?: return val admin = RestrictedLockUtils.getProfileOrDeviceOwner(app, user) Loading Loading @@ -237,8 +228,6 @@ class AppPermissionViewModel( override fun onActive() { super.onActive() appPermissionGroup = AppPermissionGroup.create(app, packageName, permGroupName, user, false) } } Loading Loading @@ -365,12 +354,11 @@ class AppPermissionViewModel( changeTarget: ChangeTarget ) { val context = fragment.context ?: return val group = appPermissionGroup ?: return val group = lightAppPermGroup ?: return val wasForegroundGranted = group.isForegroundGranted val wasBackgroundGranted = group.isBackgroundGranted group.isOneTime = false if (LocationUtils.isLocationGroupAndProvider(context, group.name, group.app.packageName)) { if (LocationUtils.isLocationGroupAndProvider(context, permGroupName, packageName)) { val packageLabel = KotlinUtils.getPackageLabel(app, packageName, user) LocationUtils.showLocationDialog(context, packageLabel) } Loading @@ -381,20 +369,17 @@ class AppPermissionViewModel( if (requestGrant) { val stateBefore = createPermissionSnapshot()!! if (shouldChangeForeground) { val runtimePermissionsGranted = group.areRuntimePermissionsGranted() group.grantRuntimePermissions(userFixed) val newGroup = KotlinUtils.grantForegroundRuntimePermissions(app, group) if (!runtimePermissionsGranted) { SafetyNetLogger.logPermissionToggled(group) if (!wasForegroundGranted) { SafetyNetLogger.logPermissionToggled(newGroup) } } if (shouldChangeBackground && group.backgroundPermissions != null) { val runtimePermissionsGranted = group.backgroundPermissions.areRuntimePermissionsGranted() group.backgroundPermissions.grantRuntimePermissions(userFixed) if (shouldChangeBackground && group.hasBackgroundPerms) { val newGroup = KotlinUtils.grantBackgroundRuntimePermissions(app, group) if (!runtimePermissionsGranted) { SafetyNetLogger.logPermissionToggled(group.backgroundPermissions) if (!wasBackgroundGranted) { SafetyNetLogger.logPermissionToggled(newGroup, true) } } logPermissionChanges(stateBefore) Loading @@ -402,24 +387,21 @@ class AppPermissionViewModel( var showDefaultDenyDialog = false var showGrantedByDefaultWarning = false if (shouldChangeForeground && group.areRuntimePermissionsGranted()) { showDefaultDenyDialog = (group.hasGrantedByDefaultPermission() || !group.doesSupportRuntimePermissions() || group.hasInstallToRuntimeSplit()) if (shouldChangeForeground && wasForegroundGranted) { showDefaultDenyDialog = (group.isForegroundGrantedByDefault || !group.supportsRuntimePerms || group.hasInstallToRuntimeSplit) showGrantedByDefaultWarning = showGrantedByDefaultWarning || group.hasGrantedByDefaultPermission() group.isForegroundGrantedByDefault } if (shouldChangeBackground && group.backgroundPermissions != null && group.backgroundPermissions.areRuntimePermissionsGranted()) { val bgGroup = group.backgroundPermissions if (shouldChangeBackground && wasBackgroundGranted) { showDefaultDenyDialog = showDefaultDenyDialog || bgGroup.hasGrantedByDefaultPermission() || !bgGroup.doesSupportRuntimePermissions() || bgGroup.hasInstallToRuntimeSplit() group.isBackgroundGrantedByDefault || !group.supportsRuntimePerms || group.hasInstallToRuntimeSplit showGrantedByDefaultWarning = showGrantedByDefaultWarning || bgGroup.hasGrantedByDefaultPermission() group.isBackgroundGrantedByDefault } if (showDefaultDenyDialog && !hasConfirmedRevoke && showGrantedByDefaultWarning) { Loading @@ -432,28 +414,25 @@ class AppPermissionViewModel( } else { val stateBefore = createPermissionSnapshot()!! if (shouldChangeForeground && group.areRuntimePermissionsGranted()) { group.revokeRuntimePermissions(userFixed) SafetyNetLogger.logPermissionToggled(group) } if (shouldChangeBackground && group.backgroundPermissions != null && group.backgroundPermissions.areRuntimePermissionsGranted()) { group.backgroundPermissions.revokeRuntimePermissions(userFixed) (wasForegroundGranted || userFixed != group.isUserFixed)) { val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group, userFixed) SafetyNetLogger.logPermissionToggled(group.backgroundPermissions) // only log if we have actually denied permissions, not if we switch from // "ask every time" to denied if (wasForegroundGranted) { SafetyNetLogger.logPermissionToggled(newGroup) } if (userFixed && !group.isUserFixed) { group.revokeRuntimePermissions(true) if (group.backgroundPermissions != null) { group.backgroundPermissions.revokeRuntimePermissions(true) } } if (!userFixed && group.isUserFixed) { group.revokeRuntimePermissions(false) if (group.backgroundPermissions != null) { group.backgroundPermissions.revokeRuntimePermissions(false) if (shouldChangeBackground && group.hasBackgroundPerms && (wasBackgroundGranted || userFixed != group.isUserFixed)) { val newGroup = KotlinUtils.revokeBackgroundRuntimePermissions(app, group, userFixed) // only log if we have actually denied permissions, not if we switch from // "ask every time" to denied if (wasBackgroundGranted) { SafetyNetLogger.logPermissionToggled(newGroup, true) } } logPermissionChanges(stateBefore) Loading @@ -461,51 +440,41 @@ class AppPermissionViewModel( } } /** * Show the All App Permissions screen with the proper filter group, package name, and user. * * @param fragment The current fragment we wish to transition from */ fun showAllPermissions(fragment: AppPermissionFragment) { val args = AllAppPermissionsFragment.createArgs(packageName, permGroupName, user) fragment.findNavController().navigate(R.id.app_to_all_perms, args) } /** * Once the user has confirmed that he/she wants to revoke a permission that was granted by * default, actually revoke the permissions. * * @param changeTarget whether to change foreground, background, or both. * @param userFixed whether the user has stated they do not wish to be prompted about the * permission any more. * */ fun onDenyAnyWay(changeTarget: ChangeTarget, userFixed: Boolean) { val group = appPermissionGroup ?: return val group = lightAppPermGroup ?: return val wasForegroundGranted = group.isForegroundGranted val wasBackgroundGranted = group.isBackgroundGranted var hasDefaultPermissions = false val stateBefore = createPermissionSnapshot() if (changeTarget andValue ChangeTarget.CHANGE_FOREGROUND != 0) { val runtimePermissionsGranted = group.areRuntimePermissionsGranted() group.revokeRuntimePermissions(userFixed) if (runtimePermissionsGranted) { SafetyNetLogger.logPermissionToggled(group) if (changeTarget andValue ChangeTarget.CHANGE_FOREGROUND != 0) { val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group, userFixed) if (wasForegroundGranted) { SafetyNetLogger.logPermissionToggled(newGroup) } hasDefaultPermissions = group.hasGrantedByDefaultPermission() hasDefaultPermissions = group.isForegroundGrantedByDefault } if (changeTarget andValue ChangeTarget.CHANGE_BACKGROUND != 0 && group.backgroundPermissions != null) { val runtimePermissionsGranted = group.backgroundPermissions.areRuntimePermissionsGranted() group.backgroundPermissions.revokeRuntimePermissions(userFixed) if (changeTarget andValue ChangeTarget.CHANGE_BACKGROUND != 0 && group.hasBackgroundPerms) { val newGroup = KotlinUtils.revokeBackgroundRuntimePermissions(app, group, userFixed) if (runtimePermissionsGranted) { SafetyNetLogger.logPermissionToggled(group.backgroundPermissions) if (wasBackgroundGranted) { SafetyNetLogger.logPermissionToggled(newGroup) } hasDefaultPermissions = hasDefaultPermissions || group.backgroundPermissions.hasGrantedByDefaultPermission() group.isBackgroundGrantedByDefault } logPermissionChanges(stateBefore!!) if (hasDefaultPermissions || !group.doesSupportRuntimePermissions()) { if (hasDefaultPermissions || !group.supportsRuntimePerms) { hasConfirmedRevoke = true } } Loading @@ -521,6 +490,16 @@ class AppPermissionViewModel( return permissionSnapshot } /** * Show the All App Permissions screen with the proper filter group, package name, and user. * * @param fragment The current fragment we wish to transition from */ fun showAllPermissions(fragment: AppPermissionFragment) { val args = AllAppPermissionsFragment.createArgs(packageName, permGroupName, user) fragment.findNavController().navigate(R.id.app_to_all_perms, args) } private fun getIndividualPermissionDetailResId(group: LightAppPermGroup): Pair<Int, Int> { return when (val numRevoked = group.permissions.filter { !it.value.isGrantedIncludingAppOp }.size) { Loading Loading @@ -585,13 +564,12 @@ class AppPermissionViewModel( data class PermissionState(val permissionName: String, val permissionGranted: Boolean) private fun logPermissionChanges(previousPermissionSnapshot: List<PermissionState>) { val group = appPermissionGroup ?: return val lightGroup = lightAppPermGroup ?: return val changeId = Random().nextLong() for ((permissionName, wasGranted) in previousPermissionSnapshot) { val permission = group.getPermission(permissionName) ?: group.backgroundPermissions?.getPermission(permissionName) val permission = lightGroup.permissions[permissionName] ?: continue val isGranted = permission.isGrantedIncludingAppOp Loading src/com/android/permissioncontroller/permission/utils/KotlinUtils.kt +109 −50 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
src/com/android/permissioncontroller/permission/data/AppPermGroupLiveData.kt +52 −1 Original line number Diff line number Diff line Loading @@ -17,10 +17,14 @@ package com.android.permissioncontroller.permission.data import android.app.Application import android.content.pm.PackageManager import android.content.pm.PermissionInfo import android.os.Build import android.os.UserHandle import android.permission.PermissionManager import android.util.Log import com.android.permissioncontroller.permission.model.livedatatypes.LightAppPermGroup import com.android.permissioncontroller.permission.model.livedatatypes.LightPackageInfo import com.android.permissioncontroller.permission.model.livedatatypes.LightPermission import com.android.permissioncontroller.permission.utils.LocationUtils import com.android.permissioncontroller.permission.utils.SoftRestrictedPermissionPolicy Loading @@ -42,6 +46,8 @@ class AppPermGroupLiveData( private val user: UserHandle ) : SmartUpdateMediatorLiveData<LightAppPermGroup>() { val LOG_TAG = this::class.java.simpleName private val permStateLiveData = PermStateRepository.getPermStateLiveData(app, packageName, permGroupName, user) private val permGroupLiveData = PermGroupRepository.getPermGroupLiveData(app, permGroupName) Loading Loading @@ -125,7 +131,52 @@ class AppPermGroupLiveData( specialLocationGrant = LocationUtils.isExtraLocationControllerPackageEnabled( userContext) } val hasInstallToRuntimeSplit = hasInstallToRuntimeSplit(packageInfo, permissionMap) value = LightAppPermGroup(packageInfo, permGroup.groupInfo, permissionMap, specialLocationGrant) hasInstallToRuntimeSplit, specialLocationGrant) } /** * Check if permission group contains a runtime permission that split from an installed * permission and the split happened in an Android version higher than app's targetSdk. * * @return `true` if there is such permission, `false` otherwise */ private fun hasInstallToRuntimeSplit( packageInfo: LightPackageInfo, permissionMap: Map<String, LightPermission> ): Boolean { val permissionManager = app.getSystemService(PermissionManager::class.java) ?: return false for (spi in permissionManager.splitPermissions) { val splitPerm = spi.splitPermission val pi = try { app.packageManager.getPermissionInfo(splitPerm, 0) } catch (e: PackageManager.NameNotFoundException) { Log.w(LOG_TAG, "No such permission: $splitPerm", e) continue } // Skip if split permission is not "install" permission. if (pi.protection != PermissionInfo.PROTECTION_NORMAL) { continue } val newPerms = spi.newPermissions for (permName in newPerms) { val newPerm = permissionMap[permName]?.permInfo ?: continue // Skip if new permission is not "runtime" permission. if (newPerm.protection != PermissionInfo.PROTECTION_DANGEROUS) { continue } if (packageInfo.targetSdkVersion < spi.targetSdk) { return true } } } return false } } No newline at end of file
src/com/android/permissioncontroller/permission/model/livedatatypes/LightAppPermGroup.kt +23 −1 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.permissioncontroller.permission.model.livedatatypes import android.os.Build import android.os.UserHandle /** Loading @@ -25,6 +26,8 @@ import android.os.UserHandle * @param packageInfo Information about the package * @param permGroupInfo Information about the permission group * @param permissions The permissions in the permission group that the package requests * @param hasInstallToRuntimeSplit If this group contains a permission that was previously an * install permission, but is currently a runtime permission * @param specialLocationGrant If this package is the location provider, or the extra location * package, then the grant state of the group is not determined by the grant state of individual * permissions, but by other system properties Loading @@ -33,10 +36,11 @@ data class LightAppPermGroup( val packageInfo: LightPackageInfo, val permGroupInfo: LightPermGroupInfo, val permissions: Map<String, LightPermission>, val hasInstallToRuntimeSplit: Boolean, val specialLocationGrant: Boolean? ) { constructor(pI: LightPackageInfo, pGI: LightPermGroupInfo, perms: Map<String, LightPermission>): this(pI, pGI, perms, null) this(pI, pGI, perms, false, null) /** * The current userHandle of this AppPermGroup. */ Loading @@ -48,6 +52,14 @@ data class LightAppPermGroup( */ val backgroundPermNames = permissions.mapNotNull { it.value.backgroundPermission } /** * The names of all foreground permissions in the permission group which are requested by the * package. */ val foregroundPermNames = permissions.mapNotNull { if (!backgroundPermNames.contains(it.key)) it.key else null } /** * Whether or not this App Permission Group has a permission which has a background mode */ Loading Loading @@ -106,6 +118,16 @@ data class LightAppPermGroup( backgroundPermNames.contains(it.key) && it.value.isGrantedIncludingAppOp } val isForegroundGrantedByDefault = permissions.any { !backgroundPermNames.contains(it.key) && it.value.isGrantedByDefault } val isBackgroundGrantedByDefault = permissions.any { backgroundPermNames.contains(it.key) && it.value.isGrantedByDefault } val supportsRuntimePerms = packageInfo.targetSdkVersion >= Build.VERSION_CODES.M /** * Whether this App Permission Group's permissions are fixed by the user */ Loading
src/com/android/permissioncontroller/permission/model/livedatatypes/LightPermission.kt +2 −0 Original line number Diff line number Diff line Loading @@ -64,4 +64,6 @@ data class LightPermission( /** Whether this permission is a runtime only permission */ val isRuntimeOnly = permInfo.protectionFlags and PermissionInfo.PROTECTION_FLAG_RUNTIME_ONLY != 0 /** Whether this permission is granted by default */ val isGrantedByDefault = flags and PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT != 0 } No newline at end of file
src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionViewModel.kt +67 −89 Original line number Diff line number Diff line Loading @@ -35,7 +35,6 @@ import com.android.permissioncontroller.PermissionControllerStatsLog.APP_PERMISS import com.android.permissioncontroller.R import com.android.permissioncontroller.permission.data.AppPermGroupLiveData import com.android.permissioncontroller.permission.data.SmartUpdateMediatorLiveData import com.android.permissioncontroller.permission.model.AppPermissionGroup import com.android.permissioncontroller.permission.model.livedatatypes.LightAppPermGroup import com.android.permissioncontroller.permission.utils.KotlinUtils import com.android.permissioncontroller.permission.utils.LocationUtils Loading Loading @@ -101,7 +100,6 @@ class AppPermissionViewModel( } private var hasConfirmedRevoke = false private var appPermissionGroup: AppPermissionGroup? = null private var lightAppPermGroup: LightAppPermGroup? = null /** Loading Loading @@ -147,13 +145,6 @@ class AppPermissionViewModel( } override fun update() { appPermissionGroup = AppPermissionGroup.create(app, packageName, permGroupName, user, false) if (appPermissionGroup == null) { value = null return } val group = appPermGroupLiveData.value ?: return val admin = RestrictedLockUtils.getProfileOrDeviceOwner(app, user) Loading Loading @@ -237,8 +228,6 @@ class AppPermissionViewModel( override fun onActive() { super.onActive() appPermissionGroup = AppPermissionGroup.create(app, packageName, permGroupName, user, false) } } Loading Loading @@ -365,12 +354,11 @@ class AppPermissionViewModel( changeTarget: ChangeTarget ) { val context = fragment.context ?: return val group = appPermissionGroup ?: return val group = lightAppPermGroup ?: return val wasForegroundGranted = group.isForegroundGranted val wasBackgroundGranted = group.isBackgroundGranted group.isOneTime = false if (LocationUtils.isLocationGroupAndProvider(context, group.name, group.app.packageName)) { if (LocationUtils.isLocationGroupAndProvider(context, permGroupName, packageName)) { val packageLabel = KotlinUtils.getPackageLabel(app, packageName, user) LocationUtils.showLocationDialog(context, packageLabel) } Loading @@ -381,20 +369,17 @@ class AppPermissionViewModel( if (requestGrant) { val stateBefore = createPermissionSnapshot()!! if (shouldChangeForeground) { val runtimePermissionsGranted = group.areRuntimePermissionsGranted() group.grantRuntimePermissions(userFixed) val newGroup = KotlinUtils.grantForegroundRuntimePermissions(app, group) if (!runtimePermissionsGranted) { SafetyNetLogger.logPermissionToggled(group) if (!wasForegroundGranted) { SafetyNetLogger.logPermissionToggled(newGroup) } } if (shouldChangeBackground && group.backgroundPermissions != null) { val runtimePermissionsGranted = group.backgroundPermissions.areRuntimePermissionsGranted() group.backgroundPermissions.grantRuntimePermissions(userFixed) if (shouldChangeBackground && group.hasBackgroundPerms) { val newGroup = KotlinUtils.grantBackgroundRuntimePermissions(app, group) if (!runtimePermissionsGranted) { SafetyNetLogger.logPermissionToggled(group.backgroundPermissions) if (!wasBackgroundGranted) { SafetyNetLogger.logPermissionToggled(newGroup, true) } } logPermissionChanges(stateBefore) Loading @@ -402,24 +387,21 @@ class AppPermissionViewModel( var showDefaultDenyDialog = false var showGrantedByDefaultWarning = false if (shouldChangeForeground && group.areRuntimePermissionsGranted()) { showDefaultDenyDialog = (group.hasGrantedByDefaultPermission() || !group.doesSupportRuntimePermissions() || group.hasInstallToRuntimeSplit()) if (shouldChangeForeground && wasForegroundGranted) { showDefaultDenyDialog = (group.isForegroundGrantedByDefault || !group.supportsRuntimePerms || group.hasInstallToRuntimeSplit) showGrantedByDefaultWarning = showGrantedByDefaultWarning || group.hasGrantedByDefaultPermission() group.isForegroundGrantedByDefault } if (shouldChangeBackground && group.backgroundPermissions != null && group.backgroundPermissions.areRuntimePermissionsGranted()) { val bgGroup = group.backgroundPermissions if (shouldChangeBackground && wasBackgroundGranted) { showDefaultDenyDialog = showDefaultDenyDialog || bgGroup.hasGrantedByDefaultPermission() || !bgGroup.doesSupportRuntimePermissions() || bgGroup.hasInstallToRuntimeSplit() group.isBackgroundGrantedByDefault || !group.supportsRuntimePerms || group.hasInstallToRuntimeSplit showGrantedByDefaultWarning = showGrantedByDefaultWarning || bgGroup.hasGrantedByDefaultPermission() group.isBackgroundGrantedByDefault } if (showDefaultDenyDialog && !hasConfirmedRevoke && showGrantedByDefaultWarning) { Loading @@ -432,28 +414,25 @@ class AppPermissionViewModel( } else { val stateBefore = createPermissionSnapshot()!! if (shouldChangeForeground && group.areRuntimePermissionsGranted()) { group.revokeRuntimePermissions(userFixed) SafetyNetLogger.logPermissionToggled(group) } if (shouldChangeBackground && group.backgroundPermissions != null && group.backgroundPermissions.areRuntimePermissionsGranted()) { group.backgroundPermissions.revokeRuntimePermissions(userFixed) (wasForegroundGranted || userFixed != group.isUserFixed)) { val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group, userFixed) SafetyNetLogger.logPermissionToggled(group.backgroundPermissions) // only log if we have actually denied permissions, not if we switch from // "ask every time" to denied if (wasForegroundGranted) { SafetyNetLogger.logPermissionToggled(newGroup) } if (userFixed && !group.isUserFixed) { group.revokeRuntimePermissions(true) if (group.backgroundPermissions != null) { group.backgroundPermissions.revokeRuntimePermissions(true) } } if (!userFixed && group.isUserFixed) { group.revokeRuntimePermissions(false) if (group.backgroundPermissions != null) { group.backgroundPermissions.revokeRuntimePermissions(false) if (shouldChangeBackground && group.hasBackgroundPerms && (wasBackgroundGranted || userFixed != group.isUserFixed)) { val newGroup = KotlinUtils.revokeBackgroundRuntimePermissions(app, group, userFixed) // only log if we have actually denied permissions, not if we switch from // "ask every time" to denied if (wasBackgroundGranted) { SafetyNetLogger.logPermissionToggled(newGroup, true) } } logPermissionChanges(stateBefore) Loading @@ -461,51 +440,41 @@ class AppPermissionViewModel( } } /** * Show the All App Permissions screen with the proper filter group, package name, and user. * * @param fragment The current fragment we wish to transition from */ fun showAllPermissions(fragment: AppPermissionFragment) { val args = AllAppPermissionsFragment.createArgs(packageName, permGroupName, user) fragment.findNavController().navigate(R.id.app_to_all_perms, args) } /** * Once the user has confirmed that he/she wants to revoke a permission that was granted by * default, actually revoke the permissions. * * @param changeTarget whether to change foreground, background, or both. * @param userFixed whether the user has stated they do not wish to be prompted about the * permission any more. * */ fun onDenyAnyWay(changeTarget: ChangeTarget, userFixed: Boolean) { val group = appPermissionGroup ?: return val group = lightAppPermGroup ?: return val wasForegroundGranted = group.isForegroundGranted val wasBackgroundGranted = group.isBackgroundGranted var hasDefaultPermissions = false val stateBefore = createPermissionSnapshot() if (changeTarget andValue ChangeTarget.CHANGE_FOREGROUND != 0) { val runtimePermissionsGranted = group.areRuntimePermissionsGranted() group.revokeRuntimePermissions(userFixed) if (runtimePermissionsGranted) { SafetyNetLogger.logPermissionToggled(group) if (changeTarget andValue ChangeTarget.CHANGE_FOREGROUND != 0) { val newGroup = KotlinUtils.revokeForegroundRuntimePermissions(app, group, userFixed) if (wasForegroundGranted) { SafetyNetLogger.logPermissionToggled(newGroup) } hasDefaultPermissions = group.hasGrantedByDefaultPermission() hasDefaultPermissions = group.isForegroundGrantedByDefault } if (changeTarget andValue ChangeTarget.CHANGE_BACKGROUND != 0 && group.backgroundPermissions != null) { val runtimePermissionsGranted = group.backgroundPermissions.areRuntimePermissionsGranted() group.backgroundPermissions.revokeRuntimePermissions(userFixed) if (changeTarget andValue ChangeTarget.CHANGE_BACKGROUND != 0 && group.hasBackgroundPerms) { val newGroup = KotlinUtils.revokeBackgroundRuntimePermissions(app, group, userFixed) if (runtimePermissionsGranted) { SafetyNetLogger.logPermissionToggled(group.backgroundPermissions) if (wasBackgroundGranted) { SafetyNetLogger.logPermissionToggled(newGroup) } hasDefaultPermissions = hasDefaultPermissions || group.backgroundPermissions.hasGrantedByDefaultPermission() group.isBackgroundGrantedByDefault } logPermissionChanges(stateBefore!!) if (hasDefaultPermissions || !group.doesSupportRuntimePermissions()) { if (hasDefaultPermissions || !group.supportsRuntimePerms) { hasConfirmedRevoke = true } } Loading @@ -521,6 +490,16 @@ class AppPermissionViewModel( return permissionSnapshot } /** * Show the All App Permissions screen with the proper filter group, package name, and user. * * @param fragment The current fragment we wish to transition from */ fun showAllPermissions(fragment: AppPermissionFragment) { val args = AllAppPermissionsFragment.createArgs(packageName, permGroupName, user) fragment.findNavController().navigate(R.id.app_to_all_perms, args) } private fun getIndividualPermissionDetailResId(group: LightAppPermGroup): Pair<Int, Int> { return when (val numRevoked = group.permissions.filter { !it.value.isGrantedIncludingAppOp }.size) { Loading Loading @@ -585,13 +564,12 @@ class AppPermissionViewModel( data class PermissionState(val permissionName: String, val permissionGranted: Boolean) private fun logPermissionChanges(previousPermissionSnapshot: List<PermissionState>) { val group = appPermissionGroup ?: return val lightGroup = lightAppPermGroup ?: return val changeId = Random().nextLong() for ((permissionName, wasGranted) in previousPermissionSnapshot) { val permission = group.getPermission(permissionName) ?: group.backgroundPermissions?.getPermission(permissionName) val permission = lightGroup.permissions[permissionName] ?: continue val isGranted = permission.isGrantedIncludingAppOp Loading
src/com/android/permissioncontroller/permission/utils/KotlinUtils.kt +109 −50 File changed.Preview size limit exceeded, changes collapsed. Show changes