Helper API for: QAS/suspension precedence validation.

Fixes: 311305567
Test: adb shell device_config put package_manager_service android.content.pm.quarantined_enabled true && atest PackageManagerTest
Change-Id: Icaaedaf272ecd1b3ec86daf94c9cfb5ead8eac31
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index a4c3bb8..87c86df 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -2934,6 +2934,15 @@
     }
 
     @Override
+    public String getSuspendingPackage(String suspendedPackage) {
+        try {
+            return mPM.getSuspendingPackage(suspendedPackage, getUserId());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    @Override
     public boolean isPackageSuspendedForUser(String packageName, int userId) {
         try {
             return mPM.isPackageSuspendedForUser(packageName, userId);
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index babfba1..98623de 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -312,6 +312,8 @@
 
     Bundle getSuspendedPackageAppExtras(String packageName, int userId);
 
+    String getSuspendingPackage(String packageName, int userId);
+
     /**
      * Backup/restore support - only the system uid may use these.
      */
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index fe31c9d..6775f9b 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -9965,6 +9965,21 @@
     }
 
     /**
+     * Get the name of the package that suspended the given package. Packages can be suspended by
+     * device administrators or apps holding {@link android.Manifest.permission#MANAGE_USERS} or
+     * {@link android.Manifest.permission#SUSPEND_APPS}.
+     *
+     * @param suspendedPackage The package that has been suspended.
+     * @return Name of the package that suspended the given package. Returns {@code null} if the
+     * given package is not currently suspended and the platform package name - i.e.
+     * {@code "android"} - if the package was suspended by a device admin.
+     * @hide
+     */
+    public @Nullable String getSuspendingPackage(@NonNull String suspendedPackage) {
+        throw new UnsupportedOperationException("getSuspendingPackage not implemented");
+    }
+
+    /**
      * Query if an app is currently stopped.
      *
      * @return {@code true} if the given package is stopped, {@code false} otherwise
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index e557f09..4e38511 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -5216,6 +5216,18 @@
         }
 
         @Override
+        public String getSuspendingPackage(String packageName, int userId) {
+            final int callingUid = Binder.getCallingUid();
+            final Computer snapshot = snapshot();
+            // This will do visibility checks as well.
+            if (!snapshot.isPackageSuspendedForUser(packageName, userId)) {
+                return null;
+            }
+            return mSuspendPackageHelper.getSuspendingPackage(snapshot, packageName, userId,
+                    callingUid);
+        }
+
+        @Override
         public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
             // allow instant applications
             ArrayList<FeatureInfo> res;