Merge remote-tracking branch 'goog/master' into mergescriptpackage
commit
e5d8dc958a
|
@ -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>
|
||||
|
|
|
@ -749,12 +749,12 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
|
|||
if (getActivePointerTrackerCount() == 1) {
|
||||
sInGesture = false;
|
||||
sTimeRecorder.onEndBatchInput(eventTime);
|
||||
mTimerProxy.cancelAllUpdateBatchInputTimers();
|
||||
if (!mIsTrackingCanceled) {
|
||||
if (DEBUG_LISTENER) {
|
||||
Log.d(TAG, String.format("[%d] onEndBatchInput : batchPoints=%d",
|
||||
mPointerId, sAggregratedPointers.getPointerSize()));
|
||||
}
|
||||
mTimerProxy.cancelAllUpdateBatchInputTimers();
|
||||
mListener.onEndBatchInput(sAggregratedPointers);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -1464,7 +1464,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
|
|||
private static final class BatchInputUpdater implements Handler.Callback {
|
||||
private final Handler mHandler;
|
||||
private LatinIME mLatinIme;
|
||||
private boolean mInBatchInput; // synchornized using "this".
|
||||
private boolean mInBatchInput; // synchronized using "this".
|
||||
|
||||
private BatchInputUpdater() {
|
||||
final HandlerThread handlerThread = new HandlerThread(
|
||||
|
@ -1496,6 +1496,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
|
|||
|
||||
// Run in the UI thread.
|
||||
public synchronized void onStartBatchInput() {
|
||||
mHandler.removeMessages(MSG_UPDATE_GESTURE_PREVIEW_AND_SUGGESTION_STRIP);
|
||||
mInBatchInput = true;
|
||||
}
|
||||
|
||||
|
@ -1503,7 +1504,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
|
|||
private synchronized void updateBatchInput(final InputPointers batchPointers,
|
||||
final LatinIME latinIme) {
|
||||
if (!mInBatchInput) {
|
||||
// Batch input has ended while the message was being delivered.
|
||||
// Batch input has ended or canceled while the message was being delivered.
|
||||
return;
|
||||
}
|
||||
final SuggestedWords suggestedWords = getSuggestedWordsGestureLocked(
|
||||
|
@ -1523,7 +1524,7 @@ public final class LatinIME extends InputMethodService implements KeyboardAction
|
|||
.sendToTarget();
|
||||
}
|
||||
|
||||
public void onCancelBatchInput(final LatinIME latinIme) {
|
||||
public synchronized void onCancelBatchInput(final LatinIME latinIme) {
|
||||
mInBatchInput = false;
|
||||
latinIme.mHandler.showGesturePreviewAndSuggestionStrip(
|
||||
SuggestedWords.EMPTY, true /* dismissGestureFloatingPreviewText */);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue