diff --git a/src/common/android.cpp b/src/common/android.cpp index 075b6b7d9..e926737a5 100644 --- a/src/common/android.cpp +++ b/src/common/android.cpp @@ -724,6 +724,48 @@ bool checkFusedGame(void **physfsIO_Out) return false; } +const char *getCRequirePath() +{ + static bool initialized = false; + static const char *path = nullptr; + + if (!initialized) + { + JNIEnv *env = (JNIEnv*) SDL_AndroidGetJNIEnv(); + jobject activity = (jobject) SDL_AndroidGetActivity(); + + jclass clazz(env->GetObjectClass(activity)); + jmethodID method_id = env->GetMethodID(clazz, "getCRequirePath", "()Ljava/lang/String;"); + + path = ""; + initialized = true; + + if (method_id) + { + jstring cpath = (jstring) env->CallObjectMethod(activity, method_id); + const char *utf = env->GetStringUTFChars(cpath, nullptr); + if (utf) + { + path = SDL_strdup(utf); + env->ReleaseStringUTFChars(cpath, utf); + } + + env->DeleteLocalRef(cpath); + } + else + { + // NoSuchMethodException is thrown in case methodID is null + env->ExceptionClear(); + return ""; + } + + env->DeleteLocalRef(activity); + env->DeleteLocalRef(clazz); + } + + return path; +} + } // android } // love diff --git a/src/common/android.h b/src/common/android.h index 68b2259bf..3c0c5a35f 100644 --- a/src/common/android.h +++ b/src/common/android.h @@ -101,6 +101,8 @@ void deinitializeVirtualArchive(); */ bool checkFusedGame(void **physfsIO_Out); +const char *getCRequirePath(); + } // android } // love diff --git a/src/modules/filesystem/wrap_Filesystem.cpp b/src/modules/filesystem/wrap_Filesystem.cpp index 62f356f0f..41db59725 100644 --- a/src/modules/filesystem/wrap_Filesystem.cpp +++ b/src/modules/filesystem/wrap_Filesystem.cpp @@ -29,6 +29,10 @@ #include "physfs/Filesystem.h" +#ifdef LOVE_ANDROID +#include "common/android.h" +#endif + // SDL #include @@ -782,6 +786,23 @@ int extloader(lua_State *L) void *handle = nullptr; auto *inst = instance(); +#ifdef LOVE_ANDROID + // Specifically Android, look the library path based on getCRequirePath first + std::string androidPath(love::android::getCRequirePath()); + + if (!androidPath.empty()) + { + // Replace ? with just the dotted filename (not tokenized_name) + replaceAll(androidPath, "?", filename); + + // Load directly, don't check for existence. + handle = SDL_LoadObject(androidPath.c_str()); + } + + if (!handle) + { +#endif // LOVE_ANDROID + for (const std::string &el : inst->getCRequirePath()) { for (const char *ext : library_extensions) @@ -811,6 +832,10 @@ int extloader(lua_State *L) break; } +#ifdef LOVE_ANDROID + } // if (!handle) +#endif + if (!handle) { lua_pushfstring(L, "\n\tno file '%s' in LOVE paths.", tokenized_name.c_str());