public int ConvertKeyBoardCode(int keyCode, KeyEvent event) { int curKeyCode = keyCode; Log.i(TAG, "revertKeyCode getScanCode = " + event.getScanCode()); switch (event.getScanCode()) { case 231: // keyboard Menu curKeyCode = KeyEvent.KEYCODE_MENU; break; case 232: // keyboard Source curKeyCode = KeyEvent.KEYCODE_DPAD_CENTER; break; case 233: // keyboard Channel Up curKeyCode = KeyEvent.KEYCODE_DPAD_UP; break; case 234: // keyboard Channel Down curKeyCode = KeyEvent.KEYCODE_DPAD_DOWN; break; case 235: // keyboard Volume Down curKeyCode = KeyEvent.KEYCODE_DPAD_LEFT; break; case 236: // keyboard Volume Up curKeyCode = KeyEvent.KEYCODE_DPAD_RIGHT; break; default: break; } return curKeyCode; }
public boolean handleHardwareButtons(int keyCode, KeyEvent evt, int combinedMetastate) { boolean down = (evt.getAction() == KeyEvent.ACTION_DOWN) || (evt.getAction() == KeyEvent.ACTION_MULTIPLE); int mouseChange = keyCode == KeyEvent.KEYCODE_VOLUME_DOWN ? RemoteVncPointer.MOUSE_BUTTON_SCROLL_DOWN : RemoteVncPointer.MOUSE_BUTTON_SCROLL_UP; if (keyCode == KeyEvent.KEYCODE_CAMERA || keyCode == KeyEvent.KEYCODE_BACK && evt.getScanCode() == 0) { if (keyCode == KeyEvent.KEYCODE_CAMERA) cameraButtonDown = down; if (down) pointerMask = RemoteVncPointer.MOUSE_BUTTON_RIGHT; else pointerMask = 0; rfb.writePointerEvent(getX(), getY(), combinedMetastate, pointerMask); return true; } else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN || keyCode == KeyEvent.KEYCODE_VOLUME_UP) { if (evt.getAction() == KeyEvent.ACTION_DOWN) { // If not auto-repeat if (scrollRunnable.scrollButton != mouseChange) { pointerMask |= mouseChange; scrollRunnable.scrollButton = mouseChange; handler.postDelayed(scrollRunnable, 200); } } else { handler.removeCallbacks(scrollRunnable); scrollRunnable.scrollButton = 0; pointerMask &= ~mouseChange; } rfb.writePointerEvent(getX(), getY(), combinedMetastate, pointerMask); return true; } return false; }
private void onKeyEvent( KeyEvent event, int action, int savedMetaState, boolean isSynthesizedImeKey) { // Use a separate action argument so we can override the key's original action, // e.g. change ACTION_MULTIPLE to ACTION_DOWN. That way we don't have to allocate // a new key event just to change its action field. // // Normally we expect event.getMetaState() to reflect the current meta-state; however, // some software-generated key events may not have event.getMetaState() set, e.g. key // events from Swype. Therefore, it's necessary to combine the key's meta-states // with the meta-states that we keep separately in KeyListener final int metaState = event.getMetaState() | savedMetaState; final int unmodifiedMetaState = metaState & ~(KeyEvent.META_ALT_MASK | KeyEvent.META_CTRL_MASK | KeyEvent.META_META_MASK); final int unicodeChar = event.getUnicodeChar(metaState); final int domPrintableKeyValue = unicodeChar >= ' ' ? unicodeChar : unmodifiedMetaState != metaState ? event.getUnicodeChar(unmodifiedMetaState) : 0; onKeyEvent( action, event.getKeyCode(), event.getScanCode(), metaState, event.getEventTime(), unicodeChar, // e.g. for Ctrl+A, Android returns 0 for unicodeChar, // but Gecko expects 'a', so we return that in baseUnicodeChar. event.getUnicodeChar(0), domPrintableKeyValue, event.getRepeatCount(), event.getFlags(), isSynthesizedImeKey); }
boolean sendKeyEvent(KeyEvent event) { if (mNativeImeAdapterAndroid == 0) return false; int action = event.getAction(); if (action != KeyEvent.ACTION_DOWN && action != KeyEvent.ACTION_UP) { // action == KeyEvent.ACTION_MULTIPLE // TODO(bulach): confirm the actual behavior. Apparently: // If event.getKeyCode() == KEYCODE_UNKNOWN, we can send a // composition key down (229) followed by a commit text with the // string from event.getUnicodeChars(). // Otherwise, we'd need to send an event with a // WebInputEvent::IsAutoRepeat modifier. We also need to verify when // we receive ACTION_MULTIPLE: we may receive it after an ACTION_DOWN, // and if that's the case, we'll need to review when to send the Char // event. return false; } mViewEmbedder.onImeEvent(); return nativeSendKeyEvent( mNativeImeAdapterAndroid, event, event.getAction(), getModifiers(event.getMetaState()), event.getEventTime(), event.getKeyCode(), event.getScanCode(), /*isSystemKey=*/ false, event.getUnicodeChar()); }
@Override public boolean onKeyDown(int keyCode, KeyEvent event) { int dir = 0; if (keyCode == 0) keyCode = event.getScanCode(); if (DeviceInfo.SONY_NAVIGATION_KEYS) { if (keyCode == ReaderView.SONY_DPAD_RIGHT_SCANCODE || keyCode == ReaderView.SONY_DPAD_DOWN_SCANCODE || keyCode == KeyEvent.KEYCODE_DPAD_DOWN || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) dir = 1; else if (keyCode == ReaderView.SONY_DPAD_LEFT_SCANCODE || keyCode == ReaderView.SONY_DPAD_UP_SCANCODE || keyCode == KeyEvent.KEYCODE_DPAD_UP || keyCode == KeyEvent.KEYCODE_DPAD_LEFT) dir = -1; } else { if (keyCode == ReaderView.NOOK_KEY_NEXT_RIGHT || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT || keyCode == ReaderView.NOOK_KEY_SHIFT_DOWN) dir = 1; if (keyCode == ReaderView.NOOK_KEY_PREV_RIGHT || keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == ReaderView.NOOK_KEY_SHIFT_UP) dir = -1; } if (dir != 0) { int firstPos = getFirstVisiblePosition(); int lastPos = getLastVisiblePosition(); int count = getCount(); int delta = 1; if (dir < 0) { View v = getChildAt(0); if (v != null) { int fh = v.getHeight(); Rect r = new Rect(0, 0, v.getWidth(), fh); getChildVisibleRect(v, r, null); delta = (r.height() < fh) ? 1 : 0; } } int nextPos = (dir > 0) ? Math.min(lastPos, count - 1) : Math.max(0, firstPos - (lastPos - firstPos) + delta); // Log.w("CoolReader", "first =" + firstPos + " last = " + lastPos + " next = " + nextPos + " // count = " + count); setSelection(nextPos); clearFocus(); return true; } return super.onKeyDown(keyCode, event); }
public boolean handleKeyCode(int keyCode, KeyEvent event, boolean appMode) throws IOException { String code = null; if (event != null) { int keyMod = 0; // META_CTRL_ON was added only in API 11, so don't use it, // use our own tracking of Ctrl key instead. // (event.getMetaState() & META_CTRL_ON) != 0 if (mHardwareControlKey || mControlKey.isActive()) { keyMod |= KEYMOD_CTRL; } if ((event.getMetaState() & META_ALT_ON) != 0) { keyMod |= KEYMOD_ALT; } if ((event.getMetaState() & META_SHIFT_ON) != 0) { keyMod |= KEYMOD_SHIFT; } // First try to map scancode code = mKeyMap.get(event.getScanCode() | KEYMOD_SCAN | keyMod); if (code == null) { code = mKeyMap.get(keyCode | keyMod); } } if (code == null && keyCode >= 0 && keyCode < mKeyCodes.length) { if (appMode) { code = mAppKeyCodes[keyCode]; } if (code == null) { code = mKeyCodes[keyCode]; } } if (code != null) { if (EmulatorDebug.LOG_CHARACTERS_FLAG) { byte[] bytes = code.getBytes(); Log.d( EmulatorDebug.LOG_TAG, "Out: '" + EmulatorDebug.bytesToString(bytes, 0, bytes.length) + "'"); } mTermSession.write(code); return true; } return false; }
private void logKeyEvent(int keyCode, KeyEvent event, boolean down) { String s = down ? "KeyDown event:" : "KeyUp event:"; s += " action " + event.getAction() + " keycode " + keyCode + " " + KeyEvent.keyCodeToString(keyCode); s += " unicode " + event.getUnicodeChar() + " " + event.getDisplayLabel(); s += " ScanCode " + event.getScanCode(); s += " MetaState " + event.getMetaState() + " Flags " + event.getFlags() + " modifiers " + event.getModifiers(); s += " source " + printSource(event.getSource()) + " device " + printDevice(event.getDeviceId()); pushText(s); }
@Override public boolean handleKeyEvent(KeyEvent event) { if (DEBUG_KEYEVENT) { Log.d( TAG, "KeyEvent: action=" + event.getAction() + ", flags=" + event.getFlags() + ", canceled=" + event.isCanceled() + ", keyCode=" + event.getKeyCode() + ", scanCode=" + event.getScanCode() + ", metaState=" + event.getMetaState() + ", repeatCount=" + event.getRepeatCount()); } if (event.getAction() != KeyEvent.ACTION_UP || event.getRepeatCount() != 0) { return false; } switch (event.getScanCode()) { case SCANCODE_TOGGLE_WIFI: toggleWifi(); break; case SCANCODE_TOGGLE_BT: toggleBluetooth(); break; case SCANCODE_TOGGLE_TOUCHPAD: toggleTouchpad(); break; case SCANCODE_BRIGHTNESS_DOWN: brightnessDown(); break; case SCANCODE_BRIGHTNESS_UP: brightnessUp(); break; case SCANCODE_BRIGHTNESS_AUTO: toggleAutoBrightness(); break; case SCANCODE_SCREENSHOT: takeScreenshot(); break; case SCANCODE_EXPLORER: launchExplorer(); return false; case SCANCODE_SETTINGS: launchSettings(); break; case SCANCODE_VOLUME_MUTE: // KEYCODE_VOLUME_MUTE is part of the aosp keyevent intercept handling, but // aosp uses it stop ringing in phone devices (no system volume mute toggle). // Since transformer devices doesn't have a telephony subsystem, we handle and // treat this event as a volume mute toggle action. the asusdec KeyHandler // mustn't mark the key event as consumed. toggleAudioMute(); return false; case SCANCODE_VOLUME_DOWN: volumeDown(); return false; case SCANCODE_VOLUME_UP: volumeUp(); return false; case SCANCODE_MEDIA_PLAY_PAUSE: mediaPlayPause(); return false; case SCANCODE_MEDIA_PREVIOUS: mediaPrevious(); return false; case SCANCODE_MEDIA_NEXT: mediaNext(); return false; case SCANCODE_CAPS_LOCK: capsLock(event); return false; default: return false; } return true; }
private static CompactKeyEvent getCompactKeyEvent(android.view.KeyEvent keyEvent) { return new CompactKeyEvent( keyEvent.getScanCode(), getCompactMetaState(keyEvent.getMetaState())); }
public boolean processLocalKeyEvent(int keyCode, KeyEvent evt) { android.util.Log.e(TAG, evt.toString() + " " + keyCode); if (rfb != null && rfb.isInNormalProtocol()) { RemotePointer pointer = vncCanvas.getPointer(); boolean down = (evt.getAction() == KeyEvent.ACTION_DOWN) || (evt.getAction() == KeyEvent.ACTION_MULTIPLE); boolean unicode = false; int metaState = 0, numchars = 1; int keyboardMetaState = evt.getMetaState(); // Add shift to metaState if necessary. if ((keyboardMetaState & 0x000000c1) != 0) metaState |= SHIFT_MASK; // If the keyboardMetaState contains any hint of CTRL, add CTRL_MASK to metaState if ((keyboardMetaState & 0x00007000) != 0) metaState |= CTRL_MASK; // If the keyboardMetaState contains left ALT, add ALT_MASK to metaState. // Leaving KeyEvent.KEYCODE_ALT_LEFT for symbol input on hardware keyboards. if ((keyboardMetaState & KeyEvent.META_ALT_RIGHT_ON) != 0) metaState |= ALT_MASK; if ((keyboardMetaState & (RemoteKeyboard.SUPER_MASK | 0x00010000)) != 0) metaState |= SUPER_MASK; if (keyCode == KeyEvent.KEYCODE_MENU) return true; // Ignore menu key if (pointer.handleHardwareButtons( keyCode, evt, metaState | onScreenMetaState | hardwareMetaState)) return true; int key = 0, keysym = 0; if (!down) { switch (evt.getScanCode()) { case SCAN_ESC: key = 0xff1b; break; case SCAN_LEFTCTRL: case SCAN_RIGHTCTRL: hardwareMetaState &= ~CTRL_MASK; break; case SCAN_F1: keysym = 0xffbe; break; case SCAN_F2: keysym = 0xffbf; break; case SCAN_F3: keysym = 0xffc0; break; case SCAN_F4: keysym = 0xffc1; break; case SCAN_F5: keysym = 0xffc2; break; case SCAN_F6: keysym = 0xffc3; break; case SCAN_F7: keysym = 0xffc4; break; case SCAN_F8: keysym = 0xffc5; break; case SCAN_F9: keysym = 0xffc6; break; case SCAN_F10: keysym = 0xffc7; break; } switch (keyCode) { case KeyEvent.KEYCODE_DPAD_CENTER: hardwareMetaState &= ~CTRL_MASK; break; // Leaving KeyEvent.KEYCODE_ALT_LEFT for symbol input on hardware keyboards. case KeyEvent.KEYCODE_ALT_RIGHT: hardwareMetaState &= ~ALT_MASK; break; } } switch (keyCode) { // case KeyEvent.KEYCODE_BACK: keysym = 0xff1b; break; case KeyEvent.KEYCODE_DPAD_LEFT: keysym = 0xff51; break; case KeyEvent.KEYCODE_DPAD_UP: keysym = 0xff52; break; case KeyEvent.KEYCODE_DPAD_RIGHT: keysym = 0xff53; break; case KeyEvent.KEYCODE_DPAD_DOWN: keysym = 0xff54; break; case KeyEvent.KEYCODE_DEL: keysym = 0xff08; break; case KeyEvent.KEYCODE_ENTER: keysym = 0xff0d; break; case KeyEvent.KEYCODE_TAB: keysym = 0xff09; break; case 92 /* KEYCODE_PAGE_UP */: keysym = 0xff55; break; case 93 /* KEYCODE_PAGE_DOWN */: keysym = 0xff56; break; case 111 /* KEYCODE_ESCAPE */: keysym = 0xff1b; break; case 112 /* KEYCODE_FORWARD_DEL */: keysym = 0xffff; break; case 113 /* KEYCODE_CTRL_LEFT */: keysym = 0xffe3; break; case 114 /* KEYCODE_CTRL_RIGHT */: keysym = 0xffe4; break; case 115 /* KEYCODE_CAPS_LOCK */: keysym = 0xffe5; break; case 116 /* KEYCODE_SCROLL_LOCK */: keysym = 0xff14; break; case 117 /* KEYCODE_META_LEFT */: keysym = 0xffeb; break; case 118 /* KEYCODE_META_RIGHT */: keysym = 0xffec; break; case 120 /* KEYCODE_SYSRQ */: keysym = 0xff61; break; case 121 /* KEYCODE_BREAK */: keysym = 0xff6b; break; case 122 /* KEYCODE_MOVE_HOME */: keysym = 0xff50; break; case 123 /* KEYCODE_MOVE_END */: keysym = 0xff57; break; case 124 /* KEYCODE_INSERT */: keysym = 0xff63; break; case 131 /* KEYCODE_F1 */: keysym = 0xffbe; break; case 132 /* KEYCODE_F2 */: keysym = 0xffbf; break; case 133 /* KEYCODE_F3 */: keysym = 0xffc0; break; case 134 /* KEYCODE_F4 */: keysym = 0xffc1; break; case 135 /* KEYCODE_F5 */: keysym = 0xffc2; break; case 136 /* KEYCODE_F6 */: keysym = 0xffc3; break; case 137 /* KEYCODE_F7 */: keysym = 0xffc4; break; case 138 /* KEYCODE_F8 */: keysym = 0xffc5; break; case 139 /* KEYCODE_F9 */: keysym = 0xffc6; break; case 140 /* KEYCODE_F10 */: keysym = 0xffc7; break; case 141 /* KEYCODE_F11 */: keysym = 0xffc8; break; case 142 /* KEYCODE_F12 */: keysym = 0xffc9; break; case 143 /* KEYCODE_NUM_LOCK */: keysym = 0xff7f; break; case 0 /* KEYCODE_UNKNOWN */: if (evt.getCharacters() != null) { key = evt.getCharacters().charAt(0); keysym = UnicodeToKeysym.translate(key); numchars = evt.getCharacters().length(); unicode = true; } break; default: // Modifier handling is a bit tricky. Alt, Ctrl, and Super should be passed // through to the VNC server so that they get handled there, but strip // them from the character before retrieving the Unicode char from it. // Don't clear Shift, we still want uppercase characters. int metaMask = (0x00007000 | 0x00070000); // KeyEvent.META_CTRL_MASK | KeyEvent.META_META_MASK // We still want alt-key combinations to give us symbols, so we only strip out // KeyEvent.META_ALT_MASK // if we've decided to send out ALT as a separate key modifier over. if ((metaState & ALT_MASK) != 0) metaMask |= 0x00000032; KeyEvent copy = new KeyEvent( evt.getDownTime(), evt.getEventTime(), evt.getAction(), evt.getKeyCode(), evt.getRepeatCount(), keyboardMetaState & ~metaMask, evt.getDeviceId(), evt.getScanCode()); key = copy.getUnicodeChar(); keysym = UnicodeToKeysym.translate(key); break; } if (down) { // Look for standard scan-codes from external keyboards switch (evt.getScanCode()) { case SCAN_ESC: keysym = 0xff1b; break; case SCAN_LEFTCTRL: case SCAN_RIGHTCTRL: hardwareMetaState |= CTRL_MASK; break; case SCAN_F1: keysym = 0xffbe; break; case SCAN_F2: keysym = 0xffbf; break; case SCAN_F3: keysym = 0xffc0; break; case SCAN_F4: keysym = 0xffc1; break; case SCAN_F5: keysym = 0xffc2; break; case SCAN_F6: keysym = 0xffc3; break; case SCAN_F7: keysym = 0xffc4; break; case SCAN_F8: keysym = 0xffc5; break; case SCAN_F9: keysym = 0xffc6; break; case SCAN_F10: keysym = 0xffc7; break; } switch (keyCode) { case KeyEvent.KEYCODE_DPAD_CENTER: hardwareMetaState |= CTRL_MASK; break; // Leaving KeyEvent.KEYCODE_ALT_LEFT for symbol input on hardware keyboards. case KeyEvent.KEYCODE_ALT_RIGHT: hardwareMetaState |= ALT_MASK; break; } } try { if (afterMenu) { afterMenu = false; if (!down && keysym != lastKeyDown) return true; } if (down) lastKeyDown = keysym; if (numchars == 1) { android.util.Log.e( TAG, "action down? = " + down + " key = " + key + " keysym = " + keysym + " onscreen metastate = " + onScreenMetaState + " keyboard metastate = " + keyboardMetaState + " RFB metastate = " + metaState + " keycode = " + keyCode + " unicode = " + evt.getUnicodeChar()); // TODO: UGLY HACK for Z10 devices running 10.1 which never send the down-event // for backspace... so we send it instead. Remove as soon as possible! if (backspaceWorkaround && keyCode == KeyEvent.KEYCODE_DEL) rfb.writeKeyEvent(keysym, (onScreenMetaState | hardwareMetaState | metaState), true); rfb.writeKeyEvent(keysym, (onScreenMetaState | hardwareMetaState | metaState), down); // If this is a unicode key, the up event will never come, so we artificially insert it. if (unicode) rfb.writeKeyEvent(keysym, (onScreenMetaState | hardwareMetaState | metaState), false); // TODO: UGLY HACK for BB10 devices which never send the up-event // for space, backspace and enter... so we send it instead. Remove as soon as possible! if (bb10 && (keyCode == KeyEvent.KEYCODE_SPACE || keyCode == KeyEvent.KEYCODE_DEL || keyCode == KeyEvent.KEYCODE_ENTER)) rfb.writeKeyEvent(keysym, (onScreenMetaState | hardwareMetaState | metaState), false); } else if (numchars > 1) { for (int i = 0; i < numchars; i++) { key = evt.getCharacters().charAt(i); // Log.e(TAG,"action down? = " + down + " key = " + key + " keysym = " + keysym + " // onscreen metastate = " + onScreenMetaState + " keyboard metastate = " + // keyboardMetaState + " RFB metastate = " + metaState + " keycode = " + keyCode + " // unicode = " + evt.getUnicodeChar()); keysym = UnicodeToKeysym.translate(key); rfb.writeKeyEvent(keysym, (onScreenMetaState | hardwareMetaState | metaState), true); rfb.writeKeyEvent(keysym, (onScreenMetaState | hardwareMetaState | metaState), false); } } } catch (Exception e) { e.printStackTrace(); } return true; } return false; }
/** * Called once when a keyboard key is pressed, then again when that same key is released. This is * not guaranteed to be notified of all soft keyboard events: certian keyboards might not call it * at all, while others might skip it in certain situations (e.g. swipe input). */ @Override public boolean dispatchKeyEvent(KeyEvent event) { int keyCode = event.getKeyCode(); // Dispatch the back button to the system to handle navigation if (keyCode == KeyEvent.KEYCODE_BACK) { JniInterface.disconnectFromHost(); return super.dispatchKeyEvent(event); } boolean pressed = event.getAction() == KeyEvent.ACTION_DOWN; // Physical keyboard must work as if it is connected to the remote host // and so events coming from physical keyboard never generate text // events. Also scan codes must be used instead of key code, so that // the keyboard layout selected on the client doesn't affect the key // codes sent to the host. if (event.getDeviceId() != KeyCharacterMap.VIRTUAL_KEYBOARD) { return JniInterface.sendKeyEvent(event.getScanCode(), 0, pressed); } // Events received from software keyboards generate TextEvent in two // cases: // 1. This is an ACTION_MULTIPLE event. // 2. Ctrl, Alt and Meta are not pressed. // This ensures that on-screen keyboard always injects input that // correspond to what user sees on the screen, while physical keyboard // acts as if it is connected to the remote host. if (event.getAction() == KeyEvent.ACTION_MULTIPLE) { JniInterface.sendTextEvent(event.getCharacters()); return true; } // For Enter getUnicodeChar() returns 10 (line feed), but we still // want to send it as KeyEvent. int unicode = keyCode != KeyEvent.KEYCODE_ENTER ? event.getUnicodeChar() : 0; boolean no_modifiers = !event.isAltPressed() && !event.isCtrlPressed() && !event.isMetaPressed(); if (pressed && unicode != 0 && no_modifiers) { mPressedTextKeys.add(keyCode); int[] codePoints = {unicode}; JniInterface.sendTextEvent(new String(codePoints, 0, 1)); return true; } if (!pressed && mPressedTextKeys.contains(keyCode)) { mPressedTextKeys.remove(keyCode); return true; } switch (keyCode) { // KEYCODE_AT, KEYCODE_POUND, KEYCODE_STAR and KEYCODE_PLUS are // deprecated, but they still need to be here for older devices and // third-party keyboards that may still generate these events. See // https://source.android.com/devices/input/keyboard-devices.html#legacy-unsupported-keys case KeyEvent.KEYCODE_AT: JniInterface.sendKeyEvent(0, KeyEvent.KEYCODE_SHIFT_LEFT, pressed); JniInterface.sendKeyEvent(0, KeyEvent.KEYCODE_2, pressed); return true; case KeyEvent.KEYCODE_POUND: JniInterface.sendKeyEvent(0, KeyEvent.KEYCODE_SHIFT_LEFT, pressed); JniInterface.sendKeyEvent(0, KeyEvent.KEYCODE_3, pressed); return true; case KeyEvent.KEYCODE_STAR: JniInterface.sendKeyEvent(0, KeyEvent.KEYCODE_SHIFT_LEFT, pressed); JniInterface.sendKeyEvent(0, KeyEvent.KEYCODE_8, pressed); return true; case KeyEvent.KEYCODE_PLUS: JniInterface.sendKeyEvent(0, KeyEvent.KEYCODE_SHIFT_LEFT, pressed); JniInterface.sendKeyEvent(0, KeyEvent.KEYCODE_EQUALS, pressed); return true; default: // We try to send all other key codes to the host directly. return JniInterface.sendKeyEvent(0, keyCode, pressed); } }