예제 #1
0
  /** Attempts to form a connection to the user-selected host. */
  public static void connectToHost(
      String username,
      String authToken,
      String hostJid,
      String hostId,
      String hostPubkey,
      Runnable successCallback) {
    synchronized (JniInterface.class) {
      if (!sLoaded) return;

      if (sConnected) {
        disconnectFromHost();
      }
    }

    sSuccessCallback = successCallback;
    SharedPreferences prefs = sContext.getPreferences(Activity.MODE_PRIVATE);
    nativeConnect(
        username,
        authToken,
        hostJid,
        hostId,
        hostPubkey,
        prefs.getString(hostId + "_id", ""),
        prefs.getString(hostId + "_secret", ""));
    sConnected = true;
  }
예제 #2
0
  /** Called whenever an action bar button is pressed. */
  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
      case R.id.actionbar_keyboard:
        ((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE)).toggleSoftInput(0, 0);
        return true;

      case R.id.actionbar_hide:
        hideActionBar();
        return true;

      case R.id.actionbar_disconnect:
        JniInterface.disconnectFromHost();
        return true;

      case R.id.actionbar_send_ctrl_alt_del:
        {
          int[] keys = {
            KeyEvent.KEYCODE_CTRL_LEFT, KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.KEYCODE_FORWARD_DEL,
          };
          for (int key : keys) {
            JniInterface.keyboardAction(key, true);
          }
          for (int key : keys) {
            JniInterface.keyboardAction(key, false);
          }
        }
        return true;

      default:
        return super.onOptionsItemSelected(item);
    }
  }
예제 #3
0
  /** Called whenever an action bar button is pressed. */
  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();

    mActivityLifecycleListener.onActivityOptionsItemSelected(this, item);

    // Whenever a user selects an option from the ActionBar, reset the auto-hide timer.
    startActionBarAutoHideTimer();

    if (id == R.id.actionbar_cardboard) {
      onCardboardItemSelected();
      return true;
    }
    if (id == R.id.actionbar_keyboard) {
      ((InputMethodManager) getSystemService(INPUT_METHOD_SERVICE)).toggleSoftInput(0, 0);
      return true;
    }
    if (id == R.id.actionbar_hide) {
      hideActionBar();
      return true;
    }
    if (id == R.id.actionbar_disconnect || id == android.R.id.home) {
      JniInterface.disconnectFromHost();
      return true;
    }
    if (id == R.id.actionbar_send_ctrl_alt_del) {
      int[] keys = {
        KeyEvent.KEYCODE_CTRL_LEFT, KeyEvent.KEYCODE_ALT_LEFT, KeyEvent.KEYCODE_FORWARD_DEL,
      };
      for (int key : keys) {
        JniInterface.sendKeyEvent(0, key, true);
      }
      for (int key : keys) {
        JniInterface.sendKeyEvent(0, key, false);
      }
      return true;
    }
    if (id == R.id.actionbar_help) {
      HelpActivity.launch(this, HELP_URL);
      return true;
    }
    return super.onOptionsItemSelected(item);
  }
예제 #4
0
  /**
   * 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);
    }
  }
예제 #5
0
 /** Called when the activity is finally finished. */
 @Override
 public void onDestroy() {
   super.onDestroy();
   JniInterface.disconnectFromHost();
 }