Implement GLFW char callback (untested)

This commit is contained in:
khanhduytran0 2020-09-23 18:06:05 +07:00
parent d6988fea87
commit d991625c9b
6 changed files with 70 additions and 118 deletions

View File

@ -24,7 +24,7 @@ android {
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 26 targetSdkVersion 26
versionCode 156235 versionCode 156235
versionName "3.2.0_6403b_20200915" versionName "3.2.0_6404b_20200923"
multiDexEnabled true //important multiDexEnabled true //important
ndk { ndk {

View File

@ -7,7 +7,7 @@ import org.lwjgl.glfw.*;
public class AndroidLWJGLKeycode { public class AndroidLWJGLKeycode {
// Fix double letters on MC 1.9 and above // Fix double letters on MC 1.9 and above
public static boolean isBackspaceAfterChar; // public static boolean isBackspaceAfterChar;
private static final ArrayMap<Integer, Integer> androidToLwjglMap; private static final ArrayMap<Integer, Integer> androidToLwjglMap;
private static String[] androidKeyNameArray; private static String[] androidKeyNameArray;
static { static {
@ -168,38 +168,37 @@ public class AndroidLWJGLKeycode {
public static void execKey(MainActivity mainActivity, KeyEvent keyEvent, int i, boolean isDown) { public static void execKey(MainActivity mainActivity, KeyEvent keyEvent, int i, boolean isDown) {
for (Map.Entry<Integer, Integer> perKey : androidToLwjglMap.entrySet()) { for (Map.Entry<Integer, Integer> perKey : androidToLwjglMap.entrySet()) {
if (perKey.getKey() == i) { if (i == 1 && (keyEvent.getSource() == InputDevice.SOURCE_MOUSE)) {
if (i == KeyEvent.KEYCODE_BACK && (keyEvent.getSource() == InputDevice.SOURCE_MOUSE)) {
// Right mouse detection // Right mouse detection
mainActivity.sendMouseButton(1, true); mainActivity.sendMouseButton(1, true);
mainActivity.sendMouseButton(1, false); mainActivity.sendMouseButton(1, false);
} else { } else if (perKey.getKey() == i) {
mainActivity.sendKeyPress(perKey.getValue(), isDown); mainActivity.sendKeyPress(perKey.getValue(), keyEvent.getModifiers(), isDown);
}
} }
} }
if (keyEvent.isAltPressed()) { if (keyEvent.isAltPressed()) {
mainActivity.sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_LEFT_ALT, isDown); mainActivity.sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_LEFT_ALT, keyEvent.getModifiers(), isDown);
} if (keyEvent.isCtrlPressed()) { } if (keyEvent.isCtrlPressed()) {
mainActivity.sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_LEFT_CONTROL, isDown); mainActivity.sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_LEFT_CONTROL, keyEvent.getModifiers(), isDown);
} if (keyEvent.isFunctionPressed()) { } if (keyEvent.isFunctionPressed()) {
// mainActivity.sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_FUNCTION, isDown); // mainActivity.sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_FUNCTION, keyEvent.getModifiers(), isDown);
} if (keyEvent.isShiftPressed()) { } if (keyEvent.isShiftPressed()) {
mainActivity.sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_LEFT_SHIFT, isDown); mainActivity.sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_LEFT_SHIFT, keyEvent.getModifiers(), isDown);
} }
try { try {
if (/* (int) keyEvent.getDisplayLabel() != KeyEvent.KEYCODE_UNKNOWN && */ !CallbackBridge.isGrabbing()) { if (/* (int) keyEvent.getDisplayLabel() != KeyEvent.KEYCODE_UNKNOWN || */ !CallbackBridge.isGrabbing()) {
mainActivity.sendKeyPress(0, (char) keyEvent.getUnicodeChar(), isDown); mainActivity.sendKeyPress(0, (char) keyEvent.getUnicodeChar(), keyEvent.getModifiers(), isDown);
} }
} catch (Throwable th) { } catch (Throwable th) {
th.printStackTrace(); th.printStackTrace();
} }
/*
if (isBackspaceAfterChar && !CallbackBridge.isGrabbing() && i != KeyEvent.KEYCODE_DEL) { if (isBackspaceAfterChar && !CallbackBridge.isGrabbing() && i != KeyEvent.KEYCODE_DEL) {
mainActivity.sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_BACKSPACE, isDown); mainActivity.sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_BACKSPACE, keyEvent.getModifiers(), isDown);
} }
*/
} }
public static void execKeyIndex(MainActivity mainActivity, int index) { public static void execKeyIndex(MainActivity mainActivity, int index) {

View File

@ -1,59 +0,0 @@
package net.kdt.pojavlaunch;
import android.text.method.*;
import android.view.*;
import android.view.inputmethod.*;
public class DroidToJavaKey {
private static StringBuilder mComposing = new StringBuilder();
private static long mMetaState;
public static void execKey(MainActivity mainActivity, KeyEvent keyEvent, int i, boolean status) {
/*
if (i >= KeyEvent.KEYCODE_F1 && i <= KeyEvent.KEYCODE_F12) {
mainActivity.sendKeyPress(i - 72, status);
} else if (i == KeyEvent.KEYCODE_DEL) {
mainActivity.sendKeyPress(Keyboard.KEY_DELETE, status);
} else if (i == KeyEvent.KEYCODE_ENTER) {
mainActivity.sendKeyPress(Keyboard.KEY_RETURN, status);
} else if (i == KeyEvent.KEYCODE_SHIFT_LEFT) {
mainActivity.sendKeyPress(Keyboard.KEY_LSHIFT, status);
} else if (i == KeyEvent.KEYCODE_SHIFT_RIGHT) {
mainActivity.sendKeyPress(Keyboard.KEY_RSHIFT, status);
} else if (i == KeyEvent.KEYCODE_DPAD_LEFT) {
mainActivity.sendKeyPress(Keyboard.KEY_LEFT, status);
} else if (i == KeyEvent.KEYCODE_DPAD_UP) {
mainActivity.sendKeyPress(Keyboard.KEY_UP, status);
} else if (i == keyEvent.KEYCODE_DPAD_RIGHT) {
mainActivity.sendKeyPress(Keyboard.KEY_RIGHT, status);
} else if (i == KeyEvent.KEYCODE_DPAD_DOWN) {
mainActivity.sendKeyPress(Keyboard.KEY_DOWN, status);
} else if (i >= KeyEvent.KEYCODE_BUTTON_1 && i <= KeyEvent.KEYCODE_BUTTON_16) {
mainActivity.sendKeyPress(i - 188, status);
}
if (!AndroidDisplay.grab) {
try {
// Old method works without dead chars:
mainActivity.sendKeyPress(keyEvent.getDisplayLabel(), status);
} catch (Throwable th) {
th.printStackTrace();
}
}
*/
// Fix press 'e' key close inventory (while search item)
// Should it be or other ways?
/*
if (!AndroidDisplay.grab && keyEvent.getDisplayLabel() != 'e') {
mainActivity.sendKeyPress(keyEvent.getDisplayLabel(), status);
} else {
mainActivity.sendKeyPress(keyEvent.getDisplayLabel());
}
*/
mainActivity.sendKeyPress(keyEvent.getDisplayLabel(), status);
}
}

View File

@ -56,7 +56,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
} }
} break; } break;
case MSG_DROP_ITEM_BUTTON_CHECK: { case MSG_DROP_ITEM_BUTTON_CHECK: {
sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_Q, true); sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_Q, 0, true);
} break; } break;
} }
} }
@ -281,7 +281,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
onClick(toggleControlButton); onClick(toggleControlButton);
this.drawerLayout.closeDrawers(); this.drawerLayout.closeDrawers();
AndroidLWJGLKeycode.isBackspaceAfterChar = mVersionInfo.minimumLauncherVersion >= 18; // AndroidLWJGLKeycode.isBackspaceAfterChar = mVersionInfo.minimumLauncherVersion >= 18;
placeMouseAt(CallbackBridge.windowWidth / 2, CallbackBridge.windowHeight / 2); placeMouseAt(CallbackBridge.windowWidth / 2, CallbackBridge.windowHeight / 2);
new Thread(new Runnable(){ new Thread(new Runnable(){
@ -429,7 +429,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
case MotionEvent.ACTION_POINTER_DOWN: // 5 case MotionEvent.ACTION_POINTER_DOWN: // 5
isTouchInHotbar = hudKeyHandled != -1; isTouchInHotbar = hudKeyHandled != -1;
if (isTouchInHotbar) { if (isTouchInHotbar) {
sendKeyPress(hudKeyHandled, true); sendKeyPress(hudKeyHandled, 0, true);
hotbarX = x; hotbarX = x;
hotbarY = y; hotbarY = y;
@ -443,7 +443,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
*/ */
if (CallbackBridge.isGrabbing()) { if (CallbackBridge.isGrabbing()) {
CallbackBridge.sendMouseKeycode(rightOverride ? LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT : LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT, true); CallbackBridge.sendMouseKeycode(rightOverride ? LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT : LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT, 0, true);
initialX = x; initialX = x;
initialY = y; initialY = y;
theHandler.sendEmptyMessageDelayed(MainActivity.MSG_LEFT_MOUSE_BUTTON_CHECK, LauncherPreferences.PREF_LONGPRESS_TRIGGER); theHandler.sendEmptyMessageDelayed(MainActivity.MSG_LEFT_MOUSE_BUTTON_CHECK, LauncherPreferences.PREF_LONGPRESS_TRIGGER);
@ -467,7 +467,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
// System.out.println((String) ("[Math.abs(" + initialX + " - " + x + ") = " + Math.abs(initialX - x) + "] < " + fingerStillThreshold)); // System.out.println((String) ("[Math.abs(" + initialX + " - " + x + ") = " + Math.abs(initialX - x) + "] < " + fingerStillThreshold));
// System.out.println((String) ("[Math.abs(" + initialY + " - " + y + ") = " + Math.abs(initialY - y) + "] < " + fingerStillThreshold)); // System.out.println((String) ("[Math.abs(" + initialY + " - " + y + ") = " + Math.abs(initialY - y) + "] < " + fingerStillThreshold));
if (isTouchInHotbar && Math.abs(hotbarX - x) < fingerStillThreshold && Math.abs(hotbarY - y) < fingerStillThreshold) { if (isTouchInHotbar && Math.abs(hotbarX - x) < fingerStillThreshold && Math.abs(hotbarY - y) < fingerStillThreshold) {
sendKeyPress(hudKeyHandled, false); sendKeyPress(hudKeyHandled, 0, false);
} else if (!triggeredLeftMouseButton && Math.abs(initialX - x) < fingerStillThreshold && Math.abs(initialY - y) < fingerStillThreshold) { } else if (!triggeredLeftMouseButton && Math.abs(initialX - x) < fingerStillThreshold && Math.abs(initialY - y) < fingerStillThreshold) {
sendMouseButton(1, true); sendMouseButton(1, true);
sendMouseButton(1, false); sendMouseButton(1, false);
@ -479,7 +479,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
triggeredLeftMouseButton = false; triggeredLeftMouseButton = false;
theHandler.removeMessages(MainActivity.MSG_LEFT_MOUSE_BUTTON_CHECK); theHandler.removeMessages(MainActivity.MSG_LEFT_MOUSE_BUTTON_CHECK);
} else { } else {
sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_Q, false); sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_Q, 0, false);
theHandler.removeMessages(MSG_DROP_ITEM_BUTTON_CHECK); theHandler.removeMessages(MSG_DROP_ITEM_BUTTON_CHECK);
} }
} }
@ -558,7 +558,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
switch (e.getActionMasked()) { switch (e.getActionMasked()) {
case MotionEvent.ACTION_DOWN: // 0 case MotionEvent.ACTION_DOWN: // 0
case MotionEvent.ACTION_POINTER_DOWN: // 5 case MotionEvent.ACTION_POINTER_DOWN: // 5
CallbackBridge.sendMouseKeycode(!CallbackBridge.mouseLeft ? LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT : LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT, true); CallbackBridge.sendMouseKeycode(!CallbackBridge.mouseLeft ? LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT : LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT, 0, true);
initialX = x; initialX = x;
initialY = y; initialY = y;
@ -571,7 +571,7 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
case MotionEvent.ACTION_CANCEL: // 3 case MotionEvent.ACTION_CANCEL: // 3
case MotionEvent.ACTION_POINTER_UP: // 6 case MotionEvent.ACTION_POINTER_UP: // 6
CallbackBridge.sendCursorPos(x, y); CallbackBridge.sendCursorPos(x, y);
CallbackBridge.sendMouseKeycode(rightOverride ? LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT : LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT, true); CallbackBridge.sendMouseKeycode(rightOverride ? LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_RIGHT : LWJGLGLFWKeycode.GLFW_MOUSE_BUTTON_LEFT, 0, true);
// CallbackBridge.putMouseEventWithCoords(!CallbackBridge.mouseLeft /* rightOverride */ ? (byte) 1 : (byte) 0, (byte) 0, x, y, 0, System.nanoTime()); // CallbackBridge.putMouseEventWithCoords(!CallbackBridge.mouseLeft /* rightOverride */ ? (byte) 1 : (byte) 0, (byte) 0, x, y, 0, System.nanoTime());
/* /*
if (!triggeredLeftMouseButton && Math.abs(initialX - x) < fingerStillThreshold && Math.abs(initialY - y) < fingerStillThreshold) { if (!triggeredLeftMouseButton && Math.abs(initialX - x) < fingerStillThreshold && Math.abs(initialY - y) < fingerStillThreshold) {
@ -788,11 +788,11 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
} }
switch (v.getId()) { switch (v.getId()) {
case R.id.control_up: sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_W, isDown); break; case R.id.control_up: sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_W, 0, isDown); break;
case R.id.control_left: sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_A, isDown); break; case R.id.control_left: sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_A, 0, isDown); break;
case R.id.control_down: sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_S, isDown); break; case R.id.control_down: sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_S, 0, isDown); break;
case R.id.control_right: sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_D, isDown); break; case R.id.control_right: sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_D, 0, isDown); break;
case R.id.control_jump: sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_SPACE, isDown); break; case R.id.control_jump: sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_SPACE, 0, isDown); break;
case R.id.control_primary: sendMouseButton(0, isDown); break; case R.id.control_primary: sendMouseButton(0, isDown); break;
case R.id.control_secondary: case R.id.control_secondary:
if (CallbackBridge.isGrabbing()) { if (CallbackBridge.isGrabbing()) {
@ -803,14 +803,14 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
} }
setRightOverride(isDown); setRightOverride(isDown);
} break; } break;
case R.id.control_debug: sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_F3, isDown); break; case R.id.control_debug: sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_F3, 0, isDown); break;
case R.id.control_shift: sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_LEFT_SHIFT, isDown); break; case R.id.control_shift: sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_LEFT_SHIFT, 0, isDown); break;
case R.id.control_inventory: sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_E, isDown); break; case R.id.control_inventory: sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_E, 0, isDown); break;
case R.id.control_talk: sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_T, isDown); break; case R.id.control_talk: sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_T, 0, isDown); break;
case R.id.control_keyboard: showKeyboard(); break; case R.id.control_keyboard: showKeyboard(); break;
case R.id.control_thirdperson: sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_F5, isDown); break; case R.id.control_thirdperson: sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_F5, 0, isDown); break;
case R.id.control_zoom: sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_C, isDown); break; case R.id.control_zoom: sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_C, 0, isDown); break;
case R.id.control_listplayers: sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_TAB, isDown); break; case R.id.control_listplayers: sendKeyPress(LWJGLGLFWKeycode.GLFW_KEY_TAB, 0, isDown); break;
} }
return false; return false;
@ -1088,23 +1088,22 @@ public class MainActivity extends AppCompatActivity implements OnTouchListener,
// this.secondaryButton.setBackgroundDrawable(this.rightOverride ? this.secondaryButtonColorBackground : this.secondaryButtonDefaultBackground); // this.secondaryButton.setBackgroundDrawable(this.rightOverride ? this.secondaryButtonColorBackground : this.secondaryButtonDefaultBackground);
} }
public void sendKeyPress(int keyCode, boolean status) { public void sendKeyPress(int keyCode, int modifiers, boolean status) {
sendKeyPress(keyCode, '\u0000', status); sendKeyPress(keyCode, '\u0000', modifiers, status);
} }
public void sendKeyPress(int keyCode, char keyChar, boolean status) { public void sendKeyPress(int keyCode, char keyChar, int modifiers, boolean status) {
// FIXME keyChar CallbackBridge.sendKeycode(keyCode, keyChar, modifiers, status);
CallbackBridge.sendKeycode(keyCode, /* keyChar, */ status);
} }
public void sendKeyPress(char keyChar) { public void sendKeyPress(char keyChar) {
sendKeyPress(0, keyChar, true); sendKeyPress(0, keyChar, 0, true);
sendKeyPress(0, keyChar, false); sendKeyPress(0, keyChar, 0, false);
} }
public void sendKeyPress(int keyCode) { public void sendKeyPress(int keyCode) {
sendKeyPress(keyCode, true); sendKeyPress(keyCode, 0, true);
sendKeyPress(keyCode, false); sendKeyPress(keyCode, 0, false);
} }
public void sendMouseButton(int button, boolean status) { public void sendMouseButton(int button, boolean status) {

View File

@ -90,7 +90,7 @@ public class ControlButton implements Cloneable
} }
public void execute(MainActivity act, boolean isDown) { public void execute(MainActivity act, boolean isDown) {
act.sendKeyPress(keycode, isDown); act.sendKeyPress(keycode, 0, isDown);
} }
public ControlButton clone() { public ControlButton clone() {

View File

@ -26,32 +26,33 @@ public class CallbackBridge {
public static void sendMouseEvent(int x, int y, int keycode, boolean isDown) { public static void sendMouseEvent(int x, int y, int keycode, boolean isDown) {
sendCursorPos(x, y); sendCursorPos(x, y);
sendMouseKeycode(keycode, isDown); sendMouseKeycode(keycode, 0, isDown);
} }
public static void sendCursorPos(int x, int y) { public static void sendCursorPos(int x, int y) {
DEBUG_STRING.append("CursorPos=" + x + ", " + y + "\n"); DEBUG_STRING.append("CursorPos=" + x + ", " + y + "\n");
mouseX = x; mouseX = x;
mouseY = y; mouseY = y;
sendData(JRE_TYPE_CURSOR_POS, x + ":" + y); sendData(JRE_TYPE_CURSOR_POS, x, y);
} }
public static void sendKeycode(int keycode, boolean isDown) { public static void sendKeycode(int keycode, char keychar, int modifiers, boolean isDown) {
sendData(JRE_TYPE_KEYCODE_CONTROL, keycode + ":" + Boolean.toString(isDown)); DEBUG_STRING.append("KeyCode=" + keycode + ", Char=" + keychar);
sendData(JRE_TYPE_KEYCODE_CONTROL, keycode, Character.toString(keychar), Boolean.toString(isDown), modifiers);
} }
public static void sendMouseKeycode(int keycode, boolean isDown) { public static void sendMouseKeycode(int keycode, int modifiers, boolean isDown) {
DEBUG_STRING.append("MouseKey=" + keycode + ", down=" + isDown + "\n"); DEBUG_STRING.append("MouseKey=" + keycode + ", down=" + isDown + "\n");
sendData(JRE_TYPE_MOUSE_KEYCODE_CONTROL, keycode + ":" + Boolean.toString(isDown)); sendData(JRE_TYPE_MOUSE_KEYCODE_CONTROL, keycode, Boolean.toString(isDown), modifiers);
} }
public static void sendMouseKeycode(int keycode) { public static void sendMouseKeycode(int keycode) {
sendMouseKeycode(keycode, true); sendMouseKeycode(keycode, 0, true);
sendMouseKeycode(keycode, false); sendMouseKeycode(keycode, 0, false);
} }
public static void sendUpdateWindowSize(int w, int h) { public static void sendUpdateWindowSize(int w, int h) {
sendData(JRE_TYPE_WINDOW_SIZE, w + ":" + h); sendData(JRE_TYPE_WINDOW_SIZE, w, h);
} }
public static boolean isGrabbing() { public static boolean isGrabbing() {
@ -68,8 +69,20 @@ public class CallbackBridge {
} }
} }
public static void sendData(int type, String data) { private static String currData;
nativeSendData(true, type, data); public static void sendData(int type, Object... dataArr) {
currData = "";
for (int i = 0; i < dataArr.length; i++) {
if (dataArr[i] instanceof int) {
currData += Integer.toString(dataArr[i]);
} else if (dataArr[i] instanceof String) {
currData += (String) dataArr[i];
} else {
currData += dataArr[i].toString();
}
currData += (i + 1 < dataArr.length ? ":" : "");
}
nativeSendData(true, type, currData);
} }
private static native void nativeSendData(boolean isAndroid, int type, String data); private static native void nativeSendData(boolean isAndroid, int type, String data);