Merge "[Rlog47] Replayer service, inspect-researchLog.py"
diff --git a/java/src/com/android/inputmethod/keyboard/internal/GestureFloatingPreviewText.java b/java/src/com/android/inputmethod/keyboard/internal/GestureFloatingPreviewText.java
index 28655a9..ab810a5 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/GestureFloatingPreviewText.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/GestureFloatingPreviewText.java
@@ -28,7 +28,6 @@
 import com.android.inputmethod.keyboard.PointerTracker;
 import com.android.inputmethod.latin.CoordinateUtils;
 import com.android.inputmethod.latin.R;
-import com.android.inputmethod.latin.ResizableIntArray;
 import com.android.inputmethod.latin.SuggestedWords;
 
 /**
@@ -44,16 +43,17 @@
  * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewRoundRadius
  */
 public class GestureFloatingPreviewText extends AbstractDrawingPreview {
-    private static final class GesturePreviewTextParams {
-        public final int mGesturePreviewTextSize;
-        public final int mGesturePreviewTextColor;
+    protected static final class GesturePreviewTextParams {
         public final int mGesturePreviewTextOffset;
         public final int mGesturePreviewTextHeight;
-        public final int mGesturePreviewColor;
         public final float mGesturePreviewHorizontalPadding;
         public final float mGesturePreviewVerticalPadding;
         public final float mGesturePreviewRoundRadius;
-        public final Paint mTextPaint;
+
+        private final int mGesturePreviewTextSize;
+        private final int mGesturePreviewTextColor;
+        private final int mGesturePreviewColor;
+        private final Paint mPaint = new Paint();
 
         private static final char[] TEXT_HEIGHT_REFERENCE_CHAR = { 'M' };
 
@@ -73,37 +73,36 @@
             mGesturePreviewRoundRadius = mainKeyboardViewAttr.getDimension(
                     R.styleable.MainKeyboardView_gestureFloatingPreviewRoundRadius, 0.0f);
 
-            final Paint textPaint = new Paint();
-            textPaint.setAntiAlias(true);
-            textPaint.setTextAlign(Align.CENTER);
-            textPaint.setTextSize(mGesturePreviewTextSize);
-            mTextPaint = textPaint;
+            final Paint textPaint = getTextPaint();
             final Rect textRect = new Rect();
             textPaint.getTextBounds(TEXT_HEIGHT_REFERENCE_CHAR, 0, 1, textRect);
             mGesturePreviewTextHeight = textRect.height();
         }
+
+        public Paint getTextPaint() {
+            mPaint.setAntiAlias(true);
+            mPaint.setTextAlign(Align.CENTER);
+            mPaint.setTextSize(mGesturePreviewTextSize);
+            mPaint.setColor(mGesturePreviewTextColor);
+            return mPaint;
+        }
+
+        public Paint getBackgroundPaint() {
+            mPaint.setColor(mGesturePreviewColor);
+            return mPaint;
+        }
     }
 
-    protected final GesturePreviewTextParams mParams;
-    protected int mPreviewWordNum;
-    protected final RectF mGesturePreviewRectangle = new RectF();
-    protected int mHighlightedWordIndex;
-
-    private static final int PREVIEW_TEXT_ARRAY_CAPACITY = 10;
-    // These variables store the positions of preview words. In multi-preview mode, the gesture
-    // floating preview at most shows PREVIEW_TEXT_ARRAY_CAPACITY words.
-    protected final ResizableIntArray mPreviewTextXArray = new ResizableIntArray(
-            PREVIEW_TEXT_ARRAY_CAPACITY);
-    protected final ResizableIntArray mPreviewTextYArray = new ResizableIntArray(
-            PREVIEW_TEXT_ARRAY_CAPACITY);
-
-    protected SuggestedWords mSuggestedWords = SuggestedWords.EMPTY;
-    public final int[] mLastPointerCoords = CoordinateUtils.newInstance();
+    private final GesturePreviewTextParams mParams;
+    private final RectF mGesturePreviewRectangle = new RectF();
+    private int mPreviewTextX;
+    private int mPreviewTextY;
+    private SuggestedWords mSuggestedWords = SuggestedWords.EMPTY;
+    private final int[] mLastPointerCoords = CoordinateUtils.newInstance();
 
     public GestureFloatingPreviewText(final View drawingView, final TypedArray typedArray) {
         super(drawingView);
         mParams = new GesturePreviewTextParams(typedArray);
-        mHighlightedWordIndex = 0;
     }
 
     public void setSuggetedWords(final SuggestedWords suggestedWords) {
@@ -114,13 +113,6 @@
         updatePreviewPosition();
     }
 
-    protected void drawText(final Canvas canvas, final String text, final float textX,
-            final float textY, final int color) {
-        final Paint paint = mParams.mTextPaint;
-        paint.setColor(color);
-        canvas.drawText(text, textX, textY, paint);
-    }
-
     @Override
     public void setPreviewPosition(final PointerTracker tracker) {
         final boolean needsToUpdateLastPointer =
@@ -142,14 +134,11 @@
                 || TextUtils.isEmpty(mSuggestedWords.getWord(0))) {
             return;
         }
-        final Paint paint = mParams.mTextPaint;
-        paint.setColor(mParams.mGesturePreviewColor);
         final float round = mParams.mGesturePreviewRoundRadius;
-        canvas.drawRoundRect(mGesturePreviewRectangle, round, round, paint);
+        canvas.drawRoundRect(
+                mGesturePreviewRectangle, round, round, mParams.getBackgroundPaint());
         final String text = mSuggestedWords.getWord(0);
-        final int textX = mPreviewTextXArray.get(0);
-        final int textY = mPreviewTextYArray.get(0);
-        drawText(canvas, text, textX, textY, mParams.mGesturePreviewTextColor);
+        canvas.drawText(text, mPreviewTextX, mPreviewTextY, mParams.getTextPaint());
     }
 
     /**
@@ -162,11 +151,10 @@
         }
         final String text = mSuggestedWords.getWord(0);
 
-        final Paint paint = mParams.mTextPaint;
         final RectF rectangle = mGesturePreviewRectangle;
 
         final int textHeight = mParams.mGesturePreviewTextHeight;
-        final float textWidth = paint.measureText(text);
+        final float textWidth = mParams.getTextPaint().measureText(text);
         final float hPad = mParams.mGesturePreviewHorizontalPadding;
         final float vPad = mParams.mGesturePreviewVerticalPadding;
         final float rectWidth = textWidth + hPad * 2.0f;
@@ -180,10 +168,8 @@
                 - mParams.mGesturePreviewTextOffset - rectHeight;
         rectangle.set(rectX, rectY, rectX + rectWidth, rectY + rectHeight);
 
-        final int textX = (int)(rectX + hPad + textWidth / 2.0f);
-        final int textY = (int)(rectY + vPad) + textHeight;
-        mPreviewTextXArray.add(0, textX);
-        mPreviewTextYArray.add(0, textY);
+        mPreviewTextX = (int)(rectX + hPad + textWidth / 2.0f);
+        mPreviewTextY = (int)(rectY + vPad) + textHeight;
         // TODO: Should narrow the invalidate region.
         getDrawingView().invalidate();
     }
diff --git a/java/src/com/android/inputmethod/research/ResearchLogger.java b/java/src/com/android/inputmethod/research/ResearchLogger.java
index d9849bd..47f3453 100644
--- a/java/src/com/android/inputmethod/research/ResearchLogger.java
+++ b/java/src/com/android/inputmethod/research/ResearchLogger.java
@@ -184,7 +184,7 @@
     private Suggest mSuggest;
     private MainKeyboardView mMainKeyboardView;
     // TODO: Check whether a superclass can be used instead of LatinIME.
-    private LatinIME mLatinIME;
+    /* package for test */ LatinIME mLatinIME;
     private final Statistics mStatistics;
     private final MotionEventReader mMotionEventReader = new MotionEventReader();
     private final Replayer mReplayer = Replayer.getInstance();
diff --git a/native/jni/src/dictionary.h b/native/jni/src/dictionary.h
index 83676b2..ecdddd7 100644
--- a/native/jni/src/dictionary.h
+++ b/native/jni/src/dictionary.h
@@ -31,15 +31,15 @@
 class Dictionary {
  public:
     // Taken from SuggestedWords.java
-    const static int KIND_TYPED = 0; // What user typed
-    const static int KIND_CORRECTION = 1; // Simple correction/suggestion
-    const static int KIND_COMPLETION = 2; // Completion (suggestion with appended chars)
-    const static int KIND_WHITELIST = 3; // Whitelisted word
-    const static int KIND_BLACKLIST = 4; // Blacklisted word
-    const static int KIND_HARDCODED = 5; // Hardcoded suggestion, e.g. punctuation
-    const static int KIND_APP_DEFINED = 6; // Suggested by the application
-    const static int KIND_SHORTCUT = 7; // A shortcut
-    const static int KIND_PREDICTION = 8; // A prediction (== a suggestion with no input)
+    static const int KIND_TYPED = 0; // What user typed
+    static const int KIND_CORRECTION = 1; // Simple correction/suggestion
+    static const int KIND_COMPLETION = 2; // Completion (suggestion with appended chars)
+    static const int KIND_WHITELIST = 3; // Whitelisted word
+    static const int KIND_BLACKLIST = 4; // Blacklisted word
+    static const int KIND_HARDCODED = 5; // Hardcoded suggestion, e.g. punctuation
+    static const int KIND_APP_DEFINED = 6; // Suggested by the application
+    static const int KIND_SHORTCUT = 7; // A shortcut
+    static const int KIND_PREDICTION = 8; // A prediction (== a suggestion with no input)
 
     Dictionary(void *dict, int dictSize, int mmapFd, int dictBufAdjust);
 
diff --git a/native/jni/src/proximity_info.cpp b/native/jni/src/proximity_info.cpp
index a0bad1a..d812745 100644
--- a/native/jni/src/proximity_info.cpp
+++ b/native/jni/src/proximity_info.cpp
@@ -24,11 +24,10 @@
 #include "geometry_utils.h"
 #include "jni.h"
 #include "proximity_info.h"
+#include "proximity_info_params.h"
 
 namespace latinime {
 
-/* static */ const float ProximityInfo::NOT_A_DISTANCE_FLOAT = -1.0f;
-
 static AK_FORCE_INLINE void safeGetOrFillZeroIntArrayRegion(JNIEnv *env, jintArray jArray,
         jsize len, jint *buffer) {
     if (jArray && buffer) {
@@ -129,17 +128,15 @@
 
 float ProximityInfo::getNormalizedSquaredDistanceFromCenterFloatG(
         const int keyId, const int x, const int y) const {
-    const static float verticalSweetSpotScaleForGeometric = 1.1f;
     const bool correctTouchPosition = hasTouchPositionCorrectionData();
-    const float centerX = static_cast<float>(correctTouchPosition
-            ? getSweetSpotCenterXAt(keyId)
+    const float centerX = static_cast<float>(correctTouchPosition ? getSweetSpotCenterXAt(keyId)
             : getKeyCenterXOfKeyIdG(keyId));
     const float visualKeyCenterY = static_cast<float>(getKeyCenterYOfKeyIdG(keyId));
     float centerY;
     if (correctTouchPosition) {
         const float sweetSpotCenterY = static_cast<float>(getSweetSpotCenterYAt(keyId));
         const float gapY = sweetSpotCenterY - visualKeyCenterY;
-        centerY = visualKeyCenterY + gapY * verticalSweetSpotScaleForGeometric;
+        centerY = visualKeyCenterY + gapY * ProximityInfoParams::VERTICAL_SWEET_SPOT_SCALE_G;
     } else {
         centerY = visualKeyCenterY;
     }
diff --git a/native/jni/src/proximity_info.h b/native/jni/src/proximity_info.h
index f3a68e4..d42c723 100644
--- a/native/jni/src/proximity_info.h
+++ b/native/jni/src/proximity_info.h
@@ -83,7 +83,6 @@
 
  private:
     DISALLOW_IMPLICIT_CONSTRUCTORS(ProximityInfo);
-    static const float NOT_A_DISTANCE_FLOAT;
 
     void initializeG();
     float calculateNormalizedSquaredDistance(const int keyIndex, const int inputIndex) const;
diff --git a/native/jni/src/proximity_info_params.cpp b/native/jni/src/proximity_info_params.cpp
index f7b3d4d..1410ab5 100644
--- a/native/jni/src/proximity_info_params.cpp
+++ b/native/jni/src/proximity_info_params.cpp
@@ -14,22 +14,25 @@
  * limitations under the License.
  */
 
+#include "defines.h"
 #include "proximity_info_params.h"
 
 namespace latinime {
-const int ProximityInfoParams::LOOKUP_RADIUS_PERCENTILE = 50;
-const int ProximityInfoParams::FIRST_POINT_TIME_OFFSET_MILLIS = 150;
-const int ProximityInfoParams::STRONG_DOUBLE_LETTER_TIME_MILLIS = 600;
-const int ProximityInfoParams::MIN_DOUBLE_LETTER_BEELINE_SPEED_PERCENTILE = 5;
-const int ProximityInfoParams::NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR_LOG_2 = 10;
-const int ProximityInfoParams::NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR =
-        1 << NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR_LOG_2;
 const float ProximityInfoParams::NOT_A_DISTANCE_FLOAT = -1.0f;
+const int ProximityInfoParams::MIN_DOUBLE_LETTER_BEELINE_SPEED_PERCENTILE = 5;
+const float ProximityInfoParams::VERTICAL_SWEET_SPOT_SCALE_G = 1.1f;
 
-// Per method constants
+/* Per method constants */
+// Used by ProximityInfoStateUtils::initGeometricDistanceInfos()
 const float ProximityInfoParams::NEAR_KEY_NORMALIZED_SQUARED_THRESHOLD = 4.0f;
+
+// Used by ProximityInfoStateUtils::updateNearKeysDistances()
 const float ProximityInfoParams::NEAR_KEY_THRESHOLD_FOR_DISTANCE = 2.0f;
+
+// Used by ProximityInfoStateUtils::isPrevLocalMin()
 const float ProximityInfoParams::MARGIN_FOR_PREV_LOCAL_MIN = 0.01f;
+
+// Used by ProximityInfoStateUtils::getPointScore()
 const int ProximityInfoParams::DISTANCE_BASE_SCALE = 100;
 const float ProximityInfoParams::NEAR_KEY_THRESHOLD_FOR_POINT_SCORE = 0.6f;
 const int ProximityInfoParams::CORNER_CHECK_DISTANCE_THRESHOLD_SCALE = 25;
@@ -39,6 +42,62 @@
 const float ProximityInfoParams::CORNER_SUM_ANGLE_THRESHOLD = M_PI_F / 4.0f;
 const float ProximityInfoParams::CORNER_SCORE = 1.0f;
 
+// Used by ProximityInfoStateUtils::refreshSpeedRates()
+const int ProximityInfoParams::NUM_POINTS_FOR_SPEED_CALCULATION = 2;
+
+// Used by ProximityInfoStateUtils::pushTouchPoint()
+const int ProximityInfoParams::LAST_POINT_SKIP_DISTANCE_SCALE = 4;
+
+// Used by ProximityInfoStateUtils::updateAlignPointProbabilities()
+const float ProximityInfoParams::MIN_PROBABILITY = 0.000001f;
+const float ProximityInfoParams::MAX_SKIP_PROBABILITY = 0.95f;
+const float ProximityInfoParams::SKIP_FIRST_POINT_PROBABILITY = 0.01f;
+const float ProximityInfoParams::SKIP_LAST_POINT_PROBABILITY = 0.1f;
+const float ProximityInfoParams::MIN_SPEED_RATE_FOR_SKIP_PROBABILITY = 0.15f;
+const float ProximityInfoParams::SPEED_WEIGHT_FOR_SKIP_PROBABILITY = 0.9f;
+const float ProximityInfoParams::SLOW_STRAIGHT_WEIGHT_FOR_SKIP_PROBABILITY = 0.6f;
+const float ProximityInfoParams::NEAREST_DISTANCE_WEIGHT = 0.5f;
+const float ProximityInfoParams::NEAREST_DISTANCE_BIAS = 0.5f;
+const float ProximityInfoParams::NEAREST_DISTANCE_WEIGHT_FOR_LAST = 0.6f;
+const float ProximityInfoParams::NEAREST_DISTANCE_BIAS_FOR_LAST = 0.4f;
+const float ProximityInfoParams::ANGLE_WEIGHT = 0.90f;
+const float ProximityInfoParams::DEEP_CORNER_ANGLE_THRESHOLD = M_PI_F * 60.0f / 180.0f;
+const float ProximityInfoParams::SKIP_DEEP_CORNER_PROBABILITY = 0.1f;
+const float ProximityInfoParams::CORNER_ANGLE_THRESHOLD = M_PI_F * 30.0f / 180.0f;
+const float ProximityInfoParams::STRAIGHT_ANGLE_THRESHOLD = M_PI_F * 15.0f / 180.0f;
+const float ProximityInfoParams::SKIP_CORNER_PROBABILITY = 0.4f;
+const float ProximityInfoParams::SPEED_MARGIN = 0.1f;
+const float ProximityInfoParams::CENTER_VALUE_OF_NORMALIZED_DISTRIBUTION = 0.0f;
+// TODO: The variance is critical for accuracy; thus, adjusting these parameter by machine
+// learning or something would be efficient.
+const float ProximityInfoParams::SPEEDxANGLE_WEIGHT_FOR_STANDARD_DIVIATION = 0.3f;
+const float ProximityInfoParams::MAX_SPEEDxANGLE_RATE_FOR_STANDERD_DIVIATION = 0.25f;
+const float ProximityInfoParams::SPEEDxNEAREST_WEIGHT_FOR_STANDARD_DIVIATION = 0.5f;
+const float ProximityInfoParams::MAX_SPEEDxNEAREST_RATE_FOR_STANDERD_DIVIATION = 0.15f;
+const float ProximityInfoParams::MIN_STANDERD_DIVIATION = 0.37f;
+const float ProximityInfoParams::PREV_DISTANCE_WEIGHT = 0.5f;
+const float ProximityInfoParams::NEXT_DISTANCE_WEIGHT = 0.6f;
+
+// Used by ProximityInfoStateUtils::suppressCharProbabilities()
+const float ProximityInfoParams::SUPPRESSION_LENGTH_WEIGHT = 1.5f;
+const float ProximityInfoParams::MIN_SUPPRESSION_RATE = 0.1f;
+const float ProximityInfoParams::SUPPRESSION_WEIGHT = 0.5f;
+const float ProximityInfoParams::SUPPRESSION_WEIGHT_FOR_PROBABILITY_GAIN = 0.1f;
+const float ProximityInfoParams::SKIP_PROBABALITY_WEIGHT_FOR_PROBABILITY_GAIN = 0.3f;
+
+// Used by ProximityInfoStateUtils::getMostProbableString()
+const float ProximityInfoParams::DEMOTION_LOG_PROBABILITY = 0.3f;
+
+// Used by ProximityInfoStateUtils::updateSampledSearchKeysVector()
 // TODO: Investigate if this is required
 const float ProximityInfoParams::SEARCH_KEY_RADIUS_RATIO = 0.95f;
+
+// Used by ProximityInfoStateUtils::calculateBeelineSpeedRate()
+const int ProximityInfoParams::LOOKUP_RADIUS_PERCENTILE = 50;
+const int ProximityInfoParams::FIRST_POINT_TIME_OFFSET_MILLIS = 150;
+const int ProximityInfoParams::STRONG_DOUBLE_LETTER_TIME_MILLIS = 600;
+
+// Used by ProximityInfoStateUtils::calculateNormalizedSquaredDistance()
+const int ProximityInfoParams::NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR = 1 << 10;
+
 } // namespace latinime
diff --git a/native/jni/src/proximity_info_params.h b/native/jni/src/proximity_info_params.h
index 978b999..7c26208 100644
--- a/native/jni/src/proximity_info_params.h
+++ b/native/jni/src/proximity_info_params.h
@@ -23,13 +23,9 @@
 
 class ProximityInfoParams {
  public:
-    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;
-    static const int NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR;
     static const float NOT_A_DISTANCE_FLOAT;
-    static const float SEARCH_KEY_RADIUS_RATIO;
+    static const int MIN_DOUBLE_LETTER_BEELINE_SPEED_PERCENTILE;
+    static const float VERTICAL_SWEET_SPOT_SCALE_G;
 
     // Used by ProximityInfoStateUtils::initGeometricDistanceInfos()
     static const float NEAR_KEY_NORMALIZED_SQUARED_THRESHOLD;
@@ -50,9 +46,63 @@
     static const float CORNER_SUM_ANGLE_THRESHOLD;
     static const float CORNER_SCORE;
 
+    // Used by ProximityInfoStateUtils::refreshSpeedRates()
+    static const int NUM_POINTS_FOR_SPEED_CALCULATION;
+
+    // Used by ProximityInfoStateUtils::pushTouchPoint()
+    static const int LAST_POINT_SKIP_DISTANCE_SCALE;
+
+    // Used by ProximityInfoStateUtils::updateAlignPointProbabilities()
+    static const float MIN_PROBABILITY;
+    static const float MAX_SKIP_PROBABILITY;
+    static const float SKIP_FIRST_POINT_PROBABILITY;
+    static const float SKIP_LAST_POINT_PROBABILITY;
+    static const float MIN_SPEED_RATE_FOR_SKIP_PROBABILITY;
+    static const float SPEED_WEIGHT_FOR_SKIP_PROBABILITY;
+    static const float SLOW_STRAIGHT_WEIGHT_FOR_SKIP_PROBABILITY;
+    static const float NEAREST_DISTANCE_WEIGHT;
+    static const float NEAREST_DISTANCE_BIAS;
+    static const float NEAREST_DISTANCE_WEIGHT_FOR_LAST;
+    static const float NEAREST_DISTANCE_BIAS_FOR_LAST;
+    static const float ANGLE_WEIGHT;
+    static const float DEEP_CORNER_ANGLE_THRESHOLD;
+    static const float SKIP_DEEP_CORNER_PROBABILITY;
+    static const float CORNER_ANGLE_THRESHOLD;
+    static const float STRAIGHT_ANGLE_THRESHOLD;
+    static const float SKIP_CORNER_PROBABILITY;
+    static const float SPEED_MARGIN;
+    static const float CENTER_VALUE_OF_NORMALIZED_DISTRIBUTION;
+    static const float SPEEDxANGLE_WEIGHT_FOR_STANDARD_DIVIATION;
+    static const float MAX_SPEEDxANGLE_RATE_FOR_STANDERD_DIVIATION;
+    static const float SPEEDxNEAREST_WEIGHT_FOR_STANDARD_DIVIATION;
+    static const float MAX_SPEEDxNEAREST_RATE_FOR_STANDERD_DIVIATION;
+    static const float MIN_STANDERD_DIVIATION;
+    static const float PREV_DISTANCE_WEIGHT;
+    static const float NEXT_DISTANCE_WEIGHT;
+
+    // Used by ProximityInfoStateUtils::suppressCharProbabilities()
+    static const float SUPPRESSION_LENGTH_WEIGHT;
+    static const float MIN_SUPPRESSION_RATE;
+    static const float SUPPRESSION_WEIGHT;
+    static const float SUPPRESSION_WEIGHT_FOR_PROBABILITY_GAIN;
+    static const float SKIP_PROBABALITY_WEIGHT_FOR_PROBABILITY_GAIN;
+
+    // Used by ProximityInfoStateUtils::getMostProbableString()
+    static const float DEMOTION_LOG_PROBABILITY;
+
+    // Used by ProximityInfoStateUtils::updateSampledSearchKeysVector()
+    static const float SEARCH_KEY_RADIUS_RATIO;
+
+    // Used by ProximityInfoStateUtils::calculateBeelineSpeedRate()
+    static const int LOOKUP_RADIUS_PERCENTILE;
+    static const int FIRST_POINT_TIME_OFFSET_MILLIS;
+    static const int STRONG_DOUBLE_LETTER_TIME_MILLIS;
+
+    // Used by ProximityInfoStateUtils::calculateNormalizedSquaredDistance()
+    static const int NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR;
+
  private:
     DISALLOW_IMPLICIT_CONSTRUCTORS(ProximityInfoParams);
-    static const int NORMALIZED_SQUARED_DISTANCE_SCALING_FACTOR_LOG_2;
 };
 } // namespace latinime
 #endif // LATINIME_PROXIMITY_INFO_PARAMS_H
diff --git a/native/jni/src/proximity_info_state.cpp b/native/jni/src/proximity_info_state.cpp
index fbdc2c8..4c1ffb3 100644
--- a/native/jni/src/proximity_info_state.cpp
+++ b/native/jni/src/proximity_info_state.cpp
@@ -89,29 +89,28 @@
     }
 
     if (xCoordinates && yCoordinates) {
-        mSampledInputSize = ProximityInfoStateUtils::updateTouchPoints(
-                mProximityInfo->getMostCommonKeyWidth(), mProximityInfo, mMaxPointToKeyLength,
-                mInputProximities, xCoordinates, yCoordinates, times, pointerIds, inputSize,
-                isGeometric, pointerId, pushTouchPointStartIndex, &mSampledInputXs,
-                &mSampledInputYs, &mSampledTimes, &mSampledLengthCache, &mSampledInputIndice);
+        mSampledInputSize = ProximityInfoStateUtils::updateTouchPoints(mProximityInfo,
+                mMaxPointToKeyLength, mInputProximities, xCoordinates, yCoordinates, times,
+                pointerIds, inputSize, isGeometric, pointerId, pushTouchPointStartIndex,
+                &mSampledInputXs, &mSampledInputYs, &mSampledTimes, &mSampledLengthCache,
+                &mSampledInputIndice);
     }
 
     if (mSampledInputSize > 0 && isGeometric) {
-        mAverageSpeed = ProximityInfoStateUtils::refreshSpeedRates(
-                inputSize, xCoordinates, yCoordinates, times, lastSavedInputSize,
-                mSampledInputSize, &mSampledInputXs, &mSampledInputYs, &mSampledTimes,
-                &mSampledLengthCache, &mSampledInputIndice, &mSpeedRates, &mDirections);
-        ProximityInfoStateUtils::refreshBeelineSpeedRates(
-                mProximityInfo->getMostCommonKeyWidth(), mAverageSpeed, inputSize,
-                xCoordinates, yCoordinates, times, mSampledInputSize, &mSampledInputXs,
-                &mSampledInputYs, &mSampledInputIndice, &mBeelineSpeedPercentiles);
+        mAverageSpeed = ProximityInfoStateUtils::refreshSpeedRates(inputSize, xCoordinates,
+                yCoordinates, times, lastSavedInputSize, mSampledInputSize, &mSampledInputXs,
+                &mSampledInputYs, &mSampledTimes, &mSampledLengthCache, &mSampledInputIndice,
+                &mSpeedRates, &mDirections);
+        ProximityInfoStateUtils::refreshBeelineSpeedRates(mProximityInfo->getMostCommonKeyWidth(),
+                mAverageSpeed, inputSize, xCoordinates, yCoordinates, times, mSampledInputSize,
+                &mSampledInputXs, &mSampledInputYs, &mSampledInputIndice,
+                &mBeelineSpeedPercentiles);
     }
 
     if (mSampledInputSize > 0) {
-        ProximityInfoStateUtils::initGeometricDistanceInfos(
-                mProximityInfo, mProximityInfo->getKeyCount(),
-                mSampledInputSize, lastSavedInputSize, &mSampledInputXs, &mSampledInputYs,
-                &mSampledNearKeysVector, &mSampledDistanceCache_G);
+        ProximityInfoStateUtils::initGeometricDistanceInfos(mProximityInfo, mSampledInputSize,
+                lastSavedInputSize, &mSampledInputXs, &mSampledInputYs, &mSampledNearKeysVector,
+                &mSampledDistanceCache_G);
         if (isGeometric) {
             // updates probabilities of skipping or mapping each key for all points.
             ProximityInfoStateUtils::updateAlignPointProbabilities(
diff --git a/native/jni/src/proximity_info_state_utils.cpp b/native/jni/src/proximity_info_state_utils.cpp
index da3f03d..f9b69d2 100644
--- a/native/jni/src/proximity_info_state_utils.cpp
+++ b/native/jni/src/proximity_info_state_utils.cpp
@@ -38,7 +38,7 @@
     return nextStartIndex;
 }
 
-/* static */ int ProximityInfoStateUtils::updateTouchPoints(const int mostCommonKeyWidth,
+/* static */ int ProximityInfoStateUtils::updateTouchPoints(
         const ProximityInfo *const proximityInfo, const int maxPointToKeyLength,
         const int *const inputProximities, const int *const inputXCoordinates,
         const int *const inputYCoordinates, const int *const times, const int *const pointerIds,
@@ -106,15 +106,14 @@
                 const float prevAngle = getAngle(
                         inputXCoordinates[i - 2], inputYCoordinates[i - 2],
                         inputXCoordinates[i - 1], inputYCoordinates[i - 1]);
-                const float currentAngle =
-                        getAngle(inputXCoordinates[i - 1], inputYCoordinates[i - 1], x, y);
+                const float currentAngle = getAngle(
+                        inputXCoordinates[i - 1], inputYCoordinates[i - 1], x, y);
                 sumAngle += getAngleDiff(prevAngle, currentAngle);
             }
 
-            if (pushTouchPoint(mostCommonKeyWidth, proximityInfo, maxPointToKeyLength,
-                    i, c, x, y, time, isGeometric /* doSampling */,
-                    i == lastInputIndex, sumAngle, currentNearKeysDistances,
-                    prevNearKeysDistances, prevPrevNearKeysDistances,
+            if (pushTouchPoint(proximityInfo, maxPointToKeyLength, i, c, x, y, time,
+                    isGeometric /* doSampling */, i == lastInputIndex, sumAngle,
+                    currentNearKeysDistances, prevNearKeysDistances, prevPrevNearKeysDistances,
                     sampledInputXs, sampledInputYs, sampledInputTimes, sampledLengthCache,
                     sampledInputIndice)) {
                 // Previous point information was popped.
@@ -222,12 +221,13 @@
 }
 
 /* static */ void ProximityInfoStateUtils::initGeometricDistanceInfos(
-        const ProximityInfo *const proximityInfo, const int keyCount, const int sampledInputSize,
+        const ProximityInfo *const proximityInfo, const int sampledInputSize,
         const int lastSavedInputSize, const std::vector<int> *const sampledInputXs,
         const std::vector<int> *const sampledInputYs,
         std::vector<NearKeycodesSet> *SampledNearKeysVector,
         std::vector<float> *SampledDistanceCache_G) {
     SampledNearKeysVector->resize(sampledInputSize);
+    const int keyCount = proximityInfo->getKeyCount();
     SampledDistanceCache_G->resize(sampledInputSize * keyCount);
     for (int i = lastSavedInputSize; i < sampledInputSize; ++i) {
         (*SampledNearKeysVector)[i].reset();
@@ -275,10 +275,11 @@
         int duration = 0;
 
         // Calculate velocity by using distances and durations of
-        // NUM_POINTS_FOR_SPEED_CALCULATION points for both forward and backward.
-        static const int NUM_POINTS_FOR_SPEED_CALCULATION = 2;
-        for (int j = index; j < min(inputSize - 1, index + NUM_POINTS_FOR_SPEED_CALCULATION);
-                ++j) {
+        // ProximityInfoParams::NUM_POINTS_FOR_SPEED_CALCULATION points for both forward and
+        // backward.
+        const int forwardNumPoints = min(inputSize - 1,
+                index + ProximityInfoParams::NUM_POINTS_FOR_SPEED_CALCULATION);
+        for (int j = index; j < forwardNumPoints; ++j) {
             if (i < sampledInputSize - 1 && j >= (*sampledInputIndice)[i + 1]) {
                 break;
             }
@@ -286,7 +287,9 @@
                     xCoordinates[j + 1], yCoordinates[j + 1]);
             duration += times[j + 1] - times[j];
         }
-        for (int j = index - 1; j >= max(0, index - NUM_POINTS_FOR_SPEED_CALCULATION); --j) {
+        const int backwardNumPoints = max(0,
+                index - ProximityInfoParams::NUM_POINTS_FOR_SPEED_CALCULATION);
+        for (int j = index - 1; j >= backwardNumPoints; --j) {
             if (i > 0 && j < (*sampledInputIndice)[i - 1]) {
                 break;
             }
@@ -434,9 +437,8 @@
 
 // Sampling touch point and pushing information to vectors.
 // Returning if previous point is popped or not.
-/* static */ bool ProximityInfoStateUtils::pushTouchPoint(const int mostCommonKeyWidth,
-        const ProximityInfo *const proximityInfo, const int maxPointToKeyLength,
-        const int inputIndex, const int nodeCodePoint, int x, int y,
+/* static */ bool ProximityInfoStateUtils::pushTouchPoint(const ProximityInfo *const proximityInfo,
+        const int maxPointToKeyLength, const int inputIndex, const int nodeCodePoint, int x, int y,
         const int time, const bool doSampling, const bool isLastPoint, const float sumAngle,
         NearKeysDistanceMap *const currentNearKeysDistances,
         const NearKeysDistanceMap *const prevNearKeysDistances,
@@ -444,7 +446,7 @@
         std::vector<int> *sampledInputXs, std::vector<int> *sampledInputYs,
         std::vector<int> *sampledInputTimes, std::vector<int> *sampledLengthCache,
         std::vector<int> *sampledInputIndice) {
-    static const int LAST_POINT_SKIP_DISTANCE_SCALE = 4;
+    const int mostCommonKeyWidth = proximityInfo->getMostCommonKeyWidth();
 
     size_t size = sampledInputXs->size();
     bool popped = false;
@@ -465,16 +467,16 @@
         }
         // Check if the last point should be skipped.
         if (isLastPoint && size > 0) {
-            if (getDistanceInt(x, y, sampledInputXs->back(),
-                    sampledInputYs->back()) * LAST_POINT_SKIP_DISTANCE_SCALE
-                            < mostCommonKeyWidth) {
+            if (getDistanceInt(x, y, sampledInputXs->back(), sampledInputYs->back())
+                    * ProximityInfoParams::LAST_POINT_SKIP_DISTANCE_SCALE < mostCommonKeyWidth) {
                 // This point is not used because it's too close to the previous point.
                 if (DEBUG_GEO_FULL) {
                     AKLOGI("p0: size = %zd, x = %d, y = %d, lx = %d, ly = %d, dist = %d, "
                            "width = %d", size, x, y, sampledInputXs->back(),
                            sampledInputYs->back(), getDistanceInt(
                                    x, y, sampledInputXs->back(), sampledInputYs->back()),
-                           mostCommonKeyWidth / LAST_POINT_SKIP_DISTANCE_SCALE);
+                           mostCommonKeyWidth
+                                   / ProximityInfoParams::LAST_POINT_SKIP_DISTANCE_SCALE);
                 }
                 return popped;
             }
@@ -664,35 +666,14 @@
         const std::vector<float> *const SampledDistanceCache_G,
         std::vector<NearKeycodesSet> *SampledNearKeysVector,
         std::vector<hash_map_compat<int, float> > *charProbabilities) {
-    static const float MIN_PROBABILITY = 0.000001f;
-    static const float MAX_SKIP_PROBABILITY = 0.95f;
-    static const float SKIP_FIRST_POINT_PROBABILITY = 0.01f;
-    static const float SKIP_LAST_POINT_PROBABILITY = 0.1f;
-    static const float MIN_SPEED_RATE_FOR_SKIP_PROBABILITY = 0.15f;
-    static const float SPEED_WEIGHT_FOR_SKIP_PROBABILITY = 0.9f;
-    static const float SLOW_STRAIGHT_WEIGHT_FOR_SKIP_PROBABILITY = 0.6f;
-    static const float NEAREST_DISTANCE_WEIGHT = 0.5f;
-    static const float NEAREST_DISTANCE_BIAS = 0.5f;
-    static const float NEAREST_DISTANCE_WEIGHT_FOR_LAST = 0.6f;
-    static const float NEAREST_DISTANCE_BIAS_FOR_LAST = 0.4f;
-
-    static const float ANGLE_WEIGHT = 0.90f;
-    static const float DEEP_CORNER_ANGLE_THRESHOLD = M_PI_F * 60.0f / 180.0f;
-    static const float SKIP_DEEP_CORNER_PROBABILITY = 0.1f;
-    static const float CORNER_ANGLE_THRESHOLD = M_PI_F * 30.0f / 180.0f;
-    static const float STRAIGHT_ANGLE_THRESHOLD = M_PI_F * 15.0f / 180.0f;
-    static const float SKIP_CORNER_PROBABILITY = 0.4f;
-    static const float SPEED_MARGIN = 0.1f;
-    static const float CENTER_VALUE_OF_NORMALIZED_DISTRIBUTION = 0.0f;
-
     charProbabilities->resize(sampledInputSize);
     // Calculates probabilities of using a point as a correlated point with the character
     // for each point.
     for (int i = start; i < sampledInputSize; ++i) {
         (*charProbabilities)[i].clear();
-        // First, calculates skip probability. Starts form MIN_SKIP_PROBABILITY.
+        // First, calculates skip probability. Starts from MAX_SKIP_PROBABILITY.
         // Note that all values that are multiplied to this probability should be in [0.0, 1.0];
-        float skipProbability = MAX_SKIP_PROBABILITY;
+        float skipProbability = ProximityInfoParams::MAX_SKIP_PROBABILITY;
 
         const float currentAngle = getPointAngle(sampledInputXs, sampledInputYs, i);
         const float speedRate = (*sampledSpeedRates)[i];
@@ -709,78 +690,74 @@
         }
 
         if (i == 0) {
-            skipProbability *= min(1.0f, nearestKeyDistance * NEAREST_DISTANCE_WEIGHT
-                    + NEAREST_DISTANCE_BIAS);
+            skipProbability *= min(1.0f,
+                    nearestKeyDistance * ProximityInfoParams::NEAREST_DISTANCE_WEIGHT
+                            + ProximityInfoParams::NEAREST_DISTANCE_BIAS);
             // Promote the first point
-            skipProbability *= SKIP_FIRST_POINT_PROBABILITY;
+            skipProbability *= ProximityInfoParams::SKIP_FIRST_POINT_PROBABILITY;
         } else if (i == sampledInputSize - 1) {
-            skipProbability *= min(1.0f, nearestKeyDistance * NEAREST_DISTANCE_WEIGHT_FOR_LAST
-                    + NEAREST_DISTANCE_BIAS_FOR_LAST);
+            skipProbability *= min(1.0f,
+                    nearestKeyDistance * ProximityInfoParams::NEAREST_DISTANCE_WEIGHT_FOR_LAST
+                            + ProximityInfoParams::NEAREST_DISTANCE_BIAS_FOR_LAST);
             // Promote the last point
-            skipProbability *= SKIP_LAST_POINT_PROBABILITY;
+            skipProbability *= ProximityInfoParams::SKIP_LAST_POINT_PROBABILITY;
         } else {
             // If the current speed is relatively slower than adjacent keys, we promote this point.
-            if ((*sampledSpeedRates)[i - 1] - SPEED_MARGIN > speedRate
-                    && speedRate < (*sampledSpeedRates)[i + 1] - SPEED_MARGIN) {
-                if (currentAngle < CORNER_ANGLE_THRESHOLD) {
+            if ((*sampledSpeedRates)[i - 1] - ProximityInfoParams::SPEED_MARGIN > speedRate
+                    && speedRate
+                            < (*sampledSpeedRates)[i + 1] - ProximityInfoParams::SPEED_MARGIN) {
+                if (currentAngle < ProximityInfoParams::CORNER_ANGLE_THRESHOLD) {
                     skipProbability *= min(1.0f, speedRate
-                            * SLOW_STRAIGHT_WEIGHT_FOR_SKIP_PROBABILITY);
+                            * ProximityInfoParams::SLOW_STRAIGHT_WEIGHT_FOR_SKIP_PROBABILITY);
                 } else {
                     // If the angle is small enough, we promote this point more. (e.g. pit vs put)
-                    skipProbability *= min(1.0f, speedRate * SPEED_WEIGHT_FOR_SKIP_PROBABILITY
-                            + MIN_SPEED_RATE_FOR_SKIP_PROBABILITY);
+                    skipProbability *= min(1.0f,
+                            speedRate * ProximityInfoParams::SPEED_WEIGHT_FOR_SKIP_PROBABILITY
+                                    + ProximityInfoParams::MIN_SPEED_RATE_FOR_SKIP_PROBABILITY);
                 }
             }
 
-            skipProbability *= min(1.0f, speedRate * nearestKeyDistance *
-                    NEAREST_DISTANCE_WEIGHT + NEAREST_DISTANCE_BIAS);
+            skipProbability *= min(1.0f,
+                    speedRate * nearestKeyDistance * ProximityInfoParams::NEAREST_DISTANCE_WEIGHT
+                            + ProximityInfoParams::NEAREST_DISTANCE_BIAS);
 
             // Adjusts skip probability by a rate depending on angle.
             // ANGLE_RATE of skipProbability is adjusted by current angle.
-            skipProbability *= (M_PI_F - currentAngle) / M_PI_F * ANGLE_WEIGHT
-                    + (1.0f - ANGLE_WEIGHT);
-            if (currentAngle > DEEP_CORNER_ANGLE_THRESHOLD) {
-                skipProbability *= SKIP_DEEP_CORNER_PROBABILITY;
+            skipProbability *= (M_PI_F - currentAngle) / M_PI_F * ProximityInfoParams::ANGLE_WEIGHT
+                    + (1.0f - ProximityInfoParams::ANGLE_WEIGHT);
+            if (currentAngle > ProximityInfoParams::DEEP_CORNER_ANGLE_THRESHOLD) {
+                skipProbability *= ProximityInfoParams::SKIP_DEEP_CORNER_PROBABILITY;
             }
             // We assume the angle of this point is the angle for point[i], point[i - 2]
             // and point[i - 3]. The reason why we don't use the angle for point[i], point[i - 1]
             // and point[i - 2] is this angle can be more affected by the noise.
             const float prevAngle = getPointsAngle(sampledInputXs, sampledInputYs, i, i - 2, i - 3);
-            if (i >= 3 && prevAngle < STRAIGHT_ANGLE_THRESHOLD
-                    && currentAngle > CORNER_ANGLE_THRESHOLD) {
-                skipProbability *= SKIP_CORNER_PROBABILITY;
+            if (i >= 3 && prevAngle < ProximityInfoParams::STRAIGHT_ANGLE_THRESHOLD
+                    && currentAngle > ProximityInfoParams::CORNER_ANGLE_THRESHOLD) {
+                skipProbability *= ProximityInfoParams::SKIP_CORNER_PROBABILITY;
             }
         }
 
-        // probabilities must be in [0.0, MAX_SKIP_PROBABILITY];
+        // probabilities must be in [0.0, ProximityInfoParams::MAX_SKIP_PROBABILITY];
         ASSERT(skipProbability >= 0.0f);
-        ASSERT(skipProbability <= MAX_SKIP_PROBABILITY);
+        ASSERT(skipProbability <= ProximityInfoParams::MAX_SKIP_PROBABILITY);
         (*charProbabilities)[i][NOT_AN_INDEX] = skipProbability;
 
         // Second, calculates key probabilities by dividing the rest probability
         // (1.0f - skipProbability).
         const float inputCharProbability = 1.0f - skipProbability;
 
-        // TODO: The variance is critical for accuracy; thus, adjusting these parameter by machine
-        // learning or something would be efficient.
-        static const float SPEEDxANGLE_WEIGHT_FOR_STANDARD_DIVIATION = 0.3f;
-        static const float MAX_SPEEDxANGLE_RATE_FOR_STANDERD_DIVIATION = 0.25f;
-        static const float SPEEDxNEAREST_WEIGHT_FOR_STANDARD_DIVIATION = 0.5f;
-        static const float MAX_SPEEDxNEAREST_RATE_FOR_STANDERD_DIVIATION = 0.15f;
-        static const float MIN_STANDERD_DIVIATION = 0.37f;
-
         const float speedxAngleRate = min(speedRate * currentAngle / M_PI_F
-                * SPEEDxANGLE_WEIGHT_FOR_STANDARD_DIVIATION,
-                        MAX_SPEEDxANGLE_RATE_FOR_STANDERD_DIVIATION);
+                * ProximityInfoParams::SPEEDxANGLE_WEIGHT_FOR_STANDARD_DIVIATION,
+                        ProximityInfoParams::MAX_SPEEDxANGLE_RATE_FOR_STANDERD_DIVIATION);
         const float speedxNearestKeyDistanceRate = min(speedRate * nearestKeyDistance
-                * SPEEDxNEAREST_WEIGHT_FOR_STANDARD_DIVIATION,
-                        MAX_SPEEDxNEAREST_RATE_FOR_STANDERD_DIVIATION);
-        const float sigma = speedxAngleRate + speedxNearestKeyDistanceRate + MIN_STANDERD_DIVIATION;
+                * ProximityInfoParams::SPEEDxNEAREST_WEIGHT_FOR_STANDARD_DIVIATION,
+                        ProximityInfoParams::MAX_SPEEDxNEAREST_RATE_FOR_STANDERD_DIVIATION);
+        const float sigma = speedxAngleRate + speedxNearestKeyDistanceRate
+                + ProximityInfoParams::MIN_STANDERD_DIVIATION;
 
         ProximityInfoUtils::NormalDistribution
-                distribution(CENTER_VALUE_OF_NORMALIZED_DISTRIBUTION, sigma);
-        static const float PREV_DISTANCE_WEIGHT = 0.5f;
-        static const float NEXT_DISTANCE_WEIGHT = 0.6f;
+                distribution(ProximityInfoParams::CENTER_VALUE_OF_NORMALIZED_DISTRIBUTION, sigma);
         // Summing up probability densities of all near keys.
         float sumOfProbabilityDensities = 0.0f;
         for (int j = 0; j < keyCount; ++j) {
@@ -797,8 +774,9 @@
                         // points because the first touch by the user can be sloppy.
                         // So we promote the first point if the distance of that point is larger
                         // than the distance of the next point.
-                        distance = (distance + nextDistance * NEXT_DISTANCE_WEIGHT)
-                                / (1.0f + NEXT_DISTANCE_WEIGHT);
+                        distance = (distance
+                                + nextDistance * ProximityInfoParams::NEXT_DISTANCE_WEIGHT)
+                                        / (1.0f + ProximityInfoParams::NEXT_DISTANCE_WEIGHT);
                     }
                 } else if (i != 0 && i == sampledInputSize - 1) {
                     // For the first point, weighted average of distances from last point and
@@ -810,8 +788,9 @@
                         // because the last touch by the user can be sloppy. So we promote the
                         // last point if the distance of that point is larger than the distance of
                         // the previous point.
-                        distance = (distance + previousDistance * PREV_DISTANCE_WEIGHT)
-                                / (1.0f + PREV_DISTANCE_WEIGHT);
+                        distance = (distance
+                                + previousDistance * ProximityInfoParams::PREV_DISTANCE_WEIGHT)
+                                        / (1.0f + ProximityInfoParams::PREV_DISTANCE_WEIGHT);
                     }
                 }
                 // TODO: Promote the first point when the extended line from the next input is near
@@ -831,8 +810,9 @@
                     const float prevDistance = sqrtf(getPointToKeyByIdLength(
                             maxPointToKeyLength, SampledDistanceCache_G, keyCount, i + 1, j));
                     if (prevDistance < distance) {
-                        distance = (distance + prevDistance * NEXT_DISTANCE_WEIGHT)
-                                / (1.0f + NEXT_DISTANCE_WEIGHT);
+                        distance = (distance
+                                + prevDistance * ProximityInfoParams::NEXT_DISTANCE_WEIGHT)
+                                        / (1.0f + ProximityInfoParams::NEXT_DISTANCE_WEIGHT);
                     }
                 } else if (i != 0 && i == sampledInputSize - 1) {
                     // For the first point, weighted average of distances from last point and
@@ -840,8 +820,9 @@
                     const float prevDistance = sqrtf(getPointToKeyByIdLength(
                             maxPointToKeyLength, SampledDistanceCache_G, keyCount, i - 1, j));
                     if (prevDistance < distance) {
-                        distance = (distance + prevDistance * PREV_DISTANCE_WEIGHT)
-                                / (1.0f + PREV_DISTANCE_WEIGHT);
+                        distance = (distance
+                                + prevDistance * ProximityInfoParams::PREV_DISTANCE_WEIGHT)
+                                        / (1.0f + ProximityInfoParams::PREV_DISTANCE_WEIGHT);
                     }
                 }
                 const float probabilityDensity = distribution.getProbabilityDensity(distance);
@@ -905,7 +886,7 @@
             hash_map_compat<int, float>::iterator it = (*charProbabilities)[i].find(j);
             if (it == (*charProbabilities)[i].end()){
                 (*SampledNearKeysVector)[i].reset(j);
-            } else if(it->second < MIN_PROBABILITY) {
+            } else if(it->second < ProximityInfoParams::MIN_PROBABILITY) {
                 // Erases from near keys vector because it has very low probability.
                 (*SampledNearKeysVector)[i].reset(j);
                 (*charProbabilities)[i].erase(j);
@@ -949,20 +930,14 @@
         std::vector<hash_map_compat<int, float> > *charProbabilities) {
     ASSERT(0 <= index0 && index0 < sampledInputSize);
     ASSERT(0 <= index1 && index1 < sampledInputSize);
-
-    static const float SUPPRESSION_LENGTH_WEIGHT = 1.5f;
-    static const float MIN_SUPPRESSION_RATE = 0.1f;
-    static const float SUPPRESSION_WEIGHT = 0.5f;
-    static const float SUPPRESSION_WEIGHT_FOR_PROBABILITY_GAIN = 0.1f;
-    static const float SKIP_PROBABALITY_WEIGHT_FOR_PROBABILITY_GAIN = 0.3f;
-
     const float keyWidthFloat = static_cast<float>(mostCommonKeyWidth);
     const float diff = fabsf(static_cast<float>((*lengthCache)[index0] - (*lengthCache)[index1]));
-    if (diff > keyWidthFloat * SUPPRESSION_LENGTH_WEIGHT) {
+    if (diff > keyWidthFloat * ProximityInfoParams::SUPPRESSION_LENGTH_WEIGHT) {
         return false;
     }
-    const float suppressionRate = MIN_SUPPRESSION_RATE
-            + diff / keyWidthFloat / SUPPRESSION_LENGTH_WEIGHT * SUPPRESSION_WEIGHT;
+    const float suppressionRate = ProximityInfoParams::MIN_SUPPRESSION_RATE
+            + diff / keyWidthFloat / ProximityInfoParams::SUPPRESSION_LENGTH_WEIGHT
+                    * ProximityInfoParams::SUPPRESSION_WEIGHT;
     for (hash_map_compat<int, float>::iterator it = (*charProbabilities)[index0].begin();
             it != (*charProbabilities)[index0].end(); ++it) {
         hash_map_compat<int, float>::iterator it2 =  (*charProbabilities)[index1].find(it->first);
@@ -974,9 +949,10 @@
             (*charProbabilities)[index0][NOT_AN_INDEX] += suppression;
 
             // Add the probability of the same key nearby index1
-            const float probabilityGain = min(suppression * SUPPRESSION_WEIGHT_FOR_PROBABILITY_GAIN,
+            const float probabilityGain = min(suppression
+                    * ProximityInfoParams::SUPPRESSION_WEIGHT_FOR_PROBABILITY_GAIN,
                     (*charProbabilities)[index1][NOT_AN_INDEX]
-                            * SKIP_PROBABALITY_WEIGHT_FOR_PROBABILITY_GAIN);
+                            * ProximityInfoParams::SKIP_PROBABALITY_WEIGHT_FOR_PROBABILITY_GAIN);
             it2->second += probabilityGain;
             (*charProbabilities)[index1][NOT_AN_INDEX] -= probabilityGain;
         }
@@ -1020,7 +996,6 @@
         int *const codePointBuf) {
     ASSERT(sampledInputSize >= 0);
     memset(codePointBuf, 0, sizeof(codePointBuf[0]) * MAX_WORD_LENGTH);
-    static const float DEMOTION_LOG_PROBABILITY = 0.3f;
     int index = 0;
     float sumLogProbability = 0.0f;
     // TODO: Current implementation is greedy algorithm. DP would be efficient for many cases.
@@ -1030,7 +1005,7 @@
         for (hash_map_compat<int, float>::const_iterator it = (*charProbabilities)[i].begin();
                 it != (*charProbabilities)[i].end(); ++it) {
             const float logProbability = (it->first != NOT_AN_INDEX)
-                    ? it->second + DEMOTION_LOG_PROBABILITY : it->second;
+                    ? it->second + ProximityInfoParams::DEMOTION_LOG_PROBABILITY : it->second;
             if (logProbability < minLogProbability) {
                 minLogProbability = logProbability;
                 character = it->first;
diff --git a/native/jni/src/proximity_info_state_utils.h b/native/jni/src/proximity_info_state_utils.h
index c8f0aeb..af0acc7 100644
--- a/native/jni/src/proximity_info_state_utils.h
+++ b/native/jni/src/proximity_info_state_utils.h
@@ -35,9 +35,8 @@
     static int trimLastTwoTouchPoints(std::vector<int> *sampledInputXs,
             std::vector<int> *sampledInputYs, std::vector<int> *sampledInputTimes,
             std::vector<int> *sampledLengthCache, std::vector<int> *sampledInputIndice);
-    static int updateTouchPoints(const int mostCommonKeyWidth,
-            const ProximityInfo *const proximityInfo, const int maxPointToKeyLength,
-            const int *const inputProximities,
+    static int updateTouchPoints(const ProximityInfo *const proximityInfo,
+            const int maxPointToKeyLength, const int *const inputProximities,
             const int *const inputXCoordinates, const int *const inputYCoordinates,
             const int *const times, const int *const pointerIds, const int inputSize,
             const bool isGeometric, const int pointerId, const int pushTouchPointStartIndex,
@@ -65,19 +64,17 @@
             std::vector<int> *beelineSpeedPercentiles);
     static float getDirection(const std::vector<int> *const sampledInputXs,
             const std::vector<int> *const sampledInputYs, const int index0, const int index1);
-    static void updateAlignPointProbabilities(
-            const float maxPointToKeyLength, const int mostCommonKeyWidth, const int keyCount,
-            const int start, const int sampledInputSize,
-            const std::vector<int> *const sampledInputXs,
+    static void updateAlignPointProbabilities(const float maxPointToKeyLength,
+            const int mostCommonKeyWidth, const int keyCount, const int start,
+            const int sampledInputSize, const std::vector<int> *const sampledInputXs,
             const std::vector<int> *const sampledInputYs,
             const std::vector<float> *const sampledSpeedRates,
             const std::vector<int> *const sampledLengthCache,
             const std::vector<float> *const SampledDistanceCache_G,
             std::vector<NearKeycodesSet> *SampledNearKeysVector,
             std::vector<hash_map_compat<int, float> > *charProbabilities);
-    static void updateSampledSearchKeysVector(
-            const ProximityInfo *const proximityInfo, const int sampledInputSize,
-            const int lastSavedInputSize,
+    static void updateSampledSearchKeysVector(const ProximityInfo *const proximityInfo,
+            const int sampledInputSize, const int lastSavedInputSize,
             const std::vector<int> *const sampledLengthCache,
             const std::vector<NearKeycodesSet> *const SampledNearKeysVector,
             std::vector<NearKeycodesSet> *sampledSearchKeysVector);
@@ -87,22 +84,18 @@
     static float getPointToKeyByIdLength(const float maxPointToKeyLength,
             const std::vector<float> *const SampledDistanceCache_G, const int keyCount,
             const int inputIndex, const int keyId);
-    static void initGeometricDistanceInfos(
-            const ProximityInfo *const proximityInfo, const int keyCount,
+    static void initGeometricDistanceInfos(const ProximityInfo *const proximityInfo,
             const int sampledInputSize, const int lastSavedInputSize,
             const std::vector<int> *const sampledInputXs,
             const std::vector<int> *const sampledInputYs,
             std::vector<NearKeycodesSet> *SampledNearKeysVector,
             std::vector<float> *SampledDistanceCache_G);
-    static void initPrimaryInputWord(
-            const int inputSize, const int *const inputProximities, int *primaryInputWord);
-    static void initNormalizedSquaredDistances(
-            const ProximityInfo *const proximityInfo, const int inputSize,
-            const int *inputXCoordinates, const int *inputYCoordinates,
-            const int *const inputProximities,
-            const std::vector<int> *const sampledInputXs,
-            const std::vector<int> *const sampledInputYs,
-            int *normalizedSquaredDistances);
+    static void initPrimaryInputWord(const int inputSize, const int *const inputProximities,
+            int *primaryInputWord);
+    static void initNormalizedSquaredDistances(const ProximityInfo *const proximityInfo,
+            const int inputSize, const int *inputXCoordinates, const int *inputYCoordinates,
+            const int *const inputProximities, const std::vector<int> *const sampledInputXs,
+            const std::vector<int> *const sampledInputYs, int *normalizedSquaredDistances);
     static void dump(const bool isGeometric, const int inputSize,
             const int *const inputXCoordinates, const int *const inputYCoordinates,
             const int sampledInputSize, const std::vector<int> *const sampledInputXs,
@@ -117,8 +110,8 @@
             const std::vector<int> *const sampledTimes,
             const std::vector<int> *const sampledInputIndices);
     // TODO: Move to most_probable_string_utils.h
-    static float getMostProbableString(
-            const ProximityInfo *const proximityInfo, const int sampledInputSize,
+    static float getMostProbableString(const ProximityInfo *const proximityInfo,
+            const int sampledInputSize,
             const std::vector<hash_map_compat<int, float> > *const charProbabilities,
             int *const codePointBuf);
 
@@ -137,11 +130,10 @@
             const NearKeysDistanceMap *const prevNearKeysDistances,
             const NearKeysDistanceMap *const prevPrevNearKeysDistances,
             std::vector<int> *sampledInputXs, std::vector<int> *sampledInputYs);
-    static bool pushTouchPoint(const int mostCommonKeyWidth,
-            const ProximityInfo *const proximityInfo, const int maxPointToKeyLength,
-            const int inputIndex, const int nodeCodePoint, int x, int y, const int time,
-            const bool doSampling, const bool isLastPoint, const float sumAngle,
-            NearKeysDistanceMap *const currentNearKeysDistances,
+    static bool pushTouchPoint(const ProximityInfo *const proximityInfo,
+            const int maxPointToKeyLength, const int inputIndex, const int nodeCodePoint, int x,
+            int y, const int time, const bool doSampling, const bool isLastPoint,
+            const float sumAngle, NearKeysDistanceMap *const currentNearKeysDistances,
             const NearKeysDistanceMap *const prevNearKeysDistances,
             const NearKeysDistanceMap *const prevPrevNearKeysDistances,
             std::vector<int> *sampledInputXs, std::vector<int> *sampledInputYs,
@@ -153,23 +145,20 @@
             const std::vector<int> *const sampledInputXs,
             const std::vector<int> *const sampledInputYs,
             const std::vector<int> *const inputIndice);
-    static float getPointAngle(
-            const std::vector<int> *const sampledInputXs,
+    static float getPointAngle(const std::vector<int> *const sampledInputXs,
             const std::vector<int> *const sampledInputYs, const int index);
-    static float getPointsAngle(
-            const std::vector<int> *const sampledInputXs,
-            const std::vector<int> *const sampledInputYs,
-            const int index0, const int index1, const int index2);
+    static float getPointsAngle(const std::vector<int> *const sampledInputXs,
+            const std::vector<int> *const sampledInputYs, const int index0, const int index1,
+            const int index2);
     static bool suppressCharProbabilities(const int mostCommonKeyWidth,
-            const int sampledInputSize, const std::vector<int> *const lengthCache,
-            const int index0, const int index1,
-            std::vector<hash_map_compat<int, float> > *charProbabilities);
+            const int sampledInputSize, const std::vector<int> *const lengthCache, const int index0,
+            const int index1, std::vector<hash_map_compat<int, float> > *charProbabilities);
     static float calculateSquaredDistanceFromSweetSpotCenter(
             const ProximityInfo *const proximityInfo, const std::vector<int> *const sampledInputXs,
             const std::vector<int> *const sampledInputYs, const int keyIndex,
             const int inputIndex);
-     static float calculateNormalizedSquaredDistance(
-            const ProximityInfo *const proximityInfo, const std::vector<int> *const sampledInputXs,
+     static float calculateNormalizedSquaredDistance(const ProximityInfo *const proximityInfo,
+            const std::vector<int> *const sampledInputXs,
             const std::vector<int> *const sampledInputYs, const int keyIndex, const int inputIndex);
 };
 } // namespace latinime