summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/ForegroundServiceTypePolicy.java47
1 files changed, 41 insertions, 6 deletions
diff --git a/core/java/android/app/ForegroundServiceTypePolicy.java b/core/java/android/app/ForegroundServiceTypePolicy.java
index 6efc4ef55180..3003b79435e2 100644
--- a/core/java/android/app/ForegroundServiceTypePolicy.java
+++ b/core/java/android/app/ForegroundServiceTypePolicy.java
@@ -49,11 +49,14 @@ import android.annotation.Nullable;
import android.annotation.SuppressLint;
import android.app.compat.CompatChanges;
import android.app.role.RoleManager;
+import android.companion.virtual.VirtualDevice;
+import android.companion.virtual.VirtualDeviceManager;
import android.compat.Compatibility;
import android.compat.annotation.ChangeId;
import android.compat.annotation.Disabled;
import android.compat.annotation.EnabledAfter;
import android.compat.annotation.Overridable;
+import android.content.AttributionSource;
import android.content.Context;
import android.content.PermissionChecker;
import android.content.pm.PackageManager;
@@ -67,6 +70,7 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.permission.PermissionCheckerManager;
+import android.permission.PermissionManager;
import android.provider.DeviceConfig;
import android.text.TextUtils;
import android.util.ArrayMap;
@@ -1174,17 +1178,48 @@ public abstract class ForegroundServiceTypePolicy {
@PackageManager.PermissionResult
public int checkPermission(@NonNull Context context, int callerUid, int callerPid,
String packageName, boolean allowWhileInUse) {
- return checkPermission(context, mName, callerUid, callerPid, packageName,
- allowWhileInUse);
+ int permissionResult = checkPermission(context, mName, callerUid, callerPid,
+ packageName, allowWhileInUse, Context.DEVICE_ID_DEFAULT);
+
+ if (permissionResult == PERMISSION_GRANTED
+ || !PermissionManager.DEVICE_AWARE_PERMISSIONS.contains(mName)) {
+ return permissionResult;
+ }
+
+ // For device aware permissions, check if the permission is granted on any other
+ // active virtual device
+ VirtualDeviceManager vdm = context.getSystemService(VirtualDeviceManager.class);
+ if (vdm == null) {
+ return permissionResult;
+ }
+
+ final List<VirtualDevice> virtualDevices = vdm.getVirtualDevices();
+ for (int i = 0, size = virtualDevices.size(); i < size; i++) {
+ final VirtualDevice virtualDevice = virtualDevices.get(i);
+ int resolvedDeviceId = PermissionManager.resolveDeviceIdForPermissionCheck(
+ context, virtualDevice.getDeviceId(), mName);
+ // we already checked on the default device context
+ if (resolvedDeviceId == Context.DEVICE_ID_DEFAULT) {
+ continue;
+ }
+ permissionResult = checkPermission(context, mName, callerUid, callerPid,
+ packageName, allowWhileInUse, resolvedDeviceId);
+ if (permissionResult == PERMISSION_GRANTED) {
+ break;
+ }
+ }
+
+ return permissionResult;
}
@SuppressLint("AndroidFrameworkRequiresPermission")
@PackageManager.PermissionResult
int checkPermission(@NonNull Context context, @NonNull String name, int callerUid,
- int callerPid, String packageName, boolean allowWhileInUse) {
+ int callerPid, String packageName, boolean allowWhileInUse, int deviceId) {
+ final AttributionSource attributionSource = new AttributionSource(callerUid,
+ packageName, null /*attributionTag*/, deviceId);
@PermissionCheckerManager.PermissionResult final int result =
- PermissionChecker.checkPermissionForPreflight(context, name,
- callerPid, callerUid, packageName);
+ PermissionChecker.checkPermissionForPreflight(context, name, attributionSource);
if (result == PERMISSION_HARD_DENIED) {
// If the user didn't grant this permission at all.
return PERMISSION_DENIED;
@@ -1196,7 +1231,7 @@ public abstract class ForegroundServiceTypePolicy {
? PERMISSION_GRANTED : PERMISSION_DENIED;
}
final AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
- final int mode = appOpsManager.unsafeCheckOpRawNoThrow(opCode, callerUid, packageName);
+ final int mode = appOpsManager.unsafeCheckOpRawNoThrow(opCode, attributionSource);
switch (mode) {
case MODE_ALLOWED:
// The appop is just allowed, plain and simple.