Create a system API to check permission by persistent device Id
The new system Api in PermissionManager is used to check permission against a persistent device Id. It uses the
same cache sPackageNamePermissionCache as the one used by PackageManager#checkPermission, but changes the cache to use
persistentDeviceId in the cache key instead of VDID.
Bug: b/315356442
Test: ag/26168815 atest DevicePermissionsTest
Change-Id: I6043229a70b30b71652466fed07fd151aff8883c
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 515d017..b55a39d 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -11276,6 +11276,7 @@
public final class PermissionManager {
method public int checkDeviceIdentifierAccess(@Nullable String, @Nullable String, @Nullable String, int, int);
+ method @FlaggedApi("android.permission.flags.device_aware_permission_apis_enabled") public static int checkPermission(@NonNull String, @NonNull String, @NonNull String, int);
method @RequiresPermission(value=android.Manifest.permission.UPDATE_APP_OPS_STATS, conditional=true) public int checkPermissionForDataDelivery(@NonNull String, @NonNull android.content.AttributionSource, @Nullable String);
method @RequiresPermission(value=android.Manifest.permission.UPDATE_APP_OPS_STATS, conditional=true) public int checkPermissionForDataDeliveryFromDataSource(@NonNull String, @NonNull android.content.AttributionSource, @Nullable String);
method public int checkPermissionForPreflight(@NonNull String, @NonNull android.content.AttributionSource);
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index d8aded40..3ec39b5 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -836,7 +836,7 @@
@Override
public int checkPermission(String permName, String pkgName) {
- return PermissionManager.checkPackageNamePermission(permName, pkgName,
+ return getPermissionManager().checkPackageNamePermission(permName, pkgName,
mContext.getDeviceId(), getUserId());
}
diff --git a/core/java/android/permission/IPermissionManager.aidl b/core/java/android/permission/IPermissionManager.aidl
index 471f95b..49e0634 100644
--- a/core/java/android/permission/IPermissionManager.aidl
+++ b/core/java/android/permission/IPermissionManager.aidl
@@ -96,7 +96,8 @@
boolean isRegisteredAttributionSource(in AttributionSourceState source);
- int checkPermission(String packageName, String permissionName, int deviceId, int userId);
+ int checkPermission(String packageName, String permissionName, String persistentDeviceId,
+ int userId);
int checkUidPermission(int uid, String permissionName, int deviceId);
}
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index 4af6e3a..cb71ec0 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -28,6 +28,7 @@
import android.Manifest;
import android.annotation.CheckResult;
import android.annotation.DurationMillisLong;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
@@ -45,6 +46,8 @@
import android.app.AppOpsManager;
import android.app.IActivityManager;
import android.app.PropertyInvalidatedCache;
+import android.companion.virtual.VirtualDevice;
+import android.companion.virtual.VirtualDeviceManager;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledAfter;
import android.content.AttributionSource;
@@ -68,6 +71,7 @@
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
+import android.permission.flags.Flags;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -240,6 +244,8 @@
private final LegacyPermissionManager mLegacyPermissionManager;
+ private final VirtualDeviceManager mVirtualDeviceManager;
+
private final ArrayMap<PackageManager.OnPermissionsChangedListener,
IOnPermissionsChangeListener> mPermissionListeners = new ArrayMap<>();
private PermissionUsageHelper mUsageHelper;
@@ -260,6 +266,7 @@
mPermissionManager = IPermissionManager.Stub.asInterface(ServiceManager.getServiceOrThrow(
"permissionmgr"));
mLegacyPermissionManager = context.getSystemService(LegacyPermissionManager.class);
+ mVirtualDeviceManager = context.getSystemService(VirtualDeviceManager.class);
}
/**
@@ -1642,15 +1649,15 @@
private static final class PackageNamePermissionQuery {
final String permName;
final String pkgName;
- final int deviceId;
+ final String persistentDeviceId;
@UserIdInt
final int userId;
PackageNamePermissionQuery(@Nullable String permName, @Nullable String pkgName,
- int deviceId, @UserIdInt int userId) {
+ @Nullable String persistentDeviceId, @UserIdInt int userId) {
this.permName = permName;
this.pkgName = pkgName;
- this.deviceId = deviceId;
+ this.persistentDeviceId = persistentDeviceId;
this.userId = userId;
}
@@ -1658,13 +1665,13 @@
public String toString() {
return TextUtils.formatSimple(
"PackageNamePermissionQuery(pkgName=\"%s\", permName=\"%s\", "
- + "deviceId=%s, userId=%s\")",
- pkgName, permName, deviceId, userId);
+ + "persistentDeviceId=%s, userId=%s\")",
+ pkgName, permName, persistentDeviceId, userId);
}
@Override
public int hashCode() {
- return Objects.hash(permName, pkgName, deviceId, userId);
+ return Objects.hash(permName, pkgName, persistentDeviceId, userId);
}
@Override
@@ -1680,17 +1687,17 @@
}
return Objects.equals(permName, other.permName)
&& Objects.equals(pkgName, other.pkgName)
- && deviceId == other.deviceId
+ && Objects.equals(persistentDeviceId, other.persistentDeviceId)
&& userId == other.userId;
}
}
/* @hide */
private static int checkPackageNamePermissionUncached(
- String permName, String pkgName, int deviceId, @UserIdInt int userId) {
+ String permName, String pkgName, String persistentDeviceId, @UserIdInt int userId) {
try {
return ActivityThread.getPermissionManager().checkPermission(
- pkgName, permName, deviceId, userId);
+ pkgName, permName, persistentDeviceId, userId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1704,7 +1711,7 @@
@Override
public Integer recompute(PackageNamePermissionQuery query) {
return checkPackageNamePermissionUncached(
- query.permName, query.pkgName, query.deviceId, query.userId);
+ query.permName, query.pkgName, query.persistentDeviceId, query.userId);
}
@Override
public boolean bypass(PackageNamePermissionQuery query) {
@@ -1717,10 +1724,65 @@
*
* @hide
*/
- public static int checkPackageNamePermission(String permName, String pkgName, int deviceId,
- @UserIdInt int userId) {
+ public int checkPackageNamePermission(String permName, String pkgName,
+ int deviceId, @UserIdInt int userId) {
+ String persistentDeviceId = getPersistentDeviceId(deviceId);
return sPackageNamePermissionCache.query(
- new PackageNamePermissionQuery(permName, pkgName, deviceId, userId));
+ new PackageNamePermissionQuery(permName, pkgName, persistentDeviceId, userId));
+ }
+
+ @Nullable
+ private String getPersistentDeviceId(int deviceId) {
+ String persistentDeviceId = null;
+
+ if (deviceId == Context.DEVICE_ID_DEFAULT) {
+ persistentDeviceId = VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT;
+ } else if (android.companion.virtual.flags.Flags.vdmPublicApis()) {
+ VirtualDevice virtualDevice = mVirtualDeviceManager.getVirtualDevice(deviceId);
+ if (virtualDevice == null) {
+ Slog.e(LOG_TAG, "Virtual device is not found with device Id " + deviceId);
+ return null;
+ }
+ persistentDeviceId = virtualDevice.getPersistentDeviceId();
+ if (persistentDeviceId == null) {
+ Slog.e(LOG_TAG, "Cannot find persistent device Id for " + deviceId);
+ }
+ } else {
+ Slog.e(LOG_TAG, "vdmPublicApis flag is not enabled when device Id " + deviceId
+ + "is not default.");
+ }
+ return persistentDeviceId;
+ }
+
+ /**
+ * Check whether a package has been granted a permission on a given device.
+ * <p>
+ * <strong>Note: </strong>This API returns the underlying permission state
+ * as-is and is mostly intended for permission managing system apps. To
+ * perform an access check for a certain app, please use the
+ * {@link Context#checkPermission} APIs instead.
+ *
+ * @param permissionName The name of the permission you are checking for.
+ * @param packageName The name of the package you are checking against.
+ * @param persistentDeviceId The persistent device id you are checking against.
+ * @param userId The user Id associated with context.
+ *
+ * @return If the package has the permission on the device, PERMISSION_GRANTED is
+ * returned. If it does not have the permission on the device, PERMISSION_DENIED
+ * is returned.
+ *
+ * @see PackageManager#PERMISSION_GRANTED
+ * @see PackageManager#PERMISSION_DENIED
+ *
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_DEVICE_AWARE_PERMISSION_APIS_ENABLED)
+ public static int checkPermission(@NonNull String permissionName, @NonNull String packageName,
+ @NonNull String persistentDeviceId, @UserIdInt int userId) {
+ return sPackageNamePermissionCache.query(
+ new PackageNamePermissionQuery(permissionName, packageName, persistentDeviceId,
+ userId));
}
/**
diff --git a/services/core/java/com/android/server/pm/BackgroundInstallControlService.java b/services/core/java/com/android/server/pm/BackgroundInstallControlService.java
index 200b17b..931fe29 100644
--- a/services/core/java/com/android/server/pm/BackgroundInstallControlService.java
+++ b/services/core/java/com/android/server/pm/BackgroundInstallControlService.java
@@ -24,6 +24,7 @@
import android.app.Flags;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStatsManagerInternal;
+import android.companion.virtual.VirtualDeviceManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.IBackgroundInstallControlService;
@@ -257,7 +258,7 @@
if (mPermissionManager.checkPermission(
installerPackageName,
android.Manifest.permission.INSTALL_PACKAGES,
- Context.DEVICE_ID_DEFAULT,
+ VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT,
userId)
!= PERMISSION_GRANTED) {
return;
@@ -464,7 +465,7 @@
return mPermissionManager.checkPermission(
pkgName,
android.Manifest.permission.INSTALL_PACKAGES,
- Context.DEVICE_ID_DEFAULT,
+ VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT,
userId)
== PERMISSION_GRANTED;
}
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index ac89fecc..9afdde5 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -69,6 +69,7 @@
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.admin.DevicePolicyManagerInternal;
+import android.companion.virtual.VirtualDeviceManager;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -4615,7 +4616,8 @@
for (int i=0; i<permissions.length; i++) {
final String permission = permissions[i];
if (mPermissionManager.checkPermission(ps.getPackageName(), permission,
- Context.DEVICE_ID_DEFAULT, userId) == PERMISSION_GRANTED) {
+ VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT, userId)
+ == PERMISSION_GRANTED) {
tmp[i] = true;
numMatch++;
} else {
diff --git a/services/core/java/com/android/server/pm/DumpHelper.java b/services/core/java/com/android/server/pm/DumpHelper.java
index 2a00a44..104e8be 100644
--- a/services/core/java/com/android/server/pm/DumpHelper.java
+++ b/services/core/java/com/android/server/pm/DumpHelper.java
@@ -22,8 +22,8 @@
import static com.android.server.pm.PackageManagerServiceUtils.dumpCriticalInfo;
import android.annotation.NonNull;
+import android.companion.virtual.VirtualDeviceManager;
import android.content.ComponentName;
-import android.content.Context;
import android.content.pm.FeatureInfo;
import android.content.pm.PackageManager;
import android.os.Binder;
@@ -162,7 +162,7 @@
PackageManager.VERSION_CODE_HIGHEST);
pw.println(mPermissionManager.checkPermission(
- pkg, perm, Context.DEVICE_ID_DEFAULT, user));
+ pkg, perm, VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT, user));
return;
} else if ("l".equals(cmd) || "libraries".equals(cmd)) {
dumpState.setDump(DumpState.DUMP_LIBS);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index b8960da..83dd0e8 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -65,6 +65,7 @@
import android.app.admin.SecurityLog;
import android.app.backup.IBackupManager;
import android.app.role.RoleManager;
+import android.companion.virtual.VirtualDeviceManager;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledAfter;
import android.content.BroadcastReceiver;
@@ -2993,8 +2994,8 @@
// NOTE: Can't remove due to unsupported app usage
public int checkPermission(String permName, String pkgName, int userId) {
- return mPermissionManager.checkPermission(pkgName, permName, Context.DEVICE_ID_DEFAULT,
- userId);
+ return mPermissionManager.checkPermission(pkgName, permName,
+ VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT, userId);
}
public String getSdkSandboxPackageName() {
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 40f2264..240e37e 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -217,7 +217,7 @@
@Override
@PackageManager.PermissionResult
- public int checkPermission(String packageName, String permissionName, int deviceId,
+ public int checkPermission(String packageName, String permissionName, String persistentDeviceId,
@UserIdInt int userId) {
// Not using Objects.requireNonNull() here for compatibility reasons.
if (packageName == null || permissionName == null) {
@@ -231,10 +231,10 @@
if (checkPermissionDelegate == null) {
return mPermissionManagerServiceImpl.checkPermission(packageName, permissionName,
- deviceId, userId);
+ persistentDeviceId, userId);
}
return checkPermissionDelegate.checkPermission(packageName, permissionName,
- deviceId, userId, mPermissionManagerServiceImpl::checkPermission);
+ persistentDeviceId, userId, mPermissionManagerServiceImpl::checkPermission);
}
@Override
@@ -620,9 +620,9 @@
private class PermissionManagerServiceInternalImpl implements PermissionManagerServiceInternal {
@Override
public int checkPermission(@NonNull String packageName, @NonNull String permissionName,
- int deviceId, @UserIdInt int userId) {
+ @NonNull String persistentDeviceId, @UserIdInt int userId) {
return PermissionManagerService.this.checkPermission(packageName, permissionName,
- deviceId, userId);
+ persistentDeviceId, userId);
}
@Override
@@ -888,7 +888,7 @@
*
* @param packageName the name of the package to be checked
* @param permissionName the name of the permission to be checked
- * @param deviceId The device ID
+ * @param persistentDeviceId The persistent device ID
* @param userId the user ID
* @param superImpl the original implementation that can be delegated to
* @return {@link android.content.pm.PackageManager#PERMISSION_GRANTED} if the package has
@@ -897,8 +897,8 @@
* @see android.content.pm.PackageManager#checkPermission(String, String)
*/
int checkPermission(@NonNull String packageName, @NonNull String permissionName,
- int deviceId, @UserIdInt int userId,
- @NonNull QuadFunction<String, String, Integer, Integer, Integer> superImpl);
+ String persistentDeviceId, @UserIdInt int userId,
+ @NonNull QuadFunction<String, String, String, Integer, Integer> superImpl);
/**
* Check whether the given UID has been granted the specified permission.
@@ -940,18 +940,19 @@
@Override
public int checkPermission(@NonNull String packageName, @NonNull String permissionName,
- int deviceId, int userId,
- @NonNull QuadFunction<String, String, Integer, Integer, Integer> superImpl) {
+ String persistentDeviceId, int userId,
+ @NonNull QuadFunction<String, String, String, Integer, Integer> superImpl) {
if (mDelegatedPackageName.equals(packageName)
&& isDelegatedPermission(permissionName)) {
final long identity = Binder.clearCallingIdentity();
try {
- return superImpl.apply("com.android.shell", permissionName, deviceId, userId);
+ return superImpl.apply("com.android.shell", permissionName, persistentDeviceId,
+ userId);
} finally {
Binder.restoreCallingIdentity(identity);
}
}
- return superImpl.apply(packageName, permissionName, deviceId, userId);
+ return superImpl.apply(packageName, permissionName, persistentDeviceId, userId);
}
@Override
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 6a57362..c33f1eb 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
@@ -910,11 +910,13 @@
}
private int checkPermission(String pkgName, String permName, int userId) {
- return checkPermission(pkgName, permName, Context.DEVICE_ID_DEFAULT, userId);
+ return checkPermission(pkgName, permName, VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT,
+ userId);
}
@Override
- public int checkPermission(String pkgName, String permName, int deviceId, int userId) {
+ public int checkPermission(String pkgName, String permName, String persistentDeviceId,
+ int userId) {
if (!mUserManagerInt.exists(userId)) {
return PackageManager.PERMISSION_DENIED;
}
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInterface.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInterface.java
index 2d824aa..d221515 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInterface.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInterface.java
@@ -387,11 +387,12 @@
*
* @param pkgName package name
* @param permName permission name
- * @param deviceId device ID
+ * @param persistentDeviceId persistent device ID
* @param userId user ID
* @return permission result {@link PackageManager.PermissionResult}
*/
- int checkPermission(String pkgName, String permName, int deviceId, @UserIdInt int userId);
+ int checkPermission(String pkgName, String permName, String persistentDeviceId,
+ @UserIdInt int userId);
/**
* Check whether a permission is granted or not to an UID.
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
index 98adeb6..132cdce 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
@@ -46,14 +46,14 @@
*
* @param packageName the name of the package you are checking against
* @param permissionName the name of the permission you are checking for
- * @param deviceId the device ID
+ * @param persistentDeviceId the persistent device ID to check permission for
* @param userId the user ID
* @return {@code PERMISSION_GRANTED} if the permission is granted, or {@code PERMISSION_DENIED}
* otherwise
*/
//@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
- int checkPermission(@NonNull String packageName, @NonNull String permissionName, int deviceId,
- @UserIdInt int userId);
+ int checkPermission(@NonNull String packageName, @NonNull String permissionName,
+ @NonNull String persistentDeviceId, @UserIdInt int userId);
/**
* Check whether a particular UID has been granted a particular permission.
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceLoggingDecorator.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceLoggingDecorator.java
index dacb8c6..e6e84f9 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceLoggingDecorator.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceLoggingDecorator.java
@@ -230,10 +230,11 @@
}
@Override
- public int checkPermission(String pkgName, String permName, int deviceId, int userId) {
+ public int checkPermission(String pkgName, String permName, String persistentDeviceId,
+ int userId) {
Log.i(LOG_TAG, "checkPermission(pkgName = " + pkgName + ", permName = " + permName
- + ", deviceId = " + deviceId + ", userId = " + userId + ")");
- return mService.checkPermission(pkgName, permName, deviceId, userId);
+ + ", persistentDeviceId = " + persistentDeviceId + ", userId = " + userId + ")");
+ return mService.checkPermission(pkgName, permName, persistentDeviceId, userId);
}
@Override
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceTestingShim.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceTestingShim.java
index 35d165b..36b2135 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceTestingShim.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceTestingShim.java
@@ -296,9 +296,12 @@
}
@Override
- public int checkPermission(String pkgName, String permName, int deviceId, int userId) {
- int oldVal = mOldImplementation.checkPermission(pkgName, permName, deviceId, userId);
- int newVal = mNewImplementation.checkPermission(pkgName, permName, deviceId, userId);
+ public int checkPermission(String pkgName, String permName, String persistentDeviceId,
+ int userId) {
+ int oldVal = mOldImplementation.checkPermission(pkgName, permName, persistentDeviceId,
+ userId);
+ int newVal = mNewImplementation.checkPermission(pkgName, permName, persistentDeviceId,
+ userId);
if (!Objects.equals(oldVal, newVal)) {
signalImplDifference("checkPermission");
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceTracingDecorator.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceTracingDecorator.java
index cbeede0..eafd907 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceTracingDecorator.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceTracingDecorator.java
@@ -324,10 +324,11 @@
}
@Override
- public int checkPermission(String pkgName, String permName, int deviceId, int userId) {
+ public int checkPermission(String pkgName, String permName, String persistentDeviceId,
+ int userId) {
Trace.traceBegin(TRACE_TAG, "TaggedTracingPermissionManagerServiceImpl#checkPermission");
try {
- return mService.checkPermission(pkgName, permName, deviceId, userId);
+ return mService.checkPermission(pkgName, permName, persistentDeviceId, userId);
} finally {
Trace.traceEnd(TRACE_TAG);
}
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 097d73a..7d8cbe6 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
@@ -423,6 +423,7 @@
with(policy) { removePermission(permission) }
}
}
+
private fun GetStateScope.getAndEnforcePermissionTree(permissionName: String): Permission {
val callingUid = Binder.getCallingUid()
val permissionTree = with(policy) { findPermissionTree(permissionName) }
@@ -486,9 +487,16 @@
)
return PackageManager.PERMISSION_DENIED
}
+
+ val persistentDeviceId = getPersistentDeviceId(deviceId)
+ if (persistentDeviceId == null) {
+ Slog.e(LOG_TAG, "Cannot find persistent device id for $deviceId.")
+ return PackageManager.PERMISSION_DENIED
+ }
+
val isPermissionGranted =
service.getState {
- isPermissionGranted(packageState, userId, permissionName, deviceId)
+ isPermissionGranted(packageState, userId, permissionName, persistentDeviceId)
}
return if (isPermissionGranted) {
PackageManager.PERMISSION_GRANTED
@@ -522,7 +530,7 @@
override fun checkPermission(
packageName: String,
permissionName: String,
- deviceId: Int,
+ persistentDeviceId: String,
userId: Int
): Int {
if (!userManagerInternal.exists(userId)) {
@@ -536,7 +544,9 @@
?: return PackageManager.PERMISSION_DENIED
val isPermissionGranted =
- service.getState { isPermissionGranted(packageState, userId, permissionName, deviceId) }
+ service.getState {
+ isPermissionGranted(packageState, userId, permissionName, persistentDeviceId)
+ }
return if (isPermissionGranted) {
PackageManager.PERMISSION_GRANTED
} else {
@@ -554,13 +564,21 @@
packageState: PackageState,
userId: Int,
permissionName: String,
- deviceId: Int
+ persistentDeviceId: String
): Boolean {
val appId = packageState.appId
// Note that instant apps can't have shared UIDs, so we only need to check the current
// package state.
val isInstantApp = packageState.getUserStateOrDefault(userId).isInstantApp
- if (isSinglePermissionGranted(appId, userId, isInstantApp, permissionName, deviceId)) {
+ if (
+ isSinglePermissionGranted(
+ appId,
+ userId,
+ isInstantApp,
+ permissionName,
+ persistentDeviceId
+ )
+ ) {
return true
}
@@ -572,7 +590,7 @@
userId,
isInstantApp,
fullerPermissionName,
- deviceId
+ persistentDeviceId
)
) {
return true
@@ -587,9 +605,9 @@
userId: Int,
isInstantApp: Boolean,
permissionName: String,
- deviceId: Int,
+ persistentDeviceId: String,
): Boolean {
- val flags = getPermissionFlagsWithPolicy(appId, userId, permissionName, deviceId)
+ val flags = getPermissionFlagsWithPolicy(appId, userId, permissionName, persistentDeviceId)
if (!PermissionFlags.isPermissionGranted(flags)) {
return false
}
@@ -626,7 +644,7 @@
packageState,
userId,
permissionName,
- Context.DEVICE_ID_DEFAULT
+ VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT
)
) {
permissionName
@@ -956,12 +974,21 @@
}
val appId = packageState.appId
- val oldFlags = getPermissionFlagsWithPolicy(appId, userId, permissionName, deviceId)
+ val persistentDeviceId = getPersistentDeviceId(deviceId)
+ if (persistentDeviceId == null) {
+ if (reportError) {
+ throw IllegalArgumentException("Cannot find persistent device Id for $deviceId")
+ }
+ return
+ }
+ val oldFlags =
+ getPermissionFlagsWithPolicy(appId, userId, permissionName, persistentDeviceId)
if (permissionName !in androidPackage.requestedPermissions && oldFlags == 0) {
if (reportError) {
Slog.e(
- LOG_TAG, "Permission $permissionName isn't requested by package $packageName"
+ LOG_TAG,
+ "Permission $permissionName isn't requested by package $packageName"
)
}
return
@@ -1096,8 +1123,18 @@
return 0
}
+ val persistentDeviceId = getPersistentDeviceId(deviceId)
+ if (persistentDeviceId == null) {
+ Slog.w(LOG_TAG, "Cannot find persistent device Id for $deviceId")
+ return 0
+ }
val flags =
- getPermissionFlagsWithPolicy(packageState.appId, userId, permissionName, deviceId)
+ getPermissionFlagsWithPolicy(
+ packageState.appId,
+ userId,
+ permissionName,
+ persistentDeviceId
+ )
return PermissionFlags.toApiFlags(flags)
}
@@ -1127,13 +1164,24 @@
}
?: return false
+ val persistentDeviceId = getPersistentDeviceId(deviceId)
+ if (persistentDeviceId == null) {
+ Slog.w(LOG_TAG, "Cannot find persistent device Id for $deviceId")
+ return false
+ }
+
service.getState {
- if (isPermissionGranted(packageState, userId, permissionName, deviceId)) {
+ if (isPermissionGranted(packageState, userId, permissionName, persistentDeviceId)) {
return false
}
val flags =
- getPermissionFlagsWithPolicy(packageState.appId, userId, permissionName, deviceId)
+ getPermissionFlagsWithPolicy(
+ packageState.appId,
+ userId,
+ permissionName,
+ persistentDeviceId
+ )
return flags.hasBits(PermissionFlags.POLICY_FIXED)
}
@@ -1183,13 +1231,19 @@
return false
}
+ val persistentDeviceId = getPersistentDeviceId(deviceId)
+ if (persistentDeviceId == null) {
+ Slog.w(LOG_TAG, "Cannot find persistent device Id for $deviceId")
+ return false
+ }
+
val flags: Int
service.getState {
- if (isPermissionGranted(packageState, userId, permissionName, deviceId)) {
+ if (isPermissionGranted(packageState, userId, permissionName, persistentDeviceId)) {
return false
}
- flags = getPermissionFlagsWithPolicy(appId, userId, permissionName, deviceId)
+ flags = getPermissionFlagsWithPolicy(appId, userId, permissionName, persistentDeviceId)
}
if (flags.hasAnyBit(UNREQUESTABLE_MASK)) {
return false
@@ -1463,7 +1517,13 @@
return
}
- val oldFlags = getPermissionFlagsWithPolicy(appId, userId, permissionName, deviceId)
+ val persistentDeviceId = getPersistentDeviceId(deviceId)
+ if (persistentDeviceId == null) {
+ Slog.e(LOG_TAG, "Cannot find persistent device Id for $deviceId")
+ return
+ }
+ val oldFlags =
+ getPermissionFlagsWithPolicy(appId, userId, permissionName, persistentDeviceId)
if (!isPermissionRequested && oldFlags == 0) {
Slog.w(
LOG_TAG,
@@ -1549,10 +1609,12 @@
appId: Int,
userId: Int,
permissionName: String,
- deviceId: Int,
+ persistentDeviceId: String,
): Int {
- return if (!Flags.deviceAwarePermissionApisEnabled() ||
- deviceId == Context.DEVICE_ID_DEFAULT) {
+ return if (
+ !Flags.deviceAwarePermissionApisEnabled() ||
+ persistentDeviceId == VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT
+ ) {
with(policy) { getPermissionFlags(appId, userId, permissionName) }
} else {
if (permissionName !in DEVICE_AWARE_PERMISSIONS) {
@@ -1563,19 +1625,8 @@
)
return with(policy) { getPermissionFlags(appId, userId, permissionName) }
}
- val virtualDeviceManagerInternal = virtualDeviceManagerInternal
- if (virtualDeviceManagerInternal == null) {
- Slog.e(LOG_TAG, "Virtual device manager service is not available.")
- return 0
- }
- val persistentDeviceId = virtualDeviceManagerInternal.getPersistentIdForDevice(deviceId)
- if (persistentDeviceId != null) {
- with(devicePolicy) {
- getPermissionFlags(appId, persistentDeviceId, userId, permissionName)
- }
- } else {
- Slog.e(LOG_TAG, "Invalid device ID $deviceId.")
- 0
+ with(devicePolicy) {
+ getPermissionFlags(appId, persistentDeviceId, userId, permissionName)
}
}
}
@@ -1587,8 +1638,9 @@
deviceId: Int,
flags: Int
): Boolean {
- return if (!Flags.deviceAwarePermissionApisEnabled() ||
- deviceId == Context.DEVICE_ID_DEFAULT) {
+ return if (
+ !Flags.deviceAwarePermissionApisEnabled() || deviceId == Context.DEVICE_ID_DEFAULT
+ ) {
with(policy) { setPermissionFlags(appId, userId, permissionName, flags) }
} else {
if (permissionName !in DEVICE_AWARE_PERMISSIONS) {
@@ -1600,23 +1652,30 @@
return with(policy) { setPermissionFlags(appId, userId, permissionName, flags) }
}
- val virtualDeviceManagerInternal = virtualDeviceManagerInternal
- if (virtualDeviceManagerInternal == null) {
- Slog.e(LOG_TAG, "Virtual device manager service is not available.")
- return false
- }
- val persistentDeviceId = virtualDeviceManagerInternal.getPersistentIdForDevice(deviceId)
+ val persistentDeviceId = getPersistentDeviceId(deviceId)
if (persistentDeviceId != null) {
with(devicePolicy) {
setPermissionFlags(appId, persistentDeviceId, userId, permissionName, flags)
}
} else {
- Slog.e(LOG_TAG, "Invalid device ID $deviceId.")
+ Slog.e(LOG_TAG, "Cannot find persistent device Id for $deviceId")
false
}
}
}
+ private fun getPersistentDeviceId(deviceId: Int): String? {
+ if (deviceId == Context.DEVICE_ID_DEFAULT) {
+ return VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT
+ }
+
+ if (virtualDeviceManagerInternal == null) {
+ virtualDeviceManagerInternal =
+ LocalServices.getService(VirtualDeviceManagerInternal::class.java)
+ }
+ return virtualDeviceManagerInternal?.getPersistentIdForDevice(deviceId)
+ }
+
/**
* This method does not enforce checks on the caller, should only be called after required
* checks.
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java
index bb91939..067dd3b 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BackgroundRestrictionTest.java
@@ -113,6 +113,7 @@
import android.app.NotificationManager;
import android.app.role.RoleManager;
import android.app.usage.AppStandbyInfo;
+import android.companion.virtual.VirtualDeviceManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -2439,7 +2440,8 @@
doReturn(granted ? PERMISSION_GRANTED : PERMISSION_DENIED)
.when(mPermissionManagerServiceInternal)
.checkPermission(
- packageName, perm, Context.DEVICE_ID_DEFAULT, UserHandle.getUserId(uid));
+ packageName, perm, VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT,
+ UserHandle.getUserId(uid));
try {
doReturn(granted ? PERMISSION_GRANTED : PERMISSION_DENIED)
.when(mIActivityManager)
diff --git a/services/tests/servicestests/src/com/android/server/pm/BackgroundInstallControlServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/BackgroundInstallControlServiceTest.java
index 8656f60..8ef716f 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BackgroundInstallControlServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BackgroundInstallControlServiceTest.java
@@ -405,7 +405,7 @@
0, mBackgroundInstallControlService.getInstallerForegroundTimeFrames().numMaps());
doReturn(PackageManager.PERMISSION_DENIED)
.when(mPermissionManager)
- .checkPermission(anyString(), anyString(), anyInt(), anyInt());
+ .checkPermission(anyString(), anyString(), anyString(), anyInt());
generateUsageEvent(UsageEvents.Event.ACTIVITY_RESUMED, USER_ID_1, INSTALLER_NAME_1, 0);
mTestLooper.dispatchAll();
assertEquals(
@@ -418,7 +418,7 @@
0, mBackgroundInstallControlService.getInstallerForegroundTimeFrames().numMaps());
doReturn(PERMISSION_GRANTED)
.when(mPermissionManager)
- .checkPermission(anyString(), anyString(), anyInt(), anyInt());
+ .checkPermission(anyString(), anyString(), anyString(), anyInt());
generateUsageEvent(UsageEvents.Event.ACTIVITY_RESUMED, USER_ID_1, INSTALLER_NAME_1, 0);
mTestLooper.dispatchAll();
assertEquals(
@@ -431,7 +431,7 @@
0, mBackgroundInstallControlService.getInstallerForegroundTimeFrames().numMaps());
doReturn(PERMISSION_GRANTED)
.when(mPermissionManager)
- .checkPermission(anyString(), anyString(), anyInt(), anyInt());
+ .checkPermission(anyString(), anyString(), anyString(), anyInt());
generateUsageEvent(UsageEvents.Event.USER_INTERACTION, USER_ID_1, INSTALLER_NAME_1, 0);
mTestLooper.dispatchAll();
assertEquals(
@@ -444,7 +444,7 @@
0, mBackgroundInstallControlService.getInstallerForegroundTimeFrames().numMaps());
doReturn(PERMISSION_GRANTED)
.when(mPermissionManager)
- .checkPermission(anyString(), anyString(), anyInt(), anyInt());
+ .checkPermission(anyString(), anyString(), anyString(), anyInt());
generateUsageEvent(
UsageEvents.Event.ACTIVITY_RESUMED,
USER_ID_1,
@@ -471,7 +471,7 @@
0, mBackgroundInstallControlService.getInstallerForegroundTimeFrames().numMaps());
doReturn(PERMISSION_GRANTED)
.when(mPermissionManager)
- .checkPermission(anyString(), anyString(), anyInt(), anyInt());
+ .checkPermission(anyString(), anyString(), anyString(), anyInt());
generateUsageEvent(
UsageEvents.Event.ACTIVITY_RESUMED,
USER_ID_1,
@@ -500,7 +500,7 @@
0, mBackgroundInstallControlService.getInstallerForegroundTimeFrames().numMaps());
doReturn(PERMISSION_GRANTED)
.when(mPermissionManager)
- .checkPermission(anyString(), anyString(), anyInt(), anyInt());
+ .checkPermission(anyString(), anyString(), anyString(), anyInt());
generateUsageEvent(
UsageEvents.Event.ACTIVITY_RESUMED,
USER_ID_1,
@@ -538,7 +538,7 @@
0, mBackgroundInstallControlService.getInstallerForegroundTimeFrames().numMaps());
doReturn(PERMISSION_GRANTED)
.when(mPermissionManager)
- .checkPermission(anyString(), anyString(), anyInt(), anyInt());
+ .checkPermission(anyString(), anyString(), anyString(), anyInt());
generateUsageEvent(
Event.ACTIVITY_STOPPED, USER_ID_1, INSTALLER_NAME_1, USAGE_EVENT_TIMESTAMP_1);
mTestLooper.dispatchAll();
@@ -622,7 +622,7 @@
// mBackgroundInstallControlService.getBackgroundInstalledPackages()
doReturn(PERMISSION_GRANTED)
.when(mPermissionManager)
- .checkPermission(anyString(), anyString(), anyInt(), anyInt());
+ .checkPermission(anyString(), anyString(), anyString(), anyInt());
generateUsageEvent(
UsageEvents.Event.ACTIVITY_RESUMED,
USER_ID_1,
@@ -671,7 +671,7 @@
// mBackgroundInstallControlService.getBackgroundInstalledPackages()
doReturn(PERMISSION_GRANTED)
.when(mPermissionManager)
- .checkPermission(anyString(), anyString(), anyInt(), anyInt());
+ .checkPermission(anyString(), anyString(), anyString(), anyInt());
generateUsageEvent(
UsageEvents.Event.ACTIVITY_RESUMED,
USER_ID_1,
@@ -725,7 +725,7 @@
// mBackgroundInstallControlService.getBackgroundInstalledPackages()
doReturn(PERMISSION_GRANTED)
.when(mPermissionManager)
- .checkPermission(anyString(), anyString(), anyInt(), anyInt());
+ .checkPermission(anyString(), anyString(), anyString(), anyInt());
generateUsageEvent(
UsageEvents.Event.ACTIVITY_RESUMED,
USER_ID_2,
@@ -780,7 +780,7 @@
// install getBackgroundInstalledPackages() is expected to return null
doReturn(PERMISSION_GRANTED)
.when(mPermissionManager)
- .checkPermission(anyString(), anyString(), anyInt(), anyInt());
+ .checkPermission(anyString(), anyString(), anyString(), anyInt());
generateUsageEvent(
UsageEvents.Event.ACTIVITY_RESUMED,
USER_ID_1,
@@ -833,7 +833,7 @@
// install getBackgroundInstalledPackages() is expected to return null
doReturn(PERMISSION_GRANTED)
.when(mPermissionManager)
- .checkPermission(anyString(), anyString(), anyInt(), anyInt());
+ .checkPermission(anyString(), anyString(), anyString(), anyInt());
generateUsageEvent(
UsageEvents.Event.ACTIVITY_RESUMED,
USER_ID_1,