private void showKeyPreviewAndUpdateKey(int keyIndex) {
   updateKey(keyIndex);
   // The modifier key, such as shift key, should not be shown as preview when multi-touch is
   // supported. On the other hand, if multi-touch is not supported, the modifier key should
   // be shown as preview.
   if (mHasDistinctMultitouch && isModifier()) {
     mProxy.showPreview(NOT_A_KEY, this);
   } else {
     mProxy.showPreview(keyIndex, this);
   }
 }
 public void updateKey(int keyIndex) {
   if (mKeyAlreadyProcessed) return;
   int oldKeyIndex = mPreviousKey;
   mPreviousKey = keyIndex;
   if (keyIndex != oldKeyIndex) {
     if (isValidKeyIndex(oldKeyIndex)) {
       // if new key index is not a key, old key was just released inside of the key.
       final boolean inside = (keyIndex == NOT_A_KEY);
       mKeys[oldKeyIndex].onReleased(inside);
       mProxy.invalidateKey(mKeys[oldKeyIndex]);
     }
     if (isValidKeyIndex(keyIndex)) {
       mKeys[keyIndex].onPressed();
       mProxy.invalidateKey(mKeys[keyIndex]);
     }
   }
 }
 public void onCancelEvent(int x, int y, long eventTime) {
   if (DEBUG) debugLog("onCancelEvt:", x, y);
   mHandler.cancelKeyTimers();
   mHandler.cancelPopupPreview();
   showKeyPreviewAndUpdateKey(NOT_A_KEY);
   mIsInSlidingKeyInput = false;
   int keyIndex = mKeyState.getKeyIndex();
   if (isValidKeyIndex(keyIndex)) mProxy.invalidateKey(mKeys[keyIndex]);
 }
 public PointerTracker(
     int id,
     UIHandler handler,
     KeyDetector keyDetector,
     UIProxy proxy,
     Resources res,
     boolean slideKeyHack) {
   if (proxy == null || handler == null || keyDetector == null) throw new NullPointerException();
   mPointerId = id;
   mProxy = proxy;
   mHandler = handler;
   mKeyDetector = keyDetector;
   mKeyboardSwitcher = KeyboardSwitcher.getInstance();
   mKeyState = new KeyState(keyDetector);
   mHasDistinctMultitouch = proxy.hasDistinctMultitouch();
   mDelayBeforeKeyRepeatStart = res.getInteger(R.integer.config_delay_before_key_repeat_start);
   mMultiTapKeyTimeout = res.getInteger(R.integer.config_multi_tap_key_timeout);
   sSlideKeyHack = slideKeyHack;
   resetMultiTap();
 }
  public void onUpEvent(int x, int y, long eventTime) {
    if (DEBUG) debugLog("onUpEvent  :", x, y);
    mHandler.cancelKeyTimers();
    mHandler.cancelPopupPreview();
    showKeyPreviewAndUpdateKey(NOT_A_KEY);
    mIsInSlidingKeyInput = false;
    sendSlideKeys();
    if (mKeyAlreadyProcessed) return;
    int keyIndex = mKeyState.onUpKey(x, y);
    if (isMinorMoveBounce(x, y, keyIndex)) {
      // Use previous fixed key index and coordinates.
      keyIndex = mKeyState.getKeyIndex();
      x = mKeyState.getKeyX();
      y = mKeyState.getKeyY();
    }
    if (!mIsRepeatableKey) {
      detectAndSendKey(keyIndex, x, y, eventTime);
    }

    if (isValidKeyIndex(keyIndex)) mProxy.invalidateKey(mKeys[keyIndex]);
  }