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

Commit 1fe943aa authored by satok's avatar satok Committed by Android (Google) Code Review
Browse files

Merge "Cleanup proximity related code"

parents 546b8275 728d1c88
Loading
Loading
Loading
Loading
+0 −62
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
**
** Copyright 2012, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">

    <string-array name="additional_proximitychars">
        <!-- Empty entry terminates the proximity chars array. -->

        <!-- Additional proximity chars for a -->
        <item>a</item>
        <item>e</item>
        <item>i</item>
        <item>o</item>
        <item>u</item>
        <item></item>
        <!-- Additional proximity chars for e -->
        <item>e</item>
        <item>a</item>
        <item>i</item>
        <item>o</item>
        <item>u</item>
        <item></item>
        <!-- Additional proximity chars for i -->
        <item>i</item>
        <item>a</item>
        <item>e</item>
        <item>o</item>
        <item>u</item>
        <item></item>
        <!-- Additional proximity chars for o -->
        <item>o</item>
        <item>a</item>
        <item>e</item>
        <item>i</item>
        <item>u</item>
        <item></item>
        <!-- Additional proximity chars for u -->
        <item>u</item>
        <item>a</item>
        <item>e</item>
        <item>i</item>
        <item>o</item>
        <item></item>
    </string-array>

</resources>
+0 −23
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
**
** Copyright 2012, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <string-array name="additional_proximitychars">
    </string-array>
</resources>
+3 −182
Original line number Diff line number Diff line
@@ -16,17 +16,9 @@

package com.android.inputmethod.keyboard;

import android.util.Log;

import java.util.Arrays;
import java.util.List;

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

    public static final int NOT_A_CODE = -1;
    private static final int ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE = 2;

    private final int mKeyHysteresisDistanceSquared;

@@ -34,12 +26,6 @@ public class KeyDetector {
    private int mCorrectionX;
    private int mCorrectionY;
    private boolean mProximityCorrectOn;
    private int mProximityThresholdSquare;

    // working area
    private static final int MAX_NEARBY_KEYS = 12;
    private final int[] mDistances = new int[MAX_NEARBY_KEYS];
    private final Key[] mNeighborKeys = new Key[MAX_NEARBY_KEYS];

    /**
     * This class handles key detection.
@@ -57,8 +43,6 @@ public class KeyDetector {
        mCorrectionX = (int)correctionX;
        mCorrectionY = (int)correctionY;
        mKeyboard = keyboard;
        final int threshold = keyboard.mMostCommonKeyWidth;
        mProximityThresholdSquare = threshold * threshold;
    }

    public int getKeyHysteresisDistanceSquared() {
@@ -87,168 +71,10 @@ public class KeyDetector {
        return mProximityCorrectOn;
    }

    public void setProximityThreshold(int threshold) {
        mProximityThresholdSquare = threshold * threshold;
    }

    public boolean alwaysAllowsSlidingInput() {
        return false;
    }

    /**
     * Computes maximum size of the array that can contain all nearby key codes returned by
     * {@link #getNearbyCodes}.
     *
     * @return Returns maximum size of the array that can contain all nearby key codes returned
     *         by {@link #getNearbyCodes}.
     */
    protected int getMaxNearbyKeys() {
        return MAX_NEARBY_KEYS;
    }

    /**
     * Allocates array that can hold all key codes returned by {@link #getNearbyCodes}
     * method. The maximum size of the array should be computed by {@link #getMaxNearbyKeys}.
     *
     * @return Allocates and returns an array that can hold all key codes returned by
     *         {@link #getNearbyCodes} method. All elements in the returned array are
     *         initialized by {@link #NOT_A_CODE} value.
     */
    public int[] newCodeArray() {
        int[] codes = new int[getMaxNearbyKeys()];
        Arrays.fill(codes, NOT_A_CODE);
        return codes;
    }

    private void initializeNearbyKeys() {
        Arrays.fill(mDistances, Integer.MAX_VALUE);
        Arrays.fill(mNeighborKeys, null);
    }

    /**
     * Insert the key into nearby keys buffer and sort nearby keys by ascending order of distance.
     * If the distance of two keys are the same, the key which the point is on should be considered
     * as a closer one.
     *
     * @param key the key to be inserted into the nearby keys buffer.
     * @param distance distance between the key's edge and user touched point.
     * @param isOnKey true if the point is on the key.
     * @return order of the key in the nearby buffer, 0 if it is the nearest key.
     */
    private int sortNearbyKeys(Key key, int distance, boolean isOnKey) {
        final int[] distances = mDistances;
        final Key[] neighborKeys = mNeighborKeys;
        for (int insertPos = 0; insertPos < distances.length; insertPos++) {
            final int comparingDistance = distances[insertPos];
            if (distance < comparingDistance || (distance == comparingDistance && isOnKey)) {
                final int nextPos = insertPos + 1;
                if (nextPos < distances.length) {
                    System.arraycopy(distances, insertPos, distances, nextPos,
                            distances.length - nextPos);
                    System.arraycopy(neighborKeys, insertPos, neighborKeys, nextPos,
                            neighborKeys.length - nextPos);
                }
                distances[insertPos] = distance;
                neighborKeys[insertPos] = key;
                return insertPos;
            }
        }
        return distances.length;
    }

    private void getNearbyKeyCodes(final int primaryCode, final int[] allCodes) {
        final Key[] neighborKeys = mNeighborKeys;
        final int maxCodesSize = allCodes.length;

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

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

        final int code = (primaryCode == NOT_A_CODE) ? allCodes[0] : primaryCode;
        if (code == NOT_A_CODE) {
            return;
        }
        final List<Integer> additionalChars = mKeyboard.getAdditionalProximityChars().get(code);
        if (additionalChars == null || additionalChars.size() == 0) {
            return;
        }
        int currentCodesSize = numCodes;
        allCodes[numCodes++] = ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE;
        if (maxCodesSize <= numCodes) {
            return;
        }
        // TODO: This is O(N^2). Assuming additionalChars.size() is up to 4 or 5.
        for (int i = 0; i < additionalChars.size(); ++i) {
            final int additionalChar = additionalChars.get(i);
            boolean contains = false;
            for (int j = 0; j < currentCodesSize; ++j) {
                if (additionalChar == allCodes[j]) {
                    contains = true;
                    break;
                }
            }
            if (!contains) {
                allCodes[numCodes++] = additionalChar;
                if (maxCodesSize <= numCodes) {
                    return;
                }
            }
        }
    }

    /**
     * Finds all possible nearby key codes around a touch event point and returns the nearest key.
     * The algorithm to determine the nearby keys depends on the threshold set by
     * {@link #setProximityThreshold(int)} and the mode set by
     * {@link #setProximityCorrectionEnabled(boolean)}.
     *
     * @param x The x-coordinate of a touch point
     * @param y The y-coordinate of a touch point
     * @param allCodes All nearby key codes except functional key are returned in this array
     */
    // TODO: Move this method to native code.
    public void getNearbyCodes(int x, int y, final int[] allCodes) {
        final int touchX = getTouchX(x);
        final int touchY = getTouchY(y);

        initializeNearbyKeys();
        Key primaryKey = null;
        for (final Key key : mKeyboard.getNearestKeys(touchX, touchY)) {
            final boolean isOnKey = key.isOnKey(touchX, touchY);
            final int distance = key.squaredDistanceToEdge(touchX, touchY);
            if (isOnKey || (mProximityCorrectOn && distance < mProximityThresholdSquare)) {
                final int insertedPosition = sortNearbyKeys(key, distance, isOnKey);
                if (insertedPosition == 0 && isOnKey) {
                    primaryKey = key;
                }
            }
        }

        getNearbyKeyCodes(primaryKey != null ? primaryKey.mCode : NOT_A_CODE, allCodes);
        if (DEBUG) {
            Log.d(TAG, "x=" + x + " y=" + y
                    + " primary=" + printableCode(primaryKey)
                    + " codes=" + printableCodes(allCodes));
        }
    }

    /**
     * Detect the key whose hitbox the touch point is in.
     *
@@ -284,15 +110,10 @@ public class KeyDetector {
        boolean addDelimiter = false;
        for (final int code : codes) {
            if (code == NOT_A_CODE) break;
            if (code == ADDITIONAL_PROXIMITY_CHAR_DELIMITER_CODE) {
                sb.append(" | ");
                addDelimiter = false;
            } else {
            if (addDelimiter) sb.append(", ");
            sb.append(Keyboard.printableCode(code));
            addDelimiter = true;
        }
        }
        return "[" + sb + "]";
    }
}
+1 −35
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
@@ -42,8 +41,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

/**
 * Loads an XML description of a keyboard and stores the attributes of the keys. A keyboard
@@ -133,8 +130,6 @@ public class Keyboard {

    private final ProximityInfo mProximityInfo;

    private final Map<Integer, List<Integer>> mAdditionalProximityChars;

    public Keyboard(Params params) {
        mId = params.mId;
        mThemeId = params.mThemeId;
@@ -153,12 +148,10 @@ public class Keyboard {
        mAltCodeKeysWhileTyping = params.mAltCodeKeysWhileTyping.toArray(
                new Key[params.mAltCodeKeysWhileTyping.size()]);
        mIconsSet = params.mIconsSet;
        mAdditionalProximityChars = params.mAdditionalProximityChars;

        mProximityInfo = new ProximityInfo(params.mId.mLocale.toString(),
                params.GRID_WIDTH, params.GRID_HEIGHT, mOccupiedWidth, mOccupiedHeight,
                mMostCommonKeyWidth, mMostCommonKeyHeight, mKeys, params.mTouchPositionCorrection,
                params.mAdditionalProximityChars);
                mMostCommonKeyWidth, mMostCommonKeyHeight, mKeys, params.mTouchPositionCorrection);
    }

    public ProximityInfo getProximityInfo() {
@@ -230,9 +223,6 @@ public class Keyboard {
        public final ArrayList<Key> mShiftKeys = new ArrayList<Key>();
        public final ArrayList<Key> mAltCodeKeysWhileTyping = new ArrayList<Key>();
        public final KeyboardIconsSet mIconsSet = new KeyboardIconsSet();
        // TODO: Should be in Key instead of Keyboard.Params?
        public final Map<Integer, List<Integer>> mAdditionalProximityChars =
                new HashMap<Integer, List<Integer>>();

        public KeyboardSet.KeysCache mKeysCache;

@@ -368,10 +358,6 @@ public class Keyboard {
        return mProximityInfo.getNearestKeys(adjustedX, adjustedY);
    }

    public Map<Integer, List<Integer>> getAdditionalProximityChars() {
        return mAdditionalProximityChars;
    }

    public static String printableCode(int code) {
        switch (code) {
        case CODE_SHIFT: return "shift";
@@ -630,7 +616,6 @@ public class Keyboard {
            mParams = params;

            setTouchPositionCorrectionData(context, params);
            setAdditionalProximityChars(context, params);

            params.GRID_WIDTH = res.getInteger(R.integer.config_keyboard_grid_width);
            params.GRID_HEIGHT = res.getInteger(R.integer.config_keyboard_grid_height);
@@ -653,25 +638,6 @@ public class Keyboard {
            params.mTouchPositionCorrection.load(data);
        }

        private static void setAdditionalProximityChars(Context context, Params params) {
            final String[] additionalChars =
                    context.getResources().getStringArray(R.array.additional_proximitychars);
            int currentPrimaryIndex = 0;
            for (int i = 0; i < additionalChars.length; ++i) {
                final String additionalChar = additionalChars[i];
                if (TextUtils.isEmpty(additionalChar)) {
                    currentPrimaryIndex = 0;
                } else if (currentPrimaryIndex == 0) {
                    currentPrimaryIndex = additionalChar.charAt(0);
                    params.mAdditionalProximityChars.put(
                            currentPrimaryIndex, new ArrayList<Integer>());
                } else if (currentPrimaryIndex != 0) {
                    final int c = additionalChar.charAt(0);
                    params.mAdditionalProximityChars.get(currentPrimaryIndex).add(c);
                }
            }
        }

        public void setAutoGenerate(KeyboardSet.KeysCache keysCache) {
            mParams.mKeysCache = keysCache;
        }
+0 −1
Original line number Diff line number Diff line
@@ -480,7 +480,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
        super.setKeyboard(keyboard);
        mKeyDetector.setKeyboard(
                keyboard, -getPaddingLeft(), -getPaddingTop() + mVerticalCorrection);
        mKeyDetector.setProximityThreshold(keyboard.mMostCommonKeyWidth);
        PointerTracker.setKeyDetector(mKeyDetector);
        mTouchScreenRegulator.setKeyboard(keyboard);
        mMoreKeysPanelCache.clear();
Loading