Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/PojavLauncher
Path: blob/v3_openjdk/app_pojavlauncher/src/main/jni/utils.c
2128 views
1
#include <jni.h>
2
#include <dlfcn.h>
3
#include <stdio.h>
4
#include <stdlib.h>
5
#include <unistd.h>
6
7
#include "log.h"
8
9
#include "utils.h"
10
11
typedef int (*Main_Function_t)(int, char**);
12
typedef void (*android_update_LD_LIBRARY_PATH_t)(char*);
13
14
long shared_awt_surface;
15
16
char** convert_to_char_array(JNIEnv *env, jobjectArray jstringArray) {
17
int num_rows = (*env)->GetArrayLength(env, jstringArray);
18
char **cArray = (char **) malloc(num_rows * sizeof(char*));
19
jstring row;
20
21
for (int i = 0; i < num_rows; i++) {
22
row = (jstring) (*env)->GetObjectArrayElement(env, jstringArray, i);
23
cArray[i] = (char*)(*env)->GetStringUTFChars(env, row, 0);
24
}
25
26
return cArray;
27
}
28
29
jobjectArray convert_from_char_array(JNIEnv *env, char **charArray, int num_rows) {
30
jobjectArray resultArr = (*env)->NewObjectArray(env, num_rows, (*env)->FindClass(env, "java/lang/String"), NULL);
31
jstring row;
32
33
for (int i = 0; i < num_rows; i++) {
34
row = (jstring) (*env)->NewStringUTF(env, charArray[i]);
35
(*env)->SetObjectArrayElement(env, resultArr, i, row);
36
}
37
38
return resultArr;
39
}
40
41
void free_char_array(JNIEnv *env, jobjectArray jstringArray, const char **charArray) {
42
int num_rows = (*env)->GetArrayLength(env, jstringArray);
43
jstring row;
44
45
for (int i = 0; i < num_rows; i++) {
46
row = (jstring) (*env)->GetObjectArrayElement(env, jstringArray, i);
47
(*env)->ReleaseStringUTFChars(env, row, charArray[i]);
48
}
49
}
50
51
jstring convertStringJVM(JNIEnv* srcEnv, JNIEnv* dstEnv, jstring srcStr) {
52
if (srcStr == NULL) {
53
return NULL;
54
}
55
56
const char* srcStrC = (*srcEnv)->GetStringUTFChars(srcEnv, srcStr, 0);
57
jstring dstStr = (*dstEnv)->NewStringUTF(dstEnv, srcStrC);
58
(*srcEnv)->ReleaseStringUTFChars(srcEnv, srcStr, srcStrC);
59
return dstStr;
60
}
61
62
JNIEXPORT void JNICALL Java_net_kdt_pojavlaunch_utils_JREUtils_setupBridgeSurfaceAWT(JNIEnv *env, jclass clazz, jlong surface) {
63
shared_awt_surface = surface;
64
}
65
66
JNIEXPORT jlong JNICALL Java_android_view_Surface_nativeGetBridgeSurfaceAWT(JNIEnv *env, jclass clazz) {
67
return (jlong) shared_awt_surface;
68
}
69
70
JNIEXPORT jint JNICALL Java_android_os_OpenJDKNativeRegister_nativeRegisterNatives(JNIEnv *env, jclass clazz, jstring registerSymbol) {
71
const char *register_symbol_c = (*env)->GetStringUTFChars(env, registerSymbol, 0);
72
void *symbol = dlsym(RTLD_DEFAULT, register_symbol_c);
73
if (symbol == NULL) {
74
printf("dlsym %s failed: %s\n", register_symbol_c, dlerror());
75
return -1;
76
}
77
78
int (*registerNativesForClass)(JNIEnv*) = symbol;
79
int result = registerNativesForClass(env);
80
(*env)->ReleaseStringUTFChars(env, registerSymbol, register_symbol_c);
81
82
return (jint) result;
83
}
84
85
JNIEXPORT void JNICALL Java_net_kdt_pojavlaunch_utils_JREUtils_setLdLibraryPath(JNIEnv *env, jclass clazz, jstring ldLibraryPath) {
86
// jclass exception_cls = (*env)->FindClass(env, "java/lang/UnsatisfiedLinkError");
87
88
android_update_LD_LIBRARY_PATH_t android_update_LD_LIBRARY_PATH;
89
90
void *libdl_handle = dlopen("libdl.so", RTLD_LAZY);
91
void *updateLdLibPath = dlsym(libdl_handle, "android_update_LD_LIBRARY_PATH");
92
if (updateLdLibPath == NULL) {
93
updateLdLibPath = dlsym(libdl_handle, "__loader_android_update_LD_LIBRARY_PATH");
94
if (updateLdLibPath == NULL) {
95
char *dl_error_c = dlerror();
96
LOGE("Error getting symbol android_update_LD_LIBRARY_PATH: %s", dl_error_c);
97
// (*env)->ThrowNew(env, exception_cls, dl_error_c);
98
}
99
}
100
101
android_update_LD_LIBRARY_PATH = (android_update_LD_LIBRARY_PATH_t) updateLdLibPath;
102
const char* ldLibPathUtf = (*env)->GetStringUTFChars(env, ldLibraryPath, 0);
103
android_update_LD_LIBRARY_PATH(ldLibPathUtf);
104
(*env)->ReleaseStringUTFChars(env, ldLibraryPath, ldLibPathUtf);
105
}
106
107
JNIEXPORT jboolean JNICALL Java_net_kdt_pojavlaunch_utils_JREUtils_dlopen(JNIEnv *env, jclass clazz, jstring name) {
108
const char *nameUtf = (*env)->GetStringUTFChars(env, name, 0);
109
void* handle = dlopen(nameUtf, RTLD_GLOBAL | RTLD_LAZY);
110
if (!handle) {
111
LOGE("dlopen %s failed: %s", nameUtf, dlerror());
112
} else {
113
LOGD("dlopen %s success", nameUtf);
114
}
115
(*env)->ReleaseStringUTFChars(env, name, nameUtf);
116
return handle != NULL;
117
}
118
119
JNIEXPORT jint JNICALL Java_net_kdt_pojavlaunch_utils_JREUtils_chdir(JNIEnv *env, jclass clazz, jstring nameStr) {
120
const char *name = (*env)->GetStringUTFChars(env, nameStr, NULL);
121
int retval = chdir(name);
122
(*env)->ReleaseStringUTFChars(env, nameStr, name);
123
return retval;
124
}
125
126
JNIEXPORT jint JNICALL Java_net_kdt_pojavlaunch_utils_JREUtils_executeBinary(JNIEnv *env, jclass clazz, jobjectArray cmdArgs) {
127
jclass exception_cls = (*env)->FindClass(env, "java/lang/UnsatisfiedLinkError");
128
jstring execFile = (*env)->GetObjectArrayElement(env, cmdArgs, 0);
129
130
char *exec_file_c = (char*) (*env)->GetStringUTFChars(env, execFile, 0);
131
void *exec_binary_handle = dlopen(exec_file_c, RTLD_LAZY);
132
133
// (*env)->ReleaseStringUTFChars(env, ldLibraryPath, ld_library_path_c);
134
(*env)->ReleaseStringUTFChars(env, execFile, exec_file_c);
135
136
char *exec_error_c = dlerror();
137
if (exec_error_c != NULL) {
138
LOGE("Error: %s", exec_error_c);
139
(*env)->ThrowNew(env, exception_cls, exec_error_c);
140
return -1;
141
}
142
143
Main_Function_t Main_Function;
144
Main_Function = (Main_Function_t) dlsym(exec_binary_handle, "main");
145
146
exec_error_c = dlerror();
147
if (exec_error_c != NULL) {
148
LOGE("Error: %s", exec_error_c);
149
(*env)->ThrowNew(env, exception_cls, exec_error_c);
150
return -1;
151
}
152
153
int cmd_argv = (*env)->GetArrayLength(env, cmdArgs);
154
char **cmd_args_c = convert_to_char_array(env, cmdArgs);
155
int result = Main_Function(cmd_argv, cmd_args_c);
156
free_char_array(env, cmdArgs, cmd_args_c);
157
return result;
158
}
159
160
JNIEnv* get_attached_env(JavaVM* jvm) {
161
JNIEnv *jvm_env = NULL;
162
jint env_result = (*jvm)->GetEnv(jvm, (void**)&jvm_env, JNI_VERSION_1_4);
163
if(env_result == JNI_EDETACHED) {
164
env_result = (*jvm)->AttachCurrentThread(jvm, &jvm_env, NULL);
165
}
166
if(env_result != JNI_OK) {
167
printf("get_attached_env failed: %i\n", env_result);
168
return NULL;
169
}
170
return jvm_env;
171
}
172
173
// METHOD 2
174
/*
175
JNIEXPORT jint JNICALL Java_net_kdt_pojavlaunch_utils_JREUtils_executeForkedBinary(JNIEnv *env, jclass clazz, jobjectArray cmdArgs) {
176
int x, status;
177
x = fork();
178
if (x > 0) {
179
wait(&status);
180
} else {
181
execvpe();
182
}
183
return status;
184
}
185
*/
186
187
188