Fix crash that happens if you call archive twice.

Also remove outdated TODO: We'll re-use the existing OP_CODE because
it's bad practice to have 2 OP_CODES that are controlled by the same
switch in settings. If they ever become out of sync the UI cannot handle
the state.

Bug: 314770049
Test: verified fix manually
Change-Id: I6a658a4c583c951795daf1f9a2cd9e7d26c3f44a
diff --git a/services/core/java/com/android/server/pm/PackageArchiver.java b/services/core/java/com/android/server/pm/PackageArchiver.java
index e3bab3f..065cd0b 100644
--- a/services/core/java/com/android/server/pm/PackageArchiver.java
+++ b/services/core/java/com/android/server/pm/PackageArchiver.java
@@ -323,6 +323,7 @@
         PackageStateInternal ps = getPackageState(packageName, snapshot,
                 Binder.getCallingUid(), userId);
         verifyNotSystemApp(ps.getFlags());
+        verifyInstalled(ps, userId);
         String responsibleInstallerPackage = getResponsibleInstallerPackage(ps);
         verifyInstaller(responsibleInstallerPackage, userId);
         ApplicationInfo installerInfo = snapshot.getApplicationInfo(
@@ -476,6 +477,14 @@
         }
     }
 
+    private void verifyInstalled(PackageStateInternal ps, int userId)
+            throws PackageManager.NameNotFoundException {
+        if (!ps.getUserStateOrDefault(userId).isInstalled()) {
+            throw new PackageManager.NameNotFoundException(
+                    TextUtils.formatSimple("%s is not installed.", ps.getPackageName()));
+        }
+    }
+
     /**
      * Returns true if the app is archivable.
      */
@@ -519,11 +528,11 @@
     /**
      * Returns true if user has opted the app out of archiving through system settings.
      */
-    // TODO(b/304256918) Switch this to a separate OP code for archiving.
     private boolean isAppOptedOutOfArchiving(String packageName, int uid) {
         return Binder.withCleanCallingIdentity(() ->
-                getAppOpsManager().checkOp(AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED,
-                        uid, packageName) == MODE_IGNORED);
+                getAppOpsManager().checkOpNoThrow(
+                        AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED, uid, packageName)
+                        == MODE_IGNORED);
     }
 
     private void verifyOptOutStatus(String packageName, int uid)
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverTest.java
index 2332988..1792b768 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/PackageArchiverTest.java
@@ -343,7 +343,7 @@
 
     @Test
     public void archiveApp_appOptedOutOfArchiving() {
-        when(mAppOpsManager.checkOp(
+        when(mAppOpsManager.checkOpNoThrow(
                 eq(AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED),
                 anyInt(), eq(PACKAGE))).thenReturn(MODE_IGNORED);
 
@@ -430,7 +430,7 @@
     @Test
     public void isAppArchivable_appOptedOutOfArchiving()
             throws PackageManager.NameNotFoundException {
-        when(mAppOpsManager.checkOp(
+        when(mAppOpsManager.checkOpNoThrow(
                 eq(AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED),
                 anyInt(), eq(PACKAGE))).thenReturn(MODE_IGNORED);