Merge "Remove unnecessary and harmful KeyboardState.onUpdateShiftState call"

main
Tadashi G. Takaoka 2012-02-16 18:37:59 -08:00 committed by Android (Google) Code Review
commit f6d26b27a0
9 changed files with 149 additions and 7 deletions

View File

@ -266,6 +266,16 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions,
} }
} }
// Implements {@link KeyboardState.SwitchActions}.
@Override
public void cancelDoubleTapTimer() {
final LatinKeyboardView keyboardView = getKeyboardView();
if (keyboardView != null) {
final TimerProxy timer = keyboardView.getTimerProxy();
timer.cancelDoubleTapTimer();
}
}
// Implements {@link KeyboardState.SwitchActions}. // Implements {@link KeyboardState.SwitchActions}.
@Override @Override
public boolean isInDoubleTapTimeout() { public boolean isInDoubleTapTimeout() {
@ -284,6 +294,16 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions,
} }
} }
// Implements {@link KeyboardState.SwitchActions}.
@Override
public void cancelLongPressTimer() {
final LatinKeyboardView keyboardView = getKeyboardView();
if (keyboardView != null) {
final TimerProxy timer = keyboardView.getTimerProxy();
timer.cancelLongPressTimer();
}
}
// Implements {@link KeyboardState.SwitchActions}. // Implements {@link KeyboardState.SwitchActions}.
@Override @Override
public void hapticAndAudioFeedback(int code) { public void hapticAndAudioFeedback(int code) {

View File

@ -232,6 +232,11 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
ViewConfiguration.getDoubleTapTimeout()); ViewConfiguration.getDoubleTapTimeout());
} }
@Override
public void cancelDoubleTapTimer() {
removeMessages(MSG_DOUBLE_TAP);
}
@Override @Override
public boolean isInDoubleTapTimeout() { public boolean isInDoubleTapTimeout() {
return hasMessages(MSG_DOUBLE_TAP); return hasMessages(MSG_DOUBLE_TAP);

View File

@ -77,6 +77,7 @@ public class PointerTracker {
public void startLongPressTimer(int code); public void startLongPressTimer(int code);
public void cancelLongPressTimer(); public void cancelLongPressTimer();
public void startDoubleTapTimer(); public void startDoubleTapTimer();
public void cancelDoubleTapTimer();
public boolean isInDoubleTapTimeout(); public boolean isInDoubleTapTimeout();
public void cancelKeyTimers(); public void cancelKeyTimers();
@ -96,6 +97,8 @@ public class PointerTracker {
@Override @Override
public void startDoubleTapTimer() {} public void startDoubleTapTimer() {}
@Override @Override
public void cancelDoubleTapTimer() {}
@Override
public boolean isInDoubleTapTimeout() { return false; } public boolean isInDoubleTapTimeout() { return false; }
@Override @Override
public void cancelKeyTimers() {} public void cancelKeyTimers() {}

View File

@ -54,7 +54,9 @@ public class KeyboardState {
public void startDoubleTapTimer(); public void startDoubleTapTimer();
public boolean isInDoubleTapTimeout(); public boolean isInDoubleTapTimeout();
public void cancelDoubleTapTimer();
public void startLongPressTimer(int code); public void startLongPressTimer(int code);
public void cancelLongPressTimer();
public void hapticAndAudioFeedback(int code); public void hapticAndAudioFeedback(int code);
} }
@ -300,6 +302,8 @@ public class KeyboardState {
} else if (code == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) { } else if (code == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
onPressSymbol(); onPressSymbol();
} else { } else {
mSwitchActions.cancelDoubleTapTimer();
mSwitchActions.cancelLongPressTimer();
mShiftKeyState.onOtherKeyPressed(); mShiftKeyState.onOtherKeyPressed();
mSymbolKeyState.onOtherKeyPressed(); mSymbolKeyState.onOtherKeyPressed();
} }
@ -348,7 +352,7 @@ public class KeyboardState {
// state. And mark as if shift key is released. // state. And mark as if shift key is released.
mShiftKeyState.onRelease(); mShiftKeyState.onRelease();
} else { } else {
// Shift key is long pressed while shift unloked state. // Shift key is long pressed while shift unlocked state.
setShiftLocked(true); setShiftLocked(true);
} }
mSwitchActions.hapticAndAudioFeedback(code); mSwitchActions.hapticAndAudioFeedback(code);
@ -364,6 +368,11 @@ public class KeyboardState {
private void updateAlphabetShiftState(boolean autoCaps) { private void updateAlphabetShiftState(boolean autoCaps) {
if (!mIsAlphabetMode) return; if (!mIsAlphabetMode) return;
if (!mShiftKeyState.isReleasing()) {
// Ignore update shift state event while the shift key is being pressed (including
// chording).
return;
}
if (!mAlphabetShiftState.isShiftLocked() && !mShiftKeyState.isIgnoring()) { if (!mAlphabetShiftState.isShiftLocked() && !mShiftKeyState.isIgnoring()) {
if (mShiftKeyState.isReleasing() && autoCaps) { if (mShiftKeyState.isReleasing() && autoCaps) {
// Only when shift key is releasing, automatic temporary upper case will be set. // Only when shift key is releasing, automatic temporary upper case will be set.

View File

@ -16,12 +16,18 @@
package com.android.inputmethod.keyboard.internal; package com.android.inputmethod.keyboard.internal;
import android.util.Log;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.PointerTracker; import com.android.inputmethod.keyboard.PointerTracker;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
public class PointerTrackerQueue { public class PointerTrackerQueue {
private static final String TAG = PointerTrackerQueue.class.getSimpleName();
private static final boolean DEBUG = false;
private final LinkedList<PointerTracker> mQueue = new LinkedList<PointerTracker>(); private final LinkedList<PointerTracker> mQueue = new LinkedList<PointerTracker>();
public synchronized void add(PointerTracker tracker) { public synchronized void add(PointerTracker tracker) {
@ -32,7 +38,11 @@ public class PointerTrackerQueue {
mQueue.remove(tracker); mQueue.remove(tracker);
} }
public synchronized void releaseAllPointersOlderThan(PointerTracker tracker, long eventTime) { public synchronized void releaseAllPointersOlderThan(PointerTracker tracker,
long eventTime) {
if (DEBUG) {
Log.d(TAG, "releaseAllPoniterOlderThan: [" + tracker.mPointerId + "] " + this);
}
if (!mQueue.contains(tracker)) { if (!mQueue.contains(tracker)) {
return; return;
} }
@ -54,6 +64,13 @@ public class PointerTrackerQueue {
} }
public synchronized void releaseAllPointersExcept(PointerTracker tracker, long eventTime) { public synchronized void releaseAllPointersExcept(PointerTracker tracker, long eventTime) {
if (DEBUG) {
if (tracker == null) {
Log.d(TAG, "releaseAllPoniters: " + this);
} else {
Log.d(TAG, "releaseAllPoniterExcept: [" + tracker.mPointerId + "] " + this);
}
}
final Iterator<PointerTracker> it = mQueue.iterator(); final Iterator<PointerTracker> it = mQueue.iterator();
while (it.hasNext()) { while (it.hasNext()) {
final PointerTracker t = it.next(); final PointerTracker t = it.next();
@ -79,8 +96,9 @@ public class PointerTrackerQueue {
for (final PointerTracker tracker : mQueue) { for (final PointerTracker tracker : mQueue) {
if (sb.length() > 0) if (sb.length() > 0)
sb.append(" "); sb.append(" ");
sb.append(tracker.mPointerId); sb.append("[" + tracker.mPointerId + " "
+ Keyboard.printableCode(tracker.getKey().mCode) + "]");
} }
return "[" + sb + "]"; return sb.toString();
} }
} }

View File

@ -325,7 +325,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
return hasMessages(MSG_UPDATE_SUGGESTIONS); return hasMessages(MSG_UPDATE_SUGGESTIONS);
} }
public void postUpdateShiftKeyState() { public void postUpdateShiftState() {
removeMessages(MSG_UPDATE_SHIFT_STATE); removeMessages(MSG_UPDATE_SHIFT_STATE);
sendMessageDelayed(obtainMessage(MSG_UPDATE_SHIFT_STATE), mDelayUpdateShiftState); sendMessageDelayed(obtainMessage(MSG_UPDATE_SHIFT_STATE), mDelayUpdateShiftState);
} }
@ -898,9 +898,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
resetComposingState(true /* alsoResetLastComposedWord */); resetComposingState(true /* alsoResetLastComposedWord */);
updateSuggestions(); updateSuggestions();
} }
mHandler.postUpdateShiftState();
} }
mExpectingUpdateSelection = false; mExpectingUpdateSelection = false;
mHandler.postUpdateShiftKeyState();
// TODO: Decide to call restartSuggestionsOnWordBeforeCursorIfAtEndOfWord() or not // TODO: Decide to call restartSuggestionsOnWordBeforeCursorIfAtEndOfWord() or not
// here. It would probably be too expensive to call directly here but we may want to post a // here. It would probably be too expensive to call directly here but we may want to post a
// message to delay it. The point would be to unify behavior between backspace to the // message to delay it. The point would be to unify behavior between backspace to the
@ -1391,7 +1392,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
mVoiceProxy.handleBackspace(); mVoiceProxy.handleBackspace();
// In many cases, we may have to put the keyboard in auto-shift state again. // In many cases, we may have to put the keyboard in auto-shift state again.
mHandler.postUpdateShiftKeyState(); mHandler.postUpdateShiftState();
if (mEnteredText != null && sameAsTextBeforeCursor(ic, mEnteredText)) { if (mEnteredText != null && sameAsTextBeforeCursor(ic, mEnteredText)) {
// Cancel multi-character input: remove the text we just entered. // Cancel multi-character input: remove the text we just entered.

View File

@ -227,4 +227,17 @@ public class KeyboardStateMultiTouchTests extends KeyboardStateTestsBase {
// Release "123?" key, switch back to alphabet. // Release "123?" key, switch back to alphabet.
releaseKey(CODE_SYMBOL, ALPHABET_UNSHIFTED); releaseKey(CODE_SYMBOL, ALPHABET_UNSHIFTED);
} }
// Chording letter key with shift key.
public void testChordingLetterAndShiftKey() {
// Press letter key and hold.
pressKey('z', ALPHABET_UNSHIFTED);
// Press shift key, {@link PointerTracker} will fire a phantom release letter key.
chordingReleaseKey('z', ALPHABET_UNSHIFTED);
chordingPressKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED);
// Press another letter key and hold.
chordingPressAndReleaseKey('J', ALPHABET_MANUAL_SHIFTED, ALPHABET_MANUAL_SHIFTED);
// Release shift key
releaseKey(CODE_SHIFT, ALPHABET_UNSHIFTED);
}
} }

View File

@ -687,4 +687,67 @@ public class KeyboardStateSingleTouchTests extends KeyboardStateTestsBase {
// Press/release "?123" key, enter symbols (not symbols shifted). // Press/release "?123" key, enter symbols (not symbols shifted).
pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED); pressAndReleaseKey(CODE_SYMBOL, SYMBOLS_UNSHIFTED, SYMBOLS_UNSHIFTED);
} }
// Rapidly type shift key.
public void testRapidShiftTyping() {
// Press/release shift key
pressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_MANUAL_SHIFTED);
// Rapidly press/release letter key.
secondPressAndReleaseKey('J', ALPHABET_MANUAL_SHIFTED, ALPHABET_UNSHIFTED);
// Rapidly press/release shift key.
secondPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_MANUAL_SHIFTED);
// Rapidly press/release letter key.
secondPressAndReleaseKey('J', ALPHABET_MANUAL_SHIFTED, ALPHABET_UNSHIFTED);
// Rapidly press/release shift key.
secondPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_MANUAL_SHIFTED);
// Rapidly press/release letter key.
secondPressAndReleaseKey('J', ALPHABET_MANUAL_SHIFTED, ALPHABET_UNSHIFTED);
// Press/release shift key to enter alphabet manual shifted.
pressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_MANUAL_SHIFTED);
// Press/release shift key
pressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_UNSHIFTED);
// Rapidly press/release letter key.
secondPressAndReleaseKey('j', ALPHABET_UNSHIFTED, ALPHABET_UNSHIFTED);
// Rapidly press/release shift key.
secondPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_MANUAL_SHIFTED);
// Rapidly press/release letter key.
secondPressAndReleaseKey('J', ALPHABET_MANUAL_SHIFTED, ALPHABET_UNSHIFTED);
// Rapidly press/release shift key.
secondPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_MANUAL_SHIFTED);
// Rapidly press/release letter key.
secondPressAndReleaseKey('J', ALPHABET_MANUAL_SHIFTED, ALPHABET_UNSHIFTED);
// Long press shift key to enter alphabet shift locked.
longPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_SHIFT_LOCKED);
// Press/release shift key
pressAndReleaseKey(CODE_SHIFT, ALPHABET_SHIFT_LOCK_SHIFTED, ALPHABET_UNSHIFTED);
// Rapidly press/release letter key.
secondPressAndReleaseKey('j', ALPHABET_UNSHIFTED, ALPHABET_UNSHIFTED);
// Rapidly press/release shift key.
secondPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_MANUAL_SHIFTED);
// Rapidly press/release letter key.
secondPressAndReleaseKey('J', ALPHABET_MANUAL_SHIFTED, ALPHABET_UNSHIFTED);
// Rapidly press/release shift key.
secondPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_MANUAL_SHIFTED);
// Rapidly press/release letter key.
secondPressAndReleaseKey('J', ALPHABET_MANUAL_SHIFTED, ALPHABET_UNSHIFTED);
// Set auto caps mode on.
setAutoCapsMode(AUTO_CAPS);
// Press/release auto caps trigger letter to enter alphabet automatic shifted.
pressAndReleaseKey(CODE_AUTO_CAPS_TRIGGER, ALPHABET_UNSHIFTED, ALPHABET_AUTOMATIC_SHIFTED);
// Press/release shift key
pressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_UNSHIFTED);
// Rapidly press/release letter key.
secondPressAndReleaseKey('j', ALPHABET_UNSHIFTED, ALPHABET_UNSHIFTED);
// Rapidly press/release shift key.
secondPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_MANUAL_SHIFTED);
// Rapidly press/release letter key.
secondPressAndReleaseKey('J', ALPHABET_MANUAL_SHIFTED, ALPHABET_UNSHIFTED);
// Rapidly press/release shift key.
secondPressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_MANUAL_SHIFTED);
// Rapidly press/release letter key.
secondPressAndReleaseKey('J', ALPHABET_MANUAL_SHIFTED, ALPHABET_UNSHIFTED);
}
} }

View File

@ -124,6 +124,11 @@ public class MockKeyboardSwitcher implements KeyboardState.SwitchActions {
mIsInDoubleTapTimeout = true; mIsInDoubleTapTimeout = true;
} }
@Override
public void cancelDoubleTapTimer() {
mIsInDoubleTapTimeout = false;
}
@Override @Override
public boolean isInDoubleTapTimeout() { public boolean isInDoubleTapTimeout() {
return mIsInDoubleTapTimeout; return mIsInDoubleTapTimeout;
@ -134,6 +139,11 @@ public class MockKeyboardSwitcher implements KeyboardState.SwitchActions {
mLongPressTimeoutCode = code; mLongPressTimeoutCode = code;
} }
@Override
public void cancelLongPressTimer() {
mLongPressTimeoutCode = 0;
}
@Override @Override
public void hapticAndAudioFeedback(int code) { public void hapticAndAudioFeedback(int code) {
// Nothing to do. // Nothing to do.