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

Commit 728d1c88 authored by satok's avatar satok
Browse files

Cleanup proximity related code

Bug: 4343280
Change-Id: I57c0f9e20d9d8911009ea97057251a7f7a81512f
parent f9c2773b
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