mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2025-09-17 16:47:14 -04:00
Fix[pojavexec]: fix incorrect JNIEnv usage in some cases (#6510)
* Fix[pojavexec]: remove central JNIEnv variables These caused some irreliability, as pojavexec isn't guaranteed to be loaded on the same thread as the call to glfwInit This fixes: - 1.3-1.5.2 setting their window size to 0,0 (and thus not working correctly) - Forge for <1.13 not resizing its window * Fix[egl_bridge]: remove attachEnvs() * Whoops[input_bridge]: remove unnecessary prints
This commit is contained in:
parent
c04e3af70d
commit
55e53ea02c
@ -215,6 +215,11 @@ int pojavInitOpenGL() {
|
||||
extern void updateMonitorSize(int width, int height);
|
||||
|
||||
EXTERNAL_API int pojavInit() {
|
||||
pojav_environ->glfwThreadVmEnv = get_attached_env(pojav_environ->runtimeJavaVMPtr);
|
||||
if(pojav_environ->glfwThreadVmEnv == NULL) {
|
||||
printf("Failed to attach Java-side JNIEnv to GLFW thread\n");
|
||||
return 0;
|
||||
}
|
||||
ANativeWindow_acquire(pojav_environ->pojavWindow);
|
||||
pojav_environ->savedWidth = ANativeWindow_getWidth(pojav_environ->pojavWindow);
|
||||
pojav_environ->savedHeight = ANativeWindow_getHeight(pojav_environ->pojavWindow);
|
||||
|
@ -51,9 +51,8 @@ struct pojav_environ_s {
|
||||
jbyte* keyDownBuffer;
|
||||
jbyte* mouseDownBuffer;
|
||||
JavaVM* runtimeJavaVMPtr;
|
||||
JNIEnv* runtimeJNIEnvPtr_JRE;
|
||||
JNIEnv* glfwThreadVmEnv;
|
||||
JavaVM* dalvikJavaVMPtr;
|
||||
JNIEnv* dalvikJNIEnvPtr_ANDROID;
|
||||
long showingWindow;
|
||||
bool isInputReady, isCursorEntered, isUseStackQueueCall, shouldUpdateMouse;
|
||||
bool shouldUpdateMonitorSize, monitorSizeConsumed;
|
||||
|
@ -30,6 +30,7 @@
|
||||
#define EVENT_TYPE_MOUSE_BUTTON 1006
|
||||
#define EVENT_TYPE_SCROLL 1007
|
||||
|
||||
static void installEMUIIteratorMititgation(JNIEnv *vmEnv);
|
||||
static void registerFunctions(JNIEnv *env);
|
||||
|
||||
jint JNI_OnLoad(JavaVM* vm, __attribute__((unused)) void* reserved) {
|
||||
@ -37,28 +38,30 @@ jint JNI_OnLoad(JavaVM* vm, __attribute__((unused)) void* reserved) {
|
||||
__android_log_print(ANDROID_LOG_INFO, "Native", "Saving DVM environ...");
|
||||
//Save dalvik global JavaVM pointer
|
||||
pojav_environ->dalvikJavaVMPtr = vm;
|
||||
(*vm)->GetEnv(vm, (void**) &pojav_environ->dalvikJNIEnvPtr_ANDROID, JNI_VERSION_1_4);
|
||||
pojav_environ->bridgeClazz = (*pojav_environ->dalvikJNIEnvPtr_ANDROID)->NewGlobalRef(pojav_environ->dalvikJNIEnvPtr_ANDROID,(*pojav_environ->dalvikJNIEnvPtr_ANDROID) ->FindClass(pojav_environ->dalvikJNIEnvPtr_ANDROID,"org/lwjgl/glfw/CallbackBridge"));
|
||||
pojav_environ->method_accessAndroidClipboard = (*pojav_environ->dalvikJNIEnvPtr_ANDROID)->GetStaticMethodID(pojav_environ->dalvikJNIEnvPtr_ANDROID, pojav_environ->bridgeClazz, "accessAndroidClipboard", "(ILjava/lang/String;)Ljava/lang/String;");
|
||||
pojav_environ->method_onGrabStateChanged = (*pojav_environ->dalvikJNIEnvPtr_ANDROID)->GetStaticMethodID(pojav_environ->dalvikJNIEnvPtr_ANDROID, pojav_environ->bridgeClazz, "onGrabStateChanged", "(Z)V");
|
||||
JNIEnv *dvEnv;
|
||||
(*vm)->GetEnv(vm, (void**) &dvEnv, JNI_VERSION_1_4);
|
||||
pojav_environ->bridgeClazz = (*dvEnv)->NewGlobalRef(dvEnv,(*dvEnv) ->FindClass(dvEnv,"org/lwjgl/glfw/CallbackBridge"));
|
||||
pojav_environ->method_accessAndroidClipboard = (*dvEnv)->GetStaticMethodID(dvEnv, pojav_environ->bridgeClazz, "accessAndroidClipboard", "(ILjava/lang/String;)Ljava/lang/String;");
|
||||
pojav_environ->method_onGrabStateChanged = (*dvEnv)->GetStaticMethodID(dvEnv, pojav_environ->bridgeClazz, "onGrabStateChanged", "(Z)V");
|
||||
pojav_environ->isUseStackQueueCall = JNI_FALSE;
|
||||
} else if (pojav_environ->dalvikJavaVMPtr != vm) {
|
||||
__android_log_print(ANDROID_LOG_INFO, "Native", "Saving JVM environ...");
|
||||
pojav_environ->runtimeJavaVMPtr = vm;
|
||||
(*vm)->GetEnv(vm, (void**) &pojav_environ->runtimeJNIEnvPtr_JRE, JNI_VERSION_1_4);
|
||||
pojav_environ->vmGlfwClass = (*pojav_environ->runtimeJNIEnvPtr_JRE)->NewGlobalRef(pojav_environ->runtimeJNIEnvPtr_JRE, (*pojav_environ->runtimeJNIEnvPtr_JRE)->FindClass(pojav_environ->runtimeJNIEnvPtr_JRE, "org/lwjgl/glfw/GLFW"));
|
||||
pojav_environ->method_glftSetWindowAttrib = (*pojav_environ->runtimeJNIEnvPtr_JRE)->GetStaticMethodID(pojav_environ->runtimeJNIEnvPtr_JRE, pojav_environ->vmGlfwClass, "glfwSetWindowAttrib", "(JII)V");
|
||||
pojav_environ->method_internalWindowSizeChanged = (*pojav_environ->runtimeJNIEnvPtr_JRE)->GetStaticMethodID(pojav_environ->runtimeJNIEnvPtr_JRE, pojav_environ->vmGlfwClass, "internalWindowSizeChanged", "(J)V");
|
||||
pojav_environ->method_internalChangeMonitorSize = (*pojav_environ->runtimeJNIEnvPtr_JRE)->GetStaticMethodID(pojav_environ->runtimeJNIEnvPtr_JRE, pojav_environ->vmGlfwClass, "internalChangeMonitorSize", "(II)V");
|
||||
jfieldID field_keyDownBuffer = (*pojav_environ->runtimeJNIEnvPtr_JRE)->GetStaticFieldID(pojav_environ->runtimeJNIEnvPtr_JRE, pojav_environ->vmGlfwClass, "keyDownBuffer", "Ljava/nio/ByteBuffer;");
|
||||
jobject keyDownBufferJ = (*pojav_environ->runtimeJNIEnvPtr_JRE)->GetStaticObjectField(pojav_environ->runtimeJNIEnvPtr_JRE, pojav_environ->vmGlfwClass, field_keyDownBuffer);
|
||||
pojav_environ->keyDownBuffer = (*pojav_environ->runtimeJNIEnvPtr_JRE)->GetDirectBufferAddress(pojav_environ->runtimeJNIEnvPtr_JRE, keyDownBufferJ);
|
||||
jfieldID field_mouseDownBuffer = (*pojav_environ->runtimeJNIEnvPtr_JRE)->GetStaticFieldID(pojav_environ->runtimeJNIEnvPtr_JRE, pojav_environ->vmGlfwClass, "mouseDownBuffer", "Ljava/nio/ByteBuffer;");
|
||||
jobject mouseDownBufferJ = (*pojav_environ->runtimeJNIEnvPtr_JRE)->GetStaticObjectField(pojav_environ->runtimeJNIEnvPtr_JRE, pojav_environ->vmGlfwClass, field_mouseDownBuffer);
|
||||
pojav_environ->mouseDownBuffer = (*pojav_environ->runtimeJNIEnvPtr_JRE)->GetDirectBufferAddress(pojav_environ->runtimeJNIEnvPtr_JRE, mouseDownBufferJ);
|
||||
hookExec();
|
||||
installLwjglDlopenHook();
|
||||
installEMUIIteratorMititgation();
|
||||
JNIEnv *vmEnv;
|
||||
(*vm)->GetEnv(vm, (void**) &vmEnv, JNI_VERSION_1_4);
|
||||
pojav_environ->vmGlfwClass = (*vmEnv)->NewGlobalRef(vmEnv, (*vmEnv)->FindClass(vmEnv, "org/lwjgl/glfw/GLFW"));
|
||||
pojav_environ->method_glftSetWindowAttrib = (*vmEnv)->GetStaticMethodID(vmEnv, pojav_environ->vmGlfwClass, "glfwSetWindowAttrib", "(JII)V");
|
||||
pojav_environ->method_internalWindowSizeChanged = (*vmEnv)->GetStaticMethodID(vmEnv, pojav_environ->vmGlfwClass, "internalWindowSizeChanged", "(J)V");
|
||||
pojav_environ->method_internalChangeMonitorSize = (*vmEnv)->GetStaticMethodID(vmEnv, pojav_environ->vmGlfwClass, "internalChangeMonitorSize", "(II)V");
|
||||
jfieldID field_keyDownBuffer = (*vmEnv)->GetStaticFieldID(vmEnv, pojav_environ->vmGlfwClass, "keyDownBuffer", "Ljava/nio/ByteBuffer;");
|
||||
jobject keyDownBufferJ = (*vmEnv)->GetStaticObjectField(vmEnv, pojav_environ->vmGlfwClass, field_keyDownBuffer);
|
||||
pojav_environ->keyDownBuffer = (*vmEnv)->GetDirectBufferAddress(vmEnv, keyDownBufferJ);
|
||||
jfieldID field_mouseDownBuffer = (*vmEnv)->GetStaticFieldID(vmEnv, pojav_environ->vmGlfwClass, "mouseDownBuffer", "Ljava/nio/ByteBuffer;");
|
||||
jobject mouseDownBufferJ = (*vmEnv)->GetStaticObjectField(vmEnv, pojav_environ->vmGlfwClass, field_mouseDownBuffer);
|
||||
pojav_environ->mouseDownBuffer = (*vmEnv)->GetDirectBufferAddress(vmEnv, mouseDownBufferJ);
|
||||
hookExec(vmEnv);
|
||||
installLwjglDlopenHook(vmEnv);
|
||||
installEMUIIteratorMititgation(vmEnv);
|
||||
}
|
||||
|
||||
if(pojav_environ->dalvikJavaVMPtr == vm) {
|
||||
@ -90,10 +93,10 @@ ADD_CALLBACK_WWIN(Scroll)
|
||||
#undef ADD_CALLBACK_WWIN
|
||||
|
||||
void updateMonitorSize(int width, int height) {
|
||||
(*pojav_environ->runtimeJNIEnvPtr_JRE)->CallStaticVoidMethod(pojav_environ->runtimeJNIEnvPtr_JRE, pojav_environ->vmGlfwClass, pojav_environ->method_internalChangeMonitorSize, width, height);
|
||||
(*pojav_environ->glfwThreadVmEnv)->CallStaticVoidMethod(pojav_environ->glfwThreadVmEnv, pojav_environ->vmGlfwClass, pojav_environ->method_internalChangeMonitorSize, width, height);
|
||||
}
|
||||
void updateWindowSize(void* window) {
|
||||
(*pojav_environ->runtimeJNIEnvPtr_JRE)->CallStaticVoidMethod(pojav_environ->runtimeJNIEnvPtr_JRE, pojav_environ->vmGlfwClass, pojav_environ->method_internalWindowSizeChanged, (jlong)window);
|
||||
(*pojav_environ->glfwThreadVmEnv)->CallStaticVoidMethod(pojav_environ->glfwThreadVmEnv, pojav_environ->vmGlfwClass, pojav_environ->method_internalWindowSizeChanged, (jlong)window);
|
||||
}
|
||||
|
||||
void pojavPumpEvents(void* window) {
|
||||
@ -246,10 +249,9 @@ jint getLibraryPath_fix(__attribute__((unused)) JNIEnv *env,
|
||||
/**
|
||||
* Install the linker hang mitigation that is meant to prevent linker hangs on old EMUI firmware.
|
||||
*/
|
||||
void installEMUIIteratorMititgation() {
|
||||
static void installEMUIIteratorMititgation(JNIEnv *env) {
|
||||
if(getenv("POJAV_EMUI_ITERATOR_MITIGATE") == NULL) return;
|
||||
__android_log_print(ANDROID_LOG_INFO, "EMUIIteratorFix", "Installing...");
|
||||
JNIEnv* env = pojav_environ->runtimeJNIEnvPtr_JRE;
|
||||
jclass sharedLibraryUtil = (*env)->FindClass(env, "org/lwjgl/system/SharedLibraryUtil");
|
||||
if(sharedLibraryUtil == NULL) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "EMUIIteratorFix", "Failed to find the target class");
|
||||
@ -482,16 +484,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSetWindowAttrib(
|
||||
// in environ for the Android UI thread but this is the only place that uses it
|
||||
// (very rarely, only in lifecycle callbacks) so i dont care
|
||||
|
||||
JavaVM* jvm = pojav_environ->runtimeJavaVMPtr;
|
||||
JNIEnv *jvm_env = NULL;
|
||||
jint env_result = (*jvm)->GetEnv(jvm, (void**)&jvm_env, JNI_VERSION_1_4);
|
||||
if(env_result == JNI_EDETACHED) {
|
||||
env_result = (*jvm)->AttachCurrentThread(jvm, &jvm_env, NULL);
|
||||
}
|
||||
if(env_result != JNI_OK) {
|
||||
printf("input_bridge nativeSetWindowAttrib() JNI call failed: %i\n", env_result);
|
||||
return;
|
||||
}
|
||||
JNIEnv *jvm_env = get_attached_env(pojav_environ->runtimeJavaVMPtr);
|
||||
|
||||
(*jvm_env)->CallStaticVoidMethod(
|
||||
jvm_env, pojav_environ->vmGlfwClass,
|
||||
|
@ -72,18 +72,18 @@ static jint hooked_ProcessImpl_forkAndExec(JNIEnv *env, jobject process, jint mo
|
||||
}
|
||||
|
||||
// Hook the forkAndExec method in the Java runtime for custom executable overriding.
|
||||
void hookExec() {
|
||||
jclass cls;
|
||||
void hookExec(JNIEnv *env) {
|
||||
jclass hookClass;
|
||||
orig_ProcessImpl_forkAndExec = dlsym(RTLD_DEFAULT, "Java_java_lang_UNIXProcess_forkAndExec");
|
||||
if (!orig_ProcessImpl_forkAndExec) {
|
||||
orig_ProcessImpl_forkAndExec = dlsym(RTLD_DEFAULT, "Java_java_lang_ProcessImpl_forkAndExec");
|
||||
cls = (*pojav_environ->runtimeJNIEnvPtr_JRE)->FindClass(pojav_environ->runtimeJNIEnvPtr_JRE, "java/lang/ProcessImpl");
|
||||
hookClass = (*env)->FindClass(env, "java/lang/ProcessImpl");
|
||||
} else {
|
||||
cls = (*pojav_environ->runtimeJNIEnvPtr_JRE)->FindClass(pojav_environ->runtimeJNIEnvPtr_JRE, "java/lang/UNIXProcess");
|
||||
hookClass = (*env)->FindClass(env, "java/lang/UNIXProcess");
|
||||
}
|
||||
JNINativeMethod methods[] = {
|
||||
{"forkAndExec", "(I[B[B[BI[BI[B[IZ)I", (void *)&hooked_ProcessImpl_forkAndExec}
|
||||
};
|
||||
(*pojav_environ->runtimeJNIEnvPtr_JRE)->RegisterNatives(pojav_environ->runtimeJNIEnvPtr_JRE, cls, methods, 1);
|
||||
(*env)->RegisterNatives(env, hookClass, methods, 1);
|
||||
printf("Registered forkAndExec\n");
|
||||
}
|
@ -185,9 +185,6 @@ JNIEXPORT jint JNICALL Java_com_oracle_dalvik_VMLauncher_launchJVM(JNIEnv *env,
|
||||
|
||||
jint res = 0;
|
||||
|
||||
// Save dalvik JNIEnv pointer for JVM launch thread
|
||||
pojav_environ->dalvikJNIEnvPtr_ANDROID = env;
|
||||
|
||||
if (argsArray == NULL) {
|
||||
LOGE("Args array null, returning");
|
||||
//handle error
|
||||
|
@ -45,9 +45,8 @@ static jlong ndlopen_bugfix(__attribute__((unused)) JNIEnv *env,
|
||||
/**
|
||||
* Install the LWJGL dlopen hook. This allows us to mitigate linker bugs and add custom library overrides.
|
||||
*/
|
||||
void installLwjglDlopenHook() {
|
||||
void installLwjglDlopenHook(JNIEnv *env) {
|
||||
__android_log_print(ANDROID_LOG_INFO, "LwjglLinkerHook", "Installing LWJGL dlopen() hook");
|
||||
JNIEnv* env = pojav_environ->runtimeJNIEnvPtr_JRE;
|
||||
jclass dynamicLinkLoader = (*env)->FindClass(env, "org/lwjgl/system/linux/DynamicLinkLoader");
|
||||
if(dynamicLinkLoader == NULL) {
|
||||
__android_log_print(ANDROID_LOG_ERROR, "LwjglLinkerHook", "Failed to find the target class");
|
||||
|
@ -157,6 +157,19 @@ JNIEXPORT jint JNICALL Java_net_kdt_pojavlaunch_utils_JREUtils_executeBinary(JNI
|
||||
return result;
|
||||
}
|
||||
|
||||
JNIEnv* get_attached_env(JavaVM* jvm) {
|
||||
JNIEnv *jvm_env = NULL;
|
||||
jint env_result = (*jvm)->GetEnv(jvm, (void**)&jvm_env, JNI_VERSION_1_4);
|
||||
if(env_result == JNI_EDETACHED) {
|
||||
env_result = (*jvm)->AttachCurrentThread(jvm, &jvm_env, NULL);
|
||||
}
|
||||
if(env_result != JNI_OK) {
|
||||
printf("get_attached_env failed: %i", env_result);
|
||||
return NULL;
|
||||
}
|
||||
return jvm_env;
|
||||
}
|
||||
|
||||
// METHOD 2
|
||||
/*
|
||||
JNIEXPORT jint JNICALL Java_net_kdt_pojavlaunch_utils_JREUtils_executeForkedBinary(JNIEnv *env, jclass clazz, jobjectArray cmdArgs) {
|
||||
|
@ -11,8 +11,8 @@ jobjectArray convert_from_char_array(JNIEnv *env, char **charArray, int num_rows
|
||||
void free_char_array(JNIEnv *env, jobjectArray jstringArray, const char **charArray);
|
||||
jstring convertStringJVM(JNIEnv* srcEnv, JNIEnv* dstEnv, jstring srcStr);
|
||||
|
||||
void hookExec();
|
||||
void installLwjglDlopenHook();
|
||||
void installEMUIIteratorMititgation();
|
||||
void hookExec(JNIEnv *env);
|
||||
void installLwjglDlopenHook(JNIEnv *env);
|
||||
JNIEnv* get_attached_env(JavaVM* jvm);
|
||||
JNIEXPORT jstring JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeClipboard(JNIEnv* env, jclass clazz, jint action, jbyteArray copySrc);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user