Fix double tap shift key enable/disable shift locked mode
Bug: 5942452 Change-Id: I2c7b1605bceac2b2f929cd4d97c417ef15c6f754
This commit is contained in:
parent
30964843db
commit
0ed2d3a449
7 changed files with 136 additions and 119 deletions
|
@ -27,6 +27,7 @@ import android.view.View;
|
|||
import android.view.inputmethod.EditorInfo;
|
||||
|
||||
import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
|
||||
import com.android.inputmethod.keyboard.PointerTracker.TimerProxy;
|
||||
import com.android.inputmethod.keyboard.internal.KeyboardState;
|
||||
import com.android.inputmethod.latin.DebugSettings;
|
||||
import com.android.inputmethod.latin.InputView;
|
||||
|
@ -270,6 +271,24 @@ public class KeyboardSwitcher implements KeyboardState.SwitchActions,
|
|||
mState.onUpdateShiftState(mInputMethodService.getCurrentAutoCapsState());
|
||||
}
|
||||
|
||||
// Implements {@link KeyboardState.SwitchActions}.
|
||||
@Override
|
||||
public void startDoubleTapTimer() {
|
||||
final LatinKeyboardView keyboardView = getKeyboardView();
|
||||
if (keyboardView != null) {
|
||||
final TimerProxy timer = keyboardView.getTimerProxy();
|
||||
timer.startDoubleTapTimer();
|
||||
}
|
||||
}
|
||||
|
||||
// Implements {@link KeyboardState.SwitchActions}.
|
||||
@Override
|
||||
public boolean isInDoubleTapTimeout() {
|
||||
final LatinKeyboardView keyboardView = getKeyboardView();
|
||||
return (keyboardView != null)
|
||||
? keyboardView.getTimerProxy().isInDoubleTapTimeout() : false;
|
||||
}
|
||||
|
||||
public boolean isInMomentarySwitchState() {
|
||||
return mState.isInMomentarySwitchState();
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ import android.os.Message;
|
|||
import android.text.TextUtils;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.GestureDetector;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
@ -64,8 +63,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
|
|||
SuddenJumpingTouchEventHandler.ProcessMotionEvent {
|
||||
private static final String TAG = LatinKeyboardView.class.getSimpleName();
|
||||
|
||||
private static final boolean ENABLE_CAPSLOCK_BY_DOUBLETAP = true;
|
||||
|
||||
// TODO: Kill process when the usability study mode was changed.
|
||||
private static final boolean ENABLE_USABILITY_STUDY_LOG = LatinImeLogger.sUsabilityStudy;
|
||||
|
||||
|
@ -111,16 +108,13 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
|
|||
private int mOldPointerCount = 1;
|
||||
private Key mOldKey;
|
||||
|
||||
// To detect double tap.
|
||||
protected GestureDetector mGestureDetector;
|
||||
|
||||
private final KeyTimerHandler mKeyTimerHandler;
|
||||
|
||||
private static class KeyTimerHandler extends StaticInnerHandlerWrapper<LatinKeyboardView>
|
||||
implements TimerProxy {
|
||||
private static final int MSG_REPEAT_KEY = 1;
|
||||
private static final int MSG_LONGPRESS_KEY = 2;
|
||||
private static final int MSG_IGNORE_DOUBLE_TAP = 3;
|
||||
private static final int MSG_DOUBLE_TAP = 3;
|
||||
private static final int MSG_KEY_TYPED = 4;
|
||||
|
||||
private final int mKeyRepeatInterval;
|
||||
|
@ -184,19 +178,20 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
|
|||
}
|
||||
|
||||
@Override
|
||||
public void cancelKeyTimers() {
|
||||
cancelKeyRepeatTimer();
|
||||
cancelLongPressTimer();
|
||||
removeMessages(MSG_IGNORE_DOUBLE_TAP);
|
||||
}
|
||||
|
||||
public void startIgnoringDoubleTap() {
|
||||
sendMessageDelayed(obtainMessage(MSG_IGNORE_DOUBLE_TAP),
|
||||
public void startDoubleTapTimer() {
|
||||
sendMessageDelayed(obtainMessage(MSG_DOUBLE_TAP),
|
||||
ViewConfiguration.getDoubleTapTimeout());
|
||||
}
|
||||
|
||||
public boolean isIgnoringDoubleTap() {
|
||||
return hasMessages(MSG_IGNORE_DOUBLE_TAP);
|
||||
@Override
|
||||
public boolean isInDoubleTapTimeout() {
|
||||
return hasMessages(MSG_DOUBLE_TAP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelKeyTimers() {
|
||||
cancelKeyRepeatTimer();
|
||||
cancelLongPressTimer();
|
||||
}
|
||||
|
||||
public void cancelAllMessages() {
|
||||
|
@ -204,53 +199,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
|
|||
}
|
||||
}
|
||||
|
||||
class DoubleTapListener extends GestureDetector.SimpleOnGestureListener {
|
||||
private boolean mProcessingShiftDoubleTapEvent = false;
|
||||
|
||||
@Override
|
||||
public boolean onDoubleTap(MotionEvent firstDown) {
|
||||
final Keyboard keyboard = getKeyboard();
|
||||
if (ENABLE_CAPSLOCK_BY_DOUBLETAP && keyboard.mId.isAlphabetKeyboard()) {
|
||||
final int pointerIndex = firstDown.getActionIndex();
|
||||
final int id = firstDown.getPointerId(pointerIndex);
|
||||
final PointerTracker tracker = PointerTracker.getPointerTracker(
|
||||
id, LatinKeyboardView.this);
|
||||
final Key key = tracker.getKeyOn((int)firstDown.getX(), (int)firstDown.getY());
|
||||
// If the first down event is on shift key.
|
||||
if (key != null && key.isShift()) {
|
||||
mProcessingShiftDoubleTapEvent = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
mProcessingShiftDoubleTapEvent = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDoubleTapEvent(MotionEvent secondTap) {
|
||||
if (mProcessingShiftDoubleTapEvent
|
||||
&& secondTap.getAction() == MotionEvent.ACTION_DOWN) {
|
||||
final MotionEvent secondDown = secondTap;
|
||||
final int pointerIndex = secondDown.getActionIndex();
|
||||
final int id = secondDown.getPointerId(pointerIndex);
|
||||
final PointerTracker tracker = PointerTracker.getPointerTracker(
|
||||
id, LatinKeyboardView.this);
|
||||
final Key key = tracker.getKeyOn((int)secondDown.getX(), (int)secondDown.getY());
|
||||
// If the second down event is also on shift key.
|
||||
if (key != null && key.isShift()) {
|
||||
// Detected a double tap on shift key. If we are in the ignoring double tap
|
||||
// mode, it means we have already turned off caps lock in
|
||||
// {@link KeyboardSwitcher#onReleaseShift} .
|
||||
onDoubleTapShiftKey(mKeyTimerHandler.isIgnoringDoubleTap());
|
||||
return true;
|
||||
}
|
||||
// Otherwise these events should not be handled as double tap.
|
||||
mProcessingShiftDoubleTapEvent = false;
|
||||
}
|
||||
return mProcessingShiftDoubleTapEvent;
|
||||
}
|
||||
}
|
||||
|
||||
public static class PointerTrackerParams {
|
||||
public final boolean mSlidingKeyInputEnabled;
|
||||
public final int mKeyRepeatStartTimeout;
|
||||
|
@ -303,11 +251,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
|
|||
|
||||
mTouchScreenRegulator = new SuddenJumpingTouchEventHandler(getContext(), this);
|
||||
|
||||
final boolean ignoreMultitouch = true;
|
||||
mGestureDetector = new GestureDetector(
|
||||
getContext(), new DoubleTapListener(), null, ignoreMultitouch);
|
||||
mGestureDetector.setIsLongpressEnabled(false);
|
||||
|
||||
mHasDistinctMultitouch = context.getPackageManager()
|
||||
.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT);
|
||||
|
||||
|
@ -342,11 +285,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
|
|||
PointerTracker.setParameters(mPointerTrackerParams);
|
||||
}
|
||||
|
||||
public void startIgnoringDoubleTap() {
|
||||
if (ENABLE_CAPSLOCK_BY_DOUBLETAP)
|
||||
mKeyTimerHandler.startIgnoringDoubleTap();
|
||||
}
|
||||
|
||||
public void setKeyboardActionListener(KeyboardActionListener listener) {
|
||||
mKeyboardActionListener = listener;
|
||||
PointerTracker.setKeyboardActionListener(listener);
|
||||
|
@ -451,17 +389,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
|
|||
return onLongPress(parentKey, tracker);
|
||||
}
|
||||
|
||||
private void onDoubleTapShiftKey(final boolean ignore) {
|
||||
// When shift key is double tapped, the first tap is correctly processed as usual tap. And
|
||||
// the second tap is treated as this double tap event, so that we need not mark tracker
|
||||
// calling setAlreadyProcessed() nor remove the tracker from mPointerQueue.
|
||||
if (ignore) {
|
||||
invokeCustomRequest(LatinIME.CODE_HAPTIC_AND_AUDIO_FEEDBACK);
|
||||
} else {
|
||||
invokeCodeInput(Keyboard.CODE_CAPSLOCK);
|
||||
}
|
||||
}
|
||||
|
||||
// This default implementation returns a more keys panel.
|
||||
protected MoreKeysPanel onCreateMoreKeysPanel(Key parentKey) {
|
||||
if (parentKey.mMoreKeys == null)
|
||||
|
@ -595,14 +522,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
|
|||
return true;
|
||||
}
|
||||
|
||||
// Gesture detector must be enabled only when mini-keyboard is not on the screen.
|
||||
if (mMoreKeysPanel == null && mGestureDetector != null
|
||||
&& mGestureDetector.onTouchEvent(me)) {
|
||||
PointerTracker.dismissAllKeyPreviews();
|
||||
mKeyTimerHandler.cancelKeyTimers();
|
||||
return true;
|
||||
}
|
||||
|
||||
final long eventTime = me.getEventTime();
|
||||
final int index = me.getActionIndex();
|
||||
final int id = me.getPointerId(index);
|
||||
|
|
|
@ -76,6 +76,8 @@ public class PointerTracker {
|
|||
public void startKeyRepeatTimer(long delay, PointerTracker tracker);
|
||||
public void startLongPressTimer(long delay, PointerTracker tracker);
|
||||
public void cancelLongPressTimer();
|
||||
public void startDoubleTapTimer();
|
||||
public boolean isInDoubleTapTimeout();
|
||||
public void cancelKeyTimers();
|
||||
|
||||
public static class Adapter implements TimerProxy {
|
||||
|
@ -90,6 +92,10 @@ public class PointerTracker {
|
|||
@Override
|
||||
public void cancelLongPressTimer() {}
|
||||
@Override
|
||||
public void startDoubleTapTimer() {}
|
||||
@Override
|
||||
public boolean isInDoubleTapTimeout() { return false; }
|
||||
@Override
|
||||
public void cancelKeyTimers() {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,6 +51,9 @@ public class KeyboardState {
|
|||
* Request to call back {@link KeyboardState#onUpdateShiftState(boolean)}.
|
||||
*/
|
||||
public void requestUpdatingShiftState();
|
||||
|
||||
public void startDoubleTapTimer();
|
||||
public boolean isInDoubleTapTimeout();
|
||||
}
|
||||
|
||||
private final SwitchActions mSwitchActions;
|
||||
|
@ -75,6 +78,10 @@ public class KeyboardState {
|
|||
private boolean mPrevMainKeyboardWasShiftLocked;
|
||||
private boolean mPrevSymbolsKeyboardWasShifted;
|
||||
|
||||
// For handling double tap.
|
||||
private boolean mIsInAlphabetUnshiftedFromShifted;
|
||||
private boolean mIsInDoubleTapShiftKey;
|
||||
|
||||
private final SavedKeyboardState mSavedKeyboardState = new SavedKeyboardState();
|
||||
|
||||
static class SavedKeyboardState {
|
||||
|
@ -256,8 +263,7 @@ public class KeyboardState {
|
|||
mSwitchActions.requestUpdatingShiftState();
|
||||
}
|
||||
|
||||
// TODO: Make this method private
|
||||
public void setSymbolsKeyboard() {
|
||||
private void setSymbolsKeyboard() {
|
||||
if (DEBUG_ACTION) {
|
||||
Log.d(TAG, "setSymbolsKeyboard");
|
||||
}
|
||||
|
@ -348,22 +354,35 @@ public class KeyboardState {
|
|||
|
||||
private void onPressShift() {
|
||||
if (mIsAlphabetMode) {
|
||||
if (mAlphabetShiftState.isShiftLocked()) {
|
||||
// Shift key is pressed while caps lock state, we will treat this state as shifted
|
||||
// caps lock state and mark as if shift key pressed while normal state.
|
||||
mIsInDoubleTapShiftKey = mSwitchActions.isInDoubleTapTimeout();
|
||||
if (!mIsInDoubleTapShiftKey) {
|
||||
// This is first tap.
|
||||
mSwitchActions.startDoubleTapTimer();
|
||||
}
|
||||
if (mIsInDoubleTapShiftKey) {
|
||||
if (mAlphabetShiftState.isManualShifted() || mIsInAlphabetUnshiftedFromShifted) {
|
||||
// Shift key has been double tapped while in manual shifted or automatic
|
||||
// shifted state.
|
||||
setShiftLocked(true);
|
||||
} else {
|
||||
// Shift key has been double tapped while in normal state. This is the second
|
||||
// tap to disable shift locked state, so just ignore this.
|
||||
}
|
||||
} else if (mAlphabetShiftState.isShiftLocked()) {
|
||||
// Shift key is pressed while shift locked state, we will treat this state as
|
||||
// shift lock shifted state and mark as if shift key pressed while normal state.
|
||||
setShifted(SHIFT_LOCK_SHIFTED);
|
||||
mShiftKeyState.onPress();
|
||||
} else if (mAlphabetShiftState.isAutomaticShifted()) {
|
||||
// Shift key is pressed while automatic temporary upper case, we have to move to
|
||||
// manual temporary upper case.
|
||||
// Shift key is pressed while automatic shifted, we have to move to manual shifted.
|
||||
setShifted(MANUAL_SHIFT);
|
||||
mShiftKeyState.onPress();
|
||||
} else if (mAlphabetShiftState.isShiftedOrShiftLocked()) {
|
||||
// In manual upper case state, we just record shift key has been pressing while
|
||||
// In manual shifted state, we just record shift key has been pressing while
|
||||
// shifted state.
|
||||
mShiftKeyState.onPressOnShifted();
|
||||
} else {
|
||||
// In base layout, chording or manual temporary upper case mode is started.
|
||||
// In base layout, chording or manual shifted mode is started.
|
||||
setShifted(MANUAL_SHIFT);
|
||||
mShiftKeyState.onPress();
|
||||
}
|
||||
|
@ -378,33 +397,40 @@ public class KeyboardState {
|
|||
private void onReleaseShift(boolean withSliding) {
|
||||
if (mIsAlphabetMode) {
|
||||
final boolean isShiftLocked = mAlphabetShiftState.isShiftLocked();
|
||||
if (mShiftKeyState.isChording()) {
|
||||
mIsInAlphabetUnshiftedFromShifted = false;
|
||||
if (mIsInDoubleTapShiftKey) {
|
||||
// Double tap shift key has been handled in {@link #onPressShift}, so that just
|
||||
// ignore this release shift key here.
|
||||
mIsInDoubleTapShiftKey = false;
|
||||
} else if (mShiftKeyState.isChording()) {
|
||||
if (mAlphabetShiftState.isShiftLockShifted()) {
|
||||
// After chording input while caps lock state.
|
||||
// After chording input while shift locked state.
|
||||
setShiftLocked(true);
|
||||
} else {
|
||||
// After chording input while normal state.
|
||||
setShifted(UNSHIFT);
|
||||
}
|
||||
} else if (mAlphabetShiftState.isShiftLockShifted() && withSliding) {
|
||||
// In caps lock state, shift has been pressed and slid out to other key.
|
||||
// In shift locked state, shift has been pressed and slid out to other key.
|
||||
setShiftLocked(true);
|
||||
} else if (isShiftLocked && !mAlphabetShiftState.isShiftLockShifted()
|
||||
&& (mShiftKeyState.isPressing() || mShiftKeyState.isPressingOnShifted())
|
||||
&& !withSliding) {
|
||||
// Shift has been long pressed, ignore this release.
|
||||
} else if (isShiftLocked && !mShiftKeyState.isIgnoring() && !withSliding) {
|
||||
// Shift has been pressed without chording while caps lock state.
|
||||
// Shift has been pressed without chording while shift locked state.
|
||||
setShiftLocked(false);
|
||||
} else if (mAlphabetShiftState.isShiftedOrShiftLocked()
|
||||
&& mShiftKeyState.isPressingOnShifted() && !withSliding) {
|
||||
// Shift has been pressed without chording while shifted state.
|
||||
setShifted(UNSHIFT);
|
||||
mIsInAlphabetUnshiftedFromShifted = true;
|
||||
} else if (mAlphabetShiftState.isManualShiftedFromAutomaticShifted()
|
||||
&& mShiftKeyState.isPressing() && !withSliding) {
|
||||
// Shift has been pressed without chording while manual temporary upper case
|
||||
// transited from automatic temporary upper case.
|
||||
// Shift has been pressed without chording while manual shifted transited from
|
||||
// automatic shifted
|
||||
setShifted(UNSHIFT);
|
||||
mIsInAlphabetUnshiftedFromShifted = true;
|
||||
}
|
||||
} else {
|
||||
// In symbol mode, switch back to the previous keyboard mode if the user chords the
|
||||
|
@ -455,10 +481,11 @@ public class KeyboardState {
|
|||
if (mIsAlphabetMode && code == Keyboard.CODE_CAPSLOCK) {
|
||||
if (mAlphabetShiftState.isShiftLocked()) {
|
||||
setShiftLocked(false);
|
||||
// Shift key is long pressed or double tapped while caps lock state, we will
|
||||
// toggle back to normal state. And mark as if shift key is released.
|
||||
// Shift key is long pressed while shift locked state, we will toggle back to normal
|
||||
// state. And mark as if shift key is released.
|
||||
mShiftKeyState.onRelease();
|
||||
} else {
|
||||
// Shift key is long pressed while shift unloked state.
|
||||
setShiftLocked(true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -256,18 +256,44 @@ public class KeyboardStateSingleTouchTests extends KeyboardStateTestsBase {
|
|||
}
|
||||
|
||||
// Double tap shift key.
|
||||
// TODO: Move double tap recognizing timer/logic into KeyboardState.
|
||||
public void testDoubleTapShift() {
|
||||
// First shift key tap.
|
||||
pressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_MANUAL_SHIFTED);
|
||||
// Second shift key tap.
|
||||
// Double tap recognized in LatinKeyboardView.KeyTimerHandler.
|
||||
secondTapShiftKey(ALPHABET_SHIFT_LOCKED);
|
||||
secondPressAndReleaseKey(CODE_SHIFT, ALPHABET_SHIFT_LOCKED, ALPHABET_SHIFT_LOCKED);
|
||||
|
||||
// First shift key tap.
|
||||
pressAndReleaseKey(CODE_SHIFT, ALPHABET_SHIFT_LOCK_SHIFTED, ALPHABET_UNSHIFTED);
|
||||
// Second shift key tap.
|
||||
// Second tap is ignored in LatinKeyboardView.KeyTimerHandler.
|
||||
secondPressAndReleaseKey(CODE_SHIFT, ALPHABET_UNSHIFTED, ALPHABET_UNSHIFTED);
|
||||
|
||||
// Press/release shift key, enter alphabet manual shifted.
|
||||
pressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_MANUAL_SHIFTED);
|
||||
|
||||
// First shift key tap.
|
||||
pressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_UNSHIFTED);
|
||||
// Second shift key tap.
|
||||
secondPressAndReleaseKey(CODE_SHIFT, ALPHABET_SHIFT_LOCKED, ALPHABET_SHIFT_LOCKED);
|
||||
|
||||
// First shift key tap.
|
||||
pressAndReleaseKey(CODE_SHIFT, ALPHABET_SHIFT_LOCK_SHIFTED, ALPHABET_UNSHIFTED);
|
||||
// Second shift key tap.
|
||||
secondPressAndReleaseKey(CODE_SHIFT, ALPHABET_UNSHIFTED, ALPHABET_UNSHIFTED);
|
||||
|
||||
// Set auto caps mode on.
|
||||
setAutoCapsMode(AUTO_CAPS);
|
||||
// Load keyboard, should be in automatic shifted.
|
||||
loadKeyboard(ALPHABET_AUTOMATIC_SHIFTED);
|
||||
|
||||
// First shift key tap.
|
||||
pressAndReleaseKey(CODE_SHIFT, ALPHABET_MANUAL_SHIFTED, ALPHABET_UNSHIFTED);
|
||||
// Second shift key tap.
|
||||
secondPressAndReleaseKey(CODE_SHIFT, ALPHABET_SHIFT_LOCKED, ALPHABET_SHIFT_LOCKED);
|
||||
|
||||
// First shift key tap.
|
||||
pressAndReleaseKey(CODE_SHIFT, ALPHABET_SHIFT_LOCK_SHIFTED, ALPHABET_UNSHIFTED);
|
||||
// Second shift key tap.
|
||||
secondPressAndReleaseKey(CODE_SHIFT, ALPHABET_UNSHIFTED, ALPHABET_UNSHIFTED);
|
||||
}
|
||||
|
||||
// Update shift state.
|
||||
|
|
|
@ -64,11 +64,16 @@ public class KeyboardStateTestsBase extends AndroidTestCase
|
|||
assertLayout(afterRotate, mSwitcher.getLayoutId());
|
||||
}
|
||||
|
||||
public void pressKey(int code, int afterPress) {
|
||||
private void pressKeyWithoutTimerExpire(int code, int afterPress) {
|
||||
mSwitcher.onPressKey(code);
|
||||
assertLayout(afterPress, mSwitcher.getLayoutId());
|
||||
}
|
||||
|
||||
public void pressKey(int code, int afterPress) {
|
||||
mSwitcher.expireDoubleTapTimeout();
|
||||
pressKeyWithoutTimerExpire(code, afterPress);
|
||||
}
|
||||
|
||||
public void releaseKey(int code, int afterRelease) {
|
||||
mSwitcher.onCodeInput(code, SINGLE);
|
||||
mSwitcher.onReleaseKey(code, NOT_SLIDING);
|
||||
|
@ -112,8 +117,8 @@ public class KeyboardStateTestsBase extends AndroidTestCase
|
|||
assertLayout(afterLongPress, mSwitcher.getLayoutId());
|
||||
}
|
||||
|
||||
public void secondTapShiftKey(int afterTap) {
|
||||
mSwitcher.onCodeInput(CODE_CAPSLOCK, SINGLE);
|
||||
assertLayout(afterTap, mSwitcher.getLayoutId());
|
||||
public void secondPressAndReleaseKey(int code, int afterPress, int afterRelease) {
|
||||
pressKeyWithoutTimerExpire(code, afterPress);
|
||||
releaseKey(code, afterRelease);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
package com.android.inputmethod.keyboard.internal;
|
||||
|
||||
import com.android.inputmethod.keyboard.Keyboard;
|
||||
import com.android.inputmethod.keyboard.internal.KeyboardState.SwitchActions;
|
||||
|
||||
public class MockKeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||
public interface Constants {
|
||||
|
@ -51,6 +50,8 @@ public class MockKeyboardSwitcher implements KeyboardState.SwitchActions {
|
|||
// Following InputConnection's behavior. Simulating InputType.TYPE_TEXT_FLAG_CAP_WORDS.
|
||||
private boolean mAutoCapsState = true;
|
||||
|
||||
private boolean mIsInDoubleTapTimeout;
|
||||
|
||||
private final KeyboardState mState = new KeyboardState(this);
|
||||
|
||||
public int getLayoutId() {
|
||||
|
@ -74,6 +75,10 @@ public class MockKeyboardSwitcher implements KeyboardState.SwitchActions {
|
|||
mAutoCapsMode = autoCaps;
|
||||
}
|
||||
|
||||
public void expireDoubleTapTimeout() {
|
||||
mIsInDoubleTapTimeout = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAlphabetKeyboard() {
|
||||
mLayout = Constants.ALPHABET_UNSHIFTED;
|
||||
|
@ -114,6 +119,16 @@ public class MockKeyboardSwitcher implements KeyboardState.SwitchActions {
|
|||
mState.onUpdateShiftState(mAutoCapsMode && mAutoCapsState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startDoubleTapTimer() {
|
||||
mIsInDoubleTapTimeout = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInDoubleTapTimeout() {
|
||||
return mIsInDoubleTapTimeout;
|
||||
}
|
||||
|
||||
public void updateShiftState() {
|
||||
mState.onUpdateShiftState(mAutoCapsMode && mAutoCapsState);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue