/**
   * 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;
  }
 public boolean zoomIn() {
   ContentViewCore contentView = this.getContentViewCore();
   return contentView != null ? contentView.zoomIn() : false;
 }