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}.
@Override
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}.
@Override
public void hapticAndAudioFeedback(int code) {

View File

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

View File

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

View File

@ -54,7 +54,9 @@ public class KeyboardState {
public void startDoubleTapTimer();
public boolean isInDoubleTapTimeout();
public void cancelDoubleTapTimer();
public void startLongPressTimer(int code);
public void cancelLongPressTimer();
public void hapticAndAudioFeedback(int code);
}
@ -300,6 +302,8 @@ public class KeyboardState {
} else if (code == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
onPressSymbol();
} else {
mSwitchActions.cancelDoubleTapTimer();
mSwitchActions.cancelLongPressTimer();
mShiftKeyState.onOtherKeyPressed();
mSymbolKeyState.onOtherKeyPressed();
}
@ -348,7 +352,7 @@ public class KeyboardState {
// state. And mark as if shift key is released.
mShiftKeyState.onRelease();
} else {
// Shift key is long pressed while shift unloked state.
// Shift key is long pressed while shift unlocked state.
setShiftLocked(true);
}
mSwitchActions.hapticAndAudioFeedback(code);
@ -364,6 +368,11 @@ public class KeyboardState {
private void updateAlphabetShiftState(boolean autoCaps) {
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 (mShiftKeyState.isReleasing() && autoCaps) {
// 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;
import android.util.Log;
import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.keyboard.PointerTracker;
import java.util.Iterator;
import java.util.LinkedList;
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>();
public synchronized void add(PointerTracker tracker) {
@ -32,7 +38,11 @@ public class PointerTrackerQueue {
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)) {
return;
}
@ -54,6 +64,13 @@ public class PointerTrackerQueue {
}
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();
while (it.hasNext()) {
final PointerTracker t = it.next();
@ -79,8 +96,9 @@ public class PointerTrackerQueue {
for (final PointerTracker tracker : mQueue) {
if (sb.length() > 0)
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);
}
public void postUpdateShiftKeyState() {
public void postUpdateShiftState() {
removeMessages(MSG_UPDATE_SHIFT_STATE);
sendMessageDelayed(obtainMessage(MSG_UPDATE_SHIFT_STATE), mDelayUpdateShiftState);
}
@ -898,9 +898,10 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
resetComposingState(true /* alsoResetLastComposedWord */);
updateSuggestions();
}
mHandler.postUpdateShiftState();
}
mExpectingUpdateSelection = false;
mHandler.postUpdateShiftKeyState();
// 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
// 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();
// 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)) {
// 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.
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).
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;
}
@Override
public void cancelDoubleTapTimer() {
mIsInDoubleTapTimeout = false;
}
@Override
public boolean isInDoubleTapTimeout() {
return mIsInDoubleTapTimeout;
@ -134,6 +139,11 @@ public class MockKeyboardSwitcher implements KeyboardState.SwitchActions {
mLongPressTimeoutCode = code;
}
@Override
public void cancelLongPressTimer() {
mLongPressTimeoutCode = 0;
}
@Override
public void hapticAndAudioFeedback(int code) {
// Nothing to do.