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

Commit 887f11ee authored by Tadashi G. Takaoka's avatar Tadashi G. Takaoka
Browse files

Remove next letters frequency handling

Bug: 3428942
Change-Id: Id62f467ce4e50c60a56d59bf96770e799a4659e2
parent a7b2ac26
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import java.util.List;

public abstract class KeyDetector {
    public static final int NOT_A_KEY = -1;
    public static final int NOT_A_CODE = -1;

    protected Keyboard mKeyboard;

@@ -105,10 +106,10 @@ public abstract class KeyDetector {
     *
     * @param x The x-coordinate of a touch point
     * @param y The y-coordinate of a touch point
     * @param allKeys All nearby key indices are returned in this array
     * @param allCodes All nearby key code except functional key are returned in this array
     * @return The nearest key index
     */
    abstract public int getKeyIndexAndNearbyCodes(int x, int y, int[] allKeys);
    abstract public int getKeyIndexAndNearbyCodes(int x, int y, final int[] allCodes);

    /**
     * Compute the most common key width in order to use it as proximity key detection threshold.
@@ -116,14 +117,14 @@ public abstract class KeyDetector {
     * @param keyboard The keyboard to compute the most common key width
     * @return The most common key width in the keyboard
     */
    public static int getMostCommonKeyWidth(Keyboard keyboard) {
    public static int getMostCommonKeyWidth(final Keyboard keyboard) {
        if (keyboard == null) return 0;
        final List<Key> keys = keyboard.getKeys();
        if (keys == null || keys.size() == 0) return 0;
        final HashMap<Integer, Integer> histogram = new HashMap<Integer, Integer>();
        int maxCount = 0;
        int mostCommonWidth = 0;
        for (Key key : keys) {
        for (final Key key : keys) {
            final Integer width = key.mWidth + key.mGap;
            Integer count = histogram.get(width);
            if (count == null)
+0 −6
Original line number Diff line number Diff line
@@ -288,12 +288,6 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
        return null;
    }

    public void setPreferredLetters(int[] frequencies) {
        LatinKeyboard latinKeyboard = getLatinKeyboard();
        if (latinKeyboard != null)
            latinKeyboard.setPreferredLetters(frequencies);
    }

    public void keyReleased() {
        LatinKeyboard latinKeyboard = getLatinKeyboard();
        if (latinKeyboard != null)
+4 −112
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import com.android.inputmethod.latin.SubtypeSwitcher;

import android.content.Context;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@@ -31,17 +32,12 @@ import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.Log;

import java.util.List;
import java.util.Locale;

// TODO: We should remove this class
public class LatinKeyboard extends Keyboard {

    private static final boolean DEBUG_PREFERRED_LETTER = false;
    private static final String TAG = "LatinKeyboard";

    public static final int OPACITY_FULLY_OPAQUE = 255;
    private static final int SPACE_LED_LENGTH_PERCENT = 80;

@@ -69,15 +65,7 @@ public class LatinKeyboard extends Keyboard {
    private final Drawable mEnabledShortcutIcon;
    private final Drawable mDisabledShortcutIcon;

    private int[] mPrefLetterFrequencies;
    private int mPrefLetter;
    private int mPrefLetterX;
    private int mPrefLetterY;
    private int mPrefDistance;

    private static final float SPACEBAR_DRAG_THRESHOLD = 0.8f;
    private static final float OVERLAP_PERCENTAGE_LOW_PROB = 0.70f;
    private static final float OVERLAP_PERCENTAGE_HIGH_PROB = 0.85f;
    // Minimum width of space key preview (proportional to keyboard width)
    private static final float SPACEBAR_POPUP_MIN_RATIO = 0.4f;
    // Height in space key the language name will be drawn. (proportional to space key height)
@@ -265,7 +253,7 @@ public class LatinKeyboard extends Keyboard {
            final boolean allowVariableTextSize = true;
            final String language = layoutSpacebar(paint, subtypeSwitcher.getInputLocale(),
                    mButtonArrowLeftIcon, mButtonArrowRightIcon, width, height,
                    getTextSizeFromTheme(textStyle, defaultTextSize),
                    getTextSizeFromTheme(mContext.getTheme(), textStyle, defaultTextSize),
                    allowVariableTextSize);

            // Draw language text with shadow
@@ -334,18 +322,9 @@ public class LatinKeyboard extends Keyboard {
        return mSpaceDragLastDiff > 0 ? 1 : -1;
    }

    public void setPreferredLetters(int[] frequencies) {
        mPrefLetterFrequencies = frequencies;
        mPrefLetter = 0;
    }

    public void keyReleased() {
        mCurrentlyInSpace = false;
        mSpaceDragLastDiff = 0;
        mPrefLetter = 0;
        mPrefLetterX = 0;
        mPrefLetterY = 0;
        mPrefDistance = Integer.MAX_VALUE;
        if (mSpaceKey != null) {
            updateLocaleDrag(Integer.MAX_VALUE);
        }
@@ -381,80 +360,6 @@ public class LatinKeyboard extends Keyboard {
                    return isOnSpace;
                }
            }
        } else if (mPrefLetterFrequencies != null) {
            // New coordinate? Reset
            if (mPrefLetterX != x || mPrefLetterY != y) {
                mPrefLetter = 0;
                mPrefDistance = Integer.MAX_VALUE;
            }
            // Handle preferred next letter
            final int[] pref = mPrefLetterFrequencies;
            if (mPrefLetter > 0) {
                if (DEBUG_PREFERRED_LETTER) {
                    if (mPrefLetter == code && !key.isOnKey(x, y)) {
                        Log.d(TAG, "CORRECTED !!!!!!");
                    }
                }
                return mPrefLetter == code;
            } else {
                final boolean isOnKey = key.isOnKey(x, y);
                int[] nearby = getNearestKeys(x, y);
                List<Key> nearbyKeys = getKeys();
                if (isOnKey) {
                    // If it's a preferred letter
                    if (inPrefList(code, pref)) {
                        // Check if its frequency is much lower than a nearby key
                        mPrefLetter = code;
                        mPrefLetterX = x;
                        mPrefLetterY = y;
                        for (int i = 0; i < nearby.length; i++) {
                            Key k = nearbyKeys.get(nearby[i]);
                            if (k != key && inPrefList(k.mCode, pref)) {
                                final int dist = distanceFrom(k, x, y);
                                if (dist < (int) (k.mWidth * OVERLAP_PERCENTAGE_LOW_PROB) &&
                                        (pref[k.mCode] > pref[mPrefLetter] * 3))  {
                                    mPrefLetter = k.mCode;
                                    mPrefDistance = dist;
                                    if (DEBUG_PREFERRED_LETTER) {
                                        Log.d(TAG, "CORRECTED ALTHOUGH PREFERRED !!!!!!");
                                    }
                                    break;
                                }
                            }
                        }

                        return mPrefLetter == code;
                    }
                }

                // Get the surrounding keys and intersect with the preferred list
                // For all in the intersection
                //   if distance from touch point is within a reasonable distance
                //       make this the pref letter
                // If no pref letter
                //   return inside;
                // else return thiskey == prefletter;

                for (int i = 0; i < nearby.length; i++) {
                    Key k = nearbyKeys.get(nearby[i]);
                    if (inPrefList(k.mCode, pref)) {
                        final int dist = distanceFrom(k, x, y);
                        if (dist < (int) (k.mWidth * OVERLAP_PERCENTAGE_HIGH_PROB)
                                && dist < mPrefDistance)  {
                            mPrefLetter = k.mCode;
                            mPrefLetterX = x;
                            mPrefLetterY = y;
                            mPrefDistance = dist;
                        }
                    }
                }
                // Didn't find any
                if (mPrefLetter == 0) {
                    return isOnKey;
                } else {
                    return mPrefLetter == code;
                }
            }
        }

        // Lock into the spacebar
@@ -463,19 +368,6 @@ public class LatinKeyboard extends Keyboard {
        return key.isOnKey(x, y);
    }

    private boolean inPrefList(int code, int[] pref) {
        if (code < pref.length && code >= 0) return pref[code] > 0;
        return false;
    }

    private int distanceFrom(Key k, int x, int y) {
        if (y > k.mY && y < k.mY + k.mHeight) {
            return Math.abs(k.mX + k.mWidth / 2 - x);
        } else {
            return Integer.MAX_VALUE;
        }
    }

    @Override
    public int[] getNearestKeys(int x, int y) {
        if (mCurrentlyInSpace) {
@@ -487,8 +379,8 @@ public class LatinKeyboard extends Keyboard {
        }
    }

    private int getTextSizeFromTheme(int style, int defValue) {
        TypedArray array = mContext.getTheme().obtainStyledAttributes(
    private static int getTextSizeFromTheme(Theme theme, int style, int defValue) {
        TypedArray array = theme.obtainStyledAttributes(
                style, new int[] { android.R.attr.textSize });
        int textSize = array.getDimensionPixelSize(array.getResourceId(0, 0), defValue);
        return textSize;
+9 −9
Original line number Diff line number Diff line
@@ -35,24 +35,24 @@ public class MiniKeyboardKeyDetector extends KeyDetector {
    }

    @Override
    public int getKeyIndexAndNearbyCodes(int x, int y, int[] allKeys) {
    public int getKeyIndexAndNearbyCodes(int x, int y, final int[] allCodes) {
        final Key[] keys = getKeys();
        final int touchX = getTouchX(x);
        final int touchY = getTouchY(y);

        int closestKeyIndex = NOT_A_KEY;
        int closestKeyDist = (y < 0) ? mSlideAllowanceSquareTop : mSlideAllowanceSquare;
        int nearestIndex = NOT_A_KEY;
        int nearestDist = (y < 0) ? mSlideAllowanceSquareTop : mSlideAllowanceSquare;
        final int keyCount = keys.length;
        for (int index = 0; index < keyCount; index++) {
            final int dist = keys[index].squaredDistanceToEdge(touchX, touchY);
            if (dist < closestKeyDist) {
                closestKeyIndex = index;
                closestKeyDist = dist;
            if (dist < nearestDist) {
                nearestIndex = index;
                nearestDist = dist;
            }
        }

        if (allKeys != null && closestKeyIndex != NOT_A_KEY)
            allKeys[0] = keys[closestKeyIndex].mCode;
        return closestKeyIndex;
        if (allCodes != null && nearestIndex != NOT_A_KEY)
            allCodes[0] = keys[nearestIndex].mCode;
        return nearestIndex;
    }
}
+79 −22
Original line number Diff line number Diff line
@@ -16,49 +16,106 @@

package com.android.inputmethod.keyboard;

import android.util.Log;

import java.util.Arrays;

public class ProximityKeyDetector extends KeyDetector {
    private static final String TAG = ProximityKeyDetector.class.getSimpleName();
    private static final boolean DEBUG = false;

    private static final int MAX_NEARBY_KEYS = 12;

    // working area
    private int[] mDistances = new int[MAX_NEARBY_KEYS];
    private final int[] mDistances = new int[MAX_NEARBY_KEYS];
    private final int[] mIndices = new int[MAX_NEARBY_KEYS];

    @Override
    protected int getMaxNearbyKeys() {
        return MAX_NEARBY_KEYS;
    }

    private void initializeNearbyKeys() {
        Arrays.fill(mDistances, Integer.MAX_VALUE);
        Arrays.fill(mIndices, NOT_A_KEY);
    }

    /**
     * Insert the key into nearby keys buffer and sort nearby keys by ascending order of distance.
     *
     * @param keyIndex index of the key.
     * @param distance distance between the key's edge and user touched point.
     * @return order of the key in the nearby buffer, 0 if it is the nearest key.
     */
    private int sortNearbyKeys(int keyIndex, int distance) {
        final int[] distances = mDistances;
        final int[] indices = mIndices;
        for (int insertPos = 0; insertPos < distances.length; insertPos++) {
            if (distance < distances[insertPos]) {
                final int nextPos = insertPos + 1;
                if (nextPos < distances.length) {
                    System.arraycopy(distances, insertPos, distances, nextPos,
                            distances.length - nextPos);
                    System.arraycopy(indices, insertPos, indices, nextPos,
                            indices.length - nextPos);
                }
                distances[insertPos] = distance;
                indices[insertPos] = keyIndex;
                return insertPos;
            }
        }
        return distances.length;
    }

    private void getNearbyKeyCodes(final int[] allCodes) {
        final Key[] keys = getKeys();
        final int[] indices = mIndices;

        // allCodes[0] should always have the key code even if it is a non-letter key.
        if (indices[0] == NOT_A_KEY) {
            allCodes[0] = NOT_A_CODE;
            return;
        }

        int numCodes = 0;
        for (int j = 0; j < indices.length && numCodes < allCodes.length; j++) {
            final int index = indices[j];
            if (index == NOT_A_KEY)
                break;
            final int code = keys[index].mCode;
            // filter out a non-letter key from nearby keys
            if (code < Keyboard.CODE_SPACE)
                continue;
            allCodes[numCodes++] = code;
        }
    }

    @Override
    public int getKeyIndexAndNearbyCodes(int x, int y, int[] allKeys) {
    public int getKeyIndexAndNearbyCodes(int x, int y, final int[] allCodes) {
        final Key[] keys = getKeys();
        final int touchX = getTouchX(x);
        final int touchY = getTouchY(y);

        initializeNearbyKeys();
        int primaryIndex = NOT_A_KEY;
        final int[] distances = mDistances;
        Arrays.fill(distances, Integer.MAX_VALUE);
        for (final int index : mKeyboard.getNearestKeys(touchX, touchY)) {
            final Key key = keys[index];
            final boolean isInside = key.isInside(touchX, touchY);
            if (isInside)
            final int distance = key.squaredDistanceToEdge(touchX, touchY);
            if (isInside || (mProximityCorrectOn && distance < mProximityThresholdSquare)) {
                final int insertedPosition = sortNearbyKeys(index, distance);
                if (insertedPosition == 0 && isInside)
                    primaryIndex = index;
            final int dist = key.squaredDistanceToEdge(touchX, touchY);
            if (isInside || (mProximityCorrectOn && dist < mProximityThresholdSquare)) {
                if (allKeys == null) continue;
                // Find insertion point
                for (int j = 0; j < distances.length; j++) {
                    if (distances[j] > dist) {
                        final int nextPos = j + 1;
                        System.arraycopy(distances, j, distances, nextPos,
                                distances.length - nextPos);
                        System.arraycopy(allKeys, j, allKeys, nextPos,
                                allKeys.length - nextPos);
                        distances[j] = dist;
                        allKeys[j] = key.mCode;
                        break;
            }
        }

        if (allCodes != null && allCodes.length > 0) {
            getNearbyKeyCodes(allCodes);
            if (DEBUG) {
                Log.d(TAG, "x=" + x + " y=" + y
                        + " primary="
                        + (primaryIndex == NOT_A_KEY ? "none" : keys[primaryIndex].mCode)
                        + " codes=" + Arrays.toString(allCodes));
            }
        }

Loading