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

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

Merge "Remove next letters frequency handling"

parents 58e01050 887f11ee
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