Context
The v1 Android plug-in loader (added in #309) discovers plug-ins as libdxrp<NNN>_<id>.so files inside the runtime APK's own lib dir, located via dladdr self-lookup. This handles the single-vendor case: the plug-in .so ships in the runtime APK's jniLibs/<ABI>/. See docs/specs/runtime/plugin-discovery.md §3.2.
Problem this issue tracks
When a second Android vendor ships their own plug-in APK (mirroring the Windows model where DisplayXRLeiaSRSetup-*.exe installs separately from the runtime), the runtime needs to discover plug-ins across APK boundaries. The runtime process can't dlopen an arbitrary .so from another APK's lib dir directly — Android's linker namespaces and app sandboxing prevent it.
v2 design sketch
Two-layer discovery on Android:
-
Local (today, v1): libdxrp*.so in the runtime APK's own lib dir. Always tried.
-
Cross-APK (v2, this issue): Enumerate installed APKs via PackageManager.getInstalledPackages(GET_META_DATA). Filter by a metadata tag on the APK's <application> element, e.g.:
<meta-data
android:name="com.displayxr.plugin"
android:value="leia_cnsdk;probe_order=50" />
For each match, get the APK's nativeLibraryDir via ApplicationInfo.nativeLibraryDir and dlopen the named .so from there. Linker should permit it within the same UID; if not, fall back to copying the .so into the runtime APK's private files dir at first use.
Why deferred
- No second Android vendor exists yet; v1 single-vendor is sufficient for the Lume Pad / Nubia Pad 2 hardware bringup.
- Requires JNI plumbing into
target_plugin_loader.c (AAssetManager access, JNIEnv* from the openxr-loader's XR_KHR_android_create_instance extension fields), which is real surface area.
- Cascade-uninstall (currently a non-goal for Android per §3.2) becomes relevant — Android doesn't fire callbacks on dependency-APK uninstall, so the runtime needs to handle "plug-in
.so vanished between sessions" gracefully.
When to revisit
- A second Android display vendor begins integration, OR
- The Leia plug-in needs to ship as a standalone APK on Android (rather than being bundled into the runtime APK's
jniLibs/).
References
Context
The v1 Android plug-in loader (added in #309) discovers plug-ins as
libdxrp<NNN>_<id>.sofiles inside the runtime APK's own lib dir, located viadladdrself-lookup. This handles the single-vendor case: the plug-in.soships in the runtime APK'sjniLibs/<ABI>/. Seedocs/specs/runtime/plugin-discovery.md§3.2.Problem this issue tracks
When a second Android vendor ships their own plug-in APK (mirroring the Windows model where
DisplayXRLeiaSRSetup-*.exeinstalls separately from the runtime), the runtime needs to discover plug-ins across APK boundaries. The runtime process can'tdlopenan arbitrary.sofrom another APK's lib dir directly — Android's linker namespaces and app sandboxing prevent it.v2 design sketch
Two-layer discovery on Android:
Local (today, v1):
libdxrp*.soin the runtime APK's own lib dir. Always tried.Cross-APK (v2, this issue): Enumerate installed APKs via
PackageManager.getInstalledPackages(GET_META_DATA). Filter by a metadata tag on the APK's<application>element, e.g.:For each match, get the APK's
nativeLibraryDirviaApplicationInfo.nativeLibraryDiranddlopenthe named.sofrom there. Linker should permit it within the same UID; if not, fall back to copying the.sointo the runtime APK's private files dir at first use.Why deferred
target_plugin_loader.c(AAssetManageraccess,JNIEnv*from the openxr-loader'sXR_KHR_android_create_instanceextension fields), which is real surface area..sovanished between sessions" gracefully.When to revisit
jniLibs/).References
src/xrt/targets/common/target_plugin_loader.c(Android branch under#elif defined(XRT_OS_ANDROID))docs/specs/runtime/plugin-discovery.md§3.2