From 5d0ce3045028808dae0550ce0df0a2984ef62faa Mon Sep 17 00:00:00 2001 From: Nikolay Igotti Date: Thu, 19 Dec 2024 10:07:26 +0300 Subject: [PATCH 1/2] Seamless interop --- arkoala-arkts/loader/src/loader.ts | 5 +++ interop/src/cpp/common-interop.cc | 8 +++++ interop/src/cpp/vmloader.cc | 52 ++++++++++++++++++++++++++++-- 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/arkoala-arkts/loader/src/loader.ts b/arkoala-arkts/loader/src/loader.ts index 084ff46b7..0a332360c 100644 --- a/arkoala-arkts/loader/src/loader.ts +++ b/arkoala-arkts/loader/src/loader.ts @@ -37,6 +37,7 @@ export interface LoaderOps { _LoadVirtualMachine(vmKind: int32, appClassPath: string, appLibPath: string): int32 _StartApplication(appUrl: string, appParams: string): KPointer _RunApplication(arg0: int32, arg1: int32): boolean + _CallVirtualMachine(type: int32, data: Uint8Array, inputLength: int32, maxOutputLength: int32): int32 } export interface NativeControl extends LoaderOps { @@ -97,6 +98,10 @@ class Application { const pipelineContext = this.getNativePipelineContext() nativeModule()._SetVsyncCallback(pipelineContext) resolve(new AppControl(this)) + + // TODO: use serializer + nativeModule()._CallVirtualMachine(1, new Uint8Array(1), 1, 0) + while (!nativeModule()._RunApplication(0, 0)) { await nativeModule()._VSyncAwait(pipelineContext) if (loopIterations != undefined) { diff --git a/interop/src/cpp/common-interop.cc b/interop/src/cpp/common-interop.cc index c1034ba64..073c09d3f 100644 --- a/interop/src/cpp/common-interop.cc +++ b/interop/src/cpp/common-interop.cc @@ -265,6 +265,7 @@ typedef KInt (*LoadVirtualMachine_t)(KInt vmKind, const char* appClassPath, cons typedef KNativePointer (*StartApplication_t)(const char* appUrl, const char* appParams); typedef KBoolean (*RunApplication_t)(const KInt arg0, const KInt arg1); typedef void (*EmitEvent_t)(const KInt type, const KInt target, const KInt arg0, const KInt arg1); +typedef KInt (*CallVirtualMachine_t)(const KInt type, KByte* data, KInt inputLength, KInt maxOutputLength); void* getImpl(const char* path, const char* name) { static void* lib = nullptr; @@ -310,6 +311,13 @@ void impl_EmitEvent(const KInt type, const KInt target, const KInt arg0, const K } KOALA_INTEROP_V4(EmitEvent, KInt, KInt, KInt, KInt) +KInt impl_CallVirtualMachine(const KInt type, KByte* data, KInt inputLength, KInt maxOutputLength) { + static CallVirtualMachine_t impl = nullptr; + if (!impl) impl = reinterpret_cast(getImpl(nullptr, "CallVirtualMachine")); + return impl(type, data, inputLength, maxOutputLength); +} +KOALA_INTEROP_4(CallVirtualMachine, KInt, KInt, KByte*, KInt, KInt) + static Callback_Caller_t g_callbackCaller = nullptr; void setCallbackCaller(Callback_Caller_t callbackCaller) { g_callbackCaller = callbackCaller; diff --git a/interop/src/cpp/vmloader.cc b/interop/src/cpp/vmloader.cc index 36332c7a7..0212463c4 100644 --- a/interop/src/cpp/vmloader.cc +++ b/interop/src/cpp/vmloader.cc @@ -124,11 +124,15 @@ struct VMEntry { void* app; void* enter; void* emitEvent; + void* callVM; + VMEntry() { vmKind = 0; app = nullptr; enter = nullptr; + emitEvent = nullptr; + callVM = nullptr; } }; @@ -272,6 +276,8 @@ struct AppInfo { const char* enterMethodSig; const char* emitEventMethodName; const char* emitEventMethodSig; + const char* callVMMethodName; + const char* callVMMethodSig; }; #ifdef KOALA_JNI @@ -285,6 +291,8 @@ const AppInfo javaAppInfo = { "(II)Z", "emitEvent", "(IIII)V", + "callVM", + "([BII)I", }; #endif @@ -299,6 +307,8 @@ const AppInfo pandaAppInfo = { "II:Z", "emitEvent", "IIII:V", + "callVM", + "[BII:I" }; #endif @@ -349,6 +359,12 @@ extern "C" DLL_EXPORT KNativePointer StartApplication(const char* appUrl, const LOGE("Cannot find emitEvent method %s\n", appInfo->emitEventMethodName); return nullptr; } + g_vmEntry.callVM = (void*)(jEnv->GetMethodID(appClass, appInfo->callVMMethodName, appInfo->callVMMethodSig)); + if (!g_vmEntry.callVM) { + LOGE("Cannot find callVM method %s\n", appInfo->callVMMethodName); + return nullptr; + } + return reinterpret_cast(jEnv->CallLongMethod( app, start)); } @@ -411,7 +427,7 @@ extern "C" DLL_EXPORT KNativePointer StartApplication(const char* appUrl, const return nullptr; } -extern "C" DLL_EXPORT KBoolean RunApplication(const KInt arg0, const KInt arg1) { +extern "C" DLL_EXPORT KBoolean RunApplication(KInt arg0, KInt arg1) { #ifdef KOALA_JNI if (g_vmEntry.vmKind == JAVA_VM_KIND) { JNIEnv* jEnv = (JNIEnv*)(g_vmEntry.env); @@ -452,7 +468,7 @@ extern "C" DLL_EXPORT KBoolean RunApplication(const KInt arg0, const KInt arg1) return 1; } -extern "C" DLL_EXPORT void EmitEvent(const KInt type, const KInt target, const KInt arg0, const KInt arg1) { +extern "C" DLL_EXPORT void EmitEvent(KInt type, KInt target, KInt arg0, KInt arg1) { #ifdef KOALA_JNI if (g_vmEntry.vmKind == JAVA_VM_KIND) { JNIEnv* jEnv = (JNIEnv*)(g_vmEntry.env); @@ -498,6 +514,38 @@ extern "C" DLL_EXPORT void EmitEvent(const KInt type, const KInt target, const K #endif } +extern "C" DLL_EXPORT KInt CallVirtualMachine(KInt vmType, KByte* data, KInt inputLength, KInt maxOutputLength) { +#ifdef KOALA_JNI + if (vmType == JAVA_VM_KIND) { + JNIEnv* jEnv = (JNIEnv*)(g_vmEntry.env); + if (!g_vmEntry.callVM) { + LOGE0("Cannot find callVM method"); + return -1; + } + // TODO: cache this array! + jbyteArray array = jEnv->NewByteArray(inputLength >= maxOutputLength ? inputLength : maxOutputLength); + jEnv->SetByteArrayRegion(array, 0, inputLength, (const jbyte*)data); + KInt result = jEnv->CallIntMethod( + (jobject)(g_vmEntry.app), + (jmethodID)(g_vmEntry.callVM), + array, + inputLength, + maxOutputLength + ); + if (jEnv->ExceptionCheck()) { + jEnv->ExceptionDescribe(); + jEnv->ExceptionClear(); + } else { + if (result > 0 && result <= maxOutputLength) { + jEnv->GetByteArrayRegion(array, 0, result, (jbyte*)data); + } + } + return result; + } +#endif + return -1; +} + void traverseDir(std::string root, std::vector& paths, int depth) { if (depth >= 50) { return; -- Gitee From 4b6855b215af13a51f6bb5139299fbc3127fae9c Mon Sep 17 00:00:00 2001 From: Nikolay Igotti Date: Thu, 26 Dec 2024 17:22:06 +0300 Subject: [PATCH 2/2] Update --- arkoala-arkts/loader/src/loader.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arkoala-arkts/loader/src/loader.ts b/arkoala-arkts/loader/src/loader.ts index 0a332360c..14f75f0e7 100644 --- a/arkoala-arkts/loader/src/loader.ts +++ b/arkoala-arkts/loader/src/loader.ts @@ -170,6 +170,9 @@ checkLoader( navigationChecker(control) break; } + case "UserApp": { + break; + } default: { console.log("Checker is unassigned! app: " + app); control.emitEvent(2, 1001, 100, 100) -- Gitee