diff --git a/test-app/app/src/main/java/com/tns/AndroidJsV8Inspector.java b/test-app/app/src/main/java/com/tns/AndroidJsV8Inspector.java index c10715f58..215ac9301 100644 --- a/test-app/app/src/main/java/com/tns/AndroidJsV8Inspector.java +++ b/test-app/app/src/main/java/com/tns/AndroidJsV8Inspector.java @@ -19,6 +19,8 @@ import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.atomic.AtomicBoolean; +import dalvik.annotation.optimization.CriticalNative; +import dalvik.annotation.optimization.FastNative; import fi.iki.elonen.NanoHTTPD; import fi.iki.elonen.NanoWSD; @@ -27,14 +29,19 @@ class AndroidJsV8Inspector { private static String ApplicationDir; private String packageName; + @CriticalNative protected native final void init(); + @FastNative protected native final void connect(Object connection); + @CriticalNative private native void scheduleBreak(); + @CriticalNative protected static native void disconnect(); + @FastNative protected native final void dispatchMessage(String message); private Handler mainHandler; diff --git a/test-app/runtime/src/main/cpp/com_tns_AndroidJsV8Inspector.cpp b/test-app/runtime/src/main/cpp/com_tns_AndroidJsV8Inspector.cpp index cdef52e62..03ce3bfa7 100644 --- a/test-app/runtime/src/main/cpp/com_tns_AndroidJsV8Inspector.cpp +++ b/test-app/runtime/src/main/cpp/com_tns_AndroidJsV8Inspector.cpp @@ -3,28 +3,42 @@ #include #include "JsV8InspectorClient.h" #include "ArgConverter.h" +#include "com_tns_AndroidJsV8Inspector.h" using namespace tns; using namespace std; -JNIEXPORT extern "C" void Java_com_tns_AndroidJsV8Inspector_init(JNIEnv* env, jobject object) { - JsV8InspectorClient::GetInstance()->init(); -} -JNIEXPORT extern "C" void Java_com_tns_AndroidJsV8Inspector_connect(JNIEnv* env, jobject instance, jobject connection) { +JNIEXPORT JNICALL void connect(JNIEnv *env, jobject instance, jobject connection) { JsV8InspectorClient::GetInstance()->disconnect(); JsV8InspectorClient::GetInstance()->connect(connection); } -JNIEXPORT extern "C" void Java_com_tns_AndroidJsV8Inspector_scheduleBreak(JNIEnv* env, jobject instance) { +JNIEXPORT JNICALL void scheduleBreak(JNIEnv *env, jobject instance) { JsV8InspectorClient::GetInstance()->scheduleBreak(); } -JNIEXPORT extern "C" void Java_com_tns_AndroidJsV8Inspector_disconnect(JNIEnv* env, jobject instance) { +JNIEXPORT JNICALL void scheduleBreakCritical() { + JsV8InspectorClient::GetInstance()->scheduleBreak(); +} + +JNIEXPORT JNICALL void disconnect(JNIEnv *env, jobject instance) { + JsV8InspectorClient::GetInstance()->disconnect(); +} + +JNIEXPORT JNICALL void disconnectCritical() { JsV8InspectorClient::GetInstance()->disconnect(); } -JNIEXPORT extern "C" void Java_com_tns_AndroidJsV8Inspector_dispatchMessage(JNIEnv* env, jobject instance, jstring jMessage) { +JNIEXPORT JNICALL void dispatchMessage(JNIEnv *env, jobject instance, jstring jMessage) { std::string message = ArgConverter::jstringToString(jMessage); JsV8InspectorClient::GetInstance()->dispatchMessage(message); } + +JNIEXPORT JNICALL void init(JNIEnv *env, jobject object) { + JsV8InspectorClient::GetInstance()->init(); +} + +JNIEXPORT JNICALL void initCritical() { + JsV8InspectorClient::GetInstance()->init(); +} diff --git a/test-app/runtime/src/main/cpp/com_tns_AndroidJsV8Inspector.h b/test-app/runtime/src/main/cpp/com_tns_AndroidJsV8Inspector.h new file mode 100644 index 000000000..004e2099e --- /dev/null +++ b/test-app/runtime/src/main/cpp/com_tns_AndroidJsV8Inspector.h @@ -0,0 +1,35 @@ +// +// Created by Osei Fortune on 07/11/2023. +// +#include "jni.h" +#include "JEnv.h" +#include "NativeScriptException.h" +#include +#include "JsV8InspectorClient.h" +#include "ArgConverter.h" + + +using namespace tns; +using namespace std; + +#ifndef COM_TNS_ANDROIDJSV8INSPECTOR_H +#define COM_TNS_ANDROIDJSV8INSPECTOR_H + +void init(JNIEnv *env, jobject object); + +void initCritical(); + +void connect(JNIEnv *env, jobject instance, jobject connection); + +void scheduleBreak(JNIEnv *env, jobject instance); + +void scheduleBreakCritical(); + +void disconnect(JNIEnv *env, jobject instance); + +void disconnectCritical(); + +void dispatchMessage(JNIEnv *env, jobject instance, jstring jMessage); + + +#endif //COM_TNS_ANDROIDJSV8INSPECTOR_H diff --git a/test-app/runtime/src/main/cpp/com_tns_AssetExtractor.cpp b/test-app/runtime/src/main/cpp/com_tns_AssetExtractor.cpp index f65609639..940a9761e 100644 --- a/test-app/runtime/src/main/cpp/com_tns_AssetExtractor.cpp +++ b/test-app/runtime/src/main/cpp/com_tns_AssetExtractor.cpp @@ -7,7 +7,7 @@ using namespace tns; using namespace std; -extern "C" JNIEXPORT void Java_com_tns_AssetExtractor_extractAssets(JNIEnv* env, jobject obj, jstring apk, jstring inputDir, jstring outputDir, jboolean _forceOverwrite) { +JNIEXPORT JNICALL void extractAssets(JNIEnv* env, jobject obj, jstring apk, jstring inputDir, jstring outputDir, jboolean _forceOverwrite) { try { AssetExtractor::ExtractAssets(env, obj, apk, inputDir, outputDir, _forceOverwrite); } catch (NativeScriptException& e) { diff --git a/test-app/runtime/src/main/cpp/com_tns_AssetExtractor.h b/test-app/runtime/src/main/cpp/com_tns_AssetExtractor.h new file mode 100644 index 000000000..60540dc38 --- /dev/null +++ b/test-app/runtime/src/main/cpp/com_tns_AssetExtractor.h @@ -0,0 +1,19 @@ +// +// Created by Osei Fortune on 07/11/2023. +// + +#include "jni.h" +#include "AssetExtractor.h" +#include "NativeScriptException.h" + +#include + +#ifndef COM_TNS_ASSETEXTRACTOR_H +#define COM_TNS_ASSETEXTRACTOR_H + +using namespace std; +using namespace tns; + +void extractAssets(JNIEnv* env, jobject obj, jstring apk, jstring inputDir, jstring outputDir, jboolean _forceOverwrite); + +#endif //COM_TNS_ASSETEXTRACTOR_H diff --git a/test-app/runtime/src/main/cpp/com_tns_Runtime.cpp b/test-app/runtime/src/main/cpp/com_tns_Runtime.cpp index 01777f9ab..fb5449baa 100644 --- a/test-app/runtime/src/main/cpp/com_tns_Runtime.cpp +++ b/test-app/runtime/src/main/cpp/com_tns_Runtime.cpp @@ -3,29 +3,35 @@ #include "NativeScriptException.h" #include "CallbackHandlers.h" #include - +#include "com_tns_AssetExtractor.h" +#include "com_tns_AndroidJsV8Inspector.h" using namespace std; using namespace tns; -JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) { - try { - Runtime::Init(vm, reserved); - } catch (NativeScriptException& e) { - e.ReThrowToJava(); - } catch (std::exception e) { - stringstream ss; - ss << "Error: c++ exception: " << e.what() << endl; - NativeScriptException nsEx(ss.str()); - nsEx.ReThrowToJava(); - } catch (...) { - NativeScriptException nsEx(std::string("Error: c++ exception!")); - nsEx.ReThrowToJava(); +#define ANDROID_O 26 + +int getApiVersion(JNIEnv *env) { + jint sdkInt = -1; + bool success = true; + jclass versionClass = env->FindClass("android/os/Build$VERSION"); + + if (versionClass == nullptr) { + success = false; } - return JNI_VERSION_1_6; + jfieldID sdkIntFieldID; + if (success) { + success = ((sdkIntFieldID = env->GetStaticFieldID(versionClass, "SDK_INT", "I")) != nullptr); + } + + if (success) { + sdkInt = env->GetStaticIntField(versionClass, sdkIntFieldID); + } + + return sdkInt; } -extern "C" JNIEXPORT void Java_com_tns_Runtime_SetManualInstrumentationMode(JNIEnv* _env, jobject obj, jstring mode) { +static JNICALL void SetManualInstrumentationMode(JNIEnv* _env, jclass _clazz, jstring mode) { try { Runtime::SetManualInstrumentationMode(mode); } catch (...) { @@ -34,7 +40,7 @@ extern "C" JNIEXPORT void Java_com_tns_Runtime_SetManualInstrumentationMode(JNIE } } -extern "C" JNIEXPORT void Java_com_tns_Runtime_initNativeScript(JNIEnv* _env, jobject obj, jint runtimeId, jstring filesPath, jstring nativeLibDir, jboolean verboseLoggingEnabled, jboolean isDebuggable, jstring packageName, jobjectArray args, jstring callingDir, jint maxLogcatObjectSize, jboolean forceLog) { +static JNICALL void initNativeScript(JNIEnv* _env, jobject obj, jint runtimeId, jstring filesPath, jstring nativeLibDir, jboolean verboseLoggingEnabled, jboolean isDebuggable, jstring packageName, jobjectArray args, jstring callingDir, jint maxLogcatObjectSize, jboolean forceLog) { try { Runtime::Init(_env, obj, runtimeId, filesPath, nativeLibDir, verboseLoggingEnabled, isDebuggable, packageName, args, callingDir, maxLogcatObjectSize, forceLog); } catch (NativeScriptException& e) { @@ -68,7 +74,7 @@ Runtime* TryGetRuntime(int runtimeId) { return runtime; } -extern "C" JNIEXPORT void Java_com_tns_Runtime_runModule(JNIEnv* _env, jobject obj, jint runtimeId, jstring scriptFile) { +static JNICALL void runModule(JNIEnv* _env, jobject obj, jint runtimeId, jstring scriptFile) { auto runtime = TryGetRuntime(runtimeId); if (runtime == nullptr) { return; @@ -96,7 +102,7 @@ extern "C" JNIEXPORT void Java_com_tns_Runtime_runModule(JNIEnv* _env, jobject o } } -extern "C" JNIEXPORT void Java_com_tns_Runtime_runWorker(JNIEnv* _env, jobject obj, jint runtimeId, jstring scriptFile) { +static JNICALL void runWorker(JNIEnv* _env, jobject obj, jint runtimeId, jstring scriptFile) { auto runtime = TryGetRuntime(runtimeId); if (runtime == nullptr) { return; @@ -124,7 +130,7 @@ extern "C" JNIEXPORT void Java_com_tns_Runtime_runWorker(JNIEnv* _env, jobject o } } -extern "C" JNIEXPORT jobject Java_com_tns_Runtime_runScript(JNIEnv* _env, jobject obj, jint runtimeId, jstring scriptFile) { +static JNICALL jobject runScript(JNIEnv* _env, jobject obj, jint runtimeId, jstring scriptFile) { jobject result = nullptr; auto runtime = TryGetRuntime(runtimeId); @@ -155,7 +161,7 @@ extern "C" JNIEXPORT jobject Java_com_tns_Runtime_runScript(JNIEnv* _env, jobjec return result; } -extern "C" JNIEXPORT jobject Java_com_tns_Runtime_callJSMethodNative(JNIEnv* _env, jobject obj, jint runtimeId, jint javaObjectID, jstring methodName, jint retType, jboolean isConstructor, jobjectArray packagedArgs) { +static JNICALL jobject callJSMethodNative(JNIEnv* _env, jobject obj, jint runtimeId, jint javaObjectID, jstring methodName, jint retType, jboolean isConstructor, jobjectArray packagedArgs) { jobject result = nullptr; auto runtime = TryGetRuntime(runtimeId); @@ -186,7 +192,7 @@ extern "C" JNIEXPORT jobject Java_com_tns_Runtime_callJSMethodNative(JNIEnv* _en return result; } -extern "C" JNIEXPORT void Java_com_tns_Runtime_createJSInstanceNative(JNIEnv* _env, jobject obj, jint runtimeId, jobject javaObject, jint javaObjectID, jstring className) { +static JNICALL void createJSInstanceNative(JNIEnv* _env, jobject obj, jint runtimeId, jobject javaObject, jint javaObjectID, jstring className) { auto runtime = TryGetRuntime(runtimeId); if (runtime == nullptr) { return; @@ -214,7 +220,7 @@ extern "C" JNIEXPORT void Java_com_tns_Runtime_createJSInstanceNative(JNIEnv* _e } } -extern "C" JNIEXPORT jint Java_com_tns_Runtime_generateNewObjectId(JNIEnv* env, jobject obj, jint runtimeId) { +static JNICALL jint generateNewObjectId(JNIEnv* env, jobject obj, jint runtimeId) { try { auto runtime = TryGetRuntime(runtimeId); if (runtime == nullptr) { @@ -236,7 +242,8 @@ extern "C" JNIEXPORT jint Java_com_tns_Runtime_generateNewObjectId(JNIEnv* env, return 0; } -extern "C" JNIEXPORT jboolean Java_com_tns_Runtime_notifyGc(JNIEnv* env, jobject obj, jint runtimeId) { + +static JNICALL jboolean notifyGc(JNIEnv* env, jobject obj, jint runtimeId) { auto runtime = TryGetRuntime(runtimeId); if (runtime == nullptr) { return JNI_FALSE; @@ -246,21 +253,21 @@ extern "C" JNIEXPORT jboolean Java_com_tns_Runtime_notifyGc(JNIEnv* env, jobject return success; } -extern "C" JNIEXPORT void Java_com_tns_Runtime_lock(JNIEnv* env, jobject obj, jint runtimeId) { +static JNICALL void rtLock(JNIEnv* env, jobject obj, jint runtimeId) { auto runtime = TryGetRuntime(runtimeId); if (runtime != nullptr) { runtime->Lock(); } } -extern "C" JNIEXPORT void Java_com_tns_Runtime_unlock(JNIEnv* env, jobject obj, jint runtimeId) { +static JNICALL void rtUnlock(JNIEnv* env, jobject obj, jint runtimeId) { auto runtime = TryGetRuntime(runtimeId); if (runtime != nullptr) { runtime->Unlock(); } } -extern "C" JNIEXPORT void Java_com_tns_Runtime_passExceptionToJsNative(JNIEnv* env, jobject obj, jint runtimeId, jthrowable exception, jstring message, jstring fullStackTrace, jstring jsStackTrace, jboolean isDiscarded) { +static JNICALL void passExceptionToJsNative(JNIEnv* env, jobject obj, jint runtimeId, jthrowable exception, jstring message, jstring fullStackTrace, jstring jsStackTrace, jboolean isDiscarded) { auto runtime = TryGetRuntime(runtimeId); if (runtime == nullptr) { return; @@ -288,11 +295,11 @@ extern "C" JNIEXPORT void Java_com_tns_Runtime_passExceptionToJsNative(JNIEnv* e } } -extern "C" JNIEXPORT jint Java_com_tns_Runtime_getPointerSize(JNIEnv* env, jobject obj) { +static JNICALL jint getPointerSize(JNIEnv* env, jobject obj) { return sizeof(void*); } -extern "C" JNIEXPORT jint Java_com_tns_Runtime_getCurrentRuntimeId(JNIEnv* _env, jobject obj) { +static JNICALL jint getCurrentRuntimeId(JNIEnv* _env, jobject obj) { Isolate* isolate = Isolate::TryGetCurrent(); if (isolate == nullptr) { return -1; @@ -303,7 +310,7 @@ extern "C" JNIEXPORT jint Java_com_tns_Runtime_getCurrentRuntimeId(JNIEnv* _env, return id; } -extern "C" JNIEXPORT void Java_com_tns_Runtime_WorkerGlobalOnMessageCallback(JNIEnv* env, jobject obj, jint runtimeId, jstring msg) { +static JNICALL void WorkerGlobalOnMessageCallback(JNIEnv* env, jobject obj, jint runtimeId, jstring msg) { // Worker Thread runtime auto runtime = TryGetRuntime(runtimeId); if (runtime == nullptr) { @@ -321,7 +328,7 @@ extern "C" JNIEXPORT void Java_com_tns_Runtime_WorkerGlobalOnMessageCallback(JNI CallbackHandlers::WorkerGlobalOnMessageCallback(isolate, msg); } -extern "C" JNIEXPORT void Java_com_tns_Runtime_WorkerObjectOnMessageCallback(JNIEnv* env, jobject obj, jint runtimeId, jint workerId, jstring msg) { +static JNICALL void WorkerObjectOnMessageCallback(JNIEnv* env, jobject obj, jint runtimeId, jint workerId, jstring msg) { // Main Thread runtime auto runtime = TryGetRuntime(runtimeId); if (runtime == nullptr) { @@ -339,7 +346,7 @@ extern "C" JNIEXPORT void Java_com_tns_Runtime_WorkerObjectOnMessageCallback(JNI CallbackHandlers::WorkerObjectOnMessageCallback(isolate, workerId, msg); } -extern "C" JNIEXPORT void Java_com_tns_Runtime_TerminateWorkerCallback(JNIEnv* env, jobject obj, jint runtimeId) { +static JNICALL void TerminateWorkerCallback(JNIEnv* env, jobject obj, jint runtimeId) { // Worker Thread runtime auto runtime = TryGetRuntime(runtimeId); if (runtime == nullptr) { @@ -363,7 +370,7 @@ extern "C" JNIEXPORT void Java_com_tns_Runtime_TerminateWorkerCallback(JNIEnv* e delete runtime; } -extern "C" JNIEXPORT void Java_com_tns_Runtime_ClearWorkerPersistent(JNIEnv* env, jobject obj, jint runtimeId, jint workerId) { +static JNICALL void ClearWorkerPersistent(JNIEnv* env, jobject obj, jint runtimeId, jint workerId) { // Worker Thread runtime auto runtime = TryGetRuntime(runtimeId); if (runtime == nullptr) { @@ -381,7 +388,7 @@ extern "C" JNIEXPORT void Java_com_tns_Runtime_ClearWorkerPersistent(JNIEnv* env CallbackHandlers::ClearWorkerPersistent(workerId); } -extern "C" JNIEXPORT void Java_com_tns_Runtime_CallWorkerObjectOnErrorHandleMain(JNIEnv* env, jobject obj, jint runtimeId, jint workerId, jstring message, jstring stackTrace, jstring filename, jint lineno, jstring threadName) { +static JNICALL void CallWorkerObjectOnErrorHandleMain(JNIEnv* env, jobject obj, jint runtimeId, jint workerId, jstring message, jstring stackTrace, jstring filename, jint lineno, jstring threadName) { // Main Thread runtime auto runtime = TryGetRuntime(runtimeId); if (runtime == nullptr) { @@ -402,7 +409,7 @@ extern "C" JNIEXPORT void Java_com_tns_Runtime_CallWorkerObjectOnErrorHandleMain } } -extern "C" JNIEXPORT void Java_com_tns_Runtime_ResetDateTimeConfigurationCache(JNIEnv* _env, jobject obj, jint runtimeId) { +static JNICALL void ResetDateTimeConfigurationCache(JNIEnv* _env, jobject obj, jint runtimeId) { auto runtime = TryGetRuntime(runtimeId); if (runtime == nullptr) { return; @@ -410,4 +417,195 @@ extern "C" JNIEXPORT void Java_com_tns_Runtime_ResetDateTimeConfigurationCache(J auto isolate = runtime->GetIsolate(); isolate->DateTimeConfigurationChangeNotification(Isolate::TimeZoneDetection::kRedetect); +} + +JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) { + try { + + JNIEnv *env; + if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6) != JNI_OK) { + return JNI_ERR; + } + + int apiVersion = getApiVersion(env); + + if (apiVersion == -1) { + __android_log_write(ANDROID_LOG_ERROR, "JS", "Could not get Android API version!"); + return JNI_ERR; + } + + jint result; + + + + + if (apiVersion >= ANDROID_O) { + // Redirect func_bangJni to fastNativeFunc since !bang JNI is not supported anymore + JNINativeMethod methodsInternal[] = { + { "SetManualInstrumentationMode", "(Ljava/lang/String;)V", (void *) SetManualInstrumentationMode }, + { "initNativeScript", "(ILjava/lang/String;Ljava/lang/String;ZZLjava/lang/String;[Ljava/lang/Object;Ljava/lang/String;IZ)V", (void *) initNativeScript }, + { "runModule", "(ILjava/lang/String;)V", (void *) runModule }, + { "runWorker", "(ILjava/lang/String;)V", (void *) runWorker }, + { "runScript", "(ILjava/lang/String;)Ljava/lang/Object;", (void *) runScript }, + { "callJSMethodNative", "(IILjava/lang/String;IZ[Ljava/lang/Object;)Ljava/lang/Object;", (void *) callJSMethodNative }, + { "createJSInstanceNative", "(ILjava/lang/Object;ILjava/lang/String;)V", (void *) createJSInstanceNative }, + { "generateNewObjectId", "(I)I", (void *) generateNewObjectId }, + { "notifyGc", "(I)Z", (void *) notifyGc }, + { "lock", "(I)V", (void *) rtLock }, + { "unlock", "(I)V", (void *) rtUnlock }, + { "passExceptionToJsNative", "(ILjava/lang/Throwable;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V", (void *) passExceptionToJsNative }, + { "getPointerSize", "()I", (void *) getPointerSize }, + { "getCurrentRuntimeId", "()I", (void *) getCurrentRuntimeId }, + { "WorkerGlobalOnMessageCallback", "(ILjava/lang/String;)V", (void *) WorkerGlobalOnMessageCallback }, + { "WorkerObjectOnMessageCallback", "(IILjava/lang/String;)V", (void *) WorkerObjectOnMessageCallback }, + { "TerminateWorkerCallback", "(I)V", (void *) TerminateWorkerCallback }, + { "ClearWorkerPersistent", "(II)V", (void *) ClearWorkerPersistent }, + { "CallWorkerObjectOnErrorHandleMain", "(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;)V", (void *) CallWorkerObjectOnErrorHandleMain }, + { "ResetDateTimeConfigurationCache", "(I)V", (void *) ResetDateTimeConfigurationCache }, + }; + + + result = env->RegisterNatives( + env->FindClass("com/tns/Runtime"), + methodsInternal, + sizeof(methodsInternal) / sizeof(JNINativeMethod)); + + + if (result != JNI_OK) { + __android_log_print(ANDROID_LOG_ERROR, "JS", "Error code %d when registering native functions!", + result); + return JNI_ERR; + } + + + JNINativeMethod assetMethodsInternal[] = { + { "extractAssets", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V", (void *) extractAssets } + }; + + result = env->RegisterNatives( + env->FindClass("com/tns/AssetExtractor"), + assetMethodsInternal, + sizeof(assetMethodsInternal) / sizeof(JNINativeMethod)); + + + + if (result != JNI_OK) { + __android_log_print(ANDROID_LOG_ERROR, "JS", "Error code %d when registering native functions!", + result); + return JNI_ERR; + } + + + JNINativeMethod inspectorMethodsInternal[] = { + { "init", "()V", (void *) initCritical }, + { "connect", "(Ljava/lang/Object;)V", (void *) connect }, + { "scheduleBreak", "()V", (void *) scheduleBreakCritical }, + { "disconnect", "()V", (void *) disconnectCritical }, + { "dispatchMessage", "(Ljava/lang/String;)V", (void *) dispatchMessage } + }; + + result = env->RegisterNatives( + env->FindClass("com/tns/AndroidJsV8Inspector"), + inspectorMethodsInternal, + sizeof(inspectorMethodsInternal) / sizeof(JNINativeMethod)); + + + } + else { + // Redirect CriticalNative function to !bang JNI function (need JNIEnv and jclass on Android 7-) + // !bang JNI notation used to demonstrate faster calls on Android 7- + JNINativeMethod methodsInternal[] = { + { "SetManualInstrumentationMode", "!(Ljava/lang/String;)V", (void *) SetManualInstrumentationMode }, + { "initNativeScript", "!(ILjava/lang/String;Ljava/lang/String;ZZLjava/lang/String;[Ljava/lang/Object;Ljava/lang/String;IZ)V", (void *) initNativeScript }, + { "runModule", "!(ILjava/lang/String;)V", (void *) runModule }, + { "runWorker", "!(ILjava/lang/String;)V", (void *) runWorker }, + { "runScript", "!(ILjava/lang/String;)Ljava/lang/Object;", (void *) runScript }, + { "callJSMethodNative", "!(IILjava/lang/String;IZ[Ljava/lang/Object;)Ljava/lang/Object;", (void *) callJSMethodNative }, + { "createJSInstanceNative", "!(ILjava/lang/Object;ILjava/lang/String;)V", (void *) createJSInstanceNative }, + { "generateNewObjectId", "!(I)I", (void *) generateNewObjectId }, + { "notifyGc", "!(I)Z", (void *) notifyGc }, + { "lock", "!(I)V", (void *) rtLock }, + { "unlock", "!(I)V", (void *) rtUnlock }, + { "passExceptionToJsNative", "!(ILjava/lang/Throwable;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V", (void *) passExceptionToJsNative }, + { "getPointerSize", "!()I", (void *) getPointerSize }, + { "getCurrentRuntimeId", "!()I", (void *) getCurrentRuntimeId }, + { "WorkerGlobalOnMessageCallback", "!(ILjava/lang/String;)V", (void *) WorkerGlobalOnMessageCallback }, + { "WorkerObjectOnMessageCallback", "!(IILjava/lang/String;)V", (void *) WorkerObjectOnMessageCallback }, + { "TerminateWorkerCallback", "!(I)V", (void *) TerminateWorkerCallback }, + { "ClearWorkerPersistent", "!(II)V", (void *) ClearWorkerPersistent }, + { "CallWorkerObjectOnErrorHandleMain", "!(IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;)V", (void *) CallWorkerObjectOnErrorHandleMain }, + { "ResetDateTimeConfigurationCache", "!(I)V", (void *) ResetDateTimeConfigurationCache }, + }; + + + + + result = env->RegisterNatives( + env->FindClass("com/tns/Runtime"), + methodsInternal, + sizeof(methodsInternal) / sizeof(JNINativeMethod)); + + + + + if (result != JNI_OK) { + __android_log_print(ANDROID_LOG_ERROR, "JS", "Error code %d when registering native functions!", + result); + return JNI_ERR; + } + + + JNINativeMethod assetMethodsInternal[] = { + { "extractAssets", "!(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V", (void *) extractAssets } + }; + + result = env->RegisterNatives( + env->FindClass("com/tns/AssetExtractor"), + assetMethodsInternal, + sizeof(assetMethodsInternal) / sizeof(JNINativeMethod)); + + + if (result != JNI_OK) { + __android_log_print(ANDROID_LOG_ERROR, "JS", "Error code %d when registering native functions!", + result); + return JNI_ERR; + } + + + JNINativeMethod inspectorMethodsInternal[] = { + { "init", "!()V", (void *) init }, + { "connect", "!(Ljava/lang/Object;)V", (void *) connect }, + { "scheduleBreak", "!()V", (void *) scheduleBreak }, + { "disconnect", "!()V", (void *) disconnect }, + { "dispatchMessage", "!(Ljava/lang/String;)V", (void *) dispatchMessage } + }; + + result = env->RegisterNatives( + env->FindClass("com/tns/AndroidJsV8Inspector"), + inspectorMethodsInternal, + sizeof(inspectorMethodsInternal) / sizeof(JNINativeMethod)); + + } + + if (result != JNI_OK) { + __android_log_print(ANDROID_LOG_ERROR, "JS", "Error code %d when registering native functions!", + result); + return JNI_ERR; + } + + + Runtime::Init(vm, reserved); + } catch (NativeScriptException& e) { + e.ReThrowToJava(); + } catch (std::exception e) { + stringstream ss; + ss << "Error: c++ exception: " << e.what() << endl; + NativeScriptException nsEx(ss.str()); + nsEx.ReThrowToJava(); + } catch (...) { + NativeScriptException nsEx(std::string("Error: c++ exception!")); + nsEx.ReThrowToJava(); + } + + return JNI_VERSION_1_6; } \ No newline at end of file diff --git a/test-app/runtime/src/main/java/com/tns/AssetExtractor.java b/test-app/runtime/src/main/java/com/tns/AssetExtractor.java index 9ebf966aa..466ed6e47 100644 --- a/test-app/runtime/src/main/java/com/tns/AssetExtractor.java +++ b/test-app/runtime/src/main/java/com/tns/AssetExtractor.java @@ -6,7 +6,10 @@ import android.content.Context; import android.util.Log; +import dalvik.annotation.optimization.FastNative; + public class AssetExtractor { + @FastNative private native void extractAssets(String apkPath, String input, String outputDir, boolean checkForNewerFiles); private final Logger logger; diff --git a/test-app/runtime/src/main/java/com/tns/Runtime.java b/test-app/runtime/src/main/java/com/tns/Runtime.java index ad8caed91..a265abd20 100644 --- a/test-app/runtime/src/main/java/com/tns/Runtime.java +++ b/test-app/runtime/src/main/java/com/tns/Runtime.java @@ -36,46 +36,69 @@ import java.util.concurrent.RunnableFuture; import java.util.concurrent.atomic.AtomicInteger; +import dalvik.annotation.optimization.CriticalNative; +import dalvik.annotation.optimization.FastNative; + public class Runtime { + @FastNative private native void initNativeScript(int runtimeId, String filesPath, String nativeLibDir, boolean verboseLoggingEnabled, boolean isDebuggable, String packageName, Object[] v8Options, String callingDir, int maxLogcatObjectSize, boolean forceLog); + @FastNative private native void runModule(int runtimeId, String filePath) throws NativeScriptException; + @FastNative private native void runWorker(int runtimeId, String filePath) throws NativeScriptException; + @FastNative private native Object runScript(int runtimeId, String filePath) throws NativeScriptException; + @FastNative private native Object callJSMethodNative(int runtimeId, int javaObjectID, String methodName, int retType, boolean isConstructor, Object... packagedArgs) throws NativeScriptException; + @FastNative private native void createJSInstanceNative(int runtimeId, Object javaObject, int javaObjectID, String canonicalName); + @FastNative private native int generateNewObjectId(int runtimeId); + @FastNative private native boolean notifyGc(int runtimeId); + @FastNative private native void lock(int runtimeId); + @FastNative private native void unlock(int runtimeId); + @FastNative private native void passExceptionToJsNative(int runtimeId, Throwable ex, String message, String fullStackTrace, String jsStackTrace, boolean isDiscarded); + @FastNative private static native int getCurrentRuntimeId(); + @FastNative public static native int getPointerSize(); + @FastNative public static native void SetManualInstrumentationMode(String mode); + @FastNative private static native void WorkerGlobalOnMessageCallback(int runtimeId, String message); + @FastNative private static native void WorkerObjectOnMessageCallback(int runtimeId, int workerId, String message); + @FastNative private static native void TerminateWorkerCallback(int runtimeId); + @FastNative private static native void ClearWorkerPersistent(int runtimeId, int workerId); + @FastNative private static native void CallWorkerObjectOnErrorHandleMain(int runtimeId, int workerId, String message, String stackTrace, String filename, int lineno, String threadName) throws NativeScriptException; + @FastNative private static native void ResetDateTimeConfigurationCache(int runtimeId); void passUncaughtExceptionToJs(Throwable ex, String message, String fullStackTrace, String jsStackTrace) { diff --git a/test-app/runtime/src/main/java/dalvik/annotation/optimization/CriticalNative.java b/test-app/runtime/src/main/java/dalvik/annotation/optimization/CriticalNative.java new file mode 100644 index 000000000..672cd1703 --- /dev/null +++ b/test-app/runtime/src/main/java/dalvik/annotation/optimization/CriticalNative.java @@ -0,0 +1,10 @@ +package dalvik.annotation.optimization; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.CLASS) // Save memory, don't instantiate as an object at runtime. +@Target(ElementType.METHOD) +public @interface CriticalNative {} \ No newline at end of file diff --git a/test-app/runtime/src/main/java/dalvik/annotation/optimization/FastNative.java b/test-app/runtime/src/main/java/dalvik/annotation/optimization/FastNative.java new file mode 100644 index 000000000..bb519e7f9 --- /dev/null +++ b/test-app/runtime/src/main/java/dalvik/annotation/optimization/FastNative.java @@ -0,0 +1,11 @@ +package dalvik.annotation.optimization; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.CLASS) +@Target({ElementType.METHOD}) +public @interface FastNative { +} \ No newline at end of file