Loading java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java +4 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,8 @@ public interface KeyboardActionListener { */ public void onEndBatchInput(InputPointers batchPointers); public void onCancelBatchInput(); /** * Called when user released a finger outside any key. */ Loading Loading @@ -107,6 +109,8 @@ public interface KeyboardActionListener { @Override public void onEndBatchInput(InputPointers batchPointers) {} @Override public void onCancelBatchInput() {} @Override public void onCancelInput() {} @Override public boolean onCustomRequest(int requestCode) { Loading java/src/com/android/inputmethod/keyboard/PointerTracker.java +36 −19 Original line number Diff line number Diff line Loading @@ -305,8 +305,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element { // true if keyboard layout has been changed. private boolean mKeyboardLayoutHasBeenChanged; // true if event is already translated to a key action. private boolean mKeyAlreadyProcessed; // true if this pointer is no longer tracking touch event. private boolean mIsTrackingCanceled; // true if this pointer has been long-pressed and is showing a more keys panel. private boolean mIsShowingMoreKeysPanel; Loading Loading @@ -517,7 +517,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { mKeyboard = keyDetector.getKeyboard(); final int keyWidth = mKeyboard.mMostCommonKeyWidth; final int keyHeight = mKeyboard.mMostCommonKeyHeight; mGestureStrokeWithPreviewPoints.setKeyboardGeometry(keyWidth); mGestureStrokeWithPreviewPoints.setKeyboardGeometry(keyWidth, mKeyboard.mOccupiedHeight); final Key newKey = mKeyDetector.detectHitKey(mKeyX, mKeyY); if (newKey != mCurrentKey) { if (mDrawingProxy != null) { Loading Loading @@ -730,15 +730,17 @@ public final class PointerTracker implements PointerTrackerQueue.Element { synchronized (sAggregratedPointers) { mGestureStrokeWithPreviewPoints.appendAllBatchPoints(sAggregratedPointers); if (getActivePointerTrackerCount() == 1) { sInGesture = false; sTimeRecorder.onEndBatchInput(eventTime); if (!mIsTrackingCanceled) { if (DEBUG_LISTENER) { Log.d(TAG, String.format("[%d] onEndBatchInput : batchPoints=%d", mPointerId, sAggregratedPointers.getPointerSize())); } sInGesture = false; sTimeRecorder.onEndBatchInput(eventTime); mListener.onEndBatchInput(sAggregratedPointers); } } } mDrawingProxy.showGesturePreviewTrail(this, isOldestTrackerInQueue(this)); } Loading Loading @@ -784,7 +786,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { if (ProductionFlag.IS_EXPERIMENTAL) { ResearchLogger.pointerTracker_onDownEvent(deltaT, distance * distance); } mKeyAlreadyProcessed = true; cancelTracking(); return; } } Loading Loading @@ -821,7 +823,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { || (key != null && key.isModifier()) || mKeyDetector.alwaysAllowsSlidingInput(); mKeyboardLayoutHasBeenChanged = false; mKeyAlreadyProcessed = false; mIsTrackingCanceled = false; resetSlidingKeyInput(); if (key != null) { // This onPress call may have changed keyboard layout. Those cases are detected at Loading Loading @@ -853,7 +855,17 @@ public final class PointerTracker implements PointerTrackerQueue.Element { final boolean isMajorEvent, final Key key) { final int gestureTime = (int)(eventTime - sGestureFirstDownTime); if (mIsDetectingGesture) { mGestureStrokeWithPreviewPoints.addPoint(x, y, gestureTime, isMajorEvent); final boolean onValidArea = mGestureStrokeWithPreviewPoints.addPointOnKeyboard( x, y, gestureTime, isMajorEvent); if (!onValidArea) { sPointerTrackerQueue.cancelAllPointerTracker(); if (DEBUG_LISTENER) { Log.d(TAG, String.format("[%d] onCancelBatchInput: batchPoints=%d", mPointerId, sAggregratedPointers.getPointerSize())); } mListener.onCancelBatchInput(); return; } mayStartBatchInput(key); if (sInGesture) { mayUpdateBatchInput(eventTime, key); Loading @@ -865,7 +877,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { if (DEBUG_MOVE_EVENT) { printTouchEvent("onMoveEvent:", x, y, eventTime); } if (mKeyAlreadyProcessed) { if (mIsTrackingCanceled) { return; } Loading Loading @@ -979,11 +991,11 @@ public final class PointerTracker implements PointerTrackerQueue.Element { + " detected sliding finger while multi touching", mPointerId)); } onUpEvent(x, y, eventTime); mKeyAlreadyProcessed = true; cancelTracking(); setReleasedKeyGraphics(oldKey); } else { if (!mIsDetectingGesture) { mKeyAlreadyProcessed = true; cancelTracking(); } setReleasedKeyGraphics(oldKey); } Loading @@ -997,7 +1009,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { onMoveToNewKey(null, x, y); } else { if (!mIsDetectingGesture) { mKeyAlreadyProcessed = true; cancelTracking(); } } } Loading Loading @@ -1060,7 +1072,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { printTouchEvent("onPhntEvent:", getLastX(), getLastY(), eventTime); } onUpEventInternal(eventTime); mKeyAlreadyProcessed = true; cancelTracking(); } private void onUpEventInternal(final long eventTime) { Loading @@ -1084,7 +1096,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { return; } if (mKeyAlreadyProcessed) { if (mIsTrackingCanceled) { return; } if (currentKey != null && !currentKey.isRepeatable()) { Loading @@ -1098,8 +1110,13 @@ public final class PointerTracker implements PointerTrackerQueue.Element { onDownEvent(x, y, SystemClock.uptimeMillis(), handler); } @Override public void cancelTracking() { mIsTrackingCanceled = true; } public void onLongPressed() { mKeyAlreadyProcessed = true; cancelTracking(); setReleasedKeyGraphics(mCurrentKey); sPointerTrackerQueue.remove(this); } Loading Loading @@ -1202,6 +1219,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, (mKeyAlreadyProcessed ? "-" : " "), title, x, y, eventTime, code)); (mIsTrackingCanceled ? "-" : " "), title, x, y, eventTime, code)); } } java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java +22 −3 Original line number Diff line number Diff line Loading @@ -27,6 +27,10 @@ public class GestureStroke { private static final boolean DEBUG = false; private static final boolean DEBUG_SPEED = false; // The height of extra area above the keyboard to draw gesture trails. // Proportional to the keyboard height. public static final float EXTRA_GESTURE_TRAIL_AREA_ABOVE_KEYBOARD_RATIO = 0.25f; public static final int DEFAULT_CAPACITY = 128; private final int mPointerId; Loading @@ -37,6 +41,8 @@ public class GestureStroke { private final GestureStrokeParams mParams; private int mKeyWidth; // pixel private int mMinYCoordinate; // pixel private int mMaxYCoordinate; // pixel // Static threshold for starting gesture detection private int mDetectFastMoveSpeedThreshold; // pixel /sec private int mDetectFastMoveTime; Loading Loading @@ -135,8 +141,10 @@ public class GestureStroke { mParams = params; } public void setKeyboardGeometry(final int keyWidth) { public void setKeyboardGeometry(final int keyWidth, final int keyboardHeight) { mKeyWidth = keyWidth; mMinYCoordinate = -(int)(keyboardHeight * EXTRA_GESTURE_TRAIL_AREA_ABOVE_KEYBOARD_RATIO); mMaxYCoordinate = keyboardHeight - 1; // TODO: Find an appropriate base metric for these length. Maybe diagonal length of the key? mDetectFastMoveSpeedThreshold = (int)(keyWidth * mParams.mDetectFastMoveSpeedThreshold); mGestureDynamicDistanceThresholdFrom = Loading Loading @@ -167,7 +175,7 @@ public class GestureStroke { elapsedTimeAfterTyping, mAfterFastTyping ? " afterFastTyping" : "")); } final int elapsedTimeFromFirstDown = (int)(downTime - gestureFirstDownTime); addPoint(x, y, elapsedTimeFromFirstDown, true /* isMajorEvent */); addPointOnKeyboard(x, y, elapsedTimeFromFirstDown, true /* isMajorEvent */); } private int getGestureDynamicDistanceThreshold(final int deltaTime) { Loading Loading @@ -277,7 +285,17 @@ public class GestureStroke { return dist; } public void addPoint(final int x, final int y, final int time, final boolean isMajorEvent) { /** * Add a touch event as a gesture point. Returns true if the touch event is on the valid * gesture area. * @param x the x-coordinate of the touch event * @param y the y-coordinate of the touch event * @param time the elapsed time in millisecond from the first gesture down * @param isMajorEvent false if this is a historical move event * @return true if the touch event is on the valid gesture area */ public boolean addPointOnKeyboard(final int x, final int y, final int time, final boolean isMajorEvent) { final int size = mEventTimes.getLength(); if (size <= 0) { // Down event Loading @@ -293,6 +311,7 @@ public class GestureStroke { updateIncrementalRecognitionSize(x, y, time); updateMajorEvent(x, y, time); } return y >= mMinYCoordinate && y < mMaxYCoordinate; } private void updateIncrementalRecognitionSize(final int x, final int y, final int time) { Loading java/src/com/android/inputmethod/keyboard/internal/GestureStrokeWithPreviewPoints.java +6 −4 Original line number Diff line number Diff line Loading @@ -56,8 +56,8 @@ public final class GestureStrokeWithPreviewPoints extends GestureStroke { } @Override public void setKeyboardGeometry(final int keyWidth) { super.setKeyboardGeometry(keyWidth); public void setKeyboardGeometry(final int keyWidth, final int keyboardHeight) { super.setKeyboardGeometry(keyWidth, keyboardHeight); final float sampleLength = keyWidth * MIN_PREVIEW_SAMPLE_LENGTH_RATIO_TO_KEY_WIDTH; mMinPreviewSampleLengthSquare = (int)(sampleLength * sampleLength); } Loading @@ -69,8 +69,9 @@ public final class GestureStrokeWithPreviewPoints extends GestureStroke { } @Override public void addPoint(final int x, final int y, final int time, final boolean isMajorEvent) { super.addPoint(x, y, time, isMajorEvent); public boolean addPointOnKeyboard(final int x, final int y, final int time, final boolean isMajorEvent) { final boolean onValidArea = super.addPointOnKeyboard(x, y, time, isMajorEvent); if (isMajorEvent || needsSampling(x, y)) { mPreviewEventTimes.add(time); mPreviewXCoordinates.add(x); Loading @@ -78,6 +79,7 @@ public final class GestureStrokeWithPreviewPoints extends GestureStroke { mLastX = x; mLastY = y; } return onValidArea; } public void appendPreviewStroke(final ResizableIntArray eventTimes, Loading java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java +10 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ public final class PointerTrackerQueue { public boolean isModifier(); public boolean isInSlidingKeyInput(); public void onPhantomUpEvent(long eventTime); public void cancelTracking(); } private static final int INITIAL_CAPACITY = 10; Loading Loading @@ -182,6 +183,15 @@ public final class PointerTrackerQueue { return false; } public synchronized void cancelAllPointerTracker() { final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers; final int arraySize = mArraySize; for (int index = 0; index < arraySize; index++) { final Element element = expandableArray.get(index); element.cancelTracking(); } } @Override public synchronized String toString() { final StringBuilder sb = new StringBuilder(); Loading Loading
java/src/com/android/inputmethod/keyboard/KeyboardActionListener.java +4 −0 Original line number Diff line number Diff line Loading @@ -80,6 +80,8 @@ public interface KeyboardActionListener { */ public void onEndBatchInput(InputPointers batchPointers); public void onCancelBatchInput(); /** * Called when user released a finger outside any key. */ Loading Loading @@ -107,6 +109,8 @@ public interface KeyboardActionListener { @Override public void onEndBatchInput(InputPointers batchPointers) {} @Override public void onCancelBatchInput() {} @Override public void onCancelInput() {} @Override public boolean onCustomRequest(int requestCode) { Loading
java/src/com/android/inputmethod/keyboard/PointerTracker.java +36 −19 Original line number Diff line number Diff line Loading @@ -305,8 +305,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element { // true if keyboard layout has been changed. private boolean mKeyboardLayoutHasBeenChanged; // true if event is already translated to a key action. private boolean mKeyAlreadyProcessed; // true if this pointer is no longer tracking touch event. private boolean mIsTrackingCanceled; // true if this pointer has been long-pressed and is showing a more keys panel. private boolean mIsShowingMoreKeysPanel; Loading Loading @@ -517,7 +517,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { mKeyboard = keyDetector.getKeyboard(); final int keyWidth = mKeyboard.mMostCommonKeyWidth; final int keyHeight = mKeyboard.mMostCommonKeyHeight; mGestureStrokeWithPreviewPoints.setKeyboardGeometry(keyWidth); mGestureStrokeWithPreviewPoints.setKeyboardGeometry(keyWidth, mKeyboard.mOccupiedHeight); final Key newKey = mKeyDetector.detectHitKey(mKeyX, mKeyY); if (newKey != mCurrentKey) { if (mDrawingProxy != null) { Loading Loading @@ -730,15 +730,17 @@ public final class PointerTracker implements PointerTrackerQueue.Element { synchronized (sAggregratedPointers) { mGestureStrokeWithPreviewPoints.appendAllBatchPoints(sAggregratedPointers); if (getActivePointerTrackerCount() == 1) { sInGesture = false; sTimeRecorder.onEndBatchInput(eventTime); if (!mIsTrackingCanceled) { if (DEBUG_LISTENER) { Log.d(TAG, String.format("[%d] onEndBatchInput : batchPoints=%d", mPointerId, sAggregratedPointers.getPointerSize())); } sInGesture = false; sTimeRecorder.onEndBatchInput(eventTime); mListener.onEndBatchInput(sAggregratedPointers); } } } mDrawingProxy.showGesturePreviewTrail(this, isOldestTrackerInQueue(this)); } Loading Loading @@ -784,7 +786,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { if (ProductionFlag.IS_EXPERIMENTAL) { ResearchLogger.pointerTracker_onDownEvent(deltaT, distance * distance); } mKeyAlreadyProcessed = true; cancelTracking(); return; } } Loading Loading @@ -821,7 +823,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { || (key != null && key.isModifier()) || mKeyDetector.alwaysAllowsSlidingInput(); mKeyboardLayoutHasBeenChanged = false; mKeyAlreadyProcessed = false; mIsTrackingCanceled = false; resetSlidingKeyInput(); if (key != null) { // This onPress call may have changed keyboard layout. Those cases are detected at Loading Loading @@ -853,7 +855,17 @@ public final class PointerTracker implements PointerTrackerQueue.Element { final boolean isMajorEvent, final Key key) { final int gestureTime = (int)(eventTime - sGestureFirstDownTime); if (mIsDetectingGesture) { mGestureStrokeWithPreviewPoints.addPoint(x, y, gestureTime, isMajorEvent); final boolean onValidArea = mGestureStrokeWithPreviewPoints.addPointOnKeyboard( x, y, gestureTime, isMajorEvent); if (!onValidArea) { sPointerTrackerQueue.cancelAllPointerTracker(); if (DEBUG_LISTENER) { Log.d(TAG, String.format("[%d] onCancelBatchInput: batchPoints=%d", mPointerId, sAggregratedPointers.getPointerSize())); } mListener.onCancelBatchInput(); return; } mayStartBatchInput(key); if (sInGesture) { mayUpdateBatchInput(eventTime, key); Loading @@ -865,7 +877,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { if (DEBUG_MOVE_EVENT) { printTouchEvent("onMoveEvent:", x, y, eventTime); } if (mKeyAlreadyProcessed) { if (mIsTrackingCanceled) { return; } Loading Loading @@ -979,11 +991,11 @@ public final class PointerTracker implements PointerTrackerQueue.Element { + " detected sliding finger while multi touching", mPointerId)); } onUpEvent(x, y, eventTime); mKeyAlreadyProcessed = true; cancelTracking(); setReleasedKeyGraphics(oldKey); } else { if (!mIsDetectingGesture) { mKeyAlreadyProcessed = true; cancelTracking(); } setReleasedKeyGraphics(oldKey); } Loading @@ -997,7 +1009,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { onMoveToNewKey(null, x, y); } else { if (!mIsDetectingGesture) { mKeyAlreadyProcessed = true; cancelTracking(); } } } Loading Loading @@ -1060,7 +1072,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { printTouchEvent("onPhntEvent:", getLastX(), getLastY(), eventTime); } onUpEventInternal(eventTime); mKeyAlreadyProcessed = true; cancelTracking(); } private void onUpEventInternal(final long eventTime) { Loading @@ -1084,7 +1096,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { return; } if (mKeyAlreadyProcessed) { if (mIsTrackingCanceled) { return; } if (currentKey != null && !currentKey.isRepeatable()) { Loading @@ -1098,8 +1110,13 @@ public final class PointerTracker implements PointerTrackerQueue.Element { onDownEvent(x, y, SystemClock.uptimeMillis(), handler); } @Override public void cancelTracking() { mIsTrackingCanceled = true; } public void onLongPressed() { mKeyAlreadyProcessed = true; cancelTracking(); setReleasedKeyGraphics(mCurrentKey); sPointerTrackerQueue.remove(this); } Loading Loading @@ -1202,6 +1219,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, (mKeyAlreadyProcessed ? "-" : " "), title, x, y, eventTime, code)); (mIsTrackingCanceled ? "-" : " "), title, x, y, eventTime, code)); } }
java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java +22 −3 Original line number Diff line number Diff line Loading @@ -27,6 +27,10 @@ public class GestureStroke { private static final boolean DEBUG = false; private static final boolean DEBUG_SPEED = false; // The height of extra area above the keyboard to draw gesture trails. // Proportional to the keyboard height. public static final float EXTRA_GESTURE_TRAIL_AREA_ABOVE_KEYBOARD_RATIO = 0.25f; public static final int DEFAULT_CAPACITY = 128; private final int mPointerId; Loading @@ -37,6 +41,8 @@ public class GestureStroke { private final GestureStrokeParams mParams; private int mKeyWidth; // pixel private int mMinYCoordinate; // pixel private int mMaxYCoordinate; // pixel // Static threshold for starting gesture detection private int mDetectFastMoveSpeedThreshold; // pixel /sec private int mDetectFastMoveTime; Loading Loading @@ -135,8 +141,10 @@ public class GestureStroke { mParams = params; } public void setKeyboardGeometry(final int keyWidth) { public void setKeyboardGeometry(final int keyWidth, final int keyboardHeight) { mKeyWidth = keyWidth; mMinYCoordinate = -(int)(keyboardHeight * EXTRA_GESTURE_TRAIL_AREA_ABOVE_KEYBOARD_RATIO); mMaxYCoordinate = keyboardHeight - 1; // TODO: Find an appropriate base metric for these length. Maybe diagonal length of the key? mDetectFastMoveSpeedThreshold = (int)(keyWidth * mParams.mDetectFastMoveSpeedThreshold); mGestureDynamicDistanceThresholdFrom = Loading Loading @@ -167,7 +175,7 @@ public class GestureStroke { elapsedTimeAfterTyping, mAfterFastTyping ? " afterFastTyping" : "")); } final int elapsedTimeFromFirstDown = (int)(downTime - gestureFirstDownTime); addPoint(x, y, elapsedTimeFromFirstDown, true /* isMajorEvent */); addPointOnKeyboard(x, y, elapsedTimeFromFirstDown, true /* isMajorEvent */); } private int getGestureDynamicDistanceThreshold(final int deltaTime) { Loading Loading @@ -277,7 +285,17 @@ public class GestureStroke { return dist; } public void addPoint(final int x, final int y, final int time, final boolean isMajorEvent) { /** * Add a touch event as a gesture point. Returns true if the touch event is on the valid * gesture area. * @param x the x-coordinate of the touch event * @param y the y-coordinate of the touch event * @param time the elapsed time in millisecond from the first gesture down * @param isMajorEvent false if this is a historical move event * @return true if the touch event is on the valid gesture area */ public boolean addPointOnKeyboard(final int x, final int y, final int time, final boolean isMajorEvent) { final int size = mEventTimes.getLength(); if (size <= 0) { // Down event Loading @@ -293,6 +311,7 @@ public class GestureStroke { updateIncrementalRecognitionSize(x, y, time); updateMajorEvent(x, y, time); } return y >= mMinYCoordinate && y < mMaxYCoordinate; } private void updateIncrementalRecognitionSize(final int x, final int y, final int time) { Loading
java/src/com/android/inputmethod/keyboard/internal/GestureStrokeWithPreviewPoints.java +6 −4 Original line number Diff line number Diff line Loading @@ -56,8 +56,8 @@ public final class GestureStrokeWithPreviewPoints extends GestureStroke { } @Override public void setKeyboardGeometry(final int keyWidth) { super.setKeyboardGeometry(keyWidth); public void setKeyboardGeometry(final int keyWidth, final int keyboardHeight) { super.setKeyboardGeometry(keyWidth, keyboardHeight); final float sampleLength = keyWidth * MIN_PREVIEW_SAMPLE_LENGTH_RATIO_TO_KEY_WIDTH; mMinPreviewSampleLengthSquare = (int)(sampleLength * sampleLength); } Loading @@ -69,8 +69,9 @@ public final class GestureStrokeWithPreviewPoints extends GestureStroke { } @Override public void addPoint(final int x, final int y, final int time, final boolean isMajorEvent) { super.addPoint(x, y, time, isMajorEvent); public boolean addPointOnKeyboard(final int x, final int y, final int time, final boolean isMajorEvent) { final boolean onValidArea = super.addPointOnKeyboard(x, y, time, isMajorEvent); if (isMajorEvent || needsSampling(x, y)) { mPreviewEventTimes.add(time); mPreviewXCoordinates.add(x); Loading @@ -78,6 +79,7 @@ public final class GestureStrokeWithPreviewPoints extends GestureStroke { mLastX = x; mLastY = y; } return onValidArea; } public void appendPreviewStroke(final ResizableIntArray eventTimes, Loading
java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java +10 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ public final class PointerTrackerQueue { public boolean isModifier(); public boolean isInSlidingKeyInput(); public void onPhantomUpEvent(long eventTime); public void cancelTracking(); } private static final int INITIAL_CAPACITY = 10; Loading Loading @@ -182,6 +183,15 @@ public final class PointerTrackerQueue { return false; } public synchronized void cancelAllPointerTracker() { final ArrayList<Element> expandableArray = mExpandableArrayOfActivePointers; final int arraySize = mArraySize; for (int index = 0; index < arraySize; index++) { final Element element = expandableArray.get(index); element.cancelTracking(); } } @Override public synchronized String toString() { final StringBuilder sb = new StringBuilder(); Loading