From 1a6fba570260ca9f837e5a6874274f39a3c0a734 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Thu, 30 Dec 2010 16:51:36 +0900 Subject: [PATCH] Fix potential keyboard layout change bug Change-Id: I2518dd1d2ef4b77fe32bb1fed4e0c722f3d120c1 --- .../inputmethod/keyboard/PointerTracker.java | 37 ++++++++++++++----- .../keyboard/PointerTrackerKeyState.java | 4 -- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java index e9a3bf2c0..49f29f923 100644 --- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java +++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java @@ -65,6 +65,9 @@ public class PointerTracker { private final PointerTrackerKeyState mKeyState; + // true if keyboard layout has been changed. + private boolean mKeyboardLayoutHasBeenChanged; + // true if event is already translated to a key action (long press or mini-keyboard) private boolean mKeyAlreadyProcessed; @@ -122,10 +125,14 @@ public class PointerTracker { mListener = listener; } - private void callListenerOnPress(int primaryCode) { + // Returns true if keyboard has been changed by this callback. + private boolean callListenerOnPressAndCheckKeyboardLayoutChange(int primaryCode) { if (DEBUG_LISTENER) Log.d(TAG, "onPress : " + keyCodePrintable(primaryCode)); mListener.onPress(primaryCode); + final boolean keyboardLayoutHasBeenChanged = mKeyboardLayoutHasBeenChanged; + mKeyboardLayoutHasBeenChanged = false; + return keyboardLayoutHasBeenChanged; } private void callListenerOnCodeInput(int primaryCode, int[] keyCodes, int x, int y) { @@ -159,8 +166,8 @@ public class PointerTracker { mKeyboard = keyboard; mKeys = keys; mKeyHysteresisDistanceSquared = (int)(keyHysteresisDistance * keyHysteresisDistance); - // Update current key index because keyboard layout has been changed. - mKeyState.onSetKeyboard(); + // Mark that keyboard layout has been changed. + mKeyboardLayoutHasBeenChanged = true; } public boolean isInSlidingKeyInput() { @@ -296,14 +303,16 @@ public class PointerTracker { // from modifier key, or 3) this pointer is on mini-keyboard. mIsAllowedSlidingKeyInput = mConfigSlidingKeyInputEnabled || isModifierInternal(keyIndex) || mKeyDetector instanceof MiniKeyboardKeyDetector; + mKeyboardLayoutHasBeenChanged = false; mKeyAlreadyProcessed = false; mIsRepeatableKey = false; mIsInSlidingKeyInput = false; if (isValidKeyIndex(keyIndex)) { - callListenerOnPress(mKeys[keyIndex].mCode); - // This onPress call may have changed keyboard layout and have updated mKeyIndex. - // If that's the case, mKeyIndex has been updated in setKeyboard(). - keyIndex = mKeyState.getKeyIndex(); + // This onPress call may have changed keyboard layout. Those cases are detected at + // {@link #setKeyboard}. In those cases, we should update keyIndex according to the new + // keyboard layout. + if (callListenerOnPressAndCheckKeyboardLayoutChange(mKeys[keyIndex].mCode)) + keyIndex = mKeyState.onDownKey(x, y, eventTime); } if (isValidKeyIndex(keyIndex)) { if (mKeys[keyIndex].mRepeatable) { @@ -327,13 +336,17 @@ public class PointerTracker { // TODO: down-to-up filter, if (eventTime-downTime) is less than threshold, just ignore // this move event. Otherwise fire {@link onDownEventInternal} and continue. - final int keyIndex = keyState.onMoveKey(x, y); + int keyIndex = keyState.onMoveKey(x, y); final Key oldKey = getKey(keyState.getKeyIndex()); if (isValidKeyIndex(keyIndex)) { if (oldKey == null) { // The pointer has been slid in to the new key, but the finger was not on any keys. // In this case, we must call onPress() to notify that the new key is being pressed. - callListenerOnPress(getKey(keyIndex).mCode); + // This onPress call may have changed keyboard layout. Those cases are detected at + // {@link #setKeyboard}. In those cases, we should update keyIndex according to the + // new keyboard layout. + if (callListenerOnPressAndCheckKeyboardLayoutChange(getKey(keyIndex).mCode)) + keyIndex = keyState.onMoveKey(x, y); keyState.onMoveToNewKey(keyIndex, x, y); startLongPressTimer(keyIndex); } else if (!isMinorMoveBounce(x, y, keyIndex)) { @@ -344,7 +357,11 @@ public class PointerTracker { callListenerOnRelease(oldKey.mCode); mHandler.cancelLongPressTimers(); if (mIsAllowedSlidingKeyInput) { - callListenerOnPress(getKey(keyIndex).mCode); + // This onPress call may have changed keyboard layout. Those cases are detected + // at {@link #setKeyboard}. In those cases, we should update keyIndex according + // to the new keyboard layout. + if (callListenerOnPressAndCheckKeyboardLayoutChange(getKey(keyIndex).mCode)) + keyIndex = keyState.onMoveKey(x, y); keyState.onMoveToNewKey(keyIndex, x, y); startLongPressTimer(keyIndex); } else { diff --git a/java/src/com/android/inputmethod/keyboard/PointerTrackerKeyState.java b/java/src/com/android/inputmethod/keyboard/PointerTrackerKeyState.java index 8b969c70a..250bb95eb 100644 --- a/java/src/com/android/inputmethod/keyboard/PointerTrackerKeyState.java +++ b/java/src/com/android/inputmethod/keyboard/PointerTrackerKeyState.java @@ -106,8 +106,4 @@ package com.android.inputmethod.keyboard; mUpTime = eventTime; return onMoveKeyInternal(x, y); } - - public void onSetKeyboard() { - mKeyIndex = mKeyDetector.getKeyIndexAndNearbyCodes(mKeyX, mKeyY, null); - } }