Merge "Remove unnecessary and harmful KeyboardState.onUpdateShiftState call"
commit
f6d26b27a0
|
@ -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) {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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() {}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in New Issue