Add internal APIs to check if a given app has USB permission or not

Bug: 254662522
Bug: 246792057
Test: CtsAppFgsTestCases from follow-up CLs
Change-Id: I943a6df64ae0b58ffd25e745b68d11e18f00b16b
diff --git a/core/java/android/hardware/usb/IUsbManager.aidl b/core/java/android/hardware/usb/IUsbManager.aidl
index 5a44244..51236fe3 100644
--- a/core/java/android/hardware/usb/IUsbManager.aidl
+++ b/core/java/android/hardware/usb/IUsbManager.aidl
@@ -79,9 +79,20 @@
     /* Returns true if the caller has permission to access the device. */
     boolean hasDevicePermission(in UsbDevice device, String packageName);
 
+    /* Returns true if the given package/pid/uid has permission to access the device. */
+    @JavaPassthrough(annotation=
+            "@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_USB)")
+    boolean hasDevicePermissionWithIdentity(in UsbDevice device, String packageName,
+            int pid, int uid);
+
     /* Returns true if the caller has permission to access the accessory. */
     boolean hasAccessoryPermission(in UsbAccessory accessory);
 
+    /* Returns true if the given pid/uid has permission to access the accessory. */
+    @JavaPassthrough(annotation=
+            "@android.annotation.RequiresPermission(android.Manifest.permission.MANAGE_USB)")
+    boolean hasAccessoryPermissionWithIdentity(in UsbAccessory accessory, int pid, int uid);
+
     /* Requests permission for the given package to access the device.
      * Will display a system dialog to query the user if permission
      * had not already been given.
diff --git a/core/java/android/hardware/usb/UsbManager.java b/core/java/android/hardware/usb/UsbManager.java
index 2c38f70..50dd0064 100644
--- a/core/java/android/hardware/usb/UsbManager.java
+++ b/core/java/android/hardware/usb/UsbManager.java
@@ -838,6 +838,28 @@
     }
 
     /**
+     * Returns true if the caller has permission to access the device. It's similar to the
+     * {@link #hasPermission(UsbDevice)} but allows to specify a different package/uid/pid.
+     *
+     * <p>Not for third-party apps.</p>
+     *
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.MANAGE_USB)
+    @RequiresFeature(PackageManager.FEATURE_USB_HOST)
+    public boolean hasPermission(@NonNull UsbDevice device, @NonNull String packageName,
+            int pid, int uid) {
+        if (mService == null) {
+            return false;
+        }
+        try {
+            return mService.hasDevicePermissionWithIdentity(device, packageName, pid, uid);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
      * Returns true if the caller has permission to access the accessory.
      * Permission might have been granted temporarily via
      * {@link #requestPermission(UsbAccessory, PendingIntent)} or
@@ -859,6 +881,27 @@
     }
 
     /**
+     * Returns true if the caller has permission to access the accessory. It's similar to the
+     * {@link #hasPermission(UsbAccessory)} but allows to specify a different uid/pid.
+     *
+     * <p>Not for third-party apps.</p>
+     *
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.MANAGE_USB)
+    @RequiresFeature(PackageManager.FEATURE_USB_ACCESSORY)
+    public boolean hasPermission(@NonNull UsbAccessory accessory, int pid, int uid) {
+        if (mService == null) {
+            return false;
+        }
+        try {
+            return mService.hasAccessoryPermissionWithIdentity(accessory, pid, uid);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+   /**
      * Requests temporary permission for the given package to access the device.
      * This may result in a system dialog being displayed to the user
      * if permission had not already been granted.
diff --git a/services/usb/java/com/android/server/usb/UsbService.java b/services/usb/java/com/android/server/usb/UsbService.java
index 86f877f..72f6cc3 100644
--- a/services/usb/java/com/android/server/usb/UsbService.java
+++ b/services/usb/java/com/android/server/usb/UsbService.java
@@ -504,6 +504,15 @@
     }
 
     @Override
+    public boolean hasDevicePermissionWithIdentity(UsbDevice device, String packageName,
+            int pid, int uid) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
+
+        final int userId = UserHandle.getUserId(uid);
+        return getPermissionsForUser(userId).hasPermission(device, packageName, pid, uid);
+    }
+
+    @Override
     public boolean hasAccessoryPermission(UsbAccessory accessory) {
         final int uid = Binder.getCallingUid();
         final int pid = Binder.getCallingPid();
@@ -518,6 +527,14 @@
     }
 
     @Override
+    public boolean hasAccessoryPermissionWithIdentity(UsbAccessory accessory, int pid, int uid) {
+        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USB, null);
+
+        final int userId = UserHandle.getUserId(uid);
+        return getPermissionsForUser(userId).hasPermission(accessory, pid, uid);
+    }
+
+    @Override
     public void requestDevicePermission(UsbDevice device, String packageName, PendingIntent pi) {
         final int uid = Binder.getCallingUid();
         final int pid = Binder.getCallingPid();