CLI API to enable testing of QAS.

Bug: 269127435
Test: atest PackageManagerTest
Change-Id: I3a9fd1cfcdd2aa9bba90d15ab446abc91795a3d7
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index c5585af..ea0f5ff 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -304,6 +304,8 @@
 
     boolean isPackageSuspendedForUser(String packageName, int userId);
 
+    boolean isPackageQuarantinedForUser(String packageName, int userId);
+
     Bundle getSuspendedPackageAppExtras(String packageName, int userId);
 
     /**
diff --git a/services/core/java/com/android/server/pm/Computer.java b/services/core/java/com/android/server/pm/Computer.java
index 6e75605..f987629 100644
--- a/services/core/java/com/android/server/pm/Computer.java
+++ b/services/core/java/com/android/server/pm/Computer.java
@@ -487,6 +487,8 @@
 
     boolean isPackageSuspendedForUser(@NonNull String packageName, @UserIdInt int userId);
 
+    boolean isPackageQuarantinedForUser(@NonNull String packageName, @UserIdInt int userId);
+
     boolean isSuspendingAnyPackages(@NonNull String suspendingPackage, @UserIdInt int userId);
 
     @NonNull
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index 7d878ec..1cfc7d7 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -4925,8 +4925,8 @@
         }
     }
 
-    @Override
-    public boolean isPackageSuspendedForUser(@NonNull String packageName, int userId) {
+    private PackageUserStateInternal getUserStageOrDefaultForUser(@NonNull String packageName,
+            int userId) {
         final int callingUid = Binder.getCallingUid();
         enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
                 false /* checkShell */, "isPackageSuspendedForUser for user " + userId);
@@ -4934,7 +4934,17 @@
         if (ps == null || shouldFilterApplicationIncludingUninstalled(ps, callingUid, userId)) {
             throw new IllegalArgumentException("Unknown target package: " + packageName);
         }
-        return ps.getUserStateOrDefault(userId).isSuspended();
+        return ps.getUserStateOrDefault(userId);
+    }
+
+    @Override
+    public boolean isPackageSuspendedForUser(@NonNull String packageName, int userId) {
+        return getUserStageOrDefaultForUser(packageName, userId).isSuspended();
+    }
+
+    @Override
+    public boolean isPackageQuarantinedForUser(@NonNull String packageName, @UserIdInt int userId) {
+        return getUserStageOrDefaultForUser(packageName, userId).isQuarantined();
     }
 
     @Override
diff --git a/services/core/java/com/android/server/pm/IPackageManagerBase.java b/services/core/java/com/android/server/pm/IPackageManagerBase.java
index fd47846..76203ac 100644
--- a/services/core/java/com/android/server/pm/IPackageManagerBase.java
+++ b/services/core/java/com/android/server/pm/IPackageManagerBase.java
@@ -955,6 +955,13 @@
 
     @Override
     @Deprecated
+    public final boolean isPackageQuarantinedForUser(@NonNull String packageName,
+            @UserIdInt int userId) {
+        return snapshot().isPackageQuarantinedForUser(packageName, userId);
+    }
+
+    @Override
+    @Deprecated
     public final boolean isSafeMode() {
         // allow instant applications
         return mService.getSafeMode();
diff --git a/services/core/java/com/android/server/pm/PackageManagerInternalBase.java b/services/core/java/com/android/server/pm/PackageManagerInternalBase.java
index 6efd067..651845e 100644
--- a/services/core/java/com/android/server/pm/PackageManagerInternalBase.java
+++ b/services/core/java/com/android/server/pm/PackageManagerInternalBase.java
@@ -755,9 +755,7 @@
     @Override
     public boolean isPackageQuarantined(@NonNull String packageName,
             @UserIdInt int userId) {
-        final PackageStateInternal packageState = getPackageStateInternal(packageName);
-        return (packageState == null) ? false
-                : packageState.getUserStateOrDefault(userId).isQuarantined();
+        return snapshot().isPackageQuarantinedForUser(packageName, userId);
     }
 
     @NonNull
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index ceae1fe..8bdbe04 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -226,6 +226,8 @@
                     return runPath();
                 case "dump":
                     return runDump();
+                case "dump-package":
+                    return runDumpPackage();
                 case "list":
                     return runList();
                 case "gc":
@@ -978,6 +980,7 @@
         boolean listInstaller = false;
         boolean showUid = false;
         boolean showVersionCode = false;
+        boolean listQuarantinedOnly = false;
         boolean listApexOnly = false;
         boolean showStopped = false;
         int uid = -1;
@@ -1008,6 +1011,9 @@
                     case "-s":
                         listSystem = true;
                         break;
+                    case "-q":
+                        listQuarantinedOnly = true;
+                        break;
                     case "-U":
                         showUid = true;
                         break;
@@ -1093,6 +1099,10 @@
                         || (listApexOnly && !isApex)) {
                     continue;
                 }
+                if (listQuarantinedOnly && !mInterface.isPackageQuarantinedForUser(info.packageName,
+                        translatedUserId)) {
+                    continue;
+                }
 
                 String name = null;
                 if (showSdks) {
@@ -3598,6 +3608,23 @@
         return 0;
     }
 
+    private int runDumpPackage() {
+        String pkg = getNextArg();
+        if (pkg == null) {
+            getErrPrintWriter().println("Error: no package specified");
+            return 1;
+        }
+        try {
+            ((IBinder) mInterface).dump(getOutFileDescriptor(), new String[]{pkg});
+        } catch (Throwable e) {
+            PrintWriter pw = getErrPrintWriter();
+            pw.println("Failure dumping service:");
+            e.printStackTrace(pw);
+            pw.flush();
+        }
+        return 0;
+    }
+
     private int runSetHarmfulAppWarning() throws RemoteException {
         int userId = UserHandle.USER_CURRENT;
 
@@ -4282,6 +4309,9 @@
         pw.println("  dump PACKAGE");
         pw.println("    Print various system state associated with the given PACKAGE.");
         pw.println("");
+        pw.println("  dump-package PACKAGE");
+        pw.println("    Print package manager state associated with the given PACKAGE.");
+        pw.println("");
         pw.println("  has-feature FEATURE_NAME [version]");
         pw.println("    Prints true and returns exit status 0 when system has a FEATURE_NAME,");
         pw.println("    otherwise prints false and returns exit status 1");
@@ -4299,7 +4329,7 @@
         pw.println("    Options:");
         pw.println("      -v: shows the location of the library in the device's filesystem");
         pw.println("");
-        pw.println("  list packages [-f] [-d] [-e] [-s] [-3] [-i] [-l] [-u] [-U] ");
+        pw.println("  list packages [-f] [-d] [-e] [-s] [-q] [-3] [-i] [-l] [-u] [-U] ");
         pw.println("      [--show-versioncode] [--apex-only] [--factory-only]");
         pw.println("      [--uid UID] [--user USER_ID] [FILTER]");
         pw.println("    Prints all packages; optionally only those whose name contains");
@@ -4309,6 +4339,7 @@
         pw.println("      -d: filter to only show disabled packages");
         pw.println("      -e: filter to only show enabled packages");
         pw.println("      -s: filter to only show system packages");
+        pw.println("      -q: filter to only show quarantined packages");
         pw.println("      -3: filter to only show third party packages");
         pw.println("      -i: see the installer for the packages");
         pw.println("      -l: ignored (used for compatibility with older releases)");