Mark session as ready on APEXd after verification

APEXd will now only verify packages when submitStagedSession is called,
and wait for an extra call from StagingManager when other verification
such us APK-container signature verification is performed.

Bug: 118865310
Bug: 123360647
Test: atest apex_e2e_tests; manual testing with packages with mismatched
APK signature

Change-Id: Ifa4d20b7d8ecbc25c8a6d9a41f92953cee374d35
diff --git a/services/core/java/com/android/server/pm/StagingManager.java b/services/core/java/com/android/server/pm/StagingManager.java
index b930d26..c4d27e5 100644
--- a/services/core/java/com/android/server/pm/StagingManager.java
+++ b/services/core/java/com/android/server/pm/StagingManager.java
@@ -153,6 +153,19 @@
         return success;
     }
 
+    private static boolean sendMarkStagedSessionReadyRequest(int sessionId) {
+        final IApexService apex = IApexService.Stub.asInterface(
+                ServiceManager.getService("apexservice"));
+        boolean success;
+        try {
+            success = apex.markStagedSessionReady(sessionId);
+        } catch (RemoteException re) {
+            Slog.e(TAG, "Unable to contact apexservice", re);
+            return false;
+        }
+        return success;
+    }
+
     private static boolean isApexSession(@NonNull PackageInstallerSession session) {
         return (session.params.installFlags & PackageManager.INSTALL_APEX) != 0;
     }
@@ -202,11 +215,18 @@
                                     + apexPackage.packageName + ". Signature of file "
                                     + apexPackage.packagePath + " does not match the signature of "
                                     + " the package already installed.");
+                    // TODO(b/118865310): abort the session on apexd.
                     return;
                 }
             }
         }
+
         session.setStagedSessionReady();
+        if (!sendMarkStagedSessionReadyRequest(session.sessionId)) {
+            session.setStagedSessionFailed(SessionInfo.VERIFICATION_FAILED,
+                            "APEX staging failed, check logcat messages from apexd for more "
+                            + "details.");
+        }
     }
 
     private void resumeSession(@NonNull PackageInstallerSession session) {
@@ -227,11 +247,16 @@
                     "APEX activation failed. Check logcat messages from apexd for "
                                   + "more information.");
         }
+        if (apexSessionInfo.isVerified) {
+            // Session has been previously submitted to apexd, but didn't complete all the
+            // pre-reboot verification, perhaps because the device rebooted in the meantime.
+            // Greedily re-trigger the pre-reboot verification.
+            mBgHandler.post(() -> preRebootVerification(session));
+        }
         if (apexSessionInfo.isActivated) {
             session.setStagedSessionApplied();
             // TODO(b/118865310) if multi-package proceed with the installation of APKs.
         }
-        // TODO(b/118865310) if (apexSessionInfo.isVerified) { /* mark this as staged in apexd */ }
         // In every other case apexd will retry to apply the session at next boot.
     }