Loading src/com/android/permissioncontroller/permission/data/AutoRevokeStateLiveData.kt +3 −4 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ package com.android.permissioncontroller.permission.data import android.app.AppOpsManager import android.app.AppOpsManager.MODE_ALLOWED import android.app.AppOpsManager.OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED import android.app.Application import android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT Loading @@ -28,6 +27,7 @@ import androidx.lifecycle.Observer import com.android.permissioncontroller.PermissionControllerApplication import com.android.permissioncontroller.permission.data.PackagePermissionsLiveData.Companion.NON_RUNTIME_NORMAL_PERMS import com.android.permissioncontroller.permission.model.livedatatypes.AutoRevokeState import com.android.permissioncontroller.permission.service.isPackageAutoRevokeExempt import com.android.permissioncontroller.permission.utils.KotlinUtils import com.android.permissioncontroller.permission.utils.Utils import kotlinx.coroutines.Job Loading @@ -41,7 +41,7 @@ import java.util.concurrent.TimeUnit * @param user The user for whom we want the package */ class AutoRevokeStateLiveData private constructor( app: Application, private val app: Application, private val packageName: String, private val user: UserHandle ) : SmartAsyncMediatorLiveData<AutoRevokeState>(), AppOpsManager.OnOpChangedListener { Loading Loading @@ -84,8 +84,7 @@ class AutoRevokeStateLiveData private constructor( return } val revocable = appOpsManager.unsafeCheckOpNoThrow( OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, uid, packageName) == MODE_ALLOWED val revocable = !isPackageAutoRevokeExempt(app, packageLiveData.getInitializedValue()) val autoRevokeState = mutableListOf<String>() permStateLiveDatas.forEach { (groupName, liveData) -> val default = liveData.value?.any { (_, permState) -> Loading src/com/android/permissioncontroller/permission/data/UserSensitivityLiveData.kt +2 −12 Original line number Diff line number Diff line Loading @@ -101,7 +101,8 @@ class UserSensitivityLiveData private constructor( // map of <uid, userSensitiveState> val sensitiveStatePerUid = mutableMapOf<Int, UidSensitivityState>() val runtimePerms = getAllRuntimePermNames() // TODO ntmyren: Figure out how to get custom runtime permissions in a less costly manner val runtimePerms = Utils.getRuntimePlatformPermissionNames() for (pkg in pkgs) { // sensitivityState for one uid Loading Loading @@ -159,17 +160,6 @@ class UserSensitivityLiveData private constructor( postValue(sensitiveStatePerUid) } private suspend fun getAllRuntimePermNames(): Set<String> { val permNames = mutableSetOf<String>() val allGroups = Utils.getPlatformPermissionGroups() allGroups.addAll(CustomPermGroupNamesLiveData.getInitializedValue()) for (groupName in allGroups) { val permGroup = PermGroupLiveData[groupName].getInitializedValue() ?: continue permNames.addAll(permGroup.permissionInfos.keys) } return permNames } private fun getAndObservePackageLiveDatas() { val packageNames = app.packageManager.getPackagesForUid(uid)?.toList() ?: emptyList() val (toAdd, toRemove) = KotlinUtils.getMapAndListDifferences(packageNames, packageLiveDatas) Loading src/com/android/permissioncontroller/permission/service/AutoRevokePermissions.kt +71 −11 Original line number Diff line number Diff line Loading @@ -44,9 +44,11 @@ import android.os.UserHandle import android.os.UserManager import android.permission.PermissionManager import android.provider.DeviceConfig import android.provider.Settings import android.util.Log import androidx.annotation.MainThread import com.android.permissioncontroller.Constants import com.android.permissioncontroller.PermissionControllerApplication import com.android.permissioncontroller.PermissionControllerStatsLog import com.android.permissioncontroller.PermissionControllerStatsLog.PERMISSION_GRANT_REQUEST_RESULT_REPORTED import com.android.permissioncontroller.PermissionControllerStatsLog.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_UNUSED_APP_PERMISSION_REVOKED Loading Loading @@ -80,17 +82,25 @@ import kotlin.random.Random private const val LOG_TAG = "AutoRevokePermissions" private const val DEBUG = false private val UNUSED_THRESHOLD_MS = if (DEBUG) SECONDS.toMillis(1) else DeviceConfig.getLong(DeviceConfig.NAMESPACE_PERMISSIONS, private val TEAMFOOD_SETTINGS = TeamfoodSettings.get() private val DEFAULT_UNUSED_THRESHOLD_MS = DAYS.toMillis(90) private val UNUSED_THRESHOLD_MS = when { DEBUG -> SECONDS.toMillis(1) TEAMFOOD_SETTINGS != null -> TEAMFOOD_SETTINGS.unusedThresholdMs else -> DeviceConfig.getLong(DeviceConfig.NAMESPACE_PERMISSIONS, PROPERTY_AUTO_REVOKE_UNUSED_THRESHOLD_MILLIS, DAYS.toMillis(90)) DEFAULT_UNUSED_THRESHOLD_MS) } private val CHECK_FREQUENCY_MS = DeviceConfig.getLong( private val DEFAULT_CHECK_FREQUENCY_MS = DAYS.toMillis(15) private val CHECK_FREQUENCY_MS = when { TEAMFOOD_SETTINGS != null -> TEAMFOOD_SETTINGS.checkFrequencyMs else -> DeviceConfig.getLong( DeviceConfig.NAMESPACE_PERMISSIONS, PROPERTY_AUTO_REVOKE_CHECK_FREQUENCY_MILLIS, DAYS.toMillis(1)) DEFAULT_CHECK_FREQUENCY_MS) } private val SERVER_LOG_ID = PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_UNUSED_APP_PERMISSION_REVOKED Loading Loading @@ -273,6 +283,14 @@ private suspend fun revokePermissionsOnUnusedApps(context: Context) { } } suspend fun isPackageAutoRevokeExempt( context: Context, pkg: LightPackageInfo ) = isPackageAutoRevokeExempt(pkg, withContext(IPC) { context.getSystemService<PermissionManager>() .getAutoRevokeExemptionGrantedPackages() }) private suspend fun isPackageAutoRevokeExempt( pkg: LightPackageInfo, manifestExemptPackages: Set<String> Loading Loading @@ -353,3 +371,45 @@ class AutoRevokeService : JobService() { return true } } private data class TeamfoodSettings( val enabledForPreRApps: Boolean, val unusedThresholdMs: Long, val checkFrequencyMs: Long ) { companion object { fun get(): TeamfoodSettings? { return Settings.Global.getString(USER_CONTEXT.contentResolver, "auto_revoke_parameters" /* Settings.Global.AUTO_REVOKE_PARAMETERS */)?.let { str -> if (DEBUG) { Log.i(LOG_TAG, "Parsing teamfood setting value: $str") } str.split(",") .mapNotNull { val keyValue = it.split("=") keyValue.getOrNull(0)?.let { key -> key to keyValue.getOrNull(1) } } .toMap() .let { pairs -> TeamfoodSettings( enabledForPreRApps = pairs["enabledForPreRApps"] == "true", unusedThresholdMs = pairs["unusedThresholdMs"]?.toLongOrNull() ?: DEFAULT_UNUSED_THRESHOLD_MS, checkFrequencyMs = pairs["checkFrequencyMs"]?.toLongOrNull() ?: DEFAULT_CHECK_FREQUENCY_MS) } }.also { if (DEBUG) { Log.i(LOG_TAG, "Parsed teamfood setting value: $it") } } } } } private val APP = PermissionControllerApplication.get() private val USER_CONTEXT = APP.forUser(myUserHandle()) No newline at end of file src/com/android/permissioncontroller/permission/utils/Utils.java +9 −0 Original line number Diff line number Diff line Loading @@ -590,6 +590,15 @@ public final class Utils { return new ArrayList<>(PLATFORM_PERMISSION_GROUPS.keySet()); } /** * Get the names of the runtime platform permissions * * @return the names of the runtime platform permissions. */ public static List<String> getRuntimePlatformPermissionNames() { return new ArrayList<>(PLATFORM_PERMISSIONS.keySet()); } /** * Should UI show this permission. * Loading Loading
src/com/android/permissioncontroller/permission/data/AutoRevokeStateLiveData.kt +3 −4 Original line number Diff line number Diff line Loading @@ -17,7 +17,6 @@ package com.android.permissioncontroller.permission.data import android.app.AppOpsManager import android.app.AppOpsManager.MODE_ALLOWED import android.app.AppOpsManager.OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED import android.app.Application import android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT Loading @@ -28,6 +27,7 @@ import androidx.lifecycle.Observer import com.android.permissioncontroller.PermissionControllerApplication import com.android.permissioncontroller.permission.data.PackagePermissionsLiveData.Companion.NON_RUNTIME_NORMAL_PERMS import com.android.permissioncontroller.permission.model.livedatatypes.AutoRevokeState import com.android.permissioncontroller.permission.service.isPackageAutoRevokeExempt import com.android.permissioncontroller.permission.utils.KotlinUtils import com.android.permissioncontroller.permission.utils.Utils import kotlinx.coroutines.Job Loading @@ -41,7 +41,7 @@ import java.util.concurrent.TimeUnit * @param user The user for whom we want the package */ class AutoRevokeStateLiveData private constructor( app: Application, private val app: Application, private val packageName: String, private val user: UserHandle ) : SmartAsyncMediatorLiveData<AutoRevokeState>(), AppOpsManager.OnOpChangedListener { Loading Loading @@ -84,8 +84,7 @@ class AutoRevokeStateLiveData private constructor( return } val revocable = appOpsManager.unsafeCheckOpNoThrow( OPSTR_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, uid, packageName) == MODE_ALLOWED val revocable = !isPackageAutoRevokeExempt(app, packageLiveData.getInitializedValue()) val autoRevokeState = mutableListOf<String>() permStateLiveDatas.forEach { (groupName, liveData) -> val default = liveData.value?.any { (_, permState) -> Loading
src/com/android/permissioncontroller/permission/data/UserSensitivityLiveData.kt +2 −12 Original line number Diff line number Diff line Loading @@ -101,7 +101,8 @@ class UserSensitivityLiveData private constructor( // map of <uid, userSensitiveState> val sensitiveStatePerUid = mutableMapOf<Int, UidSensitivityState>() val runtimePerms = getAllRuntimePermNames() // TODO ntmyren: Figure out how to get custom runtime permissions in a less costly manner val runtimePerms = Utils.getRuntimePlatformPermissionNames() for (pkg in pkgs) { // sensitivityState for one uid Loading Loading @@ -159,17 +160,6 @@ class UserSensitivityLiveData private constructor( postValue(sensitiveStatePerUid) } private suspend fun getAllRuntimePermNames(): Set<String> { val permNames = mutableSetOf<String>() val allGroups = Utils.getPlatformPermissionGroups() allGroups.addAll(CustomPermGroupNamesLiveData.getInitializedValue()) for (groupName in allGroups) { val permGroup = PermGroupLiveData[groupName].getInitializedValue() ?: continue permNames.addAll(permGroup.permissionInfos.keys) } return permNames } private fun getAndObservePackageLiveDatas() { val packageNames = app.packageManager.getPackagesForUid(uid)?.toList() ?: emptyList() val (toAdd, toRemove) = KotlinUtils.getMapAndListDifferences(packageNames, packageLiveDatas) Loading
src/com/android/permissioncontroller/permission/service/AutoRevokePermissions.kt +71 −11 Original line number Diff line number Diff line Loading @@ -44,9 +44,11 @@ import android.os.UserHandle import android.os.UserManager import android.permission.PermissionManager import android.provider.DeviceConfig import android.provider.Settings import android.util.Log import androidx.annotation.MainThread import com.android.permissioncontroller.Constants import com.android.permissioncontroller.PermissionControllerApplication import com.android.permissioncontroller.PermissionControllerStatsLog import com.android.permissioncontroller.PermissionControllerStatsLog.PERMISSION_GRANT_REQUEST_RESULT_REPORTED import com.android.permissioncontroller.PermissionControllerStatsLog.PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_UNUSED_APP_PERMISSION_REVOKED Loading Loading @@ -80,17 +82,25 @@ import kotlin.random.Random private const val LOG_TAG = "AutoRevokePermissions" private const val DEBUG = false private val UNUSED_THRESHOLD_MS = if (DEBUG) SECONDS.toMillis(1) else DeviceConfig.getLong(DeviceConfig.NAMESPACE_PERMISSIONS, private val TEAMFOOD_SETTINGS = TeamfoodSettings.get() private val DEFAULT_UNUSED_THRESHOLD_MS = DAYS.toMillis(90) private val UNUSED_THRESHOLD_MS = when { DEBUG -> SECONDS.toMillis(1) TEAMFOOD_SETTINGS != null -> TEAMFOOD_SETTINGS.unusedThresholdMs else -> DeviceConfig.getLong(DeviceConfig.NAMESPACE_PERMISSIONS, PROPERTY_AUTO_REVOKE_UNUSED_THRESHOLD_MILLIS, DAYS.toMillis(90)) DEFAULT_UNUSED_THRESHOLD_MS) } private val CHECK_FREQUENCY_MS = DeviceConfig.getLong( private val DEFAULT_CHECK_FREQUENCY_MS = DAYS.toMillis(15) private val CHECK_FREQUENCY_MS = when { TEAMFOOD_SETTINGS != null -> TEAMFOOD_SETTINGS.checkFrequencyMs else -> DeviceConfig.getLong( DeviceConfig.NAMESPACE_PERMISSIONS, PROPERTY_AUTO_REVOKE_CHECK_FREQUENCY_MILLIS, DAYS.toMillis(1)) DEFAULT_CHECK_FREQUENCY_MS) } private val SERVER_LOG_ID = PERMISSION_GRANT_REQUEST_RESULT_REPORTED__RESULT__AUTO_UNUSED_APP_PERMISSION_REVOKED Loading Loading @@ -273,6 +283,14 @@ private suspend fun revokePermissionsOnUnusedApps(context: Context) { } } suspend fun isPackageAutoRevokeExempt( context: Context, pkg: LightPackageInfo ) = isPackageAutoRevokeExempt(pkg, withContext(IPC) { context.getSystemService<PermissionManager>() .getAutoRevokeExemptionGrantedPackages() }) private suspend fun isPackageAutoRevokeExempt( pkg: LightPackageInfo, manifestExemptPackages: Set<String> Loading Loading @@ -353,3 +371,45 @@ class AutoRevokeService : JobService() { return true } } private data class TeamfoodSettings( val enabledForPreRApps: Boolean, val unusedThresholdMs: Long, val checkFrequencyMs: Long ) { companion object { fun get(): TeamfoodSettings? { return Settings.Global.getString(USER_CONTEXT.contentResolver, "auto_revoke_parameters" /* Settings.Global.AUTO_REVOKE_PARAMETERS */)?.let { str -> if (DEBUG) { Log.i(LOG_TAG, "Parsing teamfood setting value: $str") } str.split(",") .mapNotNull { val keyValue = it.split("=") keyValue.getOrNull(0)?.let { key -> key to keyValue.getOrNull(1) } } .toMap() .let { pairs -> TeamfoodSettings( enabledForPreRApps = pairs["enabledForPreRApps"] == "true", unusedThresholdMs = pairs["unusedThresholdMs"]?.toLongOrNull() ?: DEFAULT_UNUSED_THRESHOLD_MS, checkFrequencyMs = pairs["checkFrequencyMs"]?.toLongOrNull() ?: DEFAULT_CHECK_FREQUENCY_MS) } }.also { if (DEBUG) { Log.i(LOG_TAG, "Parsed teamfood setting value: $it") } } } } } private val APP = PermissionControllerApplication.get() private val USER_CONTEXT = APP.forUser(myUserHandle()) No newline at end of file
src/com/android/permissioncontroller/permission/utils/Utils.java +9 −0 Original line number Diff line number Diff line Loading @@ -590,6 +590,15 @@ public final class Utils { return new ArrayList<>(PLATFORM_PERMISSION_GROUPS.keySet()); } /** * Get the names of the runtime platform permissions * * @return the names of the runtime platform permissions. */ public static List<String> getRuntimePlatformPermissionNames() { return new ArrayList<>(PLATFORM_PERMISSIONS.keySet()); } /** * Should UI show this permission. * Loading