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

Commit 9e59bbc6 authored by Eugene Susla's avatar Eugene Susla
Browse files

Handle auto-revoke flags

Fixes: 149503808
Test: presubmit
Change-Id: If4413e556ef108e7c77ae12e68cb73c272547f7e
parent 79766375
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -68,6 +68,10 @@ data class LightPermission(
    val isGrantedByDefault = flags and PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT != 0
    /** Whether this permission is granted by role */
    val isGrantedByRole = flags and PackageManager.FLAG_PERMISSION_GRANTED_BY_ROLE != 0
    /** Whether this permission is not whitelisted from being auto-revoked when app is unused */
    val isAutoRevokable = flags and PackageManager.FLAG_PERMISSION_AUTO_REVOKE_IF_UNUSED != 0
    /** Whether [isAutoRevokable] was set by user */
    val isAutoRevokableUserSet = flags and PackageManager.FLAG_PERMISSION_AUTO_REVOKE_USER_SET != 0

    override fun toString() = buildString {
        append(name)
@@ -81,5 +85,7 @@ data class LightPermission(
        if (isOneTime) append(", OneTime")
        if (isGrantedByDefault) append(", GrantedByDefault")
        if (isGrantedByRole) append(", GrantedByRole")
        if (isAutoRevokable) append(", AutoRevokable")
        if (isAutoRevokableUserSet) append(", AutoRevokableUserSet")
    }
}
 No newline at end of file
+23 −8
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@ import android.content.BroadcastReceiver
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager.FLAG_PERMISSION_AUTO_REVOKED
import android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET
import android.os.Process.myUserHandle
import android.provider.DeviceConfig
import android.util.Log
@@ -50,6 +52,7 @@ import com.android.permissioncontroller.permission.utils.Utils.PROPERTY_AUTO_REV
import com.android.permissioncontroller.permission.utils.Utils.PROPERTY_AUTO_REVOKE_UNUSED_THRESHOLD_MILLIS
import com.android.permissioncontroller.permission.utils.application
import com.android.permissioncontroller.permission.utils.forEachInParallel
import com.android.permissioncontroller.permission.utils.updatePermissionFlags
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.GlobalScope
@@ -162,16 +165,21 @@ private suspend fun revokePermissionsOnUnusedApps(context: Context) {
                !group.isGrantedByDefault &&
                !group.isGrantedByRole) {

                val revocablePermissions = group.permissions.filter { (_, perm) ->
                    // Override whitelist with DEBUG to allow testing
                    DEBUG || perm.isAutoRevokable
                }.keys.toList()

                if (revocablePermissions.isEmpty()) {
                    return@forEachInParallel
                }

                if (DEBUG) {
                    Log.i(LOG_TAG, "revokeUnused ${pkg.packageName} - " +
                        group
                            .permissions
                            .filterValues { it.name in groupPermNames }
                            .values)
                    Log.i(LOG_TAG, "revokeUnused ${pkg.packageName} - $revocablePermissions")
                }

                val uid = group.packageInfo.uid
                for (permName in groupPermNames) {
                for (permName in revocablePermissions) {
                    PermissionControllerStatsLog.write(
                        PERMISSION_GRANT_REQUEST_RESULT_REPORTED,
                        Random.nextLong(), uid, pkg.packageName, permName, false, SERVER_LOG_ID)
@@ -183,10 +191,17 @@ private suspend fun revokePermissionsOnUnusedApps(context: Context) {
                if (packageImportance > IMPORTANCE_TOP_SLEEPING) {
                    KotlinUtils.revokeBackgroundRuntimePermissions(
                        context.application, group,
                        userFixed = false, filterPermissions = groupPermNames)
                        userFixed = false, filterPermissions = revocablePermissions)
                    KotlinUtils.revokeForegroundRuntimePermissions(
                        context.application, group,
                        userFixed = false, filterPermissions = groupPermNames)
                        userFixed = false, filterPermissions = revocablePermissions)

                    for (permission in revocablePermissions) {
                        context.packageManager.updatePermissionFlags(
                            permission, pkg.packageName, myUserHandle(),
                            FLAG_PERMISSION_AUTO_REVOKED to true,
                            FLAG_PERMISSION_USER_SET to false)
                    }
                } else {
                    Log.i(LOG_TAG,
                        "Skipping auto-revoke - app running with importance $packageImportance")
+16 −0
Original line number Diff line number Diff line
@@ -21,7 +21,9 @@ import android.app.Application
import android.app.Service
import android.content.Context
import android.content.ContextWrapper
import android.content.pm.PackageManager
import android.os.Looper
import android.os.UserHandle

/**
 * Gets an [Application] instance form a regular [Context]
@@ -39,3 +41,17 @@ val Context.application: Application get() = when (this) {
fun ensureMainThread() = check(Looper.myLooper() == Looper.getMainLooper()) {
    "Only meant to be used on the main thread"
}

/**
 * A more readable version of [PackageManager.updatePermissionFlags]
 */
fun PackageManager.updatePermissionFlags(
    permissionName: String,
    packageName: String,
    user: UserHandle,
    vararg flags: Pair<Int, Boolean>
) {
    val mask = flags.fold(0, { mask, (flag, _) -> mask or flag })
    val value = flags.fold(0, { mask, (flag, flagValue) -> if (flagValue) mask or flag else mask })
    updatePermissionFlags(permissionName, packageName, mask, value, user)
}
 No newline at end of file