summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/system-current.txt1
-rw-r--r--core/java/android/content/pm/PackageManager.java26
-rw-r--r--core/java/android/permission/IOnPermissionsChangeListener.aidl2
-rw-r--r--core/java/android/permission/PermissionManager.java9
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java4
-rw-r--r--services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt6
-rw-r--r--services/permission/java/com/android/server/permission/access/permission/DevicePermissionPolicy.kt15
-rw-r--r--services/permission/java/com/android/server/permission/access/permission/PermissionService.kt46
8 files changed, 75 insertions, 34 deletions
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index f3d10614123c..6ac8450d607b 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -4116,6 +4116,7 @@ package android.content.pm {
public static interface PackageManager.OnPermissionsChangedListener {
method public void onPermissionsChanged(int);
+ method @FlaggedApi("android.permission.flags.device_aware_permission_apis") public default void onPermissionsChanged(int, @NonNull String);
}
@IntDef(prefix={"FLAG_PERMISSION_"}, value={android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET, android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_REVOKE_ON_UPGRADE, android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT, android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED, android.content.pm.PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_DENIED, android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT, android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_SYSTEM_EXEMPT, android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_INSTALLER_EXEMPT, android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION, android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_ROLE, android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT, android.content.pm.PackageManager.FLAG_PERMISSION_ONE_TIME, android.content.pm.PackageManager.FLAG_PERMISSION_AUTO_REVOKED}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface PackageManager.PermissionFlags {
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index f87c8d045d05..b5d239beaba9 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -43,6 +43,7 @@ import android.app.PackageInstallObserver;
import android.app.PropertyInvalidatedCache;
import android.app.admin.DevicePolicyManager;
import android.app.usage.StorageStatsManager;
+import android.companion.virtual.VirtualDeviceManager;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledSince;
import android.compat.annotation.UnsupportedAppUsage;
@@ -710,12 +711,31 @@ public abstract class PackageManager {
*/
@SystemApi
public interface OnPermissionsChangedListener {
-
/**
- * Called when the permissions for a UID change.
+ * Called when the permissions for a UID change for the default device.
+ *
* @param uid The UID with a change.
+ * @see Context#DEVICE_ID_DEFAULT
*/
- public void onPermissionsChanged(int uid);
+ void onPermissionsChanged(int uid);
+
+ /**
+ * Called when the permissions for a UID change for a device, including virtual devices.
+ *
+ * @param uid The UID of permission change event.
+ * @param persistentDeviceId The persistent device ID of permission change event.
+ *
+ * @see VirtualDeviceManager.VirtualDevice#getPersistentDeviceId()
+ * @see VirtualDeviceManager#PERSISTENT_DEVICE_ID_DEFAULT
+ */
+ @FlaggedApi(android.permission.flags.Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS)
+ default void onPermissionsChanged(int uid, @NonNull String persistentDeviceId) {
+ Objects.requireNonNull(persistentDeviceId);
+ if (Objects.equals(persistentDeviceId,
+ VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT)) {
+ onPermissionsChanged(uid);
+ }
+ }
}
/** @hide */
diff --git a/core/java/android/permission/IOnPermissionsChangeListener.aidl b/core/java/android/permission/IOnPermissionsChangeListener.aidl
index cc52a7210737..afacf1a74ca6 100644
--- a/core/java/android/permission/IOnPermissionsChangeListener.aidl
+++ b/core/java/android/permission/IOnPermissionsChangeListener.aidl
@@ -21,5 +21,5 @@ package android.permission;
* {@hide}
*/
oneway interface IOnPermissionsChangeListener {
- void onPermissionsChanged(int uid);
+ void onPermissionsChanged(int uid, String deviceId);
}
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index e10ea10e2a29..7a158c548a38 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -1725,7 +1725,7 @@ public final class PermissionManager {
}
private final class OnPermissionsChangeListenerDelegate
- extends IOnPermissionsChangeListener.Stub implements Handler.Callback{
+ extends IOnPermissionsChangeListener.Stub implements Handler.Callback {
private static final int MSG_PERMISSIONS_CHANGED = 1;
private final PackageManager.OnPermissionsChangedListener mListener;
@@ -1738,8 +1738,8 @@ public final class PermissionManager {
}
@Override
- public void onPermissionsChanged(int uid) {
- mHandler.obtainMessage(MSG_PERMISSIONS_CHANGED, uid, 0).sendToTarget();
+ public void onPermissionsChanged(int uid, String deviceId) {
+ mHandler.obtainMessage(MSG_PERMISSIONS_CHANGED, uid, 0, deviceId).sendToTarget();
}
@Override
@@ -1747,7 +1747,8 @@ public final class PermissionManager {
switch (msg.what) {
case MSG_PERMISSIONS_CHANGED: {
final int uid = msg.arg1;
- mListener.onPermissionsChanged(uid);
+ final String deviceId = msg.obj.toString();
+ mListener.onPermissionsChanged(uid, deviceId);
return true;
}
default:
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
index 883b0666f979..8bd2d94667f9 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
@@ -70,6 +70,7 @@ import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.IActivityManager;
import android.app.admin.DevicePolicyManagerInternal;
+import android.companion.virtual.VirtualDeviceManager;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledAfter;
import android.content.Context;
@@ -5327,7 +5328,8 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
IOnPermissionsChangeListener callback = mPermissionListeners
.getBroadcastItem(i);
try {
- callback.onPermissionsChanged(uid);
+ callback.onPermissionsChanged(uid,
+ VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT);
} catch (RemoteException e) {
Log.e(TAG, "Permission listener is dead", e);
}
diff --git a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
index 010604f9aaaa..02032c786563 100644
--- a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
@@ -1706,7 +1706,7 @@ class AppIdPermissionPolicy : SchemePolicy() {
}
/** Listener for permission flags changes. */
- abstract class OnPermissionFlagsChangedListener {
+ interface OnPermissionFlagsChangedListener {
/**
* Called when a permission flags change has been made to the upcoming new state.
*
@@ -1714,7 +1714,7 @@ class AppIdPermissionPolicy : SchemePolicy() {
* and only call external code after [onStateMutated] when the new state has actually become
* the current state visible to external code.
*/
- abstract fun onPermissionFlagsChanged(
+ fun onPermissionFlagsChanged(
appId: Int,
userId: Int,
permissionName: String,
@@ -1727,6 +1727,6 @@ class AppIdPermissionPolicy : SchemePolicy() {
*
* Implementations should keep this method fast to avoid stalling the locked state mutation.
*/
- abstract fun onStateMutated()
+ fun onStateMutated()
}
}
diff --git a/services/permission/java/com/android/server/permission/access/permission/DevicePermissionPolicy.kt b/services/permission/java/com/android/server/permission/access/permission/DevicePermissionPolicy.kt
index 7db09f9125de..bb68bc5c791d 100644
--- a/services/permission/java/com/android/server/permission/access/permission/DevicePermissionPolicy.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/DevicePermissionPolicy.kt
@@ -263,10 +263,6 @@ class DevicePermissionPolicy : SchemePolicy() {
synchronized(listenersLock) { listeners = listeners + listener }
}
- fun removeOnPermissionFlagsChangedListener(listener: OnDevicePermissionFlagsChangedListener) {
- synchronized(listenersLock) { listeners = listeners - listener }
- }
-
private fun isDeviceAwarePermission(permissionName: String): Boolean =
DEVICE_AWARE_PERMISSIONS.contains(permissionName)
@@ -283,11 +279,8 @@ class DevicePermissionPolicy : SchemePolicy() {
}
}
- /**
- * TODO: b/289355341 - implement listener for permission changes Listener for permission flags
- * changes.
- */
- abstract class OnDevicePermissionFlagsChangedListener {
+ /** Listener for permission flags changes. */
+ interface OnDevicePermissionFlagsChangedListener {
/**
* Called when a permission flags change has been made to the upcoming new state.
*
@@ -295,7 +288,7 @@ class DevicePermissionPolicy : SchemePolicy() {
* and only call external code after [onStateMutated] when the new state has actually become
* the current state visible to external code.
*/
- abstract fun onDevicePermissionFlagsChanged(
+ fun onDevicePermissionFlagsChanged(
appId: Int,
userId: Int,
deviceId: String,
@@ -309,6 +302,6 @@ class DevicePermissionPolicy : SchemePolicy() {
*
* Implementations should keep this method fast to avoid stalling the locked state mutation.
*/
- abstract fun onStateMutated()
+ fun onStateMutated()
}
}
diff --git a/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt b/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
index ab3d78c9958c..0d196b48b3f2 100644
--- a/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
@@ -19,6 +19,7 @@ package com.android.server.permission.access.permission
import android.Manifest
import android.app.ActivityManager
import android.app.AppOpsManager
+import android.companion.virtual.VirtualDeviceManager
import android.compat.annotation.ChangeId
import android.compat.annotation.EnabledAfter
import android.content.Context
@@ -169,6 +170,7 @@ class PermissionService(private val service: AccessCheckingService) :
onPermissionsChangeListeners = OnPermissionsChangeListeners(FgThread.get().looper)
onPermissionFlagsChangedListener = OnPermissionFlagsChangedListener()
policy.addOnPermissionFlagsChangedListener(onPermissionFlagsChangedListener)
+ devicePolicy.addOnPermissionFlagsChangedListener(onPermissionFlagsChangedListener)
}
override fun getAllPermissionGroups(flags: Int): List<PermissionGroupInfo> {
@@ -2616,10 +2618,11 @@ class PermissionService(private val service: AccessCheckingService) :
/** Callback invoked when interesting actions have been taken on a permission. */
private inner class OnPermissionFlagsChangedListener :
- AppIdPermissionPolicy.OnPermissionFlagsChangedListener() {
+ AppIdPermissionPolicy.OnPermissionFlagsChangedListener,
+ DevicePermissionPolicy.OnDevicePermissionFlagsChangedListener {
private var isPermissionFlagsChanged = false
- private val runtimePermissionChangedUids = MutableIntSet()
+ private val runtimePermissionChangedUidDevices = MutableIntMap<MutableSet<String>>()
// Mapping from UID to whether only notifications permissions are revoked.
private val runtimePermissionRevokedUids = SparseBooleanArray()
private val gidsChangedUids = MutableIntSet()
@@ -2642,6 +2645,24 @@ class PermissionService(private val service: AccessCheckingService) :
oldFlags: Int,
newFlags: Int
) {
+ onDevicePermissionFlagsChanged(
+ appId,
+ userId,
+ VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT,
+ permissionName,
+ oldFlags,
+ newFlags
+ )
+ }
+
+ override fun onDevicePermissionFlagsChanged(
+ appId: Int,
+ userId: Int,
+ deviceId: String,
+ permissionName: String,
+ oldFlags: Int,
+ newFlags: Int
+ ) {
isPermissionFlagsChanged = true
val uid = UserHandle.getUid(userId, appId)
@@ -2655,12 +2676,12 @@ class PermissionService(private val service: AccessCheckingService) :
// permission flags have changed for a non-runtime permission, now we no longer do
// that because permission flags are only for runtime permissions and the listeners
// aren't being notified of non-runtime permission grant state changes anyway.
- runtimePermissionChangedUids += uid
if (wasPermissionGranted && !isPermissionGranted) {
runtimePermissionRevokedUids[uid] =
permissionName in NOTIFICATIONS_PERMISSIONS &&
runtimePermissionRevokedUids.get(uid, true)
}
+ runtimePermissionChangedUidDevices.getOrPut(uid) { mutableSetOf() } += deviceId
}
if (permission.hasGids && !wasPermissionGranted && isPermissionGranted) {
@@ -2674,10 +2695,12 @@ class PermissionService(private val service: AccessCheckingService) :
isPermissionFlagsChanged = false
}
- runtimePermissionChangedUids.forEachIndexed { _, uid ->
- onPermissionsChangeListeners.onPermissionsChanged(uid)
+ runtimePermissionChangedUidDevices.forEachIndexed { _, uid, deviceIds ->
+ deviceIds.forEach { deviceId ->
+ onPermissionsChangeListeners.onPermissionsChanged(uid, deviceId)
+ }
}
- runtimePermissionChangedUids.clear()
+ runtimePermissionChangedUidDevices.clear()
if (!isKillRuntimePermissionRevokedUidsSkipped) {
val reason =
@@ -2749,15 +2772,16 @@ class PermissionService(private val service: AccessCheckingService) :
when (msg.what) {
MSG_ON_PERMISSIONS_CHANGED -> {
val uid = msg.arg1
- handleOnPermissionsChanged(uid)
+ val deviceId = msg.obj as String
+ handleOnPermissionsChanged(uid, deviceId)
}
}
}
- private fun handleOnPermissionsChanged(uid: Int) {
+ private fun handleOnPermissionsChanged(uid: Int, deviceId: String) {
listeners.broadcast { listener ->
try {
- listener.onPermissionsChanged(uid)
+ listener.onPermissionsChanged(uid, deviceId)
} catch (e: RemoteException) {
Slog.e(LOG_TAG, "Error when calling OnPermissionsChangeListener", e)
}
@@ -2772,9 +2796,9 @@ class PermissionService(private val service: AccessCheckingService) :
listeners.unregister(listener)
}
- fun onPermissionsChanged(uid: Int) {
+ fun onPermissionsChanged(uid: Int, deviceId: String) {
if (listeners.registeredCallbackCount > 0) {
- obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0).sendToTarget()
+ obtainMessage(MSG_ON_PERMISSIONS_CHANGED, uid, 0, deviceId).sendToTarget()
}
}