Refactor the APEX package activation/deactivation logic in `otapreopt_chroot`.

This is in prevision of reusing the package deactivation logic as a
clean-up step upon Bionic bind-mounting failure.

Test: m otapreopt_chroot
Test: A/B OTA update test (asit/dexoptota/self_full).
Bug: 113373927
Bug: 120266448
Change-Id: I17b2d57252af7aca1fc27b4c051d6cc9d373c223
diff --git a/cmds/installd/otapreopt_chroot.cpp b/cmds/installd/otapreopt_chroot.cpp
index c0f8e91..1c99663 100644
--- a/cmds/installd/otapreopt_chroot.cpp
+++ b/cmds/installd/otapreopt_chroot.cpp
@@ -58,6 +58,27 @@
     }
 }
 
+static std::vector<apex::ApexFile> ActivateApexPackages() {
+    // The logic here is (partially) copied and adapted from
+    // system/apex/apexd/apexd_main.cpp.
+    //
+    // Only scan the APEX directory under /system (within the chroot dir).
+    // Note that this leaves around the loop devices created and used by
+    // libapexd's code, but this is fine, as we expect to reboot soon after.
+    apex::scanPackagesDirAndActivate(apex::kApexPackageSystemDir);
+    return apex::getActivePackages();
+}
+
+static void DeactivateApexPackages(const std::vector<apex::ApexFile>& active_packages) {
+    for (const apex::ApexFile& apex_file : active_packages) {
+        const std::string& package_path = apex_file.GetPath();
+        apex::Status status = apex::deactivatePackage(package_path);
+        if (!status.Ok()) {
+            LOG(ERROR) << "Failed to deactivate " << package_path << ": " << status.ErrorMessage();
+        }
+    }
+}
+
 // Entry for otapreopt_chroot. Expected parameters are:
 //   [cmd] [status-fd] [target-slot] "dexopt" [dexopt-params]
 // The file descriptor denoted by status-fd will be closed. The rest of the parameters will
@@ -199,15 +220,7 @@
 
     // Try to mount APEX packages in "/apex" in the chroot dir. We need at least
     // the Android Runtime APEX, as it is required by otapreopt to run dex2oat.
-    // The logic here is (partially) copied and adapted from
-    // system/apex/apexd/apexd_main.cpp.
-    //
-    // Only scan the APEX directory under /system (within the chroot dir).
-    // Note that this leaves around the loop devices created and used by
-    // libapexd's code, but this is fine, as we expect to reboot soon after.
-    apex::scanPackagesDirAndActivate(apex::kApexPackageSystemDir);
-    // Collect activated packages.
-    std::vector<apex::ApexFile> active_packages = apex::getActivePackages();
+    std::vector<apex::ApexFile> active_packages = ActivateApexPackages();
 
     // Now go on and run otapreopt.
 
@@ -229,14 +242,8 @@
         LOG(ERROR) << "Running otapreopt failed: " << error_msg;
     }
 
-    // Tear down the work down by the apexd logic above (i.e. deactivate packages).
-    for (const apex::ApexFile& apex_file : active_packages) {
-        const std::string& package_path = apex_file.GetPath();
-        apex::Status status = apex::deactivatePackage(package_path);
-        if (!status.Ok()) {
-            LOG(ERROR) << "Failed to deactivate " << package_path << ": " << status.ErrorMessage();
-        }
-    }
+    // Tear down the work down by the apexd logic. (i.e. deactivate packages).
+    DeactivateApexPackages(active_packages);
 
     if (!exec_result) {
         exit(213);