ART: Clean up library loading

Retrieve the library path from the classloader before attempting to
load, instead of getting it passed down. This allows unifying said
loading behavior for follow-up changes.

Fix up test code to support the new required data in classloader
objects.

Bug: 70901841
Test: m test-art-host
Test: device boots
Change-Id: Iaccaeb56422877abac9f7fe6f5a17364c8adf4ca
diff --git a/runtime/java_vm_ext.cc b/runtime/java_vm_ext.cc
index e159436..579552d 100644
--- a/runtime/java_vm_ext.cc
+++ b/runtime/java_vm_ext.cc
@@ -48,6 +48,7 @@
 #include "thread-inl.h"
 #include "thread_list.h"
 #include "ti/agent.h"
+#include "well_known_classes.h"
 
 namespace art {
 
@@ -853,7 +854,6 @@
 bool JavaVMExt::LoadNativeLibrary(JNIEnv* env,
                                   const std::string& path,
                                   jobject class_loader,
-                                  jstring library_path,
                                   std::string* error_msg) {
   error_msg->clear();
 
@@ -950,6 +950,9 @@
   // class unloading. Libraries will only be unloaded when the reference count (incremented by
   // dlopen) becomes zero from dlclose.
 
+  // Retrieve the library path from the classloader, if necessary.
+  ScopedLocalRef<jstring> library_path(env, GetLibrarySearchPath(env, class_loader));
+
   Locks::mutator_lock_->AssertNotHeld(self);
   const char* path_str = path.empty() ? nullptr : path.c_str();
   bool needs_native_bridge = false;
@@ -957,7 +960,7 @@
                                             runtime_->GetTargetSdkVersion(),
                                             path_str,
                                             class_loader,
-                                            library_path,
+                                            library_path.get(),
                                             &needs_native_bridge,
                                             error_msg);
 
@@ -1119,6 +1122,18 @@
   // The weak_globals table is visited by the GC itself (because it mutates the table).
 }
 
+jstring JavaVMExt::GetLibrarySearchPath(JNIEnv* env, jobject class_loader) {
+  if (class_loader == nullptr) {
+    return nullptr;
+  }
+  if (!env->IsInstanceOf(class_loader, WellKnownClasses::dalvik_system_BaseDexClassLoader)) {
+    return nullptr;
+  }
+  return reinterpret_cast<jstring>(env->CallObjectMethod(
+      class_loader,
+      WellKnownClasses::dalvik_system_BaseDexClassLoader_getLdLibraryPath));
+}
+
 // JNI Invocation interface.
 
 extern "C" jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args) {