Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4580b7e4 authored by Tadashi G. Takaoka's avatar Tadashi G. Takaoka Committed by Android (Google) Code Review
Browse files

Merge "Move gesture detection and recognition paramters to resources" into jb-mr1-dev

parents 47417ec1 80bcb996
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -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">
+17 −0
Original line number Diff line number Diff line
@@ -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
     -->
+11 −0
Original line number Diff line number Diff line
@@ -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"
+10 −4
Original line number Diff line number Diff line
@@ -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;
@@ -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(
@@ -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();
@@ -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() {
@@ -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();
@@ -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) {
+92 −40
Original line number Diff line number Diff line
@@ -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();
@@ -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
@@ -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));
        }
@@ -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) {
@@ -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() {
@@ -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