aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/keyboard/PointerTracker.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android/inputmethod/keyboard/PointerTracker.java')
-rw-r--r--java/src/com/android/inputmethod/keyboard/PointerTracker.java117
1 files changed, 74 insertions, 43 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index 91c4319e7..174239325 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -25,6 +25,7 @@ import com.android.inputmethod.accessibility.AccessibilityUtils;
import com.android.inputmethod.keyboard.internal.GestureStroke;
import com.android.inputmethod.keyboard.internal.GestureStroke.GestureStrokeParams;
import com.android.inputmethod.keyboard.internal.GestureStrokeWithPreviewPoints;
+import com.android.inputmethod.keyboard.internal.GestureStrokeWithPreviewPoints.GestureStrokePreviewParams;
import com.android.inputmethod.keyboard.internal.PointerTrackerQueue;
import com.android.inputmethod.latin.CollectionUtils;
import com.android.inputmethod.latin.Constants;
@@ -83,7 +84,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
public void dismissKeyPreview(PointerTracker tracker);
public void showSlidingKeyInputPreview(PointerTracker tracker);
public void dismissSlidingKeyInputPreview();
- public void showGesturePreviewTrail(PointerTracker tracker);
+ public void showGestureTrail(PointerTracker tracker);
}
public interface TimerProxy {
@@ -161,6 +162,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
// Parameters for pointer handling.
private static PointerTrackerParams sParams;
private static GestureStrokeParams sGestureStrokeParams;
+ private static GestureStrokePreviewParams sGesturePreviewParams;
private static boolean sNeedsPhantomSuddenMoveEventHack;
// Move this threshold to resource.
// TODO: Device specific parameter would be better for device specific hack?
@@ -176,7 +178,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
private DrawingProxy mDrawingProxy;
private TimerProxy mTimerProxy;
private KeyDetector mKeyDetector;
- private KeyboardActionListener mListener = EMPTY_LISTENER;
+ private KeyboardActionListener mListener = KeyboardActionListener.Adapter.EMPTY_LISTENER;
private Keyboard mKeyboard;
private int mPhantonSuddenMoveThreshold;
@@ -318,8 +320,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
// true if keyboard layout has been changed.
private boolean mKeyboardLayoutHasBeenChanged;
- // true if this pointer is no longer tracking touch event.
- private boolean mIsTrackingCanceled;
+ // true if this pointer is no longer triggering any action because it has been canceled.
+ private boolean mIsTrackingForActionDisabled;
// the more keys panel currently being shown. equals null if no panel is active.
private MoreKeysPanel mMoreKeysPanel;
@@ -333,22 +335,20 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
// true if a sliding key input is allowed.
private boolean mIsAllowedSlidingKeyInput;
- // Empty {@link KeyboardActionListener}
- private static final KeyboardActionListener EMPTY_LISTENER =
- new KeyboardActionListener.Adapter();
-
private final GestureStrokeWithPreviewPoints mGestureStrokeWithPreviewPoints;
public static void init(final boolean needsPhantomSuddenMoveEventHack) {
sNeedsPhantomSuddenMoveEventHack = needsPhantomSuddenMoveEventHack;
sParams = PointerTrackerParams.DEFAULT;
sGestureStrokeParams = GestureStrokeParams.DEFAULT;
+ sGesturePreviewParams = GestureStrokePreviewParams.DEFAULT;
sTimeRecorder = new TimeRecorder(sParams, sGestureStrokeParams);
}
public static void setParameters(final TypedArray mainKeyboardViewAttr) {
sParams = new PointerTrackerParams(mainKeyboardViewAttr);
sGestureStrokeParams = new GestureStrokeParams(mainKeyboardViewAttr);
+ sGesturePreviewParams = new GestureStrokePreviewParams(mainKeyboardViewAttr);
sTimeRecorder = new TimeRecorder(sParams, sGestureStrokeParams);
}
@@ -432,7 +432,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
}
mPointerId = id;
mGestureStrokeWithPreviewPoints = new GestureStrokeWithPreviewPoints(
- id, sGestureStrokeParams);
+ id, sGestureStrokeParams, sGesturePreviewParams);
setKeyDetectorInner(handler.getKeyDetector());
mListener = handler.getKeyboardActionListener();
mDrawingProxy = handler.getDrawingProxy();
@@ -441,7 +441,11 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
// Returns true if keyboard has been changed by this callback.
private boolean callListenerOnPressAndCheckKeyboardLayoutChange(final Key key) {
- if (sInGesture || mIsDetectingGesture) {
+ // While gesture input is going on, this method should be a no-operation. But when gesture
+ // input has been canceled, <code>sInGesture</code> and <code>mIsDetectingGesture</code>
+ // are set to false. To keep this method is a no-operation,
+ // <code>mIsTrackingForActionDisabled</code> should also be taken account of.
+ if (sInGesture || mIsDetectingGesture || mIsTrackingForActionDisabled) {
return false;
}
final boolean ignoreModifierKey = mIsInSlidingKeyInput && key.isModifier();
@@ -455,7 +459,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
return false;
}
if (key.isEnabled()) {
- mListener.onPressKey(key.mCode);
+ mListener.onPressKey(key.mCode, getActivePointerTrackerCount() == 1);
final boolean keyboardLayoutHasBeenChanged = mKeyboardLayoutHasBeenChanged;
mKeyboardLayoutHasBeenChanged = false;
mTimerProxy.startTypingStateTimer(key);
@@ -500,7 +504,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
// primaryCode is different from {@link Key#mCode}.
private void callListenerOnRelease(final Key key, final int primaryCode,
final boolean withSliding) {
- if (sInGesture || mIsDetectingGesture) {
+ // See the comment at {@link #callListenerOnPressAndCheckKeyboardLayoutChange(Key}}.
+ if (sInGesture || mIsDetectingGesture || mIsTrackingForActionDisabled) {
return;
}
final boolean ignoreModifierKey = mIsInSlidingKeyInput && key.isModifier();
@@ -522,6 +527,13 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
}
}
+ private void callListenerOnFinishSlidingInput() {
+ if (DEBUG_LISTENER) {
+ Log.d(TAG, String.format("[%d] onFinishSlidingInput", mPointerId));
+ }
+ mListener.onFinishSlidingInput();
+ }
+
private void callListenerOnCancelInput() {
if (DEBUG_LISTENER) {
Log.d(TAG, String.format("[%d] onCancelInput", mPointerId));
@@ -732,7 +744,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
dismissAllMoreKeysPanels();
}
mTimerProxy.cancelLongPressTimer();
- mDrawingProxy.showGesturePreviewTrail(this);
+ mDrawingProxy.showGestureTrail(this);
}
public void updateBatchInputByTimer(final long eventTime) {
@@ -745,10 +757,10 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
if (key != null) {
updateBatchInput(eventTime);
}
- if (mIsTrackingCanceled) {
+ if (mIsTrackingForActionDisabled) {
return;
}
- mDrawingProxy.showGesturePreviewTrail(this);
+ mDrawingProxy.showGestureTrail(this);
}
private void updateBatchInput(final long eventTime) {
@@ -777,7 +789,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
sInGesture = false;
sTimeRecorder.onEndBatchInput(eventTime);
mTimerProxy.cancelAllUpdateBatchInputTimers();
- if (!mIsTrackingCanceled) {
+ if (!mIsTrackingForActionDisabled) {
if (DEBUG_LISTENER) {
Log.d(TAG, String.format("[%d] onEndBatchInput : batchPoints=%d",
mPointerId, sAggregratedPointers.getPointerSize()));
@@ -786,10 +798,10 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
}
}
}
- if (mIsTrackingCanceled) {
+ if (mIsTrackingForActionDisabled) {
return;
}
- mDrawingProxy.showGesturePreviewTrail(this);
+ mDrawingProxy.showGestureTrail(this);
}
private void cancelBatchInput() {
@@ -846,7 +858,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) {
ResearchLogger.pointerTracker_onDownEvent(deltaT, distance * distance);
}
- cancelTracking();
+ cancelTrackingForAction();
return;
}
}
@@ -887,7 +899,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
|| (key != null && key.isModifier())
|| mKeyDetector.alwaysAllowsSlidingInput();
mKeyboardLayoutHasBeenChanged = false;
- mIsTrackingCanceled = false;
+ mIsTrackingForActionDisabled = false;
resetSlidingKeyInput();
if (key != null) {
// This onPress call may have changed keyboard layout. Those cases are detected at
@@ -947,7 +959,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
if (DEBUG_MOVE_EVENT) {
printTouchEvent("onMoveEvent:", x, y, eventTime);
}
- if (mIsTrackingCanceled) {
+ if (mIsTrackingForActionDisabled) {
return;
}
@@ -985,6 +997,9 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
key = onMoveKey(x, y);
}
onMoveToNewKey(key, x, y);
+ if (mIsTrackingForActionDisabled) {
+ return;
+ }
startLongPressTimer(key);
setPressedKeyGraphics(key, eventTime);
}
@@ -1028,7 +1043,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
private void processSildeOutFromOldKey(final Key oldKey) {
setReleasedKeyGraphics(oldKey);
- callListenerOnRelease(oldKey, oldKey.mCode, true);
+ callListenerOnRelease(oldKey, oldKey.mCode, true /* withSliding */);
startSlidingKeyInput(oldKey);
mTimerProxy.cancelKeyTimers();
}
@@ -1069,11 +1084,11 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
+ " detected sliding finger while multi touching", mPointerId));
}
onUpEvent(x, y, eventTime);
- cancelTracking();
+ cancelTrackingForAction();
setReleasedKeyGraphics(oldKey);
} else {
if (!mIsDetectingGesture) {
- cancelTracking();
+ cancelTrackingForAction();
}
setReleasedKeyGraphics(oldKey);
}
@@ -1087,7 +1102,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
onMoveToNewKey(null, x, y);
} else {
if (!mIsDetectingGesture) {
- cancelTracking();
+ cancelTrackingForAction();
}
}
}
@@ -1155,11 +1170,13 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
return;
}
onUpEventInternal(mLastX, mLastY, eventTime);
- cancelTracking();
+ cancelTrackingForAction();
}
private void onUpEventInternal(final int x, final int y, final long eventTime) {
mTimerProxy.cancelKeyTimers();
+ final boolean isInSlidingKeyInput = mIsInSlidingKeyInput;
+ final boolean isInSlidingKeyInputFromModifier = mIsInSlidingKeyInputFromModifier;
resetSlidingKeyInput();
mIsDetectingGesture = false;
final Key currentKey = mCurrentKey;
@@ -1168,7 +1185,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
setReleasedKeyGraphics(currentKey);
if (isShowingMoreKeysPanel()) {
- if (!mIsTrackingCanceled) {
+ if (!mIsTrackingForActionDisabled) {
final int translatedX = mMoreKeysPanel.translateX(x);
final int translatedY = mMoreKeysPanel.translateY(y);
mMoreKeysPanel.onUpEvent(translatedX, translatedY, mPointerId, eventTime);
@@ -1180,17 +1197,22 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
if (sInGesture) {
if (currentKey != null) {
- callListenerOnRelease(currentKey, currentKey.mCode, true);
+ callListenerOnRelease(currentKey, currentKey.mCode, true /* withSliding */);
}
mayEndBatchInput(eventTime);
return;
}
- if (mIsTrackingCanceled) {
+ if (mIsTrackingForActionDisabled) {
+ return;
+ }
+ if (currentKey != null && currentKey.isRepeatable() && !isInSlidingKeyInput) {
+ // Repeatable key has been registered in {@link #onDownEventInternal(int,int,long)}.
return;
}
- if (currentKey != null && !currentKey.isRepeatable()) {
- detectAndSendKey(currentKey, mKeyX, mKeyY, eventTime);
+ detectAndSendKey(currentKey, mKeyX, mKeyY, eventTime);
+ if (isInSlidingKeyInputFromModifier) {
+ callListenerOnFinishSlidingInput();
}
}
@@ -1203,16 +1225,16 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
}
@Override
- public void cancelTracking() {
+ public void cancelTrackingForAction() {
if (isShowingMoreKeysPanel()) {
return;
}
- mIsTrackingCanceled = true;
+ mIsTrackingForActionDisabled = true;
}
public void onLongPressed() {
resetSlidingKeyInput();
- cancelTracking();
+ cancelTrackingForAction();
setReleasedKeyGraphics(mCurrentKey);
sPointerTrackerQueue.remove(this);
}
@@ -1239,10 +1261,13 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
}
private void startRepeatKey(final Key key) {
- if (key != null && key.isRepeatable() && !sInGesture) {
- onRegisterKey(key);
- mTimerProxy.startKeyRepeatTimer(this);
- }
+ if (sInGesture) return;
+ if (key == null) return;
+ if (!key.isRepeatable()) return;
+ // Don't start key repeat when we are in sliding input mode.
+ if (mIsInSlidingKeyInput) return;
+ onRegisterKey(key);
+ mTimerProxy.startKeyRepeatTimer(this);
}
public void onRegisterKey(final Key key) {
@@ -1295,9 +1320,15 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
}
private void startLongPressTimer(final Key key) {
- if (key != null && key.isLongPressEnabled() && !sInGesture) {
- mTimerProxy.startLongPressTimer(this);
- }
+ if (sInGesture) return;
+ if (key == null) return;
+ if (!key.isLongPressEnabled()) return;
+ // Caveat: Please note that isLongPressEnabled() can be true even if the current key
+ // doesn't have its more keys. (e.g. spacebar, globe key)
+ // We always need to start the long press timer if the key has its more keys regardless of
+ // whether or not we are in the sliding input mode.
+ if (mIsInSlidingKeyInput && key.mMoreKeys == null) return;
+ mTimerProxy.startLongPressTimer(this);
}
private void detectAndSendKey(final Key key, final int x, final int y, final long eventTime) {
@@ -1308,7 +1339,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
final int code = key.mCode;
callListenerOnCodeInput(key, code, x, y, eventTime);
- callListenerOnRelease(key, code, false);
+ callListenerOnRelease(key, code, false /* withSliding */);
}
private void printTouchEvent(final String title, final int x, final int y,
@@ -1316,6 +1347,6 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
final Key key = mKeyDetector.detectHitKey(x, y);
final String code = KeyDetector.printableCode(key);
Log.d(TAG, String.format("[%d]%s%s %4d %4d %5d %s", mPointerId,
- (mIsTrackingCanceled ? "-" : " "), title, x, y, eventTime, code));
+ (mIsTrackingForActionDisabled ? "-" : " "), title, x, y, eventTime, code));
}
}