Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 48c2c43f authored by mrulhania's avatar mrulhania
Browse files

Handle READ_MEDIA_IMAGES/VIDEO permission in getPermissionRequestState API

READ_MEDIA_IMAGES permission becomes USER_FIXED, if user allows
only selected photos twice in permission dialog.
USER_FIXED flag is generally treated as permanent denial from user,
and subsequent permission request will be ignored by the system.

But due to photo picker, we treat READ_MEDIA_IMAGES a bit
differently. The system doesn't ignore permission request
even after USER_FIXED flag in this case, rather the
system shows photo picker directly.

Adding this special case to handle READ_MEDIA_IMAGES in new
getPermissionRequestState API, when determining whether a
permission can be requested or not.

Fix: 383956875
Test: atest android.permissionui.cts.PhotoPickerPermissionTest
FLAG: EXEMPT bug fix
Change-Id: I88d86d655fae93edbc5c3011e03a35a73f77a459
parent e60ff67b
Loading
Loading
Loading
Loading
+38 −12
Original line number Diff line number Diff line
@@ -469,8 +469,9 @@ class PermissionService(private val service: AccessCheckingService) :
        permissionName: String,
        deviceId: String
    ): Int {
        val pid = Binder.getCallingPid()
        val uid = Binder.getCallingUid()
        val result = context.checkPermission(permissionName, Binder.getCallingPid(), uid)
        val result = context.checkPermission(permissionName, pid, uid)
        if (result == PackageManager.PERMISSION_GRANTED) {
            return Context.PERMISSION_REQUEST_STATE_GRANTED
        }
@@ -481,14 +482,12 @@ class PermissionService(private val service: AccessCheckingService) :
            packageManagerLocal.withFilteredSnapshot(uid, userId).use {
                it.getPackageState(packageName)
            } ?: return Context.PERMISSION_REQUEST_STATE_UNREQUESTABLE
        val androidPackage = packageState.androidPackage
                ?: return Context.PERMISSION_REQUEST_STATE_UNREQUESTABLE
        val androidPackage =
            packageState.androidPackage ?: return Context.PERMISSION_REQUEST_STATE_UNREQUESTABLE
        if (appId != packageState.appId) {
            return Context.PERMISSION_REQUEST_STATE_UNREQUESTABLE
        }
        val permission = service.getState {
            with(policy) { getPermissions()[permissionName] }
        }
        val permission = service.getState { with(policy) { getPermissions()[permissionName] } }
        if (permission == null || !permission.isRuntime) {
            return Context.PERMISSION_REQUEST_STATE_UNREQUESTABLE
        }
@@ -496,10 +495,37 @@ class PermissionService(private val service: AccessCheckingService) :
            return Context.PERMISSION_REQUEST_STATE_UNREQUESTABLE
        }

        val permissionFlags = service.getState {
        val permissionFlags =
            service.getState {
                getPermissionFlagsWithPolicy(appId, userId, permissionName, deviceId)
            }
        return if (permissionFlags.hasAnyBit(UNREQUESTABLE_MASK)) {
        val isUnreqestable = permissionFlags.hasAnyBit(UNREQUESTABLE_MASK)
        // Special case for READ_MEDIA_IMAGES due to photo picker
        if ((permissionName == Manifest.permission.READ_MEDIA_IMAGES ||
                permissionName == Manifest.permission.READ_MEDIA_VIDEO) && isUnreqestable) {
            val isUserSelectedGranted =
                context.checkPermission(
                    Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED,
                    pid,
                    uid,
                ) == PackageManager.PERMISSION_GRANTED
            val userSelectedPermissionFlags =
                service.getState {
                    getPermissionFlagsWithPolicy(
                        appId,
                        userId,
                        Manifest.permission.READ_MEDIA_VISUAL_USER_SELECTED,
                        deviceId,
                    )
                }
            if (
                isUserSelectedGranted &&
                    userSelectedPermissionFlags.hasBits(PermissionFlags.USER_FIXED)
            ) {
                return Context.PERMISSION_REQUEST_STATE_REQUESTABLE
            }
        }
        return if (isUnreqestable) {
            Context.PERMISSION_REQUEST_STATE_UNREQUESTABLE
        } else {
            Context.PERMISSION_REQUEST_STATE_REQUESTABLE