Browse Source

Use specialized logic when loading C modules in Android.

Miku AuahDark 3 years ago
parent
commit
b79b99bbaa
3 changed files with 69 additions and 0 deletions
  1. 42 0
      src/common/android.cpp
  2. 2 0
      src/common/android.h
  3. 25 0
      src/modules/filesystem/wrap_Filesystem.cpp

+ 42 - 0
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
 

+ 2 - 0
src/common/android.h

@@ -101,6 +101,8 @@ void deinitializeVirtualArchive();
  */
 bool checkFusedGame(void **physfsIO_Out);
 
+const char *getCRequirePath();
+
 } // android
 } // love
 

+ 25 - 0
src/modules/filesystem/wrap_Filesystem.cpp

@@ -29,6 +29,10 @@
 
 #include "physfs/Filesystem.h"
 
+#ifdef LOVE_ANDROID
+#include "common/android.h"
+#endif
+
 // SDL
 #include <SDL_loadso.h>
 
@@ -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());