@Override
 public boolean onKeyDown(int keyCode, KeyEvent event) {
   switch (keyCode) {
     case KeyEvent.KEYCODE_BACK:
       Collect.getInstance()
           .getActivityLogger()
           .logInstanceAction(this, "onKeyDown.KEYCODE_BACK", "quit");
       createQuitDrawDialog();
       return true;
     case KeyEvent.KEYCODE_DPAD_RIGHT:
       if (event.isAltPressed()) {
         Collect.getInstance()
             .getActivityLogger()
             .logInstanceAction(this, "onKeyDown.KEYCODE_DPAD_RIGHT", "showNext");
         createQuitDrawDialog();
         return true;
       }
       break;
     case KeyEvent.KEYCODE_DPAD_LEFT:
       if (event.isAltPressed()) {
         Collect.getInstance()
             .getActivityLogger()
             .logInstanceAction(this, "onKeyDown.KEYCODE_DPAD_LEFT", "showPrevious");
         createQuitDrawDialog();
         return true;
       }
       break;
   }
   return super.onKeyDown(keyCode, event);
 }
예제 #2
0
 /**
  * You can call this function yourself to have the scroll view perform scrolling from a key event,
  * just as if the event had been dispatched to it by the view hierarchy.
  *
  * @param event The key event to execute.
  * @return Return true if the event was handled, else false.
  */
 public boolean executeKeyEvent(KeyEvent event) {
   mTempRect.setEmpty();
   if (!canScroll()) {
     if (isFocused()) {
       View currentFocused = findFocus();
       if (currentFocused == this) currentFocused = null;
       View nextFocused =
           FocusFinder.getInstance().findNextFocus(this, currentFocused, View.FOCUS_DOWN);
       return nextFocused != null
           && nextFocused != this
           && nextFocused.requestFocus(View.FOCUS_DOWN);
     }
     return false;
   }
   boolean handled = false;
   if (event.getAction() == KeyEvent.ACTION_DOWN) {
     switch (event.getKeyCode()) {
       case KeyEvent.KEYCODE_DPAD_UP:
         if (!event.isAltPressed()) {
           handled = arrowScroll(View.FOCUS_UP, false);
         } else {
           handled = fullScroll(View.FOCUS_UP, false);
         }
         break;
       case KeyEvent.KEYCODE_DPAD_DOWN:
         if (!event.isAltPressed()) {
           handled = arrowScroll(View.FOCUS_DOWN, false);
         } else {
           handled = fullScroll(View.FOCUS_DOWN, false);
         }
         break;
       case KeyEvent.KEYCODE_DPAD_LEFT:
         if (!event.isAltPressed()) {
           handled = arrowScroll(View.FOCUS_LEFT, true);
         } else {
           handled = fullScroll(View.FOCUS_LEFT, true);
         }
         break;
       case KeyEvent.KEYCODE_DPAD_RIGHT:
         if (!event.isAltPressed()) {
           handled = arrowScroll(View.FOCUS_RIGHT, true);
         } else {
           handled = fullScroll(View.FOCUS_RIGHT, true);
         }
         break;
     }
   }
   return handled;
 }
예제 #3
0
 @Override
 public boolean onKeyDown(int keyCode, KeyEvent event) {
   if (event.isAltPressed() == true) {
     return false;
   }
   return super.onKeyDown(keyCode, event);
 }
예제 #4
0
 /**
  * Convert a KeyEvent into a long which can be kept in settings and compared to key presses when
  * the service is in use.
  *
  * @param keyEvent The key event to convert. The (non-extended) keycode must not be a modifier.
  * @return An extended key code that includes modifier information
  */
 public static long keyEventToExtendedKeyCode(KeyEvent keyEvent) {
   long returnValue = keyEvent.getKeyCode();
   returnValue |= (keyEvent.isShiftPressed()) ? (((long) KeyEvent.META_SHIFT_ON) << 32) : 0;
   returnValue |= (keyEvent.isCtrlPressed()) ? (((long) KeyEvent.META_CTRL_ON) << 32) : 0;
   returnValue |= (keyEvent.isAltPressed()) ? (((long) KeyEvent.META_ALT_ON) << 32) : 0;
   return returnValue;
 }
예제 #5
0
  /**
   * You can call this function yourself to have the scroll view perform scrolling from a key event,
   * just as if the event had been dispatched to it by the view hierarchy.
   *
   * @param event The key event to execute.
   * @return Return true if the event was handled, else false.
   */
  public boolean executeKeyEvent(KeyEvent event) {
    mTempRect.setEmpty();

    boolean handled = false;

    if (event.getAction() == KeyEvent.ACTION_DOWN) {
      switch (event.getKeyCode()) {
          //            case KeyEvent.KEYCODE_DPAD_LEFT:
          //                if(canScrollH()){
          //                    if (!event.isAltPressed()) {
          //                        handled = arrowScrollH(View.FOCUS_LEFT);
          //                    } else {
          //                        handled = fullScrollH(View.FOCUS_LEFT);
          //                    }
          //                }
          //                break;
          //            case KeyEvent.KEYCODE_DPAD_RIGHT:
          //                if(canScrollH()){
          //                    if (!event.isAltPressed()) {
          //                        handled = arrowScrollH(View.FOCUS_RIGHT);
          //                    } else {
          //                        handled = fullScrollH(View.FOCUS_RIGHT);
          //                    }
          //                }
          //                break;
        case KeyEvent.KEYCODE_DPAD_UP:
          if (canScrollV()) {
            if (!event.isAltPressed()) {
              handled = arrowScrollV(View.FOCUS_UP);
            } else {
              handled = fullScrollV(View.FOCUS_UP);
            }
          }
          break;
        case KeyEvent.KEYCODE_DPAD_DOWN:
          if (canScrollV()) {
            if (!event.isAltPressed()) {
              handled = arrowScrollV(View.FOCUS_DOWN);
            } else {
              handled = fullScrollV(View.FOCUS_DOWN);
            }
          }
          break;
      }
    }
    return handled;
  }
예제 #6
0
 //
 // onXperiaKey
 //
 private boolean onXperiaKey(int keycode, KeyEvent event, int isDown) {
   if (keycode == KeyEvent.KEYCODE_BACK && !event.isAltPressed()) return false;
   ControllerInfo.KeyInfo info =
       controller.controllerInfo.keyinfosMappedByAndroidKeycode.get(keycode);
   if (info != null) {
     bbcKeyEvent(info.scancode, shiftDown ? 1 : 0, isDown);
     return true;
   }
   return false;
 }
 @Override
 public boolean onKey(View v, int keyCode, KeyEvent event) {
   KeyModifiers m = new KeyModifiers();
   m.shift = event.isShiftPressed();
   m.alt = event.isAltPressed();
   final char k = TranslateKey(keyCode, m);
   if (k == 0) return false;
   if (event.getAction() == KeyEvent.ACTION_DOWN) Emulator.the.OnKey(k, true, m.shift, m.alt);
   else Emulator.the.OnKey(k, false, false, false);
   return true;
 }
예제 #8
0
  @Override
  public boolean onKeyUp(int keyCode, KeyEvent event) {

    if (keyCode == KeyEvent.KEYCODE_BACK) {
      // We don't want to swallow the back button press
      return false;
    }

    // NOTE: Most keyboards, and specifically the Android default keyboard when
    // entering non-ascii characters, will not trigger KeyEvent events as documented
    // here: http://developer.android.com/reference/android/view/KeyEvent.html

    // Log.e("KeyDown", "------------");
    // Log.e("KeyDown", "keyChar:" + (int) event.getDisplayLabel());
    // Log.e("KeyDown", "utfChar:" + (char)event.getUnicodeChar());
    // Log.e("KeyDown", "intUtfChar:" + event.getUnicodeChar());

    final NetworkPackage np = new NetworkPackage(MousePadPlugin.PACKAGE_TYPE_MOUSEPAD_REQUEST);

    boolean modifier = false;
    if (event.isAltPressed()) {
      np.set("alt", true);
      modifier = true;
    }

    if (Build.VERSION.SDK_INT >= 11) {
      if (event.isCtrlPressed()) {
        np.set("ctrl", true);
        modifier = true;
      }
    }

    if (event.isShiftPressed()) {
      np.set("shift", true);
    }

    int specialKey = SpecialKeysMap.get(keyCode, -1);

    if (specialKey != -1) {
      np.set("specialKey", specialKey);
    } else if (event.getDisplayLabel() != 0 && modifier) {
      // Alt will change the utf symbol to non-ascii characters, we want the plain original letter
      // Since getDisplayLabel will always have a value, we have to check for special keys before
      char keyCharacter = event.getDisplayLabel();
      np.set("key", new String(new char[] {keyCharacter}).toLowerCase());
    } else {
      // A normal key, but still not handled by the KeyInputConnection (happens with numbers)
      np.set("key", new String(new char[] {(char) event.getUnicodeChar()}));
    }

    sendKeyPressPackage(np);
    return true;
  }
예제 #9
0
  @SuppressLint("NewApi")
  @Override
  public boolean onKeyDown(int keyCode, KeyEvent event) {
    // Eat these keys, to avoid accidental exits / other screwups.
    // Maybe there's even more we need to eat on tablets?
    boolean repeat = event.getRepeatCount() > 0;
    switch (keyCode) {
      case KeyEvent.KEYCODE_BACK:
        if (event.isAltPressed()) {
          NativeApp.keyDown(
              0, 1004, repeat); // special custom keycode for the O button on Xperia Play
        } else if (NativeApp.isAtTopLevel()) {
          Log.i(TAG, "IsAtTopLevel returned true.");
          // Pass through the back event.
          return super.onKeyDown(keyCode, event);
        } else {
          NativeApp.keyDown(0, keyCode, repeat);
        }
        return true;
      case KeyEvent.KEYCODE_MENU:
      case KeyEvent.KEYCODE_SEARCH:
        NativeApp.keyDown(0, keyCode, repeat);
        return true;

      case KeyEvent.KEYCODE_DPAD_UP:
      case KeyEvent.KEYCODE_DPAD_DOWN:
      case KeyEvent.KEYCODE_DPAD_LEFT:
      case KeyEvent.KEYCODE_DPAD_RIGHT:
        // Joysticks are supported in Honeycomb MR1 and later via the onGenericMotionEvent method.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1
            && event.getSource() == InputDevice.SOURCE_JOYSTICK) {
          return super.onKeyDown(keyCode, event);
        }
        // Fall through
      default:
        // send the rest of the keys through.
        // TODO: get rid of the three special cases above by adjusting the native side of the code.
        // Log.d(TAG, "Key down: " + keyCode + ", KeyEvent: " + event);
        return NativeApp.keyDown(0, keyCode, repeat);
    }
  }
예제 #10
0
  @SuppressLint("NewApi")
  @Override
  public boolean onKeyUp(int keyCode, KeyEvent event) {
    switch (keyCode) {
      case KeyEvent.KEYCODE_BACK:
        if (event.isAltPressed()) {
          NativeApp.keyUp(0, 1004); // special custom keycode
        } else if (NativeApp.isAtTopLevel()) {
          Log.i(TAG, "IsAtTopLevel returned true.");
          return super.onKeyUp(keyCode, event);
        } else {
          NativeApp.keyUp(0, keyCode);
        }
        return true;
      case KeyEvent.KEYCODE_MENU:
      case KeyEvent.KEYCODE_SEARCH:
        // Search probably should also be ignored. We send it to the app.
        NativeApp.keyUp(0, keyCode);
        return true;

      case KeyEvent.KEYCODE_DPAD_UP:
      case KeyEvent.KEYCODE_DPAD_DOWN:
      case KeyEvent.KEYCODE_DPAD_LEFT:
      case KeyEvent.KEYCODE_DPAD_RIGHT:
        // Joysticks are supported in Honeycomb MR1 and later via the onGenericMotionEvent method.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1
            && event.getSource() == InputDevice.SOURCE_JOYSTICK) {
          return super.onKeyUp(keyCode, event);
        }
        // Fall through
      default:
        // send the rest of the keys through.
        // TODO: get rid of the three special cases above by adjusting the native side of the code.
        // Log.d(TAG, "Key down: " + keyCode + ", KeyEvent: " + event);
        return NativeApp.keyUp(0, keyCode);
    }
  }
예제 #11
0
 private static int getMetaState(KeyEvent event) {
   return (event.isCtrlPressed() ? CTRL : 0)
       | (event.isAltPressed() ? ALT : 0)
       | (event.isShiftPressed() ? SHIFT : 0);
 }
예제 #12
0
  /**
   * This should be called from the Activity's onKeyDown() to handle keyboard shortcuts.
   *
   * <p>Note: onKeyDown() is called after the active view or web page has had a chance to handle the
   * key event. So the keys handled here *can* be overridden by any view or web page.
   *
   * @param event The KeyEvent to handle.
   * @param activity The ChromeActivity in which the key was pressed.
   * @param isCurrentTabVisible Whether page-related actions are valid, e.g. reload, zoom in. This
   *     should be false when in the tab switcher.
   * @param tabSwitchingEnabled Whether shortcuts that switch between tabs are enabled (e.g.
   *     Ctrl+Tab, Ctrl+3).
   * @return Whether the key event was handled.
   */
  public static boolean onKeyDown(
      KeyEvent event,
      ChromeActivity activity,
      boolean isCurrentTabVisible,
      boolean tabSwitchingEnabled) {
    int keyCode = event.getKeyCode();
    if (event.getRepeatCount() != 0 || KeyEvent.isModifierKey(keyCode)) return false;
    if (KeyEvent.isGamepadButton(keyCode)) {
      if (isGamepadAPIActive(activity)) return false;
    } else if (!event.isCtrlPressed()
        && !event.isAltPressed()
        && keyCode != KeyEvent.KEYCODE_F3
        && keyCode != KeyEvent.KEYCODE_F5
        && keyCode != KeyEvent.KEYCODE_F10
        && keyCode != KeyEvent.KEYCODE_FORWARD) {
      return false;
    }

    TabModel curModel = activity.getCurrentTabModel();
    int count = curModel.getCount();

    int metaState = getMetaState(event);
    int keyCodeAndMeta = keyCode | metaState;

    switch (keyCodeAndMeta) {
      case CTRL | SHIFT | KeyEvent.KEYCODE_T:
        activity.onMenuOrKeyboardAction(R.id.open_recently_closed_tab, false);
        return true;
      case CTRL | KeyEvent.KEYCODE_T:
        activity.onMenuOrKeyboardAction(
            curModel.isIncognito() ? R.id.new_incognito_tab_menu_id : R.id.new_tab_menu_id, false);
        return true;
      case CTRL | KeyEvent.KEYCODE_N:
        activity.onMenuOrKeyboardAction(R.id.new_tab_menu_id, false);
        return true;
      case CTRL | SHIFT | KeyEvent.KEYCODE_N:
        activity.onMenuOrKeyboardAction(R.id.new_incognito_tab_menu_id, false);
        return true;
        // Alt+E represents a special character ´ (latin code: &#180) in Android.
        // If an EditText or ContentView has focus, Alt+E will be swallowed by
        // the default dispatchKeyEvent and cannot open the menu.
      case ALT | KeyEvent.KEYCODE_E:
      case ALT | KeyEvent.KEYCODE_F:
      case KeyEvent.KEYCODE_F10:
      case KeyEvent.KEYCODE_BUTTON_Y:
        activity.onMenuOrKeyboardAction(R.id.show_menu, false);
        return true;
    }

    if (isCurrentTabVisible) {
      if (tabSwitchingEnabled && (metaState == CTRL || metaState == ALT)) {
        int numCode = keyCode - KeyEvent.KEYCODE_0;
        if (numCode > 0 && numCode <= Math.min(count, 8)) {
          // Ctrl+1 to Ctrl+8: select tab by index
          TabModelUtils.setIndex(curModel, numCode - 1);
          return true;
        } else if (numCode == 9 && count != 0) {
          // Ctrl+9: select last tab
          TabModelUtils.setIndex(curModel, count - 1);
          return true;
        }
      }

      switch (keyCodeAndMeta) {
        case CTRL | KeyEvent.KEYCODE_TAB:
        case CTRL | KeyEvent.KEYCODE_PAGE_DOWN:
        case KeyEvent.KEYCODE_BUTTON_R1:
          if (tabSwitchingEnabled && count > 1) {
            TabModelUtils.setIndex(curModel, (curModel.index() + 1) % count);
          }
          return true;
        case CTRL | SHIFT | KeyEvent.KEYCODE_TAB:
        case CTRL | KeyEvent.KEYCODE_PAGE_UP:
        case KeyEvent.KEYCODE_BUTTON_L1:
          if (tabSwitchingEnabled && count > 1) {
            TabModelUtils.setIndex(curModel, (curModel.index() + count - 1) % count);
          }
          return true;
        case CTRL | KeyEvent.KEYCODE_W:
        case CTRL | KeyEvent.KEYCODE_F4:
        case KeyEvent.KEYCODE_BUTTON_B:
          TabModelUtils.closeCurrentTab(curModel);
          return true;
        case CTRL | KeyEvent.KEYCODE_F:
        case CTRL | KeyEvent.KEYCODE_G:
        case CTRL | SHIFT | KeyEvent.KEYCODE_G:
        case KeyEvent.KEYCODE_F3:
        case SHIFT | KeyEvent.KEYCODE_F3:
          activity.onMenuOrKeyboardAction(R.id.find_in_page_id, false);
          return true;
        case CTRL | KeyEvent.KEYCODE_L:
        case ALT | KeyEvent.KEYCODE_D:
        case KeyEvent.KEYCODE_BUTTON_X:
          activity.onMenuOrKeyboardAction(R.id.focus_url_bar, false);
          return true;
        case CTRL | SHIFT | KeyEvent.KEYCODE_B:
          activity.onMenuOrKeyboardAction(R.id.all_bookmarks_menu_id, false);
          return true;
        case KeyEvent.KEYCODE_BOOKMARK:
        case CTRL | KeyEvent.KEYCODE_D:
          activity.onMenuOrKeyboardAction(R.id.bookmark_this_page_id, false);
          return true;
        case CTRL | KeyEvent.KEYCODE_H:
          activity.onMenuOrKeyboardAction(R.id.open_history_menu_id, false);
          return true;
        case CTRL | KeyEvent.KEYCODE_P:
          activity.onMenuOrKeyboardAction(R.id.print_id, false);
          return true;
        case CTRL | KeyEvent.KEYCODE_PLUS:
        case CTRL | KeyEvent.KEYCODE_EQUALS:
        case CTRL | SHIFT | KeyEvent.KEYCODE_PLUS:
        case CTRL | SHIFT | KeyEvent.KEYCODE_EQUALS:
        case KeyEvent.KEYCODE_ZOOM_IN:
          ContentViewCore cvc = activity.getCurrentContentViewCore();
          if (cvc != null) cvc.zoomIn();
          return true;
        case CTRL | KeyEvent.KEYCODE_MINUS:
        case KeyEvent.KEYCODE_ZOOM_OUT:
          cvc = activity.getCurrentContentViewCore();
          if (cvc != null) cvc.zoomOut();
          return true;
        case CTRL | KeyEvent.KEYCODE_0:
          cvc = activity.getCurrentContentViewCore();
          if (cvc != null) cvc.zoomReset();
          return true;
        case SHIFT | CTRL | KeyEvent.KEYCODE_R:
        case CTRL | KeyEvent.KEYCODE_R:
        case SHIFT | KeyEvent.KEYCODE_F5:
        case KeyEvent.KEYCODE_F5:
          Tab tab = activity.getActivityTab();
          if (tab != null) {
            if ((keyCodeAndMeta & SHIFT) == SHIFT) {
              tab.reloadIgnoringCache();
            } else {
              tab.reload();
            }

            if (activity.getToolbarManager() != null
                && tab.getWebContents() != null
                && tab.getWebContents().focusLocationBarByDefault()) {
              activity.getToolbarManager().revertLocationBarChanges();
            } else {
              tab.requestFocus();
            }
          }
          return true;
        case ALT | KeyEvent.KEYCODE_DPAD_LEFT:
          tab = activity.getActivityTab();
          if (tab != null && tab.canGoBack()) tab.goBack();
          return true;
        case ALT | KeyEvent.KEYCODE_DPAD_RIGHT:
        case KeyEvent.KEYCODE_FORWARD:
        case KeyEvent.KEYCODE_BUTTON_START:
          tab = activity.getActivityTab();
          if (tab != null && tab.canGoForward()) tab.goForward();
          return true;
        case CTRL | SHIFT | KeyEvent.KEYCODE_SLASH: // i.e. Ctrl+?
          activity.onMenuOrKeyboardAction(R.id.help_id, false);
          return true;
      }
    }

    return false;
  }
예제 #13
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);
    }
  }
  /**
   * Overrides default directional pad behavior:
   *
   * <ul>
   *   <li>Up/down: Increases/decreases text navigation granularity
   *   <li>Left/right: Moves to previous/next unit of text
   * </ul>
   *
   * <p>If one of the following conditions is met, default behavior is preserved:
   *
   * <ul>
   *   <li>No input connection available
   *   <li>Input view is hidden
   *   <li>Not currently editing text
   *   <li>Cannot move in the specified direction
   * </ul>
   */
  @Override
  public boolean onKeyUp(int keyCode, KeyEvent event) {
    if (mUserCommandHandler.onKeyUp(event)) {
      return true;
    }

    final AccessibleInputConnection aic = getCurrentInputConnection();
    if (aic == null || !aic.hasExtractedText()) {
      return super.onKeyUp(keyCode, event);
    }

    final KeyEvent downEvent = mPreviousDpadDownEvent;
    mPreviousDpadDownEvent = null;

    final KeyEvent metaDownEvent = mPreviousMetaDownEvent;
    mPreviousMetaDownEvent = null;

    if (downEvent != null) {
      boolean captureEvent = false;

      switch (downEvent.getKeyCode()) {
        case KeyEvent.KEYCODE_DPAD_LEFT:
          if (!event.isAltPressed()) {
            captureEvent = previousUnit(mGranularity, 1, event.isShiftPressed());
          } else {
            mWasUpDownPressed = true;
          }
          break;
        case KeyEvent.KEYCODE_DPAD_RIGHT:
          if (!event.isAltPressed()) {
            captureEvent = nextUnit(mGranularity, 1, event.isShiftPressed());
          } else {
            mWasUpDownPressed = true;
          }
          break;
        case KeyEvent.KEYCODE_DPAD_UP:
          if (event.isAltPressed()) {
            adjustGranularity(1);
            captureEvent = true;
          } else {
            mWasUpDownPressed = true;
          }
          break;
        case KeyEvent.KEYCODE_DPAD_DOWN:
          if (event.isAltPressed()) {
            adjustGranularity(-1);
            captureEvent = true;
          } else {
            mWasUpDownPressed = true;
          }
          break;
      }

      if (captureEvent) {
        return true;
      }
    }

    // If we didn't capture the meta event, attempt to send the previous
    // meta down event and then preserve default behavior.
    if (metaDownEvent != null) {
      if (!super.onKeyDown(metaDownEvent.getKeyCode(), metaDownEvent)) {
        aic.sendKeyEvent(metaDownEvent);
      }
    }

    // If we didn't capture the event, attempt to send the previous down
    // event and then preserve default behavior.
    if (downEvent != null) {
      if (!super.onKeyDown(downEvent.getKeyCode(), downEvent)) {
        aic.sendKeyEvent(downEvent);
      }
    }

    if (!super.onKeyUp(keyCode, event)) {
      aic.sendKeyEvent(event);
    }

    return true;
  }
예제 #15
0
  /**
   * Converts the {@link KeyEvent} into low-level events and sends them to the host as either
   * key-events or text-events. This contains some logic for handling some special keys, and avoids
   * sending a key-up event for a key that was previously injected as a text-event.
   */
  public boolean sendKeyEvent(KeyEvent event) {
    int keyCode = event.getKeyCode();
    boolean pressed = event.getAction() == KeyEvent.ACTION_DOWN;

    // 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) {
      mInjector.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};
      mInjector.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:
        mInjector.sendKeyEvent(0, KeyEvent.KEYCODE_SHIFT_LEFT, pressed);
        mInjector.sendKeyEvent(0, KeyEvent.KEYCODE_2, pressed);
        return true;

      case KeyEvent.KEYCODE_POUND:
        mInjector.sendKeyEvent(0, KeyEvent.KEYCODE_SHIFT_LEFT, pressed);
        mInjector.sendKeyEvent(0, KeyEvent.KEYCODE_3, pressed);
        return true;

      case KeyEvent.KEYCODE_STAR:
        mInjector.sendKeyEvent(0, KeyEvent.KEYCODE_SHIFT_LEFT, pressed);
        mInjector.sendKeyEvent(0, KeyEvent.KEYCODE_8, pressed);
        return true;

      case KeyEvent.KEYCODE_PLUS:
        mInjector.sendKeyEvent(0, KeyEvent.KEYCODE_SHIFT_LEFT, pressed);
        mInjector.sendKeyEvent(0, KeyEvent.KEYCODE_EQUALS, pressed);
        return true;

      default:
        // We try to send all other key codes to the host directly.
        return mInjector.sendKeyEvent(0, keyCode, pressed);
    }
  }
예제 #16
0
  @Override
  public boolean onKey(View v, int keyCode, android.view.KeyEvent e) {
    for (int i = 0, n = keyListeners.size(); i < n; i++)
      if (keyListeners.get(i).onKey(v, keyCode, e)) return true;

    synchronized (this) {
      KeyEvent event = null;

      if (e.getKeyCode() == android.view.KeyEvent.KEYCODE_UNKNOWN
          && e.getAction() == android.view.KeyEvent.ACTION_MULTIPLE) {
        String chars = e.getCharacters();
        for (int i = 0; i < chars.length(); i++) {
          event = usedKeyEvents.obtain();
          event.keyCode = 0;
          event.keyChar = chars.charAt(i);
          event.type = KeyEvent.KEY_TYPED;
          keyEvents.add(event);
        }
        return false;
      }

      char character = (char) e.getUnicodeChar();
      // Android doesn't report a unicode char for back space. hrm...
      if (keyCode == 67) character = '\b';

      switch (e.getAction()) {
        case android.view.KeyEvent.ACTION_DOWN:
          event = usedKeyEvents.obtain();
          event.keyChar = 0;
          event.keyCode = e.getKeyCode();
          event.type = KeyEvent.KEY_DOWN;

          // Xperia hack for circle key. gah...
          if (keyCode == android.view.KeyEvent.KEYCODE_BACK && e.isAltPressed()) {
            keyCode = Keys.BUTTON_CIRCLE;
            event.keyCode = keyCode;
          }

          keyEvents.add(event);
          keys.put(event.keyCode, null);
          break;
        case android.view.KeyEvent.ACTION_UP:
          event = usedKeyEvents.obtain();
          event.keyChar = 0;
          event.keyCode = e.getKeyCode();
          event.type = KeyEvent.KEY_UP;
          // Xperia hack for circle key. gah...
          if (keyCode == android.view.KeyEvent.KEYCODE_BACK && e.isAltPressed()) {
            keyCode = Keys.BUTTON_CIRCLE;
            event.keyCode = keyCode;
          }
          keyEvents.add(event);

          event = usedKeyEvents.obtain();
          event.keyChar = character;
          event.keyCode = 0;
          event.type = KeyEvent.KEY_TYPED;
          keyEvents.add(event);

          if (keyCode == Keys.BUTTON_CIRCLE) keys.remove(Keys.BUTTON_CIRCLE);
          else keys.remove(e.getKeyCode());
      }
      app.getGraphics().requestRendering();
    }

    // circle button on Xperia Play shouldn't need catchBack == true
    if (keyCode == Keys.BUTTON_CIRCLE) return true;
    if (catchBack && keyCode == android.view.KeyEvent.KEYCODE_BACK) return true;
    if (catchMenu && keyCode == android.view.KeyEvent.KEYCODE_MENU) return true;
    return false;
  }
예제 #17
0
  public boolean executeKeyEvent(KeyEvent var1) {
    boolean var4 = false;
    this.mTempRect.setEmpty();
    boolean var3;
    if (!this.canScroll()) {
      var3 = var4;
      if (this.isFocused()) {
        var3 = var4;
        if (var1.getKeyCode() != 4) {
          View var5 = this.findFocus();
          View var6 = var5;
          if (var5 == this) {
            var6 = null;
          }

          var6 = FocusFinder.getInstance().findNextFocus(this, var6, 130);
          var3 = var4;
          if (var6 != null) {
            var3 = var4;
            if (var6 != this) {
              var3 = var4;
              if (var6.requestFocus(130)) {
                var3 = true;
              }
            }
          }
        }
      }

      return var3;
    } else {
      var4 = false;
      var3 = var4;
      if (var1.getAction() == 0) {
        switch (var1.getKeyCode()) {
          case 19:
            if (!var1.isAltPressed()) {
              var3 = this.arrowScroll(33);
            } else {
              var3 = this.fullScroll(33);
            }
            break;
          case 20:
            if (!var1.isAltPressed()) {
              var3 = this.arrowScroll(130);
            } else {
              var3 = this.fullScroll(130);
            }
            break;
          case 62:
            short var2;
            if (var1.isShiftPressed()) {
              var2 = 33;
            } else {
              var2 = 130;
            }

            this.pageScroll(var2);
            var3 = var4;
            break;
          default:
            var3 = var4;
        }
      }

      return var3;
    }
  }