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

Commit 16e9d343 authored by Satoshi Kataoka's avatar Satoshi Kataoka Committed by Android (Google) Code Review
Browse files

Merge "Tweak beeline speed"

parents b5fc0e02 6ae8dd43
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -86,7 +86,7 @@
    <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>
    <integer name="config_gesture_recognition_update_time">300</integer>
    <integer name="config_gesture_recognition_update_time">100</integer>
    <fraction name="config_gesture_recognition_speed_threshold">550%</fraction>
    <!-- Suppress showing key preview duration after batch input in millisecond -->
    <integer name="config_suppress_key_preview_after_batch_input_duration">1000</integer>
+11 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.inputmethod.latin;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
@@ -42,6 +43,7 @@ public final class DebugSettings extends PreferenceFragment

    private boolean mServiceNeedsRestart = false;
    private CheckBoxPreference mDebugMode;
    private CheckBoxPreference mStatisticsLoggingPref;

    @Override
    public void onCreate(Bundle icicle) {
@@ -59,6 +61,7 @@ public final class DebugSettings extends PreferenceFragment
        }
        final Preference statisticsLoggingPref = findPreference(PREF_STATISTICS_LOGGING_KEY);
        if (statisticsLoggingPref instanceof CheckBoxPreference) {
            mStatisticsLoggingPref = (CheckBoxPreference) statisticsLoggingPref;
            if (!SHOW_STATISTICS_LOGGING) {
                getPreferenceScreen().removePreference(statisticsLoggingPref);
            }
@@ -80,6 +83,14 @@ public final class DebugSettings extends PreferenceFragment
        if (key.equals(DEBUG_MODE_KEY)) {
            if (mDebugMode != null) {
                mDebugMode.setChecked(prefs.getBoolean(DEBUG_MODE_KEY, false));
                final boolean checked = mDebugMode.isChecked();
                if (mStatisticsLoggingPref != null) {
                    if (checked) {
                        getPreferenceScreen().addPreference(mStatisticsLoggingPref);
                    } else {
                        getPreferenceScreen().removePreference(mStatisticsLoggingPref);
                    }
                }
                updateDebugMode();
                mServiceNeedsRestart = true;
            }
+6 −0
Original line number Diff line number Diff line
@@ -429,4 +429,10 @@ typedef enum {
    // Additional proximity char which can differ by language.
    ADDITIONAL_PROXIMITY_CHAR
} ProximityType;

typedef enum {
    NOT_A_DOUBLE_LETTER,
    A_DOUBLE_LETTER,
    A_STRONG_DOUBLE_LETTER
} DoubleLetterLevel;
#endif // LATINIME_DEFINES_H
+61 −24
Original line number Diff line number Diff line
@@ -31,6 +31,10 @@ const int ProximityInfoState::NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR =
        1 << NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR_LOG_2;
const float ProximityInfoState::NOT_A_DISTANCE_FLOAT = -1.0f;
const int ProximityInfoState::NOT_A_CODE = -1;
const int ProximityInfoState::LOOKUP_RADIUS_PERCENTILE = 50;
const int ProximityInfoState::FIRST_POINT_TIME_OFFSET_MILLIS = 150;
const int ProximityInfoState::STRONG_DOUBLE_LETTER_TIME_MILLIS = 600;
const int ProximityInfoState::MIN_DOUBLE_LETTER_BEELINE_SPEED_PERCENTILE = 5;

void ProximityInfoState::initInputParams(const int pointerId, const float maxPointToKeyLength,
        const ProximityInfo *proximityInfo, const int *const inputCodes, const int inputSize,
@@ -105,7 +109,7 @@ void ProximityInfoState::initInputParams(const int pointerId, const float maxPoi
        mNearKeysVector.clear();
        mSearchKeysVector.clear();
        mSpeedRates.clear();
        mBeelineSpeedRates.clear();
        mBeelineSpeedPercentiles.clear();
        mCharProbabilities.clear();
        mDirections.clear();
    }
@@ -253,9 +257,9 @@ void ProximityInfoState::initInputParams(const int pointerId, const float maxPoi
        AKLOGI("===== sampled points =====");
        for (int i = 0; i < mSampledInputSize; ++i) {
            if (isGeometric) {
                AKLOGI("%d: x = %d, y = %d, time = %d, relative speed = %.4f, beeline speed = %.4f",
                AKLOGI("%d: x = %d, y = %d, time = %d, relative speed = %.4f, beeline speed = %d",
                        i, mSampledInputXs[i], mSampledInputYs[i], mTimes[i], mSpeedRates[i],
                        getBeelineSpeedRate(i));
                        getBeelineSpeedPercentile(i));
            }
            sampledX << mSampledInputXs[i];
            sampledY << mSampledInputYs[i];
@@ -366,54 +370,65 @@ void ProximityInfoState::refreshSpeedRates(const int inputSize, const int *const
    }
}

static const int MAX_PERCENTILE = 100;
void ProximityInfoState::refreshBeelineSpeedRates(const int inputSize,
        const int *const xCoordinates, const int *const yCoordinates, const int * times) {
    mBeelineSpeedRates.resize(mSampledInputSize);
    if (DEBUG_SAMPLING_POINTS){
        AKLOGI("--- refresh beeline speed rates");
    }
    mBeelineSpeedPercentiles.resize(mSampledInputSize);
    for (int i = 0; i < mSampledInputSize; ++i) {
        mBeelineSpeedRates[i] = calculateBeelineSpeedRate(
                i, inputSize, xCoordinates, yCoordinates, times);
        mBeelineSpeedPercentiles[i] = static_cast<int>(calculateBeelineSpeedRate(
                i, inputSize, xCoordinates, yCoordinates, times) * MAX_PERCENTILE);
    }
}

float ProximityInfoState::calculateBeelineSpeedRate(
        const int id, const int inputSize, const int *const xCoordinates,
        const int *const yCoordinates, const int * times) const {
    static const int MAX_PERCENTILE = 100;
    static const int LOOKUP_TIME_PERCENTILE = 30;
    static const int LOOKUP_RADIUS_PERCENTILE = 50;
    if (mSampledInputSize <= 0 || mAverageSpeed < 0.1f) {
    if (mSampledInputSize <= 0 || mAverageSpeed < 0.001f) {
        if (DEBUG_SAMPLING_POINTS){
            AKLOGI("--- invalid state: cancel. size = %d, ave = %f",
                    mSampledInputSize, mAverageSpeed);
        }
        return 1.0f;
    }
    const int lookupRadius =
            mProximityInfo->getMostCommonKeyWidth() * LOOKUP_RADIUS_PERCENTILE / MAX_PERCENTILE;
    const int x0 = mSampledInputXs[id];
    const int y0 = mSampledInputYs[id];
    const int lookupTime =
            (mTimes.back() - mTimes.front()) * LOOKUP_TIME_PERCENTILE / MAX_PERCENTILE;
    if (lookupTime <= 0) {
        return 1.0f;
    }
    const int actualInputIndex = mInputIndice[id];
    int tempTime = 0;
    int tempBeelineDistance = 0;
    int start = mInputIndice[id];
    int start = actualInputIndex;
    // lookup forward
    while (start > 0 && tempTime < lookupTime && tempBeelineDistance < lookupRadius) {
    while (start > 0 && tempBeelineDistance < lookupRadius) {
        tempTime += times[start] - times[start - 1];
        --start;
        tempBeelineDistance = getDistanceInt(x0, y0, xCoordinates[start], yCoordinates[start]);
    }
    // Exclusive unless this is an edge point
    if (start > 0 && start < actualInputIndex) {
        ++start;
    }
    tempTime= 0;
    tempBeelineDistance = 0;
    int end = mInputIndice[id];
    int end = actualInputIndex;
    // lookup backward
    while (end < static_cast<int>(inputSize - 1) && tempTime < lookupTime
            && tempBeelineDistance < lookupRadius) {
    while (end < (inputSize - 1) && tempBeelineDistance < lookupRadius) {
        tempTime += times[end + 1] - times[end];
        ++end;
        tempBeelineDistance = getDistanceInt(x0, y0, xCoordinates[start], yCoordinates[start]);
        tempBeelineDistance = getDistanceInt(x0, y0, xCoordinates[end], yCoordinates[end]);
    }
    // Exclusive unless this is an edge point
    if (end > actualInputIndex && end < (inputSize - 1)) {
        --end;
    }

    if (start == end) {
    if (start >= end) {
        if (DEBUG_DOUBLE_LETTER) {
            AKLOGI("--- double letter: start == end %d", start);
        }
        return 1.0f;
    }

@@ -422,11 +437,33 @@ float ProximityInfoState::calculateBeelineSpeedRate(
    const int x3 = xCoordinates[end];
    const int y3 = yCoordinates[end];
    const int beelineDistance = getDistanceInt(x2, y2, x3, y3);
    const int time = times[end] - times[start];
    int adjustedStartTime = times[start];
    if (start == 0 && actualInputIndex == 0 && inputSize > 1) {
        adjustedStartTime += FIRST_POINT_TIME_OFFSET_MILLIS;
    }
    int adjustedEndTime = times[end];
    if (end == (inputSize - 1) && inputSize > 1) {
        adjustedEndTime -= FIRST_POINT_TIME_OFFSET_MILLIS;
    }
    const int time = adjustedEndTime - adjustedStartTime;
    if (time <= 0) {
        return 1.0f;
    }
    return (static_cast<float>(beelineDistance) / static_cast<float>(time)) / mAverageSpeed;

    if (time >= STRONG_DOUBLE_LETTER_TIME_MILLIS){
        return 0.0f;
    }
    if (DEBUG_DOUBLE_LETTER) {
        AKLOGI("--- (%d, %d) double letter: start = %d, end = %d, dist = %d, time = %d, speed = %f,"
                " ave = %f, val = %f, start time = %d, end time = %d",
                id, mInputIndice[id], start, end, beelineDistance, time,
                (static_cast<float>(beelineDistance) / static_cast<float>(time)), mAverageSpeed,
                ((static_cast<float>(beelineDistance) / static_cast<float>(time)) / mAverageSpeed),
                adjustedStartTime, adjustedEndTime);
    }
    // Offset 1%
    // TODO: Detect double letter more smartly
    return 0.01f + static_cast<float>(beelineDistance) / static_cast<float>(time) / mAverageSpeed;
}

bool ProximityInfoState::checkAndReturnIsContinuationPossible(const int inputSize,
+20 −5
Original line number Diff line number Diff line
@@ -39,6 +39,10 @@ class ProximityInfoState {
    static const int NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR;
    static const float NOT_A_DISTANCE_FLOAT;
    static const int NOT_A_CODE;
    static const int LOOKUP_RADIUS_PERCENTILE;
    static const int FIRST_POINT_TIME_OFFSET_MILLIS;
    static const int STRONG_DOUBLE_LETTER_TIME_MILLIS;
    static const int MIN_DOUBLE_LETTER_BEELINE_SPEED_PERCENTILE;

    /////////////////////////////////////////
    // Defined in proximity_info_state.cpp //
@@ -56,8 +60,8 @@ class ProximityInfoState {
              mHasTouchPositionCorrectionData(false), mMostCommonKeyWidthSquare(0), mLocaleStr(),
              mKeyCount(0), mCellHeight(0), mCellWidth(0), mGridHeight(0), mGridWidth(0),
              mIsContinuationPossible(false), mSampledInputXs(), mSampledInputYs(), mTimes(),
              mInputIndice(), mLengthCache(), mDistanceCache(), mSpeedRates(),
              mDirections(), mBeelineSpeedRates(), mCharProbabilities(), mNearKeysVector(),
              mInputIndice(), mLengthCache(), mBeelineSpeedPercentiles(), mDistanceCache(),
              mSpeedRates(), mDirections(), mCharProbabilities(), mNearKeysVector(),
              mSearchKeysVector(), mTouchPositionCorrectionEnabled(false), mSampledInputSize(0) {
        memset(mInputCodes, 0, sizeof(mInputCodes));
        memset(mNormalizedSquaredDistances, 0, sizeof(mNormalizedSquaredDistances));
@@ -167,8 +171,19 @@ class ProximityInfoState {
        return mSpeedRates[index];
    }

    AK_FORCE_INLINE float getBeelineSpeedRate(const int id) const {
        return mBeelineSpeedRates[id];
    AK_FORCE_INLINE int getBeelineSpeedPercentile(const int id) const {
        return mBeelineSpeedPercentiles[id];
    }

    AK_FORCE_INLINE DoubleLetterLevel getDoubleLetterLevel(const int id) const {
        const int beelineSpeedRate = getBeelineSpeedPercentile(id);
        if (beelineSpeedRate == 0) {
            return A_STRONG_DOUBLE_LETTER;
        } else if (beelineSpeedRate < MIN_DOUBLE_LETTER_BEELINE_SPEED_PERCENTILE) {
            return A_DOUBLE_LETTER;
        } else {
            return NOT_A_DOUBLE_LETTER;
        }
    }

    float getDirection(const int index) const {
@@ -259,10 +274,10 @@ class ProximityInfoState {
    std::vector<int> mTimes;
    std::vector<int> mInputIndice;
    std::vector<int> mLengthCache;
    std::vector<int> mBeelineSpeedPercentiles;
    std::vector<float> mDistanceCache;
    std::vector<float> mSpeedRates;
    std::vector<float> mDirections;
    std::vector<float> mBeelineSpeedRates;
    // probabilities of skipping or mapping to a key for each point.
    std::vector<hash_map_compat<int, float> > mCharProbabilities;
    // The vector for the key code set which holds nearby keys for each sampled input point