add JNI_OnLoad to Android library. This is needed to manually call ::filament::backend::VirtualMachineEnv::JNI_OnLoad

This commit is contained in:
Nick Fisher
2025-05-12 14:15:11 +08:00
parent bb272f2579
commit 2f5ce65684
2 changed files with 68 additions and 14 deletions

View File

@@ -1,16 +1,68 @@
#include <android/native_window_jni.h>
#include <android/log.h>
#include <android/native_activity.h>
#include <android/native_window_jni.h>
#include <jni.h>
#include <dlfcn.h>
#include <android/log.h>
typedef void (*JNI_OnLoad_Func)(JavaVM*);
extern "C" {
JNIEXPORT jlong JNICALL Java_dev_thermion_android_NativeWindowHelper_00024Companion_getNativeWindowFromSurface(
JNIEnv* env,
jclass clazz,
jobject surface
) {
ANativeWindow* window = ANativeWindow_fromSurface(env, surface);
return (jlong)window;
}
JNIEXPORT jlong JNICALL
Java_dev_thermion_android_NativeWindowHelper_00024Companion_getNativeWindowFromSurface(
JNIEnv *env, jclass clazz, jobject surface) {
ANativeWindow *window = ANativeWindow_fromSurface(env, surface);
return (jlong)window;
}
JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
void* filamentLib = dlopen("libthermion_dart.so", RTLD_NOW);
if (!filamentLib) {
__android_log_print(ANDROID_LOG_ERROR, "thermion_android",
"Failed to load Filament library: %s", dlerror());
return false;
}
dlerror();
JNI_OnLoad_Func vmEnvOnLoad = (JNI_OnLoad_Func)dlsym(filamentLib,
"_ZN8filament17VirtualMachineEnv10JNI_OnLoadEP7_JavaVM");
// Check for errors
const char* dlsym_error = dlerror();
if (dlsym_error) {
__android_log_print(ANDROID_LOG_ERROR, "thermion_android",
"Failed to find VirtualMachineEnv::JNI_OnLoad: %s", dlsym_error);
dlclose(filamentLib);
return false;
}
// Call the function
vmEnvOnLoad(vm);
JNIEnv *env;
if (vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6) != JNI_OK) {
return JNI_ERR;
}
jclass c =
env->FindClass("dev/thermion/android/NativeWindowHelper$Companion");
if (c == nullptr)
return JNI_ERR;
static const JNINativeMethod methods[] = {
{"getNativeWindowFromSurface", "(Landroid/view/Surface;)J",
reinterpret_cast<void *>(
Java_dev_thermion_android_NativeWindowHelper_00024Companion_getNativeWindowFromSurface)},
};
int rc = env->RegisterNatives(c, methods,
sizeof(methods) / sizeof(JNINativeMethod));
if (rc != JNI_OK)
return rc;
return JNI_VERSION_1_6;
}
}

View File

@@ -25,10 +25,7 @@ import java.util.*
class NativeWindowHelper {
companion object {
init {
System.loadLibrary("thermion_flutter_android")
}
external fun getNativeWindowFromSurface(surface: Surface): Long
external fun getNativeWindowFromSurface(surface: Surface): Long
}
}
@@ -62,6 +59,9 @@ class ThermionFlutterPlugin: FlutterPlugin, MethodCallHandler, ActivityAware {
this.flutterPluginBinding = flutterPluginBinding
channel = MethodChannel(flutterPluginBinding.binaryMessenger, CHANNEL_NAME)
channel.setMethodCallHandler(this)
Log.d("thermion_flutter", "Loading library")
System.loadLibrary("thermion_flutter_android")
Log.d("thermion_flutter", "Loaded")
}
override fun onAttachedToActivity(binding: ActivityPluginBinding) {
@@ -81,7 +81,7 @@ class ThermionFlutterPlugin: FlutterPlugin, MethodCallHandler, ActivityAware {
result.error("DIMENSION_MISMATCH", "Both dimensions must be greater than zero (you provided $width x $height)", null)
return
}
Log.i("thermion_flutter", "Creating SurfaceTexture ${width}x${height}")
Log.d("thermion_flutter", "Creating SurfaceTexture ${width}x${height}")
val surfaceTextureEntry = flutterPluginBinding.textureRegistry.createSurfaceTexture()
val surfaceTexture = surfaceTextureEntry.surfaceTexture()
@@ -95,6 +95,8 @@ class ThermionFlutterPlugin: FlutterPlugin, MethodCallHandler, ActivityAware {
val flutterTextureId = surfaceTextureEntry.id()
textures[flutterTextureId] = TextureEntry(surfaceTextureEntry, surfaceTexture, surface)
//val surface = surfaceView.holder.surface
Log.d("thermion_flutter", "Loading library")
System.loadLibrary("thermion_flutter_android")
val nativeWindowPtr = NativeWindowHelper.getNativeWindowFromSurface(surface)
//val nativeWindow = _lib.get_native_window_from_surface(surface as Object, JNIEnv.CURRENT)
result.success(listOf(flutterTextureId, flutterTextureId, nativeWindowPtr))