Loading java/res/values/attrs.xml +17 −0 Original line number Diff line number Diff line Loading @@ -127,6 +127,23 @@ <attr name="ignoreAltCodeKeyTimeout" format="integer" /> <!-- More keys keyboard will shown at touched point. --> <attr name="showMoreKeysKeyboardAtTouchedPoint" format="boolean" /> <!-- Static threshold for gesture after fast typing (msec) --> <attr name="gestureStaticTimeThresholdAfterFastTyping" format="integer" /> <!-- Static threshold for starting gesture detection (keyWidth%/sec) --> <attr name="gestureDetectFastMoveSpeedThreshold" format="fraction" /> <!-- Dynamic threshold for gesture after fast typing (msec) --> <attr name="gestureDynamicThresholdDecayDuration" format="integer" /> <!-- Time based threshold values for gesture detection (msec) --> <attr name="gestureDynamicTimeThresholdFrom" format="integer" /> <attr name="gestureDynamicTimeThresholdTo" format="integer" /> <!-- Distance based threshold values for gesture detection (keyWidth%/sec) --> <attr name="gestureDynamicDistanceThresholdFrom" format="fraction" /> <attr name="gestureDynamicDistanceThresholdTo" format="fraction" /> <!-- Parameter for gesture sampling (keyWidth%/sec) --> <attr name="gestureSamplingMinimumDistance" format="fraction" /> <!-- Parameters for gesture recognition (msec) and (keyWidth%/sec) --> <attr name="gestureRecognitionMinimumTime" format="integer" /> <attr name="gestureRecognitionSpeedThreshold" format="fraction" /> </declare-styleable> <declare-styleable name="SuggestionStripView"> Loading java/res/values/config.xml +17 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,23 @@ <!-- Showing more keys keyboard, just above the touched point if true, aligned to the key if false --> <bool name="config_show_more_keys_keyboard_at_touched_point">false</bool> <!-- Static threshold for gesture after fast typing (msec) --> <integer name="config_gesture_static_time_threshold_after_fast_typing">350</integer> <!-- Static threshold for starting gesture detection (keyWidth%/sec) --> <fraction name="config_gesture_detect_fast_move_speed_threshold">150%</fraction> <!-- Dynamic threshold for gesture after fast typing (msec) --> <integer name="config_gesture_dynamic_threshold_decay_duration">450</integer> <!-- Time based threshold values for gesture detection (msec) --> <integer name="config_gesture_dynamic_time_threshold_from">300</integer> <integer name="config_gesture_dynamic_time_threshold_to">20</integer> <!-- Distance based threshold values for gesture detection (keyWidth%/sec) --> <fraction name="config_gesture_dynamic_distance_threshold_from">600%</fraction> <fraction name="config_gesture_dynamic_distance_threshold_to">35%</fraction> <!-- Parameter for gesture sampling (keyWidth%/sec) --> <fraction name="config_gesture_sampling_minimum_distance">16.6666%</fraction> <!-- Parameters for gesture recognition (msec) and (keyWidth%/sec) --> <integer name="config_gesture_recognition_minimum_time">100</integer> <fraction name="config_gesture_recognition_speed_threshold">550%</fraction> <!-- Configuration for auto correction --> Loading java/res/values/styles.xml +11 −0 Original line number Diff line number Diff line Loading @@ -94,6 +94,17 @@ <item name="languageOnSpacebarFadeoutAnimator">@anim/language_on_spacebar_fadeout</item> <item name="altCodeKeyWhileTypingFadeoutAnimator">@anim/alt_code_key_while_typing_fadeout</item> <item name="altCodeKeyWhileTypingFadeinAnimator">@anim/alt_code_key_while_typing_fadein</item> <!-- Common attributes of MainKeyboardView for gesture typing detection and recognition --> <item name="gestureStaticTimeThresholdAfterFastTyping">@integer/config_gesture_static_time_threshold_after_fast_typing</item> <item name="gestureDetectFastMoveSpeedThreshold">@fraction/config_gesture_detect_fast_move_speed_threshold</item> <item name="gestureDynamicThresholdDecayDuration">@integer/config_gesture_dynamic_threshold_decay_duration</item> <item name="gestureDynamicTimeThresholdFrom">@integer/config_gesture_dynamic_time_threshold_from</item> <item name="gestureDynamicTimeThresholdTo">@integer/config_gesture_dynamic_time_threshold_to</item> <item name="gestureDynamicDistanceThresholdFrom">@fraction/config_gesture_dynamic_distance_threshold_from</item> <item name="gestureDynamicDistanceThresholdTo">@fraction/config_gesture_dynamic_distance_threshold_to</item> <item name="gestureSamplingMinimumDistance">@fraction/config_gesture_sampling_minimum_distance</item> <item name="gestureRecognitionMinimumTime">@integer/config_gesture_recognition_minimum_time</item> <item name="gestureRecognitionSpeedThreshold">@fraction/config_gesture_recognition_speed_threshold</item> </style> <style name="MainKeyboardView" Loading java/src/com/android/inputmethod/keyboard/PointerTracker.java +10 −4 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.view.MotionEvent; 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.PointerTrackerQueue; import com.android.inputmethod.latin.CollectionUtils; Loading Loading @@ -135,7 +136,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { mTouchNoiseThresholdDistanceSquared = 0; } public PointerTrackerParams(TypedArray mainKeyboardViewAttr) { public PointerTrackerParams(final TypedArray mainKeyboardViewAttr) { mSlidingKeyInputEnabled = mainKeyboardViewAttr.getBoolean( R.styleable.MainKeyboardView_slidingKeyInputEnable, false); mTouchNoiseThresholdTime = mainKeyboardViewAttr.getInt( Loading @@ -150,6 +151,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { // Parameters for pointer handling. private static PointerTrackerParams sParams; private static GestureStrokeParams sGestureStrokeParams; private static boolean sNeedsPhantomSuddenMoveEventHack; private static final ArrayList<PointerTracker> sTrackers = CollectionUtils.newArrayList(); Loading Loading @@ -222,10 +224,12 @@ public final class PointerTracker implements PointerTrackerQueue.Element { } sNeedsPhantomSuddenMoveEventHack = needsPhantomSuddenMoveEventHack; sParams = PointerTrackerParams.DEFAULT; sGestureStrokeParams = GestureStrokeParams.DEFAULT; } public static void setParameters(final TypedArray mainKeyboardViewAttr) { sParams = new PointerTrackerParams(mainKeyboardViewAttr); sGestureStrokeParams = new GestureStrokeParams(mainKeyboardViewAttr); } private static void updateGestureHandlingMode() { Loading Loading @@ -296,7 +300,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element { throw new NullPointerException(); } mPointerId = id; mGestureStrokeWithPreviewPoints = new GestureStrokeWithPreviewPoints(id); mGestureStrokeWithPreviewPoints = new GestureStrokeWithPreviewPoints( id, sGestureStrokeParams); setKeyDetectorInner(handler.getKeyDetector()); mListener = handler.getKeyboardActionListener(); mDrawingProxy = handler.getDrawingProxy(); Loading Loading @@ -587,10 +592,11 @@ public final class PointerTracker implements PointerTrackerQueue.Element { private void mayUpdateBatchInput(final long eventTime, final Key key) { if (key != null) { synchronized (sAggregratedPointers) { mGestureStrokeWithPreviewPoints.appendIncrementalBatchPoints(sAggregratedPointers); final GestureStroke stroke = mGestureStrokeWithPreviewPoints; stroke.appendIncrementalBatchPoints(sAggregratedPointers); final int size = sAggregratedPointers.getPointerSize(); if (size > sLastRecognitionPointSize && GestureStroke.hasRecognitionTimePast(eventTime, sLastRecognitionTime)) { && stroke.hasRecognitionTimePast(eventTime, sLastRecognitionTime)) { sLastRecognitionPointSize = size; sLastRecognitionTime = eventTime; if (DEBUG_LISTENER) { Loading java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java +92 −40 Original line number Diff line number Diff line Loading @@ -14,10 +14,13 @@ package com.android.inputmethod.keyboard.internal; import android.content.res.TypedArray; import android.util.Log; import com.android.inputmethod.latin.InputPointers; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.ResizableIntArray; import com.android.inputmethod.latin.ResourceUtils; public class GestureStroke { private static final String TAG = GestureStroke.class.getSimpleName(); Loading @@ -31,6 +34,8 @@ public class GestureStroke { private final ResizableIntArray mXCoordinates = new ResizableIntArray(DEFAULT_CAPACITY); private final ResizableIntArray mYCoordinates = new ResizableIntArray(DEFAULT_CAPACITY); private final GestureStrokeParams mParams; private int mKeyWidth; // pixel // Static threshold for starting gesture detection private int mDetectFastMoveSpeedThreshold; // pixel /sec Loading @@ -51,53 +56,100 @@ public class GestureStroke { private int mIncrementalRecognitionSize; private int mLastIncrementalBatchSize; // TODO: Move some of these to resource. public static final class GestureStrokeParams { // Static threshold for gesture after fast typing public static final int GESTURE_STATIC_TIME_THRESHOLD_AFTER_FAST_TYPING = 350; // msec public final int mStaticTimeThresholdAfterFastTyping; // msec // Static threshold for starting gesture detection private static final float DETECT_FAST_MOVE_SPEED_THRESHOLD = 1.5f; // keyWidth / sec public final float mDetectFastMoveSpeedThreshold; // keyWidth/sec // Dynamic threshold for gesture after fast typing private static final int GESTURE_DYNAMIC_THRESHOLD_DECAY_DURATION = 450; // msec public final int mDynamicThresholdDecayDuration; // msec // Time based threshold values private static final int GESTURE_DYNAMIC_TIME_THRESHOLD_FROM = 300; // msec private static final int GESTURE_DYNAMIC_TIME_THRESHOLD_TO = 20; // msec public final int mDynamicTimeThresholdFrom; // msec public final int mDynamicTimeThresholdTo; // msec // Distance based threshold values private static final float GESTURE_DYNAMIC_DISTANCE_THRESHOLD_FROM = 6.0f; // keyWidth private static final float GESTURE_DYNAMIC_DISTANCE_THRESHOLD_TO = 0.35f; // keyWidth public final float mDynamicDistanceThresholdFrom; // keyWidth public final float mDynamicDistanceThresholdTo; // keyWidth // Parameters for gesture sampling private static final float GESTURE_SAMPLING_MINIMUM_DISTANCE = 1.0f / 6.0f; // keyWidth public final float mSamplingMinimumDistance; // keyWidth // Parameters for gesture recognition private static final int GESTURE_RECOGNITION_MINIMUM_TIME = 100; // msec private static final float GESTURE_RECOGNITION_SPEED_THRESHOLD = 5.5f; // keyWidth / sec public final int mRecognitionMinimumTime; // msec public final float mRecognitionSpeedThreshold; // keyWidth/sec // Default GestureStroke parameters for test. public static final GestureStrokeParams FOR_TEST = new GestureStrokeParams(); public static final GestureStrokeParams DEFAULT = FOR_TEST; private GestureStrokeParams() { // These parameter values are default and intended for testing. mStaticTimeThresholdAfterFastTyping = 350; // msec mDetectFastMoveSpeedThreshold = 1.5f; // keyWidth / sec mDynamicThresholdDecayDuration = 450; // msec mDynamicTimeThresholdFrom = 300; // msec mDynamicTimeThresholdTo = 20; // msec mDynamicDistanceThresholdFrom = 6.0f; // keyWidth mDynamicDistanceThresholdTo = 0.35f; // keyWidth // The following parameters' change will affect the result of regression test. mSamplingMinimumDistance = 1.0f / 6.0f; // keyWidth mRecognitionMinimumTime = 100; // msec mRecognitionSpeedThreshold = 5.5f; // keyWidth / sec } public GestureStrokeParams(final TypedArray mainKeyboardViewAttr) { mStaticTimeThresholdAfterFastTyping = mainKeyboardViewAttr.getInt( R.styleable.MainKeyboardView_gestureStaticTimeThresholdAfterFastTyping, DEFAULT.mStaticTimeThresholdAfterFastTyping); mDetectFastMoveSpeedThreshold = ResourceUtils.getFraction(mainKeyboardViewAttr, R.styleable.MainKeyboardView_gestureDetectFastMoveSpeedThreshold, DEFAULT.mDetectFastMoveSpeedThreshold); mDynamicThresholdDecayDuration = mainKeyboardViewAttr.getInt( R.styleable.MainKeyboardView_gestureDynamicThresholdDecayDuration, DEFAULT.mDynamicThresholdDecayDuration); mDynamicTimeThresholdFrom = mainKeyboardViewAttr.getInt( R.styleable.MainKeyboardView_gestureDynamicTimeThresholdFrom, DEFAULT.mDynamicTimeThresholdFrom); mDynamicTimeThresholdTo = mainKeyboardViewAttr.getInt( R.styleable.MainKeyboardView_gestureDynamicTimeThresholdTo, DEFAULT.mDynamicTimeThresholdTo); mDynamicDistanceThresholdFrom = ResourceUtils.getFraction(mainKeyboardViewAttr, R.styleable.MainKeyboardView_gestureDynamicDistanceThresholdFrom, DEFAULT.mDynamicDistanceThresholdFrom); mDynamicDistanceThresholdTo = ResourceUtils.getFraction(mainKeyboardViewAttr, R.styleable.MainKeyboardView_gestureDynamicDistanceThresholdTo, DEFAULT.mDynamicDistanceThresholdTo); mSamplingMinimumDistance = ResourceUtils.getFraction(mainKeyboardViewAttr, R.styleable.MainKeyboardView_gestureSamplingMinimumDistance, DEFAULT.mSamplingMinimumDistance); mRecognitionMinimumTime = mainKeyboardViewAttr.getInt( R.styleable.MainKeyboardView_gestureRecognitionMinimumTime, DEFAULT.mRecognitionMinimumTime); mRecognitionSpeedThreshold = ResourceUtils.getFraction(mainKeyboardViewAttr, R.styleable.MainKeyboardView_gestureRecognitionSpeedThreshold, DEFAULT.mRecognitionSpeedThreshold); } } private static final int MSEC_PER_SEC = 1000; public GestureStroke(final int pointerId) { public GestureStroke(final int pointerId, final GestureStrokeParams params) { mPointerId = pointerId; mParams = params; } public void setKeyboardGeometry(final int keyWidth) { mKeyWidth = keyWidth; // TODO: Find an appropriate base metric for these length. Maybe diagonal length of the key? mDetectFastMoveSpeedThreshold = (int)(keyWidth * DETECT_FAST_MOVE_SPEED_THRESHOLD); mDetectFastMoveSpeedThreshold = (int)(keyWidth * mParams.mDetectFastMoveSpeedThreshold); mGestureDynamicDistanceThresholdFrom = (int)(keyWidth * GESTURE_DYNAMIC_DISTANCE_THRESHOLD_FROM); mGestureDynamicDistanceThresholdTo = (int)(keyWidth * GESTURE_DYNAMIC_DISTANCE_THRESHOLD_TO); mGestureSamplingMinimumDistance = (int)(keyWidth * GESTURE_SAMPLING_MINIMUM_DISTANCE); mGestureRecognitionSpeedThreshold = (int)(keyWidth * GESTURE_RECOGNITION_SPEED_THRESHOLD); (int)(keyWidth * mParams.mDynamicDistanceThresholdFrom); mGestureDynamicDistanceThresholdTo = (int)(keyWidth * mParams.mDynamicDistanceThresholdTo); mGestureSamplingMinimumDistance = (int)(keyWidth * mParams.mSamplingMinimumDistance); mGestureRecognitionSpeedThreshold = (int)(keyWidth * mParams.mRecognitionSpeedThreshold); if (DEBUG) { Log.d(TAG, String.format( "[%d] setKeyboardGeometry: keyWidth=%3d tT=%3d >> %3d tD=%3d >> %3d", mPointerId, keyWidth, GESTURE_DYNAMIC_TIME_THRESHOLD_FROM, GESTURE_DYNAMIC_TIME_THRESHOLD_TO, mParams.mDynamicTimeThresholdFrom, mParams.mDynamicTimeThresholdTo, mGestureDynamicDistanceThresholdFrom, mGestureDynamicDistanceThresholdTo)); } Loading @@ -107,7 +159,7 @@ public class GestureStroke { final long gestureFirstDownTime, final long lastTypingTime) { reset(); final long elapsedTimeAfterTyping = downTime - lastTypingTime; if (elapsedTimeAfterTyping < GESTURE_STATIC_TIME_THRESHOLD_AFTER_FAST_TYPING) { if (elapsedTimeAfterTyping < mParams.mStaticTimeThresholdAfterFastTyping) { mAfterFastTyping = true; } if (DEBUG) { Loading @@ -119,23 +171,23 @@ public class GestureStroke { } private int getGestureDynamicDistanceThreshold(final int deltaTime) { if (!mAfterFastTyping || deltaTime >= GESTURE_DYNAMIC_THRESHOLD_DECAY_DURATION) { if (!mAfterFastTyping || deltaTime >= mParams.mDynamicThresholdDecayDuration) { return mGestureDynamicDistanceThresholdTo; } final int decayedThreshold = (mGestureDynamicDistanceThresholdFrom - mGestureDynamicDistanceThresholdTo) * deltaTime / GESTURE_DYNAMIC_THRESHOLD_DECAY_DURATION; * deltaTime / mParams.mDynamicThresholdDecayDuration; return mGestureDynamicDistanceThresholdFrom - decayedThreshold; } private int getGestureDynamicTimeThreshold(final int deltaTime) { if (!mAfterFastTyping || deltaTime >= GESTURE_DYNAMIC_THRESHOLD_DECAY_DURATION) { return GESTURE_DYNAMIC_TIME_THRESHOLD_TO; if (!mAfterFastTyping || deltaTime >= mParams.mDynamicThresholdDecayDuration) { return mParams.mDynamicTimeThresholdTo; } final int decayedThreshold = (GESTURE_DYNAMIC_TIME_THRESHOLD_FROM - GESTURE_DYNAMIC_TIME_THRESHOLD_TO) * deltaTime / GESTURE_DYNAMIC_THRESHOLD_DECAY_DURATION; return GESTURE_DYNAMIC_TIME_THRESHOLD_FROM - decayedThreshold; (mParams.mDynamicTimeThresholdFrom - mParams.mDynamicTimeThresholdTo) * deltaTime / mParams.mDynamicThresholdDecayDuration; return mParams.mDynamicTimeThresholdFrom - decayedThreshold; } public boolean isStartOfAGesture() { Loading Loading @@ -249,9 +301,9 @@ public class GestureStroke { } } public static final boolean hasRecognitionTimePast( public final boolean hasRecognitionTimePast( final long currentTime, final long lastRecognitionTime) { return currentTime > lastRecognitionTime + GESTURE_RECOGNITION_MINIMUM_TIME; return currentTime > lastRecognitionTime + mParams.mRecognitionMinimumTime; } public void appendAllBatchPoints(final InputPointers out) { Loading Loading
java/res/values/attrs.xml +17 −0 Original line number Diff line number Diff line Loading @@ -127,6 +127,23 @@ <attr name="ignoreAltCodeKeyTimeout" format="integer" /> <!-- More keys keyboard will shown at touched point. --> <attr name="showMoreKeysKeyboardAtTouchedPoint" format="boolean" /> <!-- Static threshold for gesture after fast typing (msec) --> <attr name="gestureStaticTimeThresholdAfterFastTyping" format="integer" /> <!-- Static threshold for starting gesture detection (keyWidth%/sec) --> <attr name="gestureDetectFastMoveSpeedThreshold" format="fraction" /> <!-- Dynamic threshold for gesture after fast typing (msec) --> <attr name="gestureDynamicThresholdDecayDuration" format="integer" /> <!-- Time based threshold values for gesture detection (msec) --> <attr name="gestureDynamicTimeThresholdFrom" format="integer" /> <attr name="gestureDynamicTimeThresholdTo" format="integer" /> <!-- Distance based threshold values for gesture detection (keyWidth%/sec) --> <attr name="gestureDynamicDistanceThresholdFrom" format="fraction" /> <attr name="gestureDynamicDistanceThresholdTo" format="fraction" /> <!-- Parameter for gesture sampling (keyWidth%/sec) --> <attr name="gestureSamplingMinimumDistance" format="fraction" /> <!-- Parameters for gesture recognition (msec) and (keyWidth%/sec) --> <attr name="gestureRecognitionMinimumTime" format="integer" /> <attr name="gestureRecognitionSpeedThreshold" format="fraction" /> </declare-styleable> <declare-styleable name="SuggestionStripView"> Loading
java/res/values/config.xml +17 −0 Original line number Diff line number Diff line Loading @@ -69,6 +69,23 @@ <!-- Showing more keys keyboard, just above the touched point if true, aligned to the key if false --> <bool name="config_show_more_keys_keyboard_at_touched_point">false</bool> <!-- Static threshold for gesture after fast typing (msec) --> <integer name="config_gesture_static_time_threshold_after_fast_typing">350</integer> <!-- Static threshold for starting gesture detection (keyWidth%/sec) --> <fraction name="config_gesture_detect_fast_move_speed_threshold">150%</fraction> <!-- Dynamic threshold for gesture after fast typing (msec) --> <integer name="config_gesture_dynamic_threshold_decay_duration">450</integer> <!-- Time based threshold values for gesture detection (msec) --> <integer name="config_gesture_dynamic_time_threshold_from">300</integer> <integer name="config_gesture_dynamic_time_threshold_to">20</integer> <!-- Distance based threshold values for gesture detection (keyWidth%/sec) --> <fraction name="config_gesture_dynamic_distance_threshold_from">600%</fraction> <fraction name="config_gesture_dynamic_distance_threshold_to">35%</fraction> <!-- Parameter for gesture sampling (keyWidth%/sec) --> <fraction name="config_gesture_sampling_minimum_distance">16.6666%</fraction> <!-- Parameters for gesture recognition (msec) and (keyWidth%/sec) --> <integer name="config_gesture_recognition_minimum_time">100</integer> <fraction name="config_gesture_recognition_speed_threshold">550%</fraction> <!-- Configuration for auto correction --> Loading
java/res/values/styles.xml +11 −0 Original line number Diff line number Diff line Loading @@ -94,6 +94,17 @@ <item name="languageOnSpacebarFadeoutAnimator">@anim/language_on_spacebar_fadeout</item> <item name="altCodeKeyWhileTypingFadeoutAnimator">@anim/alt_code_key_while_typing_fadeout</item> <item name="altCodeKeyWhileTypingFadeinAnimator">@anim/alt_code_key_while_typing_fadein</item> <!-- Common attributes of MainKeyboardView for gesture typing detection and recognition --> <item name="gestureStaticTimeThresholdAfterFastTyping">@integer/config_gesture_static_time_threshold_after_fast_typing</item> <item name="gestureDetectFastMoveSpeedThreshold">@fraction/config_gesture_detect_fast_move_speed_threshold</item> <item name="gestureDynamicThresholdDecayDuration">@integer/config_gesture_dynamic_threshold_decay_duration</item> <item name="gestureDynamicTimeThresholdFrom">@integer/config_gesture_dynamic_time_threshold_from</item> <item name="gestureDynamicTimeThresholdTo">@integer/config_gesture_dynamic_time_threshold_to</item> <item name="gestureDynamicDistanceThresholdFrom">@fraction/config_gesture_dynamic_distance_threshold_from</item> <item name="gestureDynamicDistanceThresholdTo">@fraction/config_gesture_dynamic_distance_threshold_to</item> <item name="gestureSamplingMinimumDistance">@fraction/config_gesture_sampling_minimum_distance</item> <item name="gestureRecognitionMinimumTime">@integer/config_gesture_recognition_minimum_time</item> <item name="gestureRecognitionSpeedThreshold">@fraction/config_gesture_recognition_speed_threshold</item> </style> <style name="MainKeyboardView" Loading
java/src/com/android/inputmethod/keyboard/PointerTracker.java +10 −4 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.view.MotionEvent; 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.PointerTrackerQueue; import com.android.inputmethod.latin.CollectionUtils; Loading Loading @@ -135,7 +136,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { mTouchNoiseThresholdDistanceSquared = 0; } public PointerTrackerParams(TypedArray mainKeyboardViewAttr) { public PointerTrackerParams(final TypedArray mainKeyboardViewAttr) { mSlidingKeyInputEnabled = mainKeyboardViewAttr.getBoolean( R.styleable.MainKeyboardView_slidingKeyInputEnable, false); mTouchNoiseThresholdTime = mainKeyboardViewAttr.getInt( Loading @@ -150,6 +151,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { // Parameters for pointer handling. private static PointerTrackerParams sParams; private static GestureStrokeParams sGestureStrokeParams; private static boolean sNeedsPhantomSuddenMoveEventHack; private static final ArrayList<PointerTracker> sTrackers = CollectionUtils.newArrayList(); Loading Loading @@ -222,10 +224,12 @@ public final class PointerTracker implements PointerTrackerQueue.Element { } sNeedsPhantomSuddenMoveEventHack = needsPhantomSuddenMoveEventHack; sParams = PointerTrackerParams.DEFAULT; sGestureStrokeParams = GestureStrokeParams.DEFAULT; } public static void setParameters(final TypedArray mainKeyboardViewAttr) { sParams = new PointerTrackerParams(mainKeyboardViewAttr); sGestureStrokeParams = new GestureStrokeParams(mainKeyboardViewAttr); } private static void updateGestureHandlingMode() { Loading Loading @@ -296,7 +300,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element { throw new NullPointerException(); } mPointerId = id; mGestureStrokeWithPreviewPoints = new GestureStrokeWithPreviewPoints(id); mGestureStrokeWithPreviewPoints = new GestureStrokeWithPreviewPoints( id, sGestureStrokeParams); setKeyDetectorInner(handler.getKeyDetector()); mListener = handler.getKeyboardActionListener(); mDrawingProxy = handler.getDrawingProxy(); Loading Loading @@ -587,10 +592,11 @@ public final class PointerTracker implements PointerTrackerQueue.Element { private void mayUpdateBatchInput(final long eventTime, final Key key) { if (key != null) { synchronized (sAggregratedPointers) { mGestureStrokeWithPreviewPoints.appendIncrementalBatchPoints(sAggregratedPointers); final GestureStroke stroke = mGestureStrokeWithPreviewPoints; stroke.appendIncrementalBatchPoints(sAggregratedPointers); final int size = sAggregratedPointers.getPointerSize(); if (size > sLastRecognitionPointSize && GestureStroke.hasRecognitionTimePast(eventTime, sLastRecognitionTime)) { && stroke.hasRecognitionTimePast(eventTime, sLastRecognitionTime)) { sLastRecognitionPointSize = size; sLastRecognitionTime = eventTime; if (DEBUG_LISTENER) { Loading
java/src/com/android/inputmethod/keyboard/internal/GestureStroke.java +92 −40 Original line number Diff line number Diff line Loading @@ -14,10 +14,13 @@ package com.android.inputmethod.keyboard.internal; import android.content.res.TypedArray; import android.util.Log; import com.android.inputmethod.latin.InputPointers; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.ResizableIntArray; import com.android.inputmethod.latin.ResourceUtils; public class GestureStroke { private static final String TAG = GestureStroke.class.getSimpleName(); Loading @@ -31,6 +34,8 @@ public class GestureStroke { private final ResizableIntArray mXCoordinates = new ResizableIntArray(DEFAULT_CAPACITY); private final ResizableIntArray mYCoordinates = new ResizableIntArray(DEFAULT_CAPACITY); private final GestureStrokeParams mParams; private int mKeyWidth; // pixel // Static threshold for starting gesture detection private int mDetectFastMoveSpeedThreshold; // pixel /sec Loading @@ -51,53 +56,100 @@ public class GestureStroke { private int mIncrementalRecognitionSize; private int mLastIncrementalBatchSize; // TODO: Move some of these to resource. public static final class GestureStrokeParams { // Static threshold for gesture after fast typing public static final int GESTURE_STATIC_TIME_THRESHOLD_AFTER_FAST_TYPING = 350; // msec public final int mStaticTimeThresholdAfterFastTyping; // msec // Static threshold for starting gesture detection private static final float DETECT_FAST_MOVE_SPEED_THRESHOLD = 1.5f; // keyWidth / sec public final float mDetectFastMoveSpeedThreshold; // keyWidth/sec // Dynamic threshold for gesture after fast typing private static final int GESTURE_DYNAMIC_THRESHOLD_DECAY_DURATION = 450; // msec public final int mDynamicThresholdDecayDuration; // msec // Time based threshold values private static final int GESTURE_DYNAMIC_TIME_THRESHOLD_FROM = 300; // msec private static final int GESTURE_DYNAMIC_TIME_THRESHOLD_TO = 20; // msec public final int mDynamicTimeThresholdFrom; // msec public final int mDynamicTimeThresholdTo; // msec // Distance based threshold values private static final float GESTURE_DYNAMIC_DISTANCE_THRESHOLD_FROM = 6.0f; // keyWidth private static final float GESTURE_DYNAMIC_DISTANCE_THRESHOLD_TO = 0.35f; // keyWidth public final float mDynamicDistanceThresholdFrom; // keyWidth public final float mDynamicDistanceThresholdTo; // keyWidth // Parameters for gesture sampling private static final float GESTURE_SAMPLING_MINIMUM_DISTANCE = 1.0f / 6.0f; // keyWidth public final float mSamplingMinimumDistance; // keyWidth // Parameters for gesture recognition private static final int GESTURE_RECOGNITION_MINIMUM_TIME = 100; // msec private static final float GESTURE_RECOGNITION_SPEED_THRESHOLD = 5.5f; // keyWidth / sec public final int mRecognitionMinimumTime; // msec public final float mRecognitionSpeedThreshold; // keyWidth/sec // Default GestureStroke parameters for test. public static final GestureStrokeParams FOR_TEST = new GestureStrokeParams(); public static final GestureStrokeParams DEFAULT = FOR_TEST; private GestureStrokeParams() { // These parameter values are default and intended for testing. mStaticTimeThresholdAfterFastTyping = 350; // msec mDetectFastMoveSpeedThreshold = 1.5f; // keyWidth / sec mDynamicThresholdDecayDuration = 450; // msec mDynamicTimeThresholdFrom = 300; // msec mDynamicTimeThresholdTo = 20; // msec mDynamicDistanceThresholdFrom = 6.0f; // keyWidth mDynamicDistanceThresholdTo = 0.35f; // keyWidth // The following parameters' change will affect the result of regression test. mSamplingMinimumDistance = 1.0f / 6.0f; // keyWidth mRecognitionMinimumTime = 100; // msec mRecognitionSpeedThreshold = 5.5f; // keyWidth / sec } public GestureStrokeParams(final TypedArray mainKeyboardViewAttr) { mStaticTimeThresholdAfterFastTyping = mainKeyboardViewAttr.getInt( R.styleable.MainKeyboardView_gestureStaticTimeThresholdAfterFastTyping, DEFAULT.mStaticTimeThresholdAfterFastTyping); mDetectFastMoveSpeedThreshold = ResourceUtils.getFraction(mainKeyboardViewAttr, R.styleable.MainKeyboardView_gestureDetectFastMoveSpeedThreshold, DEFAULT.mDetectFastMoveSpeedThreshold); mDynamicThresholdDecayDuration = mainKeyboardViewAttr.getInt( R.styleable.MainKeyboardView_gestureDynamicThresholdDecayDuration, DEFAULT.mDynamicThresholdDecayDuration); mDynamicTimeThresholdFrom = mainKeyboardViewAttr.getInt( R.styleable.MainKeyboardView_gestureDynamicTimeThresholdFrom, DEFAULT.mDynamicTimeThresholdFrom); mDynamicTimeThresholdTo = mainKeyboardViewAttr.getInt( R.styleable.MainKeyboardView_gestureDynamicTimeThresholdTo, DEFAULT.mDynamicTimeThresholdTo); mDynamicDistanceThresholdFrom = ResourceUtils.getFraction(mainKeyboardViewAttr, R.styleable.MainKeyboardView_gestureDynamicDistanceThresholdFrom, DEFAULT.mDynamicDistanceThresholdFrom); mDynamicDistanceThresholdTo = ResourceUtils.getFraction(mainKeyboardViewAttr, R.styleable.MainKeyboardView_gestureDynamicDistanceThresholdTo, DEFAULT.mDynamicDistanceThresholdTo); mSamplingMinimumDistance = ResourceUtils.getFraction(mainKeyboardViewAttr, R.styleable.MainKeyboardView_gestureSamplingMinimumDistance, DEFAULT.mSamplingMinimumDistance); mRecognitionMinimumTime = mainKeyboardViewAttr.getInt( R.styleable.MainKeyboardView_gestureRecognitionMinimumTime, DEFAULT.mRecognitionMinimumTime); mRecognitionSpeedThreshold = ResourceUtils.getFraction(mainKeyboardViewAttr, R.styleable.MainKeyboardView_gestureRecognitionSpeedThreshold, DEFAULT.mRecognitionSpeedThreshold); } } private static final int MSEC_PER_SEC = 1000; public GestureStroke(final int pointerId) { public GestureStroke(final int pointerId, final GestureStrokeParams params) { mPointerId = pointerId; mParams = params; } public void setKeyboardGeometry(final int keyWidth) { mKeyWidth = keyWidth; // TODO: Find an appropriate base metric for these length. Maybe diagonal length of the key? mDetectFastMoveSpeedThreshold = (int)(keyWidth * DETECT_FAST_MOVE_SPEED_THRESHOLD); mDetectFastMoveSpeedThreshold = (int)(keyWidth * mParams.mDetectFastMoveSpeedThreshold); mGestureDynamicDistanceThresholdFrom = (int)(keyWidth * GESTURE_DYNAMIC_DISTANCE_THRESHOLD_FROM); mGestureDynamicDistanceThresholdTo = (int)(keyWidth * GESTURE_DYNAMIC_DISTANCE_THRESHOLD_TO); mGestureSamplingMinimumDistance = (int)(keyWidth * GESTURE_SAMPLING_MINIMUM_DISTANCE); mGestureRecognitionSpeedThreshold = (int)(keyWidth * GESTURE_RECOGNITION_SPEED_THRESHOLD); (int)(keyWidth * mParams.mDynamicDistanceThresholdFrom); mGestureDynamicDistanceThresholdTo = (int)(keyWidth * mParams.mDynamicDistanceThresholdTo); mGestureSamplingMinimumDistance = (int)(keyWidth * mParams.mSamplingMinimumDistance); mGestureRecognitionSpeedThreshold = (int)(keyWidth * mParams.mRecognitionSpeedThreshold); if (DEBUG) { Log.d(TAG, String.format( "[%d] setKeyboardGeometry: keyWidth=%3d tT=%3d >> %3d tD=%3d >> %3d", mPointerId, keyWidth, GESTURE_DYNAMIC_TIME_THRESHOLD_FROM, GESTURE_DYNAMIC_TIME_THRESHOLD_TO, mParams.mDynamicTimeThresholdFrom, mParams.mDynamicTimeThresholdTo, mGestureDynamicDistanceThresholdFrom, mGestureDynamicDistanceThresholdTo)); } Loading @@ -107,7 +159,7 @@ public class GestureStroke { final long gestureFirstDownTime, final long lastTypingTime) { reset(); final long elapsedTimeAfterTyping = downTime - lastTypingTime; if (elapsedTimeAfterTyping < GESTURE_STATIC_TIME_THRESHOLD_AFTER_FAST_TYPING) { if (elapsedTimeAfterTyping < mParams.mStaticTimeThresholdAfterFastTyping) { mAfterFastTyping = true; } if (DEBUG) { Loading @@ -119,23 +171,23 @@ public class GestureStroke { } private int getGestureDynamicDistanceThreshold(final int deltaTime) { if (!mAfterFastTyping || deltaTime >= GESTURE_DYNAMIC_THRESHOLD_DECAY_DURATION) { if (!mAfterFastTyping || deltaTime >= mParams.mDynamicThresholdDecayDuration) { return mGestureDynamicDistanceThresholdTo; } final int decayedThreshold = (mGestureDynamicDistanceThresholdFrom - mGestureDynamicDistanceThresholdTo) * deltaTime / GESTURE_DYNAMIC_THRESHOLD_DECAY_DURATION; * deltaTime / mParams.mDynamicThresholdDecayDuration; return mGestureDynamicDistanceThresholdFrom - decayedThreshold; } private int getGestureDynamicTimeThreshold(final int deltaTime) { if (!mAfterFastTyping || deltaTime >= GESTURE_DYNAMIC_THRESHOLD_DECAY_DURATION) { return GESTURE_DYNAMIC_TIME_THRESHOLD_TO; if (!mAfterFastTyping || deltaTime >= mParams.mDynamicThresholdDecayDuration) { return mParams.mDynamicTimeThresholdTo; } final int decayedThreshold = (GESTURE_DYNAMIC_TIME_THRESHOLD_FROM - GESTURE_DYNAMIC_TIME_THRESHOLD_TO) * deltaTime / GESTURE_DYNAMIC_THRESHOLD_DECAY_DURATION; return GESTURE_DYNAMIC_TIME_THRESHOLD_FROM - decayedThreshold; (mParams.mDynamicTimeThresholdFrom - mParams.mDynamicTimeThresholdTo) * deltaTime / mParams.mDynamicThresholdDecayDuration; return mParams.mDynamicTimeThresholdFrom - decayedThreshold; } public boolean isStartOfAGesture() { Loading Loading @@ -249,9 +301,9 @@ public class GestureStroke { } } public static final boolean hasRecognitionTimePast( public final boolean hasRecognitionTimePast( final long currentTime, final long lastRecognitionTime) { return currentTime > lastRecognitionTime + GESTURE_RECOGNITION_MINIMUM_TIME; return currentTime > lastRecognitionTime + mParams.mRecognitionMinimumTime; } public void appendAllBatchPoints(final InputPointers out) { Loading