summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> 2025-03-03 15:46:22 -0800
committer Android (Google) Code Review <android-gerrit@google.com> 2025-03-03 15:46:22 -0800
commit58c6f5ecac7b3bb057838604c11fe05f8818df04 (patch)
treedbdfc6f88ef0aa387943ca2e7cdf16b2f92148ea
parent6316f2f53b580fd0d71307dba97b7207726109bf (diff)
parent5af0642d636909877dac52c91ec8f276f73bb882 (diff)
Merge "DO NOT MERGE Display the system gallery storage permission as system fixed" into udc-mainline-prod
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/data/AppPermGroupUiInfoLiveData.kt31
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/data/LightAppPermGroupLiveData.kt74
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/LightAppPermGroup.kt23
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/service/RuntimePermissionsUpgradeController.kt3
-rw-r--r--PermissionController/src/com/android/permissioncontroller/permission/utils/KotlinUtils.kt9
-rw-r--r--PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/permission/utils/GrantRevokeTests.kt2
6 files changed, 91 insertions, 51 deletions
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/data/AppPermGroupUiInfoLiveData.kt b/PermissionController/src/com/android/permissioncontroller/permission/data/AppPermGroupUiInfoLiveData.kt
index b17098a13..ede8d7463 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/data/AppPermGroupUiInfoLiveData.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/data/AppPermGroupUiInfoLiveData.kt
@@ -18,6 +18,7 @@ package com.android.permissioncontroller.permission.data
import android.Manifest
import android.Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED
+import android.Manifest.permission_group.READ_MEDIA_VISUAL
import android.Manifest.permission_group.STORAGE
import android.app.AppOpsManager
import android.app.Application
@@ -258,9 +259,14 @@ private constructor(
allPermInfos: Map<String, LightPermInfo>,
pkg: LightPackageInfo
): PermGrantState {
- val specialLocationState = getIsSpecialLocationState()
+ val specialLocationState = LightAppPermGroupLiveData
+ .isSpecialLocationGranted(app, packageName, permGroupName, user)
+ val specialFixedStorage = LightAppPermGroupLiveData
+ .isSpecialFixedStorageGranted(app, packageName, permGroupName, pkg.uid)
if (isStorage && isFullFilesAccessGranted(pkg)) {
return PermGrantState.PERMS_ALLOWED
+ } else if (permGroupName == READ_MEDIA_VISUAL && specialFixedStorage) {
+ return PermGrantState.PERMS_ALLOWED
}
var hasPermWithBackground = false
@@ -332,29 +338,6 @@ private constructor(
return PermGrantState.PERMS_DENIED
}
- private fun getIsSpecialLocationState(): Boolean? {
- if (!isSpecialLocation) {
- return null
- }
-
- val userContext = Utils.getUserContext(app, user)
- if (LocationUtils.isLocationGroupAndProvider(userContext, permGroupName, packageName)) {
- return LocationUtils.isLocationEnabled(userContext)
- }
- // The permission of the extra location controller package is determined by the
- // status of the controller package itself.
- if (
- LocationUtils.isLocationGroupAndControllerExtraPackage(
- userContext,
- permGroupName,
- packageName
- )
- ) {
- return LocationUtils.isExtraLocationControllerPackageEnabled(userContext)
- }
- return null
- }
-
private fun isFullFilesAccessGranted(pkg: LightPackageInfo): Boolean {
val packageState =
if (!FullStoragePermissionAppsLiveData.isStale) {
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/data/LightAppPermGroupLiveData.kt b/PermissionController/src/com/android/permissioncontroller/permission/data/LightAppPermGroupLiveData.kt
index db606f68d..27f5a4a9d 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/data/LightAppPermGroupLiveData.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/data/LightAppPermGroupLiveData.kt
@@ -16,7 +16,13 @@
package com.android.permissioncontroller.permission.data
+import android.Manifest.permission_group.READ_MEDIA_VISUAL
+import android.Manifest.permission_group.STORAGE
+import android.app.AppOpsManager
+import android.app.AppOpsManager.MODE_ALLOWED
+import android.app.AppOpsManager.OPSTR_WRITE_MEDIA_IMAGES
import android.app.Application
+import android.app.role.RoleManager
import android.content.pm.PackageManager
import android.content.pm.PermissionInfo
import android.os.Build
@@ -119,20 +125,6 @@ private constructor(
LightPermission(packageInfo, permInfo, permState, foregroundPerms)
}
- // Determine if this app permission group is a special location package or provider
- var specialLocationGrant: Boolean? = null
- val userContext = Utils.getUserContext(app, user)
- if (LocationUtils.isLocationGroupAndProvider(userContext, permGroupName, packageName)) {
- specialLocationGrant = LocationUtils.isLocationEnabled(userContext)
- } else if (
- LocationUtils.isLocationGroupAndControllerExtraPackage(app, permGroupName, packageName)
- ) {
- // The permission of the extra location controller package is determined by the status
- // of the controller package itself.
- specialLocationGrant =
- LocationUtils.isExtraLocationControllerPackageEnabled(userContext)
- }
-
val hasInstallToRuntimeSplit = hasInstallToRuntimeSplit(packageInfo, permissionMap)
value =
LightAppPermGroup(
@@ -140,7 +132,8 @@ private constructor(
permGroup.groupInfo,
permissionMap,
hasInstallToRuntimeSplit,
- specialLocationGrant
+ isSpecialLocationGranted(app, packageName, permGroupName, user),
+ isSpecialFixedStorageGranted(app, packageName, permGroupName, packageInfo.uid)
)
}
@@ -226,5 +219,56 @@ private constructor(
key.third
)
}
+
+ private const val SYSTEM_GALLERY_ROLE_NAME = "android.app.role.SYSTEM_GALLERY"
+
+ // Returns true if this app is the location provider or location extra package, and location
+ // access is granted, false if it is the provider/extra, and location is not granted, and
+ // null if it is not a special package
+ fun isSpecialLocationGranted(
+ app: Application,
+ packageName: String,
+ permGroupName: String,
+ user: UserHandle
+ ): Boolean? {
+ val userContext = Utils.getUserContext(app, user)
+ return if (
+ LocationUtils.isLocationGroupAndProvider(userContext, permGroupName, packageName)
+ ) {
+ LocationUtils.isLocationEnabled(userContext)
+ } else if (
+ LocationUtils.isLocationGroupAndControllerExtraPackage(app, permGroupName, packageName)
+ ) {
+ // The permission of the extra location controller package is determined by the status
+ // of the controller package itself.
+ LocationUtils.isExtraLocationControllerPackageEnabled(userContext)
+ } else {
+ null
+ }
+ }
+
+ // Gallery role is static, so we only need to get the set gallery app once
+ private val systemGalleryApps: List<String> by lazy {
+ val roleManager = PermissionControllerApplication.get()
+ .getSystemService(RoleManager::class.java) ?: return@lazy emptyList()
+ roleManager.getRoleHolders(SYSTEM_GALLERY_ROLE_NAME)
+ }
+
+ fun isSpecialFixedStorageGranted(
+ app: Application,
+ packageName: String,
+ permGroupName: String,
+ uid: Int
+ ): Boolean {
+ if (permGroupName != READ_MEDIA_VISUAL && permGroupName != STORAGE) {
+ return false
+ }
+ if (packageName !in systemGalleryApps) {
+ return false
+ }
+ // This is the storage group, and the gallery app. Check the write media app op
+ val appOps = app.getSystemService(AppOpsManager::class.java)
+ return appOps.unsafeCheckOpNoThrow(OPSTR_WRITE_MEDIA_IMAGES, uid, packageName) == MODE_ALLOWED
+ }
}
}
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/LightAppPermGroup.kt b/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/LightAppPermGroup.kt
index c7e78d414..d7a7c7f15 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/LightAppPermGroup.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/model/livedatatypes/LightAppPermGroup.kt
@@ -35,19 +35,24 @@ import com.android.permissioncontroller.permission.utils.Utils
* @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
+ * @param specialFixedStorageGrant If this package holds the SYSTEM_GALLERY role, and has the
+ * WRITE_MEDIA_IMAGES app op granted, then we should show the grant state of the storage
+ * permissions as system fixed and granted.
+ *
*/
data class LightAppPermGroup(
val packageInfo: LightPackageInfo,
val permGroupInfo: LightPermGroupInfo,
val allPermissions: Map<String, LightPermission>,
val hasInstallToRuntimeSplit: Boolean,
- val specialLocationGrant: Boolean?
+ val specialLocationGrant: Boolean?,
+ val specialFixedStorageGrant: Boolean,
) {
constructor(
pI: LightPackageInfo,
pGI: LightPermGroupInfo,
perms: Map<String, LightPermission>
- ) : this(pI, pGI, perms, false, null)
+ ) : this(pI, pGI, perms, false, null, false)
/** All unrestricted permissions. Usually restricted permissions are ignored */
val permissions: Map<String, LightPermission> =
@@ -80,7 +85,8 @@ data class LightAppPermGroup(
permissions.filter { it.key in foregroundPermNames },
packageInfo,
isPlatformPermissionGroup,
- specialLocationGrant
+ specialLocationGrant,
+ specialFixedStorageGrant,
)
val background =
@@ -88,7 +94,8 @@ data class LightAppPermGroup(
permissions.filter { it.key in backgroundPermNames },
packageInfo,
isPlatformPermissionGroup,
- specialLocationGrant
+ specialLocationGrant,
+ specialFixedStorageGrant,
)
/** Whether or not this App Permission Group has a permission which has a background mode */
@@ -164,18 +171,20 @@ data class LightAppPermGroup(
* contained in the full group
* @param isPlatformPermissionGroup Whether this is a platform permission group
* @param specialLocationGrant Whether this is a special location package
+ * @param specialFixedStorageGrant Whether this is a special storage grant
*/
data class AppPermSubGroup
internal constructor(
private val permissions: Map<String, LightPermission>,
private val packageInfo: LightPackageInfo,
private val isPlatformPermissionGroup: Boolean,
- private val specialLocationGrant: Boolean?
+ private val specialLocationGrant: Boolean?,
+ private val specialFixedStorageGrant: Boolean
) {
/** Whether any of this App Permission SubGroup's permissions are granted */
val isGranted =
specialLocationGrant
- ?: permissions.any {
+ ?: specialFixedStorageGrant || permissions.any {
val mayGrantByPlatformOrSystem =
!isPlatformPermissionGroup || it.value.isPlatformOrSystem
it.value.isGranted && mayGrantByPlatformOrSystem
@@ -213,7 +222,7 @@ data class LightAppPermGroup(
val isPolicyFixed = permissions.any { it.value.isPolicyFixed }
/** Whether any of this App Permission Subgroup's permissions are fixed by the system */
- val isSystemFixed = permissions.any { it.value.isSystemFixed }
+ val isSystemFixed = permissions.any { it.value.isSystemFixed } || specialFixedStorageGrant
/** Whether any of this App Permission Subgroup's permissions are fixed by the user */
val isUserFixed = permissions.any { it.value.isUserFixed }
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/service/RuntimePermissionsUpgradeController.kt b/PermissionController/src/com/android/permissioncontroller/permission/service/RuntimePermissionsUpgradeController.kt
index 630e86f65..fcadb68c3 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/service/RuntimePermissionsUpgradeController.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/service/RuntimePermissionsUpgradeController.kt
@@ -479,7 +479,8 @@ internal object RuntimePermissionsUpgradeController {
bgApp.permGroupInfo,
allPermissionsWithxemption,
bgApp.hasInstallToRuntimeSplit,
- bgApp.specialLocationGrant
+ bgApp.specialLocationGrant,
+ bgApp.specialFixedStorageGrant,
)
}
diff --git a/PermissionController/src/com/android/permissioncontroller/permission/utils/KotlinUtils.kt b/PermissionController/src/com/android/permissioncontroller/permission/utils/KotlinUtils.kt
index fcd7ef7b9..34073d280 100644
--- a/PermissionController/src/com/android/permissioncontroller/permission/utils/KotlinUtils.kt
+++ b/PermissionController/src/com/android/permissioncontroller/permission/utils/KotlinUtils.kt
@@ -783,7 +783,8 @@ object KotlinUtils {
group.permGroupInfo,
newPerms,
group.hasInstallToRuntimeSplit,
- group.specialLocationGrant
+ group.specialLocationGrant,
+ group.specialFixedStorageGrant,
)
}
@@ -888,7 +889,8 @@ object KotlinUtils {
group.permGroupInfo,
newPerms,
group.hasInstallToRuntimeSplit,
- group.specialLocationGrant
+ group.specialLocationGrant,
+ group.specialFixedStorageGrant,
)
// If any permission in the group is one time granted, start one time permission session.
if (newGroup.permissions.any { it.value.isOneTime && it.value.isGranted }) {
@@ -1156,7 +1158,8 @@ object KotlinUtils {
group.permGroupInfo,
newPerms,
group.hasInstallToRuntimeSplit,
- group.specialLocationGrant
+ group.specialLocationGrant,
+ group.specialFixedStorageGrant,
)
if (wasOneTime && !anyPermsOfPackageOneTimeGranted(app, newGroup.packageInfo, newGroup)) {
diff --git a/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/permission/utils/GrantRevokeTests.kt b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/permission/utils/GrantRevokeTests.kt
index b1e309628..03eb1ef80 100644
--- a/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/permission/utils/GrantRevokeTests.kt
+++ b/PermissionController/tests/mocking/src/com/android/permissioncontroller/tests/mocking/permission/utils/GrantRevokeTests.kt
@@ -227,7 +227,7 @@ class GrantRevokeTests {
perms: Map<String, LightPermission> = emptyMap()
): LightAppPermGroup {
val pGi = LightPermGroupInfo(PERM_GROUP_NAME, TEST_PACKAGE_NAME, 0, 0, 0, false)
- return LightAppPermGroup(pkgInfo, pGi, perms, false, false)
+ return LightAppPermGroup(pkgInfo, pGi, perms, false, false, false)
}
/**