diff --git a/arkoala-arkts/loader/src/loader.ts b/arkoala-arkts/loader/src/loader.ts index 084ff46b73948ca3842e02f606b03534baa4932d..14f75f0e73418fbf23764893683efeb1e5d02e46 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) { @@ -165,6 +170,9 @@ checkLoader( navigationChecker(control) break; } + case "UserApp": { + break; + } default: { console.log("Checker is unassigned! app: " + app); control.emitEvent(2, 1001, 100, 100) diff --git a/interop/src/cpp/common-interop.cc b/interop/src/cpp/common-interop.cc index c1034ba6445bc7e81646cf4425ab80c9e8dfa4c3..073c09d3fc5f85c8977b360b019ef205ab8844cf 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 36332c7a7cfdf0ca2a1b771f4f3bef20030fb493..0212463c4749577688b460050c574a9bab3529ba 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;