Skip to content

Commit

Permalink
enhancement: optimize JVM JNI usage by using @fastNative annotation
Browse files Browse the repository at this point in the history
  • Loading branch information
twaik committed Dec 28, 2024
1 parent 07fe7f0 commit cc36f7e
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 41 deletions.
67 changes: 39 additions & 28 deletions app/src/main/cpp/lorie/activity.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,7 @@ static jclass FindMethodOrDie(JNIEnv *env, jclass clazz, const char* name, const
return method;
}

JNIEXPORT void JNICALL
Java_com_termux_x11_LorieView_nativeInit(JNIEnv *env, jobject thiz) {
static void nativeInit(JNIEnv *env, jobject thiz) {
JavaVM* vm;
if (!Charset.self) {
// Init clipboard-related JNI stuff
Expand Down Expand Up @@ -167,16 +166,14 @@ static int xcallback(int fd, int events, __unused void* data) {
return 1;
}

JNIEXPORT void JNICALL
Java_com_termux_x11_LorieView_connect(__unused JNIEnv* env, __unused jobject cls, jint fd) {
static void connect_(__unused JNIEnv* env, __unused jobject cls, jint fd) {
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
conn_fd = fd;
ALooper_addFd(ALooper_forThread(), fd, 0, ALOOPER_EVENT_INPUT | ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP, xcallback, NULL);
log(DEBUG, "XCB connection is successfull");
}

JNIEXPORT void JNICALL
Java_com_termux_x11_LorieView_startLogcat(JNIEnv *env, __unused jobject cls, jint fd) {
static void startLogcat(JNIEnv *env, __unused jobject cls, jint fd) {
log(DEBUG, "Starting logcat with output to given fd");

switch(fork()) {
Expand All @@ -195,24 +192,21 @@ Java_com_termux_x11_LorieView_startLogcat(JNIEnv *env, __unused jobject cls, jin
}
}

JNIEXPORT void JNICALL
Java_com_termux_x11_LorieView_setClipboardSyncEnabled(__unused JNIEnv* env, __unused jobject cls, jboolean enable, __unused jboolean ignored) {
static void setClipboardSyncEnabled(__unused JNIEnv* env, __unused jobject cls, jboolean enable, __unused jboolean ignored) {
if (conn_fd != -1) {
lorieEvent e = { .clipboardEnable = { .t = EVENT_CLIPBOARD_ENABLE, .enable = enable } };
write(conn_fd, &e, sizeof(e));
}
}

JNIEXPORT void JNICALL
Java_com_termux_x11_LorieView_sendClipboardAnnounce(__unused JNIEnv *env, __unused jobject thiz) {
static void sendClipboardAnnounce(__unused JNIEnv *env, __unused jobject thiz) {
if (conn_fd != -1) {
lorieEvent e = { .type = EVENT_CLIPBOARD_ANNOUNCE };
write(conn_fd, &e, sizeof(e));
}
}

JNIEXPORT void JNICALL
Java_com_termux_x11_LorieView_sendClipboardEvent(JNIEnv *env, __unused jobject thiz, jbyteArray text) {
static void sendClipboardEvent(JNIEnv *env, __unused jobject thiz, jbyteArray text) {
if (conn_fd != -1 && text) {
jsize length = (*env)->GetArrayLength(env, text);
jbyte* str = (*env)->GetByteArrayElements(env, text, NULL);
Expand All @@ -223,8 +217,7 @@ Java_com_termux_x11_LorieView_sendClipboardEvent(JNIEnv *env, __unused jobject t
}
}

JNIEXPORT void JNICALL
Java_com_termux_x11_LorieView_sendWindowChange(__unused JNIEnv* env, __unused jobject cls, jint width, jint height, jint framerate, jstring jname) {
static void sendWindowChange(__unused JNIEnv* env, __unused jobject cls, jint width, jint height, jint framerate, jstring jname) {
if (conn_fd != -1) {
const char *name = (!jname || width <= 0 || height <= 0) ? NULL : (*env)->GetStringUTFChars(env, jname, JNI_FALSE);
lorieEvent e = { .screenSize = { .t = EVENT_SCREEN_SIZE, .width = width, .height = height, .framerate = framerate, .name_size = (name ? strlen(name) : 0) } };
Expand All @@ -236,42 +229,37 @@ Java_com_termux_x11_LorieView_sendWindowChange(__unused JNIEnv* env, __unused jo
}
}

JNIEXPORT void JNICALL
Java_com_termux_x11_LorieView_sendMouseEvent(__unused JNIEnv* env, __unused jobject cls, jfloat x, jfloat y, jint which_button, jboolean button_down, jboolean relative) {
static void sendMouseEvent(__unused JNIEnv* env, __unused jobject cls, jfloat x, jfloat y, jint which_button, jboolean button_down, jboolean relative) {
if (conn_fd != -1) {
lorieEvent e = { .mouse = { .t = EVENT_MOUSE, .x = x, .y = y, .detail = which_button, .down = button_down, .relative = relative } };
write(conn_fd, &e, sizeof(e));
}
}

JNIEXPORT void JNICALL
Java_com_termux_x11_LorieView_sendTouchEvent(__unused JNIEnv* env, __unused jobject cls, jint action, jint id, jint x, jint y) {
static void sendTouchEvent(__unused JNIEnv* env, __unused jobject cls, jint action, jint id, jint x, jint y) {
if (conn_fd != -1 && action != -1) {
lorieEvent e = { .touch = { .t = EVENT_TOUCH, .type = action, .id = id, .x = x, .y = y } };
write(conn_fd, &e, sizeof(e));
}
}

JNIEXPORT void JNICALL
Java_com_termux_x11_LorieView_sendStylusEvent(__unused JNIEnv *env, __unused jobject thiz, jfloat x, jfloat y,
jint pressure, jint tilt_x, jint tilt_y,
jint orientation, jint buttons, jboolean eraser, jboolean mouse) {
static void sendStylusEvent(__unused JNIEnv *env, __unused jobject thiz, jfloat x, jfloat y,
jint pressure, jint tilt_x, jint tilt_y,
jint orientation, jint buttons, jboolean eraser, jboolean mouse) {
if (conn_fd != -1) {
lorieEvent e = { .stylus = { .t = EVENT_STYLUS, .x = x, .y = y, .pressure = pressure, .tilt_x = tilt_x, .tilt_y = tilt_y, .orientation = orientation, .buttons = buttons, .eraser = eraser, .mouse = mouse } };
write(conn_fd, &e, sizeof(e));
}
}

JNIEXPORT void JNICALL
Java_com_termux_x11_LorieView_requestStylusEnabled(__unused JNIEnv *env, __unused jclass clazz, jboolean enabled) {
static void requestStylusEnabled(__unused JNIEnv *env, __unused jclass clazz, jboolean enabled) {
if (conn_fd != -1) {
lorieEvent e = { .stylusEnable = { .t = EVENT_STYLUS_ENABLE, .enable = enabled } };
write(conn_fd, &e, sizeof(e));
}
}

JNIEXPORT jboolean JNICALL
Java_com_termux_x11_LorieView_sendKeyEvent(__unused JNIEnv* env, __unused jobject cls, jint scan_code, jint key_code, jboolean key_down) {
static jboolean sendKeyEvent(__unused JNIEnv* env, __unused jobject cls, jint scan_code, jint key_code, jboolean key_down) {
if (conn_fd != -1) {
int code = (scan_code) ?: android_to_linux_keycode[key_code];
log(DEBUG, "Sending key: %d (%d %d %d)", code + 8, scan_code, key_code, key_down);
Expand All @@ -282,8 +270,7 @@ Java_com_termux_x11_LorieView_sendKeyEvent(__unused JNIEnv* env, __unused jobjec
return true;
}

JNIEXPORT void JNICALL
Java_com_termux_x11_LorieView_sendTextEvent(JNIEnv *env, __unused jobject thiz, jbyteArray text) {
static void sendTextEvent(JNIEnv *env, __unused jobject thiz, jbyteArray text) {
if (conn_fd != -1 && text) {
jsize length = (*env)->GetArrayLength(env, text);
jbyte *str = (*env)->GetByteArrayElements(env, text, NULL);
Expand Down Expand Up @@ -319,6 +306,30 @@ Java_com_termux_x11_LorieView_sendTextEvent(JNIEnv *env, __unused jobject thiz,
}
}

JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv* env;
static JNINativeMethod methods[] = {
{"nativeInit", "()V", (void *)&nativeInit},
{"connect", "(I)V", (void *)&connect_},
{"startLogcat", "(I)V", (void *)&startLogcat},
{"setClipboardSyncEnabled", "(ZZ)V", (void *)&setClipboardSyncEnabled},
{"sendClipboardAnnounce", "()V", (void *)&sendClipboardAnnounce},
{"sendClipboardEvent", "([B)V", (void *)&sendClipboardEvent},
{"sendWindowChange", "(IIILjava/lang/String;)V", (void *)&sendWindowChange},
{"sendMouseEvent", "(FFIZZ)V", (void *)&sendMouseEvent},
{"sendTouchEvent", "(IIII)V", (void *)&sendTouchEvent},
{"sendStylusEvent", "(FFIIIIIZZ)V", (void *)&sendStylusEvent},
{"requestStylusEnabled", "(Z)V", (void *)&requestStylusEnabled},
{"sendKeyEvent", "(IIZ)Z", (void *)&sendKeyEvent},
{"sendTextEvent", "([B)V", (void *)&sendTextEvent},
};
(*vm)->AttachCurrentThread(vm, &env, NULL);
jclass cls = (*env)->FindClass(env, "com/termux/x11/LorieView");
(*env)->RegisterNatives(env, cls, methods, sizeof(methods)/sizeof(methods[0]));
return JNI_VERSION_1_6;
}


// It is needed to redirect stderr to logcat
static void* stderrToLogcatThread(__unused void* cookie) {
FILE *fp;
Expand Down
28 changes: 15 additions & 13 deletions app/src/main/java/com/termux/x11/LorieView.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
import java.nio.charset.StandardCharsets;
import java.util.regex.PatternSyntaxException;

import dalvik.annotation.optimization.FastNative;

@Keep @SuppressLint("WrongConstant")
@SuppressWarnings("deprecation")
public class LorieView extends SurfaceView implements InputStub {
Expand Down Expand Up @@ -362,19 +364,19 @@ public boolean commitText(CharSequence text, int newCursorPosition) {
}
}

private native void nativeInit();
static native void connect(int fd);
static native void startLogcat(int fd);
static native void setClipboardSyncEnabled(boolean enabled, boolean ignored);
public native void sendClipboardAnnounce();
public native void sendClipboardEvent(byte[] text);
static native void sendWindowChange(int width, int height, int framerate, String name);
public native void sendMouseEvent(float x, float y, int whichButton, boolean buttonDown, boolean relative);
public native void sendTouchEvent(int action, int id, int x, int y);
public native void sendStylusEvent(float x, float y, int pressure, int tiltX, int tiltY, int orientation, int buttons, boolean eraser, boolean mouseMode);
static public native void requestStylusEnabled(boolean enabled);
public native boolean sendKeyEvent(int scanCode, int keyCode, boolean keyDown);
public native void sendTextEvent(byte[] text);
@FastNative private native void nativeInit();
@FastNative static native void connect(int fd);
@FastNative static native void startLogcat(int fd);
@FastNative static native void setClipboardSyncEnabled(boolean enabled, boolean ignored);
@FastNative public native void sendClipboardAnnounce();
@FastNative public native void sendClipboardEvent(byte[] text);
@FastNative static native void sendWindowChange(int width, int height, int framerate, String name);
@FastNative public native void sendMouseEvent(float x, float y, int whichButton, boolean buttonDown, boolean relative);
@FastNative public native void sendTouchEvent(int action, int id, int x, int y);
@FastNative public native void sendStylusEvent(float x, float y, int pressure, int tiltX, int tiltY, int orientation, int buttons, boolean eraser, boolean mouseMode);
@FastNative static public native void requestStylusEnabled(boolean enabled);
@FastNative public native boolean sendKeyEvent(int scanCode, int keyCode, boolean keyDown);
@FastNative public native void sendTextEvent(byte[] text);

static {
System.loadLibrary("lorie");
Expand Down

0 comments on commit cc36f7e

Please sign in to comment.