Merge "Use apexd to set up chroot apex dir" into sc-dev
diff --git a/cmds/installd/Android.bp b/cmds/installd/Android.bp
index 5c2211f..a546236 100644
--- a/cmds/installd/Android.bp
+++ b/cmds/installd/Android.bp
@@ -189,8 +189,8 @@
         "liblog",
         "libutils",
     ],
-    static_libs: [
-        "libapexd",
+    required: [
+      "apexd"
     ],
 }
 
diff --git a/cmds/installd/otapreopt_chroot.cpp b/cmds/installd/otapreopt_chroot.cpp
index 379cf92..c04b558 100644
--- a/cmds/installd/otapreopt_chroot.cpp
+++ b/cmds/installd/otapreopt_chroot.cpp
@@ -20,6 +20,7 @@
 #include <sys/stat.h>
 #include <sys/wait.h>
 
+#include <array>
 #include <fstream>
 #include <sstream>
 
@@ -31,10 +32,6 @@
 #include <libdm/dm.h>
 #include <selinux/android.h>
 
-#include <apex_file_repository.h>
-#include <apex_constants.h>
-#include <apexd.h>
-
 #include "installd_constants.h"
 #include "otapreopt_utils.h"
 
@@ -64,47 +61,14 @@
     }
 }
 
-static std::vector<apex::ApexFile> ActivateApexPackages() {
-    // The logic here is (partially) copied and adapted from
-    // system/apex/apexd/apexd.cpp.
-    //
-    // Only scan the APEX directory under /system, /system_ext and /vendor (within the chroot dir).
-    std::vector<std::string> apex_dirs{apex::kApexPackageSystemDir, apex::kApexPackageSystemExtDir,
-                                       apex::kApexPackageVendorDir};
-    // Initialize ApexFileRepository used internally in ScanPackagesDirAndActivate.
-    // This is a quick fix to fix apex activation in otapreopt_chroot.
-    apex::ApexFileRepository::GetInstance().AddPreInstalledApex(apex_dirs);
-    for (const auto& dir : apex_dirs) {
-        // Cast call to void to suppress warn_unused_result.
-        static_cast<void>(apex::ScanPackagesDirAndActivate(dir.c_str()));
-    }
-    return apex::GetActivePackages();
-}
+static void ActivateApexPackages() {
+    std::vector<std::string> apexd_cmd{"/system/bin/apexd", "--otachroot-bootstrap"};
+    std::string apexd_error_msg;
 
-static void CreateApexInfoList(const std::vector<apex::ApexFile>& apex_files) {
-    // Setup the apex-info-list.xml file
-    const std::string apex_info_file = std::string(apex::kApexRoot) + "/" + apex::kApexInfoList;
-    std::fstream xml(apex_info_file.c_str(), std::ios::out | std::ios::trunc);
-    if (!xml.is_open()) {
-        PLOG(ERROR) << "Failed to open " << apex_info_file;
-        exit(216);
-    }
-
-    // we do not care about inactive apexs
-    std::vector<apex::ApexFile> inactive;
-    apex::CollectApexInfoList(xml, apex_files, inactive);
-    xml.flush();
-    xml.close();
-}
-
-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();
-        base::Result<void> status = apex::DeactivatePackage(package_path);
-        if (!status.ok()) {
-            LOG(ERROR) << "Failed to deactivate " << package_path << ": "
-                       << status.error();
-        }
+    bool exec_result = Exec(apexd_cmd, &apexd_error_msg);
+    if (!exec_result) {
+        PLOG(ERROR) << "Running otapreopt failed: " << apexd_error_msg;
+        exit(220);
     }
 }
 
@@ -269,8 +233,7 @@
 
     // Try to mount APEX packages in "/apex" in the chroot dir. We need at least
     // the ART APEX, as it is required by otapreopt to run dex2oat.
-    std::vector<apex::ApexFile> active_packages = ActivateApexPackages();
-    CreateApexInfoList(active_packages);
+    ActivateApexPackages();
 
     // Check that an ART APEX has been activated; clean up and exit
     // early otherwise.
@@ -278,16 +241,27 @@
       "com.android.art",
       "com.android.runtime",
     };
-    for (std::string_view apex : kRequiredApexs) {
-        if (std::none_of(active_packages.begin(), active_packages.end(),
-                         [&](const apex::ApexFile& package) {
-                             return package.GetManifest().name() == apex;
-                         })) {
-            LOG(FATAL_WITHOUT_ABORT) << "No activated " << apex << " APEX package.";
-            DeactivateApexPackages(active_packages);
-            exit(217);
+    std::array<bool, arraysize(kRequiredApexs)> found_apexs{ false, false };
+    DIR* apex_dir = opendir("/apex");
+    if (apex_dir == nullptr) {
+        PLOG(ERROR) << "unable to open /apex";
+        exit(220);
+    }
+    for (dirent* entry = readdir(apex_dir); entry != nullptr; entry = readdir(apex_dir)) {
+        for (int i = 0; i < found_apexs.size(); i++) {
+            if (kRequiredApexs[i] == std::string_view(entry->d_name)) {
+                found_apexs[i] = true;
+                break;
+            }
         }
     }
+    closedir(apex_dir);
+    auto it = std::find(found_apexs.cbegin(), found_apexs.cend(), false);
+    if (it != found_apexs.cend()) {
+        LOG(ERROR) << "No activated " << kRequiredApexs[std::distance(found_apexs.cbegin(), it)]
+                   << " package!";
+        exit(221);
+    }
 
     // Setup /linkerconfig. Doing it after the chroot means it doesn't need its own category
     if (selinux_android_restorecon("/linkerconfig", 0) < 0) {
@@ -323,9 +297,6 @@
         LOG(ERROR) << "Running otapreopt failed: " << error_msg;
     }
 
-    // Tear down the work down by the apexd logic. (i.e. deactivate packages).
-    DeactivateApexPackages(active_packages);
-
     if (!exec_result) {
         exit(213);
     }