Make extra APEXes available to payload
Bug: 391225143
Test: apply aosp/3455572, run `vm_shell.sh start-microdroid
--auto-connect -- --debug full`. Check if the following line is shown.
01-21 04:36:29.358 70 70 I microdroid_launcher: Linked APEX
namespace com_android_i18n with shared libs
libicui18n.so:libicuuc.so:libicu_jni.so:libandroidicu.so:libicu.so
Change-Id: Ifd94b4181fa686e1060db582fe13cad84c770b53
diff --git a/guest/microdroid_launcher/Android.bp b/guest/microdroid_launcher/Android.bp
index 42c18cb..893ee98 100644
--- a/guest/microdroid_launcher/Android.bp
+++ b/guest/microdroid_launcher/Android.bp
@@ -12,5 +12,10 @@
"libdl_android",
"liblog",
],
+ static_libs: [
+ "libapexutil",
+ "libprotobuf-cpp-lite",
+ "lib_apex_manifest_proto_lite",
+ ],
header_libs: ["vm_payload_headers"],
}
diff --git a/guest/microdroid_launcher/main.cpp b/guest/microdroid_launcher/main.cpp
index 5ae9956..8e3d4e4 100644
--- a/guest/microdroid_launcher/main.cpp
+++ b/guest/microdroid_launcher/main.cpp
@@ -16,7 +16,9 @@
#include <android-base/logging.h>
#include <android-base/result.h>
+#include <android-base/strings.h>
#include <android/dlext.h>
+#include <apexutil.h>
#include <dlfcn.h>
#include <cstdlib>
@@ -25,8 +27,11 @@
#include "vm_main.h"
+using android::apex::GetActivePackages;
using android::base::Error;
+using android::base::Join;
using android::base::Result;
+using android::base::StringReplace;
extern "C" {
enum {
@@ -43,6 +48,8 @@
extern bool android_link_namespaces(struct android_namespace_t* from,
struct android_namespace_t* to,
const char* shared_libs_sonames);
+
+extern struct android_namespace_t* android_get_exported_namespace(const char* name);
} // extern "C"
static Result<void*> load(const std::string& libname);
@@ -108,6 +115,32 @@
return Error() << "Failed to link namespace: " << dlerror();
}
+ // Make libraries provided by APEXes available to the payload
+ for (const auto& [_path, manifest] : GetActivePackages("/apex")) {
+ std::string namespace_name = StringReplace(manifest.name(), ".", "_", /* all */ true);
+ android_namespace_t* apex_ns = android_get_exported_namespace(namespace_name.c_str());
+ if (apex_ns == nullptr) {
+ // This means the namespace is configured as 'visible=false'. We can't link to an
+ // invisible namespace.
+ continue;
+ }
+
+ std::vector<std::string> libs = {manifest.providenativelibs().begin(),
+ manifest.providenativelibs().end()};
+ if (libs.size() == 0) {
+ continue;
+ }
+ std::string shared_lib_sonames = Join(libs, ':');
+
+ if (!android_link_namespaces(new_ns, apex_ns, shared_lib_sonames.c_str())) {
+ return Error() << "Failed to link APEX namespace " << namespace_name << ": "
+ << dlerror();
+ }
+
+ LOG(INFO) << "Linked APEX namespace " << namespace_name << " with shared libs "
+ << shared_lib_sonames;
+ }
+
const android_dlextinfo info = {
.flags = ANDROID_DLEXT_USE_NAMESPACE,
.library_namespace = new_ns,