diff --git a/thermion_flutter/thermion_flutter/android/build.gradle b/thermion_flutter/thermion_flutter/android/build.gradle index 8563c70f..39a221c7 100644 --- a/thermion_flutter/thermion_flutter/android/build.gradle +++ b/thermion_flutter/thermion_flutter/android/build.gradle @@ -43,22 +43,18 @@ android { defaultConfig { minSdkVersion 22 - ndk { - abiFilters 'arm64-v8a' // 'x86_64' 'armeabi-v7a' - } } externalNativeBuild { cmake { path "CMakeLists.txt" - version "3.18.1" + version "3.22.1" } } } dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" - api "net.java.dev.jna:jna:5.10.0@aar" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2" } diff --git a/thermion_flutter/thermion_flutter/android/src/main/cpp/ThermionFlutterAndroid.cpp b/thermion_flutter/thermion_flutter/android/src/main/cpp/ThermionFlutterAndroid.cpp index 91e84f4d..80a27a06 100644 --- a/thermion_flutter/thermion_flutter/android/src/main/cpp/ThermionFlutterAndroid.cpp +++ b/thermion_flutter/thermion_flutter/android/src/main/cpp/ThermionFlutterAndroid.cpp @@ -1,34 +1,16 @@ #include #include - -#include "ResourceBuffer.h" +#include extern "C" { - - typedef void (*FilamentRenderCallback)(void *const owner); - - void* get_native_window_from_surface( - jobject surface, - JNIEnv* env - ) { - void* window = ANativeWindow_fromSurface(env, surface); - return window; - } - - ResourceLoaderWrapper* make_resource_loader_wrapper_android(LoadFilamentResourceFromOwner loadFn, FreeFilamentResourceFromOwner freeFn, void* owner) { - ResourceLoaderWrapper *rlw = (ResourceLoaderWrapper *)malloc(sizeof(ResourceLoaderWrapper)); - rlw->loadToOut = nullptr; - rlw->freeResource = nullptr; - rlw->loadResource = nullptr; - rlw->loadFromOwner = loadFn; - rlw->freeFromOwner = freeFn; - rlw->owner = owner; - return rlw; - } - - // this does nothing, but we need it for JNA to return the correct pointer - FilamentRenderCallback make_render_callback_fn_pointer(FilamentRenderCallback callback) { - return callback; - } - + 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; + } } + + diff --git a/thermion_flutter/thermion_flutter/android/src/main/include/ResourceBuffer.h b/thermion_flutter/thermion_flutter/android/src/main/include/ResourceBuffer.h deleted file mode 100644 index eab0ee0d..00000000 --- a/thermion_flutter/thermion_flutter/android/src/main/include/ResourceBuffer.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef RESOURCE_BUFFER_H -#define RESOURCE_BUFFER_H - -#include -#include - -// -// A ResourceBuffer is a unified interface for working with -// binary assets across various platforms. -// This is simply: -// 1) a pointer to some data -// 2) the length of the data -// 3) an ID that can be passed back to the native platform to release the underlying asset when needed. -// -typedef struct ResourceBuffer -{ - const void *const data; - const int32_t size; - const int32_t id; - -#if defined(__cplusplus) - ResourceBuffer(void *const data, int32_t size, int32_t id) : data(data), size(size), id(id) {} -#endif -} ResourceBuffer; - -typedef void (*LoadFilamentResourceIntoOutPointer)(const char *uri, ResourceBuffer *out); -typedef ResourceBuffer (*LoadFilamentResource)(const char *uri); -typedef ResourceBuffer (*LoadFilamentResourceFromOwner)(const char *const, void *const owner); -typedef void (*FreeFilamentResource)(ResourceBuffer); -typedef void (*FreeFilamentResourceFromOwner)(ResourceBuffer, void *const owner); - -typedef struct ResourceLoaderWrapper -{ - LoadFilamentResource loadResource; - FreeFilamentResource freeResource; - LoadFilamentResourceFromOwner loadFromOwner; - FreeFilamentResourceFromOwner freeFromOwner; - void *owner; - LoadFilamentResourceIntoOutPointer loadToOut; -} ResourceLoaderWrapper; - -void *make_resource_loader(LoadFilamentResourceFromOwner loadFn, FreeFilamentResourceFromOwner freeFn, void *const owner); - -#endif diff --git a/thermion_flutter/thermion_flutter/android/src/main/kotlin/dev/thermion/android/FilamentInterop.kt b/thermion_flutter/thermion_flutter/android/src/main/kotlin/dev/thermion/android/FilamentInterop.kt deleted file mode 100644 index 044f039d..00000000 --- a/thermion_flutter/thermion_flutter/android/src/main/kotlin/dev/thermion/android/FilamentInterop.kt +++ /dev/null @@ -1,39 +0,0 @@ -package dev.thermion.android - -import com.sun.jna.ptr.PointerByReference -import com.sun.jna.ptr.IntByReference - -import android.view.Surface - -import android.content.res.AssetManager -import com.sun.jna.* - -open class ResourceBuffer: Structure(), Structure.ByValue { - @JvmField var data: Pointer = Pointer(0); - @JvmField var size: Int = 0; - @JvmField var id: Int = 0; - override fun getFieldOrder(): List { - return listOf("data", "size", "id") - } -} - -interface LoadFilamentResourceFromOwner : Callback { - fun loadResourceFromOwner(resourceName: String?, owner: Pointer?): ResourceBuffer -} - -interface FreeFilamentResourceFromOwner : Callback { - fun freeResourceFromOwner(rb: ResourceBuffer, owner: Pointer?) -} - -interface RenderCallback : Callback { - fun renderCallback(owner:Pointer?) -} - -interface FilamentInterop : Library { - -fun get_native_window_from_surface(surface:Object, env:JNIEnv) : Pointer?; -fun make_render_callback_fn_pointer(renderCallback:RenderCallback) : Pointer -fun make_resource_loader_wrapper_android(loadResourceFromOwner: LoadFilamentResourceFromOwner, freeResource: FreeFilamentResourceFromOwner, owner:Pointer?) : Pointer; - -} - diff --git a/thermion_flutter/thermion_flutter/android/src/main/kotlin/dev/thermion/android/HotReloadPathHelper.kt b/thermion_flutter/thermion_flutter/android/src/main/kotlin/dev/thermion/android/HotReloadPathHelper.kt deleted file mode 100644 index 1716d4d3..00000000 --- a/thermion_flutter/thermion_flutter/android/src/main/kotlin/dev/thermion/android/HotReloadPathHelper.kt +++ /dev/null @@ -1,28 +0,0 @@ -import java.io.* -import java.nio.file.FileSystems -import java.nio.file.Files -import java.nio.file.Path -import kotlin.io.path.absolutePathString -import kotlin.io.path.listDirectoryEntries -import android.util.Log - - -class HotReloadPathHelper { - companion object { - fun getAssetPath(path: String, packageName: String): String? { - val packagePath = "/data/user/0/${packageName}/code_cache/" - Log.v("thermion_flutter", "Looking for hot reloaded asset ${path} under package path ${packagePath}") - val files = File(packagePath).walkBottomUp().filter { - it.path.endsWith(path) - }.sortedBy { - it.lastModified() - }.toList() - if(files.size > 0) { - Log.v("thermion_flutter", "Using hot reloaded asset at ${files.last().path}") - return files.last().path; - } - Log.v("thermion_flutter", "No hot reloaded asset found.") - return null; - } - } -} \ No newline at end of file diff --git a/thermion_flutter/thermion_flutter/android/src/main/kotlin/dev/thermion/android/ThermionFlutterPlugin.kt b/thermion_flutter/thermion_flutter/android/src/main/kotlin/dev/thermion/android/ThermionFlutterPlugin.kt index be0c913f..1a3bed24 100644 --- a/thermion_flutter/thermion_flutter/android/src/main/kotlin/dev/thermion/android/ThermionFlutterPlugin.kt +++ b/thermion_flutter/thermion_flutter/android/src/main/kotlin/dev/thermion/android/ThermionFlutterPlugin.kt @@ -1,7 +1,5 @@ package dev.thermion.android - -import HotReloadPathHelper import android.app.Activity import android.content.res.AssetManager import android.graphics.* @@ -12,7 +10,6 @@ import android.view.Surface import androidx.annotation.NonNull import androidx.annotation.RequiresApi import androidx.lifecycle.Lifecycle -import com.sun.jna.* import io.flutter.FlutterInjector import io.flutter.embedding.engine.FlutterJNI import io.flutter.embedding.engine.plugins.FlutterPlugin @@ -26,34 +23,16 @@ import io.flutter.view.TextureRegistry.SurfaceTextureEntry import java.io.File import java.util.* - -class LoadFilamentResourceFromOwnerImpl(plugin:ThermionFlutterPlugin) : LoadFilamentResourceFromOwner { - var plugin = plugin - override fun loadResourceFromOwner(path: String?, owner: Pointer?): ResourceBuffer { - return plugin.loadResourceFromOwner(path, owner) - } -} - -class FreeFilamentResourceFromOwnerImpl(plugin:ThermionFlutterPlugin) : FreeFilamentResourceFromOwner { - var plugin = plugin - override fun freeResourceFromOwner(rb: ResourceBuffer, owner: Pointer?) { - plugin.freeResourceFromOwner(rb, owner) - } -} - -class RenderCallbackImpl(plugin:ThermionFlutterPlugin) : RenderCallback { - var plugin = plugin - override fun renderCallback(owner:Pointer?) { - plugin.renderCallback(); - - if(!plugin._surface!!.isValid) { - Log.e("thermion_flutter", "Error: surface is no longer valid") +class NativeWindowHelper { + companion object { + init { + System.loadLibrary("thermion_flutter_android") + } + external fun getNativeWindowFromSurface(surface: Surface): Long } - } } -/** ThermionFlutterPlugin */ -class ThermionFlutterPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, LoadFilamentResourceFromOwner, FreeFilamentResourceFromOwner { +class ThermionFlutterPlugin: FlutterPlugin, MethodCallHandler, ActivityAware { companion object { const val CHANNEL_NAME = "dev.thermion.flutter/event" @@ -66,8 +45,6 @@ class ThermionFlutterPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, Lo private var lifecycle: Lifecycle? = null - private lateinit var _lib : FilamentInterop - private data class TextureEntry( val surfaceTextureEntry: SurfaceTextureEntry, val surfaceTexture: SurfaceTexture, @@ -79,17 +56,12 @@ class ThermionFlutterPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, Lo var _surface: Surface? = null private val textures: MutableMap = mutableMapOf() - private lateinit var activity:Activity - private var loadResourceWrapper:LoadFilamentResourceFromOwnerImpl = LoadFilamentResourceFromOwnerImpl(this) - private var freeResourceWrapper:FreeFilamentResourceFromOwnerImpl = FreeFilamentResourceFromOwnerImpl(this) - override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { this.flutterPluginBinding = flutterPluginBinding channel = MethodChannel(flutterPluginBinding.binaryMessenger, CHANNEL_NAME) channel.setMethodCallHandler(this) - _lib = Native.loadLibrary("thermion_flutter_android", FilamentInterop::class.java, Collections.singletonMap(Library.OPTION_ALLOW_OBJECTS, true)) } override fun onAttachedToActivity(binding: ActivityPluginBinding) { @@ -98,68 +70,6 @@ class ThermionFlutterPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, Lo activity.window.setFormat(PixelFormat.RGBA_8888) } - val _resources:MutableMap = mutableMapOf(); - var _lastId = 1 - - override fun loadResourceFromOwner(path: String?, owner: Pointer?): ResourceBuffer { - Log.i("thermion_flutter", "Loading resource from path $path") - var data:ByteArray? = null - if(path!!.startsWith("file://")) { - data = File(path!!.substring(6)).readBytes() - } else { - var assetPath = path - if(assetPath.startsWith("asset://")) { - assetPath = assetPath!!.substring(8) - } - val loader = FlutterInjector.instance().flutterLoader() - val key = loader.getLookupKeyForAsset(assetPath) - val hotReloadPath = HotReloadPathHelper.getAssetPath(key, activity.getPackageName()) - if (hotReloadPath != null) { - data = File(hotReloadPath).readBytes() - } else { - Log.i("thermion_flutter", "Loading resource from main asset bundle at ${assetPath}") - - val assetManager: AssetManager = activity.assets - try { - data = assetManager.open(key).readBytes() - Log.i("thermion_flutter", "Loaded ${data.size} bytes") - } catch (e:Exception) { - Log.e("thermion_flutter", "Failed to open asset at ${assetPath}", null) - } - } - } - val rb = ResourceBuffer(); - try { - if (data != null) { - val dataPtr = Memory(data.size.toLong()) - dataPtr.write(0, data, 0, data.size) - rb.data = dataPtr - rb.size = data.size - rb.id = _lastId - _resources[rb] = dataPtr; - _lastId++ - } else { - rb.id = 0 - rb.size = 0 - rb.data = Pointer(0) - } - } catch(e:Exception) { - Log.e("thermion_flutter", "Error setting resource buffer : $e", null); - } - rb.write(); - return rb; - - } - - override fun freeResourceFromOwner(rb: ResourceBuffer, owner: Pointer?) { - _resources.remove(rb) - } - - fun renderCallback() { - // noop, log or check surface.valid() is you want - } - - @RequiresApi(Build.VERSION_CODES.M) override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { when (call.method) { @@ -184,8 +94,10 @@ class ThermionFlutterPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, Lo } else { val flutterTextureId = surfaceTextureEntry.id() textures[flutterTextureId] = TextureEntry(surfaceTextureEntry, surfaceTexture, surface) - val nativeWindow = _lib.get_native_window_from_surface(surface as Object, JNIEnv.CURRENT) - result.success(listOf(flutterTextureId, flutterTextureId, Pointer.nativeValue(nativeWindow))) + //val surface = surfaceView.holder.surface + val nativeWindowPtr = NativeWindowHelper.getNativeWindowFromSurface(surface) + //val nativeWindow = _lib.get_native_window_from_surface(surface as Object, JNIEnv.CURRENT) + result.success(listOf(flutterTextureId, flutterTextureId, nativeWindowPtr)) } } "destroyTexture" -> { @@ -215,10 +127,6 @@ class ThermionFlutterPlugin: FlutterPlugin, MethodCallHandler, ActivityAware, Lo "getSharedContext" -> { result.success(null) } - "getRenderCallback" -> { - val renderCallbackFnPointer = _lib.make_render_callback_fn_pointer(RenderCallbackImpl(this)) - result.success(listOf(Pointer.nativeValue(renderCallbackFnPointer), 0)) - } else -> { result.notImplemented() }