mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2026-10-15 20:49:28 -04:00
Move some native codes to there
This commit is contained in:
1 parent
97893a2222
commit
2f0f4f8ee6
13 files changed
+568
-15
No files matched your search
@@ -15,6 +15,10 @@ android {
|
||||
versionCode 156235
|
||||
versionName "3.2.0_6401b_20200822"
|
||||
multiDexEnabled true //important
|
||||
|
||||
ndk {
|
||||
abiFilters "armeabi-v7a"
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
@@ -28,6 +32,12 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
ndkBuild {
|
||||
path file('src/main/jni/Android.mk')
|
||||
}
|
||||
}
|
||||
|
||||
// Keep the following configuration in order to might make Minecraft 1.12 support.
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
|
||||
Binary file not shown.
@@ -28,7 +28,7 @@ public class InstallModActivity extends AppCompatActivity
|
||||
Surface surface = new Surface(tex);
|
||||
Field field = surface.getClass().getDeclaredField("mNativeObject");
|
||||
field.setAccessible(true);
|
||||
BinaryExecutor.setupBridgeSurfaceAWT((long) field.get(surface));
|
||||
JREUtils.setupBridgeSurfaceAWT((long) field.get(surface));
|
||||
} catch (Throwable th) {
|
||||
Tools.showError(InstallModActivity.this, th, true);
|
||||
}
|
||||
@@ -97,12 +97,12 @@ public class InstallModActivity extends AppCompatActivity
|
||||
|
||||
System.out.println(Arrays.toString(javaArgList.toArray(new String[0])));
|
||||
|
||||
BinaryExecutor.setJavaEnvironment(this);
|
||||
JREUtils.setJavaEnvironment(this);
|
||||
|
||||
BinaryExecutor.redirectStdio();
|
||||
BinaryExecutor.setJavaEnvironment(this);
|
||||
BinaryExecutor.initJavaRuntime();
|
||||
BinaryExecutor.chdir(Tools.MAIN_PATH);
|
||||
JREUtils.redirectStdio();
|
||||
JREUtils.setJavaEnvironment(this);
|
||||
JREUtils.initJavaRuntime();
|
||||
JREUtils.chdir(Tools.MAIN_PATH);
|
||||
|
||||
VMLauncher.launchJVM(javaArgList.toArray(new String[0]));
|
||||
} catch (Throwable th) {
|
||||
|
||||
+3
-4
@@ -4,10 +4,9 @@ import android.system.*;
|
||||
import java.io.*;
|
||||
import android.content.*;
|
||||
|
||||
// This class should be named as 'LoadMe' as original
|
||||
public class BinaryExecutor
|
||||
public class JREUtils
|
||||
{
|
||||
private BinaryExecutor() {}
|
||||
private JREUtils() {}
|
||||
|
||||
public static void initJavaRuntime() {
|
||||
dlopen(Tools.homeJreDir + "/lib/jli/libjli.so");
|
||||
@@ -79,6 +78,6 @@ public class BinaryExecutor
|
||||
public static native int executeBinary(String[] args);
|
||||
|
||||
static {
|
||||
System.loadLibrary("binexecutor");
|
||||
System.loadLibrary("pojavexec");
|
||||
}
|
||||
}
|
||||
@@ -643,7 +643,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
|
||||
if (!isCalled) {
|
||||
isCalled = true;
|
||||
|
||||
BinaryExecutor.setupBridgeWindow(new Surface(texture));
|
||||
JREUtils.setupBridgeWindow(new Surface(texture));
|
||||
|
||||
new Thread(new Runnable(){
|
||||
|
||||
@@ -1027,7 +1027,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
|
||||
// can fix java?
|
||||
// setEnvironment("ORIGIN", Tools.homeJreDir + "/lib");
|
||||
|
||||
BinaryExecutor.setJavaEnvironment(this);
|
||||
JREUtils.setJavaEnvironment(this);
|
||||
|
||||
if (LAUNCH_TYPE == LTYPE_PROCESS) {
|
||||
mLaunchShell.writeToProcess("cd $HOME");
|
||||
@@ -1044,7 +1044,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
|
||||
Os.dup2(FileDescriptor.out, OsConstants.STDOUT_FILENO);
|
||||
*/
|
||||
|
||||
BinaryExecutor.redirectStdio();
|
||||
JREUtils.redirectStdio();
|
||||
// DEPRECATED constructor (String) api 29
|
||||
/*
|
||||
FileObserver fobs = new FileObserver(logFile.getAbsolutePath(), FileObserver.MODIFY){
|
||||
@@ -1071,8 +1071,8 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
|
||||
}
|
||||
}, "RuntimeLogThread").start();
|
||||
|
||||
BinaryExecutor.initJavaRuntime();
|
||||
BinaryExecutor.chdir(Tools.MAIN_PATH);
|
||||
JREUtils.initJavaRuntime();
|
||||
JREUtils.chdir(Tools.MAIN_PATH);
|
||||
|
||||
if (new File(Tools.MAIN_PATH, "strace.txt").exists()) {
|
||||
startStrace(android.os.Process.myTid());
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_LDLIBS := -ldl -llog -lEGL -landroid
|
||||
LOCAL_MODULE := pojavexec
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
egl_bridge.c \
|
||||
jre_launcher.c \
|
||||
utils.c
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# NDK_TOOLCHAIN_VERSION := 4.9
|
||||
APP_PLATFORM := android-21
|
||||
APP_STL := system
|
||||
APP_ABI := armeabi-v7a x86
|
||||
# arm64-v8a x86_64
|
||||
@@ -0,0 +1,129 @@
|
||||
#include <jni.h>
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <EGL/egl.h>
|
||||
|
||||
#include <android/native_window.h>
|
||||
#include <android/native_window_jni.h>
|
||||
|
||||
struct ANativeWindow* windowBridge;
|
||||
|
||||
struct PotatoBridge {
|
||||
void* eglContext;
|
||||
void* eglDisplay;
|
||||
void* eglSurface;
|
||||
/*
|
||||
void* eglSurfaceRead;
|
||||
void* eglSurfaceDraw;
|
||||
*/
|
||||
};
|
||||
struct PotatoBridge potatoBridge;
|
||||
|
||||
JNIEXPORT void JNICALL Java_net_kdt_pojavlaunch_JREUtils_setupBridgeWindow(JNIEnv* env, jclass clazz, jobject surface) {
|
||||
windowBridge = ANativeWindow_fromSurface(env, surface);
|
||||
}
|
||||
|
||||
// Called from JNI_OnLoad of liblwjgl_opengl32
|
||||
void pojav_openGLOnLoad() {
|
||||
printf("ANativeWindow pointer = %p\n", windowBridge);
|
||||
|
||||
potatoBridge.eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
if (potatoBridge.eglDisplay == EGL_NO_DISPLAY) {
|
||||
printf("Error: eglGetDefaultDisplay() failed: %p\n", eglGetError());
|
||||
return; // -1;
|
||||
}
|
||||
|
||||
eglMakeCurrent(potatoBridge.eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
|
||||
if (!eglInitialize(potatoBridge.eglDisplay, NULL, NULL)) {
|
||||
printf("Error: eglInitialize() failed\n");
|
||||
return; // -2;
|
||||
}
|
||||
|
||||
static const EGLint attribs[] = {
|
||||
EGL_RED_SIZE, 1,
|
||||
EGL_GREEN_SIZE, 1,
|
||||
EGL_BLUE_SIZE, 1,
|
||||
EGL_DEPTH_SIZE, 1,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||
EGL_NONE
|
||||
};
|
||||
static const EGLint ctx_attribs[] = {
|
||||
EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
EGLConfig config;
|
||||
EGLint num_configs;
|
||||
EGLint vid;
|
||||
|
||||
if (!eglChooseConfig(potatoBridge.eglDisplay, attribs, &config, 1, &num_configs)) {
|
||||
printf("Error: couldn't get an EGL visual config\n");
|
||||
return; // -3;
|
||||
}
|
||||
|
||||
assert(config);
|
||||
assert(num_configs > 0);
|
||||
|
||||
if (!eglGetConfigAttrib(potatoBridge.eglDisplay, config, EGL_NATIVE_VISUAL_ID, &vid)) {
|
||||
printf("Error: eglGetConfigAttrib() failed\n");
|
||||
return; // -4;
|
||||
}
|
||||
|
||||
eglBindAPI(EGL_OPENGL_ES_API);
|
||||
|
||||
potatoBridge.eglContext = eglCreateContext(potatoBridge.eglDisplay, config, EGL_NO_CONTEXT, ctx_attribs);
|
||||
if (!potatoBridge.eglContext) {
|
||||
printf("Error: eglCreateContext failed\n");
|
||||
return; // -5;
|
||||
}
|
||||
|
||||
// test eglQueryContext()
|
||||
{
|
||||
EGLint val;
|
||||
eglQueryContext(potatoBridge.eglDisplay, potatoBridge.eglContext, EGL_CONTEXT_CLIENT_VERSION, &val);
|
||||
assert(val == 2);
|
||||
}
|
||||
|
||||
potatoBridge.eglSurface = eglCreateWindowSurface(potatoBridge.eglDisplay, config, windowBridge, NULL);
|
||||
|
||||
if (!potatoBridge.eglSurface) {
|
||||
printf("Error: eglCreateWindowSurface failed: %p\n", eglGetError());
|
||||
return; // -6;
|
||||
}
|
||||
|
||||
// sanity checks
|
||||
{
|
||||
EGLint val;
|
||||
assert(eglGetConfigAttrib(potatoBridge.eglDisplay, config, EGL_SURFACE_TYPE, &val));
|
||||
assert(val & EGL_WINDOW_BIT);
|
||||
}
|
||||
|
||||
printf("EGLContext=%p, EGLDisplay=%p, EGLSurface=%p\n",
|
||||
potatoBridge.eglContext,
|
||||
potatoBridge.eglDisplay,
|
||||
potatoBridge.eglSurface
|
||||
);
|
||||
|
||||
if (eglMakeCurrent(potatoBridge.eglDisplay, potatoBridge.eglSurface, potatoBridge.eglSurface, potatoBridge.eglContext) == EGL_FALSE) {
|
||||
printf("Error: eglMakeCurrent() failed: %p\n", eglGetError());
|
||||
}
|
||||
}
|
||||
|
||||
void pojav_openGLOnUnload() {
|
||||
eglMakeCurrent(potatoBridge.eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||
eglDestroySurface(potatoBridge.eglDisplay, potatoBridge.eglSurface);
|
||||
eglDestroyContext(potatoBridge.eglDisplay, potatoBridge.eglContext);
|
||||
eglTerminate(potatoBridge.eglDisplay);
|
||||
eglReleaseThread();
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_GLFW_nativeEglSwapBuffers(JNIEnv *env, jclass clazz) {
|
||||
return eglSwapBuffers(potatoBridge.eglDisplay, potatoBridge.eglSurface);
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_GLFW_nativeEglSwapInterval(JNIEnv *env, jclass clazz, jint interval) {
|
||||
return eglSwapInterval(potatoBridge.eglDisplay, interval);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
#include <jni.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <android/log.h>
|
||||
#include <dlfcn.h>
|
||||
// Boardwalk: missing include
|
||||
#include <string.h>
|
||||
|
||||
#include "log.h"
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
// PojavLancher: fixme: are these wrong?
|
||||
#define FULL_VERSION "1.9.0-internal"
|
||||
#define DOT_VERSION "1.9"
|
||||
|
||||
typedef jint JNI_CreateJavaVM_func(JavaVM **pvm, void **penv, void *args);
|
||||
|
||||
typedef jint JLI_Launch_func(int argc, char ** argv, /* main argc, argc */
|
||||
int jargc, const char** jargv, /* java args */
|
||||
int appclassc, const char** appclassv, /* app classpath */
|
||||
const char* fullversion, /* full version defined */
|
||||
const char* dotversion, /* dot version defined */
|
||||
const char* pname, /* program name */
|
||||
const char* lname, /* launcher name */
|
||||
jboolean javaargs, /* JAVA_ARGS */
|
||||
jboolean cpwildcard, /* classpath wildcard*/
|
||||
jboolean javaw, /* windows-only javaw */
|
||||
jint ergo /* ergonomics class policy */
|
||||
);
|
||||
|
||||
JavaVM *runtimeJavaVMPtr = NULL;;
|
||||
JNIEnv *runtimeJNIEnvPtr = NULL;
|
||||
|
||||
JavaVM *dalvikJavaVMPtr = NULL;
|
||||
JNIEnv *dalvikJNIEnvPtr = NULL;
|
||||
|
||||
jint JNI_OnLoad(JavaVM* vm, void* reserved)
|
||||
{
|
||||
if (dalvikJavaVMPtr == NULL) {
|
||||
//Save dalvik global JavaVM pointer
|
||||
dalvikJavaVMPtr = vm;
|
||||
LOGD("JNI_OnLoad calling GetEnv()");
|
||||
JNIEnv* env = NULL;
|
||||
(*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4);
|
||||
/* Boardwalk: not used
|
||||
LOGD("JNI_OnLoad calling initDalvikProxySelectorData()");
|
||||
initDalvikProxySelectorData(env);
|
||||
*/
|
||||
}
|
||||
LOGD("JNI_OnLoad returning()");
|
||||
return JNI_VERSION_1_4;
|
||||
}
|
||||
|
||||
static void logArgs(int argc, char** argv) {
|
||||
/* BlockLauncher: disable logging
|
||||
int i;
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
LOGD("arg[%d]: %s", i, argv[i]);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_oracle_dalvik_VMLauncher_createLaunchMainJVM(JNIEnv *env, jclass clazz, jobjectArray vmArgArr, jstring mainClassStr, jobjectArray mainArgArr) {
|
||||
void *libjvm = dlopen("libjvm.so", RTLD_NOW + RTLD_GLOBAL);
|
||||
if (libjvm == NULL) {
|
||||
LOGE("dlopen failed to open libjvm.so (dlerror %s).", dlerror());
|
||||
return -1;
|
||||
}
|
||||
|
||||
JNI_CreateJavaVM_func *jl_JNI_CreateJavaVM = (JNI_CreateJavaVM_func *) dlsym(libjvm, "JNI_CreateJavaVM");
|
||||
if (jl_JNI_CreateJavaVM == NULL) {
|
||||
LOGE("dlsym failed to get JNI_CreateJavaVM (dlerror %s).", dlerror());
|
||||
return -1;
|
||||
}
|
||||
|
||||
int vm_argc = (*env)->GetArrayLength(env, vmArgArr);
|
||||
char **vm_argv = convert_to_char_array(env, vmArgArr);
|
||||
|
||||
int main_argc = (*env)->GetArrayLength(env, mainArgArr);
|
||||
char **main_argv = convert_to_char_array(env, mainArgArr);
|
||||
|
||||
JavaVMInitArgs vm_args;
|
||||
JavaVMOption options[vm_argc];
|
||||
for (int i = 0; i < vm_argc; i++) {
|
||||
options[i].optionString = vm_argv[i];
|
||||
}
|
||||
vm_args.version = JNI_VERSION_1_6;
|
||||
vm_args.options = options;
|
||||
vm_args.nOptions = vm_argc;
|
||||
vm_args.ignoreUnrecognized = JNI_FALSE;
|
||||
|
||||
jint res = (jint) jl_JNI_CreateJavaVM(&runtimeJavaVMPtr, (void**)&runtimeJNIEnvPtr, &vm_args);
|
||||
// delete options;
|
||||
|
||||
char *main_class_c = (*env)->GetStringUTFChars(env, mainClassStr, 0);
|
||||
|
||||
jclass mainClass = (*runtimeJNIEnvPtr)->FindClass(runtimeJNIEnvPtr, main_class_c);
|
||||
jmethodID mainMethod = (*runtimeJNIEnvPtr)->GetStaticMethodID(runtimeJNIEnvPtr, mainClass, "main", "([Ljava/lang/String;)V");
|
||||
|
||||
// Need recreate jobjectArray to make JNIEnv is 'runtimeJNIEnvPtr'.
|
||||
jobjectArray runtime_main_argv = convert_from_char_array(runtimeJNIEnvPtr, main_argv, main_argc);
|
||||
(*runtimeJNIEnvPtr)->CallStaticVoidMethod(runtimeJNIEnvPtr, mainClass, mainMethod, runtime_main_argv);
|
||||
|
||||
(*env)->ReleaseStringUTFChars(env, mainClassStr, main_class_c);
|
||||
free_char_array(env, mainArgArr, main_argv);
|
||||
free_char_array(env, vmArgArr, vm_argv);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static jint launchJVM(int argc, char** argv) {
|
||||
logArgs(argc, argv);
|
||||
|
||||
void* libjli = dlopen("libjli.so", RTLD_LAZY | RTLD_GLOBAL);
|
||||
// Boardwalk: silence
|
||||
// LOGD("JLI lib = %x", (int)libjli);
|
||||
if (NULL == libjli) {
|
||||
LOGE("JLI lib = NULL: %s", dlerror());
|
||||
return 0;
|
||||
}
|
||||
LOGD("Found JLI lib");
|
||||
|
||||
JLI_Launch_func *pJLI_Launch =
|
||||
(JLI_Launch_func *)dlsym(libjli, "JLI_Launch");
|
||||
// Boardwalk: silence
|
||||
// LOGD("JLI_Launch = 0x%x", *(int*)&pJLI_Launch);
|
||||
|
||||
if (NULL == pJLI_Launch) {
|
||||
LOGE("JLI_Launch = NULL");
|
||||
return 0;
|
||||
}
|
||||
|
||||
LOGD("Calling JLI_Launch");
|
||||
|
||||
return pJLI_Launch(argc, argv,
|
||||
0, NULL, 0, NULL, FULL_VERSION,
|
||||
DOT_VERSION, *argv, *argv, /* "java", "openjdk", */
|
||||
JNI_FALSE, JNI_TRUE, JNI_FALSE, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: com_oracle_embedded_launcher_VMLauncher
|
||||
* Method: launchJVM
|
||||
* Signature: ([Ljava/lang/String;)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_oracle_dalvik_VMLauncher_launchJVM(JNIEnv *env, jclass clazz, jobjectArray argsArray) {
|
||||
jint res = 0;
|
||||
// int i;
|
||||
|
||||
// Save dalvik JNIEnv pointer for JVM launch thread
|
||||
dalvikJNIEnvPtr = env;
|
||||
|
||||
if (argsArray == NULL) {
|
||||
LOGE("Args array null, returning");
|
||||
//handle error
|
||||
return 0;
|
||||
}
|
||||
|
||||
int argc = (*env)->GetArrayLength(env, argsArray);
|
||||
char **argv = convert_to_char_array(env, argsArray);
|
||||
|
||||
LOGD("Done processing args");
|
||||
|
||||
res = launchJVM(argc, argv);
|
||||
|
||||
LOGD("Freeing args");
|
||||
free_char_array(env, argsArray, argv);
|
||||
|
||||
LOGD("Free done");
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifdef __ANDROID__
|
||||
#include <android/log.h>
|
||||
|
||||
#define TAG "LaunchJVM"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
|
||||
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, TAG, __VA_ARGS__)
|
||||
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
|
||||
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
|
||||
#else
|
||||
#define LOGE(...) printf(__VA_ARGS__)
|
||||
#define LOGW(...) printf(__VA_ARGS__)
|
||||
#define LOGI(...) printf(__VA_ARGS__)
|
||||
#define LOGD(...) printf(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
#include <jni.h>
|
||||
#include <dlfcn.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "log.h"
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
typedef int (*Main_Function_t)(int, char**);
|
||||
typedef void (*android_update_LD_LIBRARY_PATH_t)(char*);
|
||||
|
||||
long shared_awt_surface;
|
||||
|
||||
char** convert_to_char_array(JNIEnv *env, jobjectArray jstringArray) {
|
||||
int num_rows = (*env)->GetArrayLength(env, jstringArray);
|
||||
char **cArray = (char **) malloc(num_rows * sizeof(char*));
|
||||
jstring row;
|
||||
|
||||
for (int i = 0; i < num_rows; i++) {
|
||||
row = (jstring) (*env)->GetObjectArrayElement(env, jstringArray, i);
|
||||
cArray[i] = (char*)(*env)->GetStringUTFChars(env, row, 0);
|
||||
}
|
||||
|
||||
return cArray;
|
||||
}
|
||||
|
||||
jobjectArray convert_from_char_array(JNIEnv *env, char **charArray, int num_rows) {
|
||||
jobjectArray resultArr = (*env)->NewObjectArray(env, num_rows, (*env)->FindClass(env, "java/lang/String"), NULL);
|
||||
jstring row;
|
||||
|
||||
for (int i = 0; i < num_rows; i++) {
|
||||
row = (jstring) (*env)->NewStringUTF(env, charArray[i]);
|
||||
(*env)->SetObjectArrayElement(env, resultArr, i, row);
|
||||
}
|
||||
|
||||
return resultArr;
|
||||
}
|
||||
|
||||
void free_char_array(JNIEnv *env, jobjectArray jstringArray, const char **charArray) {
|
||||
int num_rows = (*env)->GetArrayLength(env, jstringArray);
|
||||
jstring row;
|
||||
|
||||
for (int i = 0; i < num_rows; i++) {
|
||||
row = (jstring) (*env)->GetObjectArrayElement(env, jstringArray, i);
|
||||
(*env)->ReleaseStringUTFChars(env, row, charArray[i]);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_net_kdt_pojavlaunch_JREUtils_setupBridgeSurfaceAWT(JNIEnv *env, jclass clazz, jlong surface) {
|
||||
shared_awt_surface = surface;
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_android_view_Surface_nativeGetBridgeSurfaceAWT(JNIEnv *env, jclass clazz) {
|
||||
return (jlong) shared_awt_surface;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_android_os_OpenJDKNativeRegister_nativeRegisterNatives(JNIEnv *env, jclass clazz, jstring registerSymbol) {
|
||||
const char *register_symbol_c = (*env)->GetStringUTFChars(env, registerSymbol, 0);
|
||||
void *symbol = dlsym(RTLD_DEFAULT, register_symbol_c);
|
||||
if (symbol == NULL) {
|
||||
printf("dlsym %s failed: %s\n", register_symbol_c, dlerror());
|
||||
return -1;
|
||||
}
|
||||
|
||||
int (*registerNativesForClass)(JNIEnv*) = symbol;
|
||||
int result = registerNativesForClass(env);
|
||||
(*env)->ReleaseStringUTFChars(env, registerSymbol, register_symbol_c);
|
||||
|
||||
return (jint) result;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_net_kdt_pojavlaunch_JREUtils_setLdLibraryPath(JNIEnv *env, jclass clazz, jstring ldLibraryPath) {
|
||||
// jclass exception_cls = (*env)->FindClass(env, "java/lang/UnsatisfiedLinkError");
|
||||
|
||||
android_update_LD_LIBRARY_PATH_t android_update_LD_LIBRARY_PATH;
|
||||
|
||||
void *libdl_handle = dlopen("libdl.so", RTLD_LAZY);
|
||||
void *updateLdLibPath = dlsym(libdl_handle, "android_update_LD_LIBRARY_PATH");
|
||||
if (updateLdLibPath == NULL) {
|
||||
updateLdLibPath = dlsym(libdl_handle, "__loader_android_update_LD_LIBRARY_PATH");
|
||||
if (updateLdLibPath == NULL) {
|
||||
char *dl_error_c = dlerror();
|
||||
LOGE("Error getting symbol android_update_LD_LIBRARY_PATH: %s", dl_error_c);
|
||||
// (*env)->ThrowNew(env, exception_cls, dl_error_c);
|
||||
}
|
||||
}
|
||||
|
||||
android_update_LD_LIBRARY_PATH = (android_update_LD_LIBRARY_PATH_t) updateLdLibPath;
|
||||
const char* ldLibPathUtf = (*env)->GetStringUTFChars(env, ldLibraryPath, 0);
|
||||
android_update_LD_LIBRARY_PATH(ldLibPathUtf);
|
||||
(*env)->ReleaseStringUTFChars(env, ldLibraryPath, ldLibPathUtf);
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_net_kdt_pojavlaunch_JREUtils_dlopen(JNIEnv *env, jclass clazz, jstring name) {
|
||||
const char *nameUtf = (*env)->GetStringUTFChars(env, name, 0);
|
||||
void* handle = dlopen(nameUtf, RTLD_GLOBAL | RTLD_LAZY);
|
||||
if (!handle) {
|
||||
LOGE("dlopen %s failed: %s", nameUtf, dlerror());
|
||||
} else {
|
||||
LOGD("dlopen %s success", nameUtf);
|
||||
}
|
||||
(*env)->ReleaseStringUTFChars(env, name, nameUtf);
|
||||
return handle != NULL;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_net_kdt_pojavlaunch_JREUtils_chdir(JNIEnv *env, jclass clazz, jstring nameStr) {
|
||||
const char *name = (*env)->GetStringUTFChars(env, nameStr, NULL);
|
||||
int retval = chdir(name);
|
||||
(*env)->ReleaseStringUTFChars(env, nameStr, name);
|
||||
return retval;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_net_kdt_pojavlaunch_JREUtils_executeBinary(JNIEnv *env, jclass clazz, jobjectArray cmdArgs) {
|
||||
jclass exception_cls = (*env)->FindClass(env, "java/lang/UnsatisfiedLinkError");
|
||||
jstring execFile = (*env)->GetObjectArrayElement(env, cmdArgs, 0);
|
||||
|
||||
char *exec_file_c = (char*) (*env)->GetStringUTFChars(env, execFile, 0);
|
||||
void *exec_binary_handle = dlopen(exec_file_c, RTLD_LAZY);
|
||||
|
||||
// (*env)->ReleaseStringUTFChars(env, ldLibraryPath, ld_library_path_c);
|
||||
(*env)->ReleaseStringUTFChars(env, execFile, exec_file_c);
|
||||
|
||||
char *exec_error_c = dlerror();
|
||||
if (exec_error_c != NULL) {
|
||||
LOGE("Error: %s", exec_error_c);
|
||||
(*env)->ThrowNew(env, exception_cls, exec_error_c);
|
||||
return -1;
|
||||
}
|
||||
|
||||
Main_Function_t Main_Function;
|
||||
Main_Function = (Main_Function_t) dlsym(exec_binary_handle, "main");
|
||||
|
||||
exec_error_c = dlerror();
|
||||
if (exec_error_c != NULL) {
|
||||
LOGE("Error: %s", exec_error_c);
|
||||
(*env)->ThrowNew(env, exception_cls, exec_error_c);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int cmd_argv = (*env)->GetArrayLength(env, cmdArgs);
|
||||
char **cmd_args_c = convert_to_char_array(env, cmdArgs);
|
||||
int result = Main_Function(cmd_argv, cmd_args_c);
|
||||
free_char_array(env, cmdArgs, cmd_args_c);
|
||||
return result;
|
||||
}
|
||||
|
||||
// METHOD 2
|
||||
/*
|
||||
JNIEXPORT jint JNICALL Java_net_kdt_pojavlaunch_JREUtils_executeForkedBinary(JNIEnv *env, jclass clazz, jobjectArray cmdArgs) {
|
||||
int x, status;
|
||||
x = fork();
|
||||
if (x > 0) {
|
||||
wait(&status);
|
||||
} else {
|
||||
execvpe();
|
||||
}
|
||||
return status;
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef _BINARY_UTILS_H_
|
||||
#define _BINARY_UTILS_H_
|
||||
|
||||
char** convert_to_char_array(JNIEnv *env, jobjectArray jstringArray);
|
||||
jobjectArray convert_from_char_array(JNIEnv *env, char **charArray, int num_rows);
|
||||
void free_char_array(JNIEnv *env, jobjectArray jstringArray, const char **charArray);
|
||||
|
||||
#endif // _BINARY_UTILS_H_
|
||||
|
||||
Binary file not shown.
Reference in new issue
Block a user