Add native support for BaseDexClassLoader shared libraries.
bug: 112405321
Test: 688-shared-library
Change-Id: Ia993b3ded71d4491a59fb78b0282eacdb66634bd
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index b747225..ba520f9 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -2404,6 +2404,35 @@
return ClassPathEntry(nullptr, nullptr);
}
+bool ClassLinker::FindClassInSharedLibraries(ScopedObjectAccessAlreadyRunnable& soa,
+ Thread* self,
+ const char* descriptor,
+ size_t hash,
+ Handle<mirror::ClassLoader> class_loader,
+ /*out*/ ObjPtr<mirror::Class>* result) {
+ ArtField* field =
+ jni::DecodeArtField(WellKnownClasses::dalvik_system_BaseDexClassLoader_sharedLibraryLoaders);
+ ObjPtr<mirror::Object> raw_shared_libraries = field->GetObject(class_loader.Get());
+ if (raw_shared_libraries == nullptr) {
+ return true;
+ }
+
+ StackHandleScope<2> hs(self);
+ Handle<mirror::ObjectArray<mirror::ClassLoader>> shared_libraries(
+ hs.NewHandle(raw_shared_libraries->AsObjectArray<mirror::ClassLoader>()));
+ MutableHandle<mirror::ClassLoader> temp_loader = hs.NewHandle<mirror::ClassLoader>(nullptr);
+ for (int32_t i = 0; i < shared_libraries->GetLength(); ++i) {
+ temp_loader.Assign(shared_libraries->Get(i));
+ if (!FindClassInBaseDexClassLoader(soa, self, descriptor, hash, temp_loader, result)) {
+ return false; // One of the shared libraries is not supported.
+ }
+ if (*result != nullptr) {
+ return true; // Found the class up the chain.
+ }
+ }
+ return true;
+}
+
bool ClassLinker::FindClassInBaseDexClassLoader(ScopedObjectAccessAlreadyRunnable& soa,
Thread* self,
const char* descriptor,
@@ -2419,6 +2448,7 @@
if (IsPathOrDexClassLoader(soa, class_loader)) {
// For regular path or dex class loader the search order is:
// - parent
+ // - shared libraries
// - class loader dex files
// Handles as RegisterDexFile may allocate dex caches (and cause thread suspension).
@@ -2431,6 +2461,13 @@
return true; // Found the class up the chain.
}
+ if (!FindClassInSharedLibraries(soa, self, descriptor, hash, class_loader, result)) {
+ return false; // One of the shared library loader is not supported.
+ }
+ if (*result != nullptr) {
+ return true; // Found the class in a shared library.
+ }
+
// Search the current class loader classpath.
*result = FindClassInBaseDexClassLoaderClassPath(soa, descriptor, hash, class_loader);
return true;
@@ -2439,6 +2476,7 @@
if (IsDelegateLastClassLoader(soa, class_loader)) {
// For delegate last, the search order is:
// - boot class path
+ // - shared libraries
// - class loader dex files
// - parent
*result = FindClassInBootClassLoaderClassPath(self, descriptor, hash);
@@ -2446,6 +2484,13 @@
return true; // The class is part of the boot class path.
}
+ if (!FindClassInSharedLibraries(soa, self, descriptor, hash, class_loader, result)) {
+ return false; // One of the shared library loader is not supported.
+ }
+ if (*result != nullptr) {
+ return true; // Found the class in a shared library.
+ }
+
*result = FindClassInBaseDexClassLoaderClassPath(soa, descriptor, hash, class_loader);
if (*result != nullptr) {
return true; // Found the class in the current class loader