am 391e83dc
: Merge "Add null analysis annotations to keyboard package"
* commit '391e83dc8f2643fb415d7116170b922de827e0a1': Add null analysis annotations to keyboard package
This commit is contained in:
commit
10f4d6e524
17 changed files with 219 additions and 100 deletions
|
@ -43,6 +43,9 @@ import com.android.inputmethod.latin.common.StringUtils;
|
|||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Class for describing the position and characteristics of a single key in the keyboard.
|
||||
*/
|
||||
|
@ -113,9 +116,11 @@ public class Key implements Comparable<Key> {
|
|||
/** Y coordinate of the top-left corner of the key in the keyboard layout, excluding the gap. */
|
||||
private final int mY;
|
||||
/** Hit bounding box of the key */
|
||||
@Nonnull
|
||||
private final Rect mHitBox = new Rect();
|
||||
|
||||
/** More keys. It is guaranteed that this is null or an array of one or more elements */
|
||||
@Nullable
|
||||
private final MoreKeySpec[] mMoreKeys;
|
||||
/** More keys column number and flags */
|
||||
private final int mMoreKeysColumnAndFlags;
|
||||
|
@ -158,8 +163,9 @@ public class Key implements Comparable<Key> {
|
|||
private static final int ACTION_FLAGS_ALT_CODE_WHILE_TYPING = 0x04;
|
||||
private static final int ACTION_FLAGS_ENABLE_LONG_PRESS = 0x08;
|
||||
|
||||
@Nullable
|
||||
private final KeyVisualAttributes mKeyVisualAttributes;
|
||||
|
||||
@Nullable
|
||||
private final OptionalAttributes mOptionalAttributes;
|
||||
|
||||
private static final class OptionalAttributes {
|
||||
|
@ -181,6 +187,7 @@ public class Key implements Comparable<Key> {
|
|||
mVisualInsetsRight = visualInsetsRight;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static OptionalAttributes newInstance(final String outputText, final int altCode,
|
||||
final int disabledIconId, final int visualInsetsLeft, final int visualInsetsRight) {
|
||||
if (outputText == null && altCode == CODE_UNSPECIFIED
|
||||
|
@ -204,10 +211,10 @@ public class Key implements Comparable<Key> {
|
|||
* Constructor for a key on <code>MoreKeyKeyboard</code>, on <code>MoreSuggestions</code>,
|
||||
* and in a <GridRows/>.
|
||||
*/
|
||||
public Key(final String label, final int iconId, final int code, final String outputText,
|
||||
final String hintLabel, final int labelFlags, final int backgroundType, final int x,
|
||||
final int y, final int width, final int height, final int horizontalGap,
|
||||
final int verticalGap) {
|
||||
public Key(@Nullable final String label, final int iconId, final int code,
|
||||
@Nullable final String outputText, @Nullable final String hintLabel,
|
||||
final int labelFlags, final int backgroundType, final int x, final int y,
|
||||
final int width, final int height, final int horizontalGap, final int verticalGap) {
|
||||
mWidth = width - horizontalGap;
|
||||
mHeight = height - verticalGap;
|
||||
mHorizontalGap = horizontalGap;
|
||||
|
@ -245,8 +252,9 @@ public class Key implements Comparable<Key> {
|
|||
* @param row the row that this key belongs to. row's x-coordinate will be the right edge of
|
||||
* this key.
|
||||
*/
|
||||
public Key(final String keySpec, final TypedArray keyAttr, final KeyStyle style,
|
||||
final KeyboardParams params, final KeyboardRow row) {
|
||||
public Key(@Nullable final String keySpec, @Nonnull final TypedArray keyAttr,
|
||||
@Nonnull final KeyStyle style, @Nonnull final KeyboardParams params,
|
||||
@Nonnull final KeyboardRow row) {
|
||||
mHorizontalGap = isSpacer() ? 0 : params.mHorizontalGap;
|
||||
mVerticalGap = params.mVerticalGap;
|
||||
|
||||
|
@ -403,11 +411,11 @@ public class Key implements Comparable<Key> {
|
|||
*
|
||||
* @param key the original key.
|
||||
*/
|
||||
protected Key(final Key key) {
|
||||
protected Key(@Nonnull final Key key) {
|
||||
this(key, key.mMoreKeys);
|
||||
}
|
||||
|
||||
private Key(final Key key, final MoreKeySpec[] moreKeys) {
|
||||
private Key(@Nonnull final Key key, @Nullable final MoreKeySpec[] moreKeys) {
|
||||
// Final attributes.
|
||||
mCode = key.mCode;
|
||||
mLabel = key.mLabel;
|
||||
|
@ -433,8 +441,9 @@ public class Key implements Comparable<Key> {
|
|||
mEnabled = key.mEnabled;
|
||||
}
|
||||
|
||||
public static Key removeRedundantMoreKeys(final Key key,
|
||||
final MoreKeySpec.LettersOnBaseLayout lettersOnBaseLayout) {
|
||||
@Nonnull
|
||||
public static Key removeRedundantMoreKeys(@Nonnull final Key key,
|
||||
@Nonnull final MoreKeySpec.LettersOnBaseLayout lettersOnBaseLayout) {
|
||||
final MoreKeySpec[] moreKeys = key.getMoreKeys();
|
||||
final MoreKeySpec[] filteredMoreKeys = MoreKeySpec.removeRedundantMoreKeys(
|
||||
moreKeys, lettersOnBaseLayout);
|
||||
|
@ -554,14 +563,17 @@ public class Key implements Comparable<Key> {
|
|||
return mCode;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getLabel() {
|
||||
return mLabel;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getHintLabel() {
|
||||
return mHintLabel;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public MoreKeySpec[] getMoreKeys() {
|
||||
return mMoreKeys;
|
||||
}
|
||||
|
@ -620,6 +632,7 @@ public class Key implements Comparable<Key> {
|
|||
return mKeyVisualAttributes;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public final Typeface selectTypeface(final KeyDrawParams params) {
|
||||
switch (mLabelFlags & LABEL_FLAGS_FONT_MASK) {
|
||||
case LABEL_FLAGS_FONT_NORMAL:
|
||||
|
@ -696,6 +709,7 @@ public class Key implements Comparable<Key> {
|
|||
return params.mLetterSize;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public Typeface selectPreviewTypeface(final KeyDrawParams params) {
|
||||
if (previewHasLetterSize()) {
|
||||
return selectTypeface(params);
|
||||
|
@ -780,6 +794,7 @@ public class Key implements Comparable<Key> {
|
|||
return (mMoreKeysColumnAndFlags & MORE_KEYS_FLAGS_NO_PANEL_AUTO_MORE_KEY) != 0;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public final String getOutputText() {
|
||||
final OptionalAttributes attrs = mOptionalAttributes;
|
||||
return (attrs != null) ? attrs.mOutputText : null;
|
||||
|
@ -794,6 +809,7 @@ public class Key implements Comparable<Key> {
|
|||
return mIconId;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Drawable getIcon(final KeyboardIconsSet iconSet, final int alpha) {
|
||||
final OptionalAttributes attrs = mOptionalAttributes;
|
||||
final int disabledIconId = (attrs != null) ? attrs.mDisabledIconId : ICON_UNDEFINED;
|
||||
|
@ -805,6 +821,7 @@ public class Key implements Comparable<Key> {
|
|||
return icon;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Drawable getPreviewIcon(final KeyboardIconsSet iconSet) {
|
||||
return iconSet.getIconDrawable(getIconId());
|
||||
}
|
||||
|
@ -897,6 +914,7 @@ public class Key implements Comparable<Key> {
|
|||
mEnabled = enabled;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public Rect getHitBox() {
|
||||
return mHitBox;
|
||||
}
|
||||
|
@ -968,8 +986,10 @@ public class Key implements Comparable<Key> {
|
|||
* @return the background drawable of the key.
|
||||
* @see android.graphics.drawable.StateListDrawable#setState(int[])
|
||||
*/
|
||||
public final Drawable selectBackgroundDrawable(final Drawable keyBackground,
|
||||
final Drawable functionalKeyBackground, final Drawable spacebarBackground) {
|
||||
@Nonnull
|
||||
public final Drawable selectBackgroundDrawable(@Nonnull final Drawable keyBackground,
|
||||
@Nonnull final Drawable functionalKeyBackground,
|
||||
@Nonnull final Drawable spacebarBackground) {
|
||||
final Drawable background;
|
||||
if (mBackgroundType == BACKGROUND_TYPE_FUNCTIONAL) {
|
||||
background = functionalKeyBackground;
|
||||
|
|
|
@ -28,6 +28,9 @@ import java.util.ArrayList;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Loads an XML description of a keyboard and stores the attributes of the keys. A keyboard
|
||||
* consists of rows of keys.
|
||||
|
@ -47,6 +50,7 @@ import java.util.List;
|
|||
* </pre>
|
||||
*/
|
||||
public class Keyboard {
|
||||
@Nonnull
|
||||
public final KeyboardId mId;
|
||||
public final int mThemeId;
|
||||
|
||||
|
@ -78,17 +82,22 @@ public class Keyboard {
|
|||
public final int mMaxMoreKeysKeyboardColumn;
|
||||
|
||||
/** List of keys in this keyboard */
|
||||
@Nonnull
|
||||
private final List<Key> mSortedKeys;
|
||||
@Nonnull
|
||||
public final List<Key> mShiftKeys;
|
||||
@Nonnull
|
||||
public final List<Key> mAltCodeKeysWhileTyping;
|
||||
@Nonnull
|
||||
public final KeyboardIconsSet mIconsSet;
|
||||
|
||||
private final SparseArray<Key> mKeyCache = new SparseArray<>();
|
||||
|
||||
@Nonnull
|
||||
private final ProximityInfo mProximityInfo;
|
||||
private final boolean mProximityCharsCorrectionEnabled;
|
||||
|
||||
public Keyboard(final KeyboardParams params) {
|
||||
public Keyboard(@Nonnull final KeyboardParams params) {
|
||||
mId = params.mId;
|
||||
mThemeId = params.mThemeId;
|
||||
mOccupiedHeight = params.mOccupiedHeight;
|
||||
|
@ -114,7 +123,7 @@ public class Keyboard {
|
|||
mProximityCharsCorrectionEnabled = params.mProximityCharsCorrectionEnabled;
|
||||
}
|
||||
|
||||
protected Keyboard(final Keyboard keyboard) {
|
||||
protected Keyboard(@Nonnull final Keyboard keyboard) {
|
||||
mId = keyboard.mId;
|
||||
mThemeId = keyboard.mThemeId;
|
||||
mOccupiedHeight = keyboard.mOccupiedHeight;
|
||||
|
@ -150,6 +159,7 @@ public class Keyboard {
|
|||
return canAssumeNativeHasProximityCharsInfoOfAllKeys || Character.isLetter(code);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public ProximityInfo getProximityInfo() {
|
||||
return mProximityInfo;
|
||||
}
|
||||
|
@ -160,10 +170,12 @@ public class Keyboard {
|
|||
* The list may contain {@link Key.Spacer} object as well.
|
||||
* @return the sorted unmodifiable list of {@link Key}s of this keyboard.
|
||||
*/
|
||||
@Nonnull
|
||||
public List<Key> getSortedKeys() {
|
||||
return mSortedKeys;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Key getKey(final int code) {
|
||||
if (code == Constants.CODE_UNSPECIFIED) {
|
||||
return null;
|
||||
|
@ -185,7 +197,7 @@ public class Keyboard {
|
|||
}
|
||||
}
|
||||
|
||||
public boolean hasKey(final Key aKey) {
|
||||
public boolean hasKey(@Nonnull final Key aKey) {
|
||||
if (mKeyCache.indexOfValue(aKey) >= 0) {
|
||||
return true;
|
||||
}
|
||||
|
@ -211,6 +223,7 @@ public class Keyboard {
|
|||
* @return the list of the nearest keys to the given point. If the given
|
||||
* point is out of range, then an array of size zero is returned.
|
||||
*/
|
||||
@Nonnull
|
||||
public List<Key> getNearestKeys(final int x, final int y) {
|
||||
// Avoid dead pixels at edges of the keyboard
|
||||
final int adjustedX = Math.max(0, Math.min(x, mOccupiedWidth - 1));
|
||||
|
@ -218,7 +231,8 @@ public class Keyboard {
|
|||
return mProximityInfo.getNearestKeys(adjustedX, adjustedY);
|
||||
}
|
||||
|
||||
public int[] getCoordinates(final int[] codePoints) {
|
||||
@Nonnull
|
||||
public int[] getCoordinates(@Nonnull final int[] codePoints) {
|
||||
final int length = codePoints.length;
|
||||
final int[] coordinates = CoordinateUtils.newCoordinateArray(length);
|
||||
for (int i = 0; i < length; ++i) {
|
||||
|
|
|
@ -72,6 +72,7 @@ public final class KeyboardLayoutSet {
|
|||
private static final String KEYBOARD_LAYOUT_SET_RESOURCE_PREFIX = "keyboard_layout_set_";
|
||||
|
||||
private final Context mContext;
|
||||
@Nonnull
|
||||
private final Params mParams;
|
||||
|
||||
// How many layouts we forcibly keep in cache. This only includes ALPHABET (default) and
|
||||
|
@ -84,6 +85,7 @@ public final class KeyboardLayoutSet {
|
|||
private static final Keyboard[] sForcibleKeyboardCache = new Keyboard[FORCIBLE_CACHE_SIZE];
|
||||
private static final HashMap<KeyboardId, SoftReference<Keyboard>> sKeyboardCache =
|
||||
new HashMap<>();
|
||||
@Nonnull
|
||||
private static final KeysCache sKeysCache = new KeysCache();
|
||||
private final static HashMap<InputMethodSubtype, Integer> sScriptIdsForSubtypes =
|
||||
new HashMap<>();
|
||||
|
@ -145,7 +147,8 @@ public final class KeyboardLayoutSet {
|
|||
sKeysCache.clear();
|
||||
}
|
||||
|
||||
public static int getScriptId(final Resources resources, final InputMethodSubtype subtype) {
|
||||
public static int getScriptId(final Resources resources,
|
||||
@Nonnull final InputMethodSubtype subtype) {
|
||||
final Integer value = sScriptIdsForSubtypes.get(subtype);
|
||||
if (null == value) {
|
||||
final int scriptId = Builder.readScriptId(resources, subtype);
|
||||
|
@ -155,11 +158,12 @@ public final class KeyboardLayoutSet {
|
|||
return value;
|
||||
}
|
||||
|
||||
KeyboardLayoutSet(final Context context, final Params params) {
|
||||
KeyboardLayoutSet(final Context context, @Nonnull final Params params) {
|
||||
mContext = context;
|
||||
mParams = params;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public Keyboard getKeyboard(final int baseKeyboardLayoutSetElementId) {
|
||||
final int keyboardLayoutSetElementId;
|
||||
switch (mParams.mMode) {
|
||||
|
@ -203,6 +207,7 @@ public final class KeyboardLayoutSet {
|
|||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private Keyboard getKeyboard(final ElementParams elementParams, final KeyboardId id) {
|
||||
final SoftReference<Keyboard> ref = sKeyboardCache.get(id);
|
||||
final Keyboard cachedKeyboard = (ref == null) ? null : ref.get();
|
||||
|
|
|
@ -103,7 +103,8 @@ public class KeyboardView extends View {
|
|||
// TODO: Consider having a dummy keyboard object to make this @Nonnull
|
||||
@Nullable
|
||||
private Keyboard mKeyboard;
|
||||
protected final KeyDrawParams mKeyDrawParams = new KeyDrawParams();
|
||||
@Nonnull
|
||||
private final KeyDrawParams mKeyDrawParams = new KeyDrawParams();
|
||||
|
||||
// Drawing
|
||||
/** True if all keys should be drawn */
|
||||
|
@ -120,6 +121,7 @@ public class KeyboardView extends View {
|
|||
@Nonnull
|
||||
private final Paint mPaint = new Paint();
|
||||
private final Paint.FontMetrics mFontMetrics = new Paint.FontMetrics();
|
||||
|
||||
public KeyboardView(final Context context, final AttributeSet attrs) {
|
||||
this(context, attrs, R.attr.keyboardViewStyle);
|
||||
}
|
||||
|
@ -210,6 +212,11 @@ public class KeyboardView extends View {
|
|||
return mVerticalCorrection;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
protected KeyDrawParams getKeyDrawParams() {
|
||||
return mKeyDrawParams;
|
||||
}
|
||||
|
||||
protected void updateKeyDrawParams(final int keyHeight) {
|
||||
mKeyDrawParams.updateParams(keyHeight, mKeyVisualAttributes);
|
||||
}
|
||||
|
|
|
@ -484,7 +484,7 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy
|
|||
|
||||
locatePreviewPlacerView();
|
||||
getLocationInWindow(mOriginCoords);
|
||||
mKeyPreviewChoreographer.placeAndShowKeyPreview(key, keyboard.mIconsSet, mKeyDrawParams,
|
||||
mKeyPreviewChoreographer.placeAndShowKeyPreview(key, keyboard.mIconsSet, getKeyDrawParams(),
|
||||
getWidth(), mOriginCoords, mDrawingPreviewPlacerView, isHardwareAccelerated());
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,8 @@ import com.android.inputmethod.latin.R;
|
|||
import com.android.inputmethod.latin.common.StringUtils;
|
||||
import com.android.inputmethod.latin.utils.TypefaceUtils;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public final class MoreKeysKeyboard extends Keyboard {
|
||||
private final int mDefaultKeyCoordX;
|
||||
|
||||
|
@ -328,6 +330,7 @@ public final class MoreKeysKeyboard extends Keyboard {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public MoreKeysKeyboard build() {
|
||||
final MoreKeysKeyboardParams params = mParams;
|
||||
final int moreKeyFlags = mParentKey.getMoreKeyLabelFlags();
|
||||
|
|
|
@ -28,6 +28,8 @@ import java.util.Arrays;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class ProximityInfo {
|
||||
private static final String TAG = ProximityInfo.class.getSimpleName();
|
||||
private static final boolean DEBUG = false;
|
||||
|
@ -36,6 +38,7 @@ public class ProximityInfo {
|
|||
public static final int MAX_PROXIMITY_CHARS_SIZE = 16;
|
||||
/** Number of key widths from current touch point to search for nearest keys. */
|
||||
private static final float SEARCH_DISTANCE = 1.2f;
|
||||
@Nonnull
|
||||
private static final List<Key> EMPTY_KEY_LIST = Collections.emptyList();
|
||||
private static final float DEFAULT_TOUCH_POSITION_CORRECTION_RADIUS = 0.15f;
|
||||
|
||||
|
@ -49,13 +52,16 @@ public class ProximityInfo {
|
|||
private final int mKeyboardHeight;
|
||||
private final int mMostCommonKeyWidth;
|
||||
private final int mMostCommonKeyHeight;
|
||||
@Nonnull
|
||||
private final List<Key> mSortedKeys;
|
||||
@Nonnull
|
||||
private final List<Key>[] mGridNeighbors;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
ProximityInfo(final int gridWidth, final int gridHeight, final int minWidth, final int height,
|
||||
final int mostCommonKeyWidth, final int mostCommonKeyHeight, final List<Key> sortedKeys,
|
||||
final TouchPositionCorrection touchPositionCorrection) {
|
||||
final int mostCommonKeyWidth, final int mostCommonKeyHeight,
|
||||
@Nonnull final List<Key> sortedKeys,
|
||||
@Nonnull final TouchPositionCorrection touchPositionCorrection) {
|
||||
mGridWidth = gridWidth;
|
||||
mGridHeight = gridHeight;
|
||||
mGridSize = mGridWidth * mGridHeight;
|
||||
|
@ -104,7 +110,8 @@ public class ProximityInfo {
|
|||
return count;
|
||||
}
|
||||
|
||||
private long createNativeProximityInfo(final TouchPositionCorrection touchPositionCorrection) {
|
||||
private long createNativeProximityInfo(
|
||||
@Nonnull final TouchPositionCorrection touchPositionCorrection) {
|
||||
final List<Key>[] gridNeighborKeys = mGridNeighbors;
|
||||
final int[] proximityCharsArray = new int[mGridSize * MAX_PROXIMITY_CHARS_SIZE];
|
||||
Arrays.fill(proximityCharsArray, Constants.NOT_A_CODE);
|
||||
|
@ -163,7 +170,7 @@ public class ProximityInfo {
|
|||
infoIndex++;
|
||||
}
|
||||
|
||||
if (touchPositionCorrection != null && touchPositionCorrection.isValid()) {
|
||||
if (touchPositionCorrection.isValid()) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "touchPositionCorrection: ON");
|
||||
}
|
||||
|
@ -385,10 +392,8 @@ y |---+---+---+---+-v-+-|-+---+---+---+---+---| | thresholdBase and get
|
|||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public List<Key> getNearestKeys(final int x, final int y) {
|
||||
if (mGridNeighbors == null) {
|
||||
return EMPTY_KEY_LIST;
|
||||
}
|
||||
if (x >= 0 && x < mKeyboardMinWidth && y >= 0 && y < mKeyboardHeight) {
|
||||
int index = (y / mCellHeight) * mGridWidth + (x / mCellWidth);
|
||||
if (index < mGridSize) {
|
||||
|
|
|
@ -20,8 +20,12 @@ import android.graphics.Typeface;
|
|||
|
||||
import com.android.inputmethod.latin.utils.ResourceUtils;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public final class KeyDrawParams {
|
||||
public Typeface mTypeface;
|
||||
@Nonnull
|
||||
public Typeface mTypeface = Typeface.DEFAULT;
|
||||
|
||||
public int mLetterSize;
|
||||
public int mLabelSize;
|
||||
|
@ -49,7 +53,7 @@ public final class KeyDrawParams {
|
|||
|
||||
public KeyDrawParams() {}
|
||||
|
||||
private KeyDrawParams(final KeyDrawParams copyFrom) {
|
||||
private KeyDrawParams(@Nonnull final KeyDrawParams copyFrom) {
|
||||
mTypeface = copyFrom.mTypeface;
|
||||
|
||||
mLetterSize = copyFrom.mLetterSize;
|
||||
|
@ -77,7 +81,7 @@ public final class KeyDrawParams {
|
|||
mAnimAlpha = copyFrom.mAnimAlpha;
|
||||
}
|
||||
|
||||
public void updateParams(final int keyHeight, final KeyVisualAttributes attr) {
|
||||
public void updateParams(final int keyHeight, @Nullable final KeyVisualAttributes attr) {
|
||||
if (attr == null) {
|
||||
return;
|
||||
}
|
||||
|
@ -117,8 +121,9 @@ public final class KeyDrawParams {
|
|||
attr.mHintLabelOffCenterRatio, mHintLabelOffCenterRatio);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public KeyDrawParams mayCloneAndUpdateParams(final int keyHeight,
|
||||
final KeyVisualAttributes attr) {
|
||||
@Nullable final KeyVisualAttributes attr) {
|
||||
if (attr == null) {
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,9 @@ import static com.android.inputmethod.latin.common.Constants.CODE_UNSPECIFIED;
|
|||
import com.android.inputmethod.latin.common.Constants;
|
||||
import com.android.inputmethod.latin.common.StringUtils;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* The string parser of the key specification.
|
||||
*
|
||||
|
@ -53,11 +56,11 @@ public final class KeySpecParser {
|
|||
// Intentional empty constructor for utility class.
|
||||
}
|
||||
|
||||
private static boolean hasIcon(final String keySpec) {
|
||||
private static boolean hasIcon(@Nonnull final String keySpec) {
|
||||
return keySpec.startsWith(KeyboardIconsSet.PREFIX_ICON);
|
||||
}
|
||||
|
||||
private static boolean hasCode(final String keySpec, final int labelEnd) {
|
||||
private static boolean hasCode(@Nonnull final String keySpec, final int labelEnd) {
|
||||
if (labelEnd <= 0 || labelEnd + 1 >= keySpec.length()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -72,7 +75,8 @@ public final class KeySpecParser {
|
|||
return false;
|
||||
}
|
||||
|
||||
private static String parseEscape(final String text) {
|
||||
@Nonnull
|
||||
private static String parseEscape(@Nonnull final String text) {
|
||||
if (text.indexOf(BACKSLASH) < 0) {
|
||||
return text;
|
||||
}
|
||||
|
@ -91,7 +95,7 @@ public final class KeySpecParser {
|
|||
return sb.toString();
|
||||
}
|
||||
|
||||
private static int indexOfLabelEnd(final String keySpec) {
|
||||
private static int indexOfLabelEnd(@Nonnull final String keySpec) {
|
||||
final int length = keySpec.length();
|
||||
if (keySpec.indexOf(BACKSLASH) < 0) {
|
||||
final int labelEnd = keySpec.indexOf(VERTICAL_BAR);
|
||||
|
@ -116,22 +120,25 @@ public final class KeySpecParser {
|
|||
return -1;
|
||||
}
|
||||
|
||||
private static String getBeforeLabelEnd(final String keySpec, final int labelEnd) {
|
||||
@Nonnull
|
||||
private static String getBeforeLabelEnd(@Nonnull final String keySpec, final int labelEnd) {
|
||||
return (labelEnd < 0) ? keySpec : keySpec.substring(0, labelEnd);
|
||||
}
|
||||
|
||||
private static String getAfterLabelEnd(final String keySpec, final int labelEnd) {
|
||||
@Nonnull
|
||||
private static String getAfterLabelEnd(@Nonnull final String keySpec, final int labelEnd) {
|
||||
return keySpec.substring(labelEnd + /* VERTICAL_BAR */1);
|
||||
}
|
||||
|
||||
private static void checkDoubleLabelEnd(final String keySpec, final int labelEnd) {
|
||||
private static void checkDoubleLabelEnd(@Nonnull final String keySpec, final int labelEnd) {
|
||||
if (indexOfLabelEnd(getAfterLabelEnd(keySpec, labelEnd)) < 0) {
|
||||
return;
|
||||
}
|
||||
throw new KeySpecParserError("Multiple " + VERTICAL_BAR + ": " + keySpec);
|
||||
}
|
||||
|
||||
public static String getLabel(final String keySpec) {
|
||||
@Nullable
|
||||
public static String getLabel(@Nullable final String keySpec) {
|
||||
if (keySpec == null) {
|
||||
// TODO: Throw {@link KeySpecParserError} once Key.keyLabel attribute becomes mandatory.
|
||||
return null;
|
||||
|
@ -147,7 +154,8 @@ public final class KeySpecParser {
|
|||
return label;
|
||||
}
|
||||
|
||||
private static String getOutputTextInternal(final String keySpec, final int labelEnd) {
|
||||
@Nullable
|
||||
private static String getOutputTextInternal(@Nonnull final String keySpec, final int labelEnd) {
|
||||
if (labelEnd <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
@ -155,7 +163,8 @@ public final class KeySpecParser {
|
|||
return parseEscape(getAfterLabelEnd(keySpec, labelEnd));
|
||||
}
|
||||
|
||||
public static String getOutputText(final String keySpec) {
|
||||
@Nullable
|
||||
public static String getOutputText(@Nullable final String keySpec) {
|
||||
if (keySpec == null) {
|
||||
// TODO: Throw {@link KeySpecParserError} once Key.keyLabel attribute becomes mandatory.
|
||||
return null;
|
||||
|
@ -184,7 +193,7 @@ public final class KeySpecParser {
|
|||
return (StringUtils.codePointCount(label) == 1) ? null : label;
|
||||
}
|
||||
|
||||
public static int getCode(final String keySpec) {
|
||||
public static int getCode(@Nullable final String keySpec) {
|
||||
if (keySpec == null) {
|
||||
// TODO: Throw {@link KeySpecParserError} once Key.keyLabel attribute becomes mandatory.
|
||||
return CODE_UNSPECIFIED;
|
||||
|
@ -211,7 +220,7 @@ public final class KeySpecParser {
|
|||
return (StringUtils.codePointCount(label) == 1) ? label.codePointAt(0) : CODE_OUTPUT_TEXT;
|
||||
}
|
||||
|
||||
public static int parseCode(final String text, final int defaultCode) {
|
||||
public static int parseCode(@Nullable final String text, final int defaultCode) {
|
||||
if (text == null) {
|
||||
return defaultCode;
|
||||
}
|
||||
|
@ -226,7 +235,7 @@ public final class KeySpecParser {
|
|||
return defaultCode;
|
||||
}
|
||||
|
||||
public static int getIconId(final String keySpec) {
|
||||
public static int getIconId(@Nullable final String keySpec) {
|
||||
if (keySpec == null) {
|
||||
// TODO: Throw {@link KeySpecParserError} once Key.keyLabel attribute becomes mandatory.
|
||||
return KeyboardIconsSet.ICON_UNDEFINED;
|
||||
|
|
|
@ -18,18 +18,22 @@ package com.android.inputmethod.keyboard.internal;
|
|||
|
||||
import android.content.res.TypedArray;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class KeyStyle {
|
||||
private final KeyboardTextsSet mTextsSet;
|
||||
|
||||
public abstract String[] getStringArray(TypedArray a, int index);
|
||||
public abstract String getString(TypedArray a, int index);
|
||||
public abstract @Nullable String[] getStringArray(TypedArray a, int index);
|
||||
public abstract @Nullable String getString(TypedArray a, int index);
|
||||
public abstract int getInt(TypedArray a, int index, int defaultValue);
|
||||
public abstract int getFlags(TypedArray a, int index);
|
||||
|
||||
protected KeyStyle(final KeyboardTextsSet textsSet) {
|
||||
protected KeyStyle(@Nonnull final KeyboardTextsSet textsSet) {
|
||||
mTextsSet = textsSet;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String parseString(final TypedArray a, final int index) {
|
||||
if (a.hasValue(index)) {
|
||||
return mTextsSet.resolveTextReference(a.getString(index));
|
||||
|
@ -37,6 +41,7 @@ public abstract class KeyStyle {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String[] parseStringArray(final TypedArray a, final int index) {
|
||||
if (a.hasValue(index)) {
|
||||
final String text = mTextsSet.resolveTextReference(a.getString(index));
|
||||
|
|
|
@ -29,33 +29,42 @@ import org.xmlpull.v1.XmlPullParserException;
|
|||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public final class KeyStylesSet {
|
||||
private static final String TAG = KeyStylesSet.class.getSimpleName();
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
@Nonnull
|
||||
private final HashMap<String, KeyStyle> mStyles = new HashMap<>();
|
||||
|
||||
@Nonnull
|
||||
private final KeyboardTextsSet mTextsSet;
|
||||
@Nonnull
|
||||
private final KeyStyle mEmptyKeyStyle;
|
||||
@Nonnull
|
||||
private static final String EMPTY_STYLE_NAME = "<empty>";
|
||||
|
||||
public KeyStylesSet(final KeyboardTextsSet textsSet) {
|
||||
public KeyStylesSet(@Nonnull final KeyboardTextsSet textsSet) {
|
||||
mTextsSet = textsSet;
|
||||
mEmptyKeyStyle = new EmptyKeyStyle(textsSet);
|
||||
mStyles.put(EMPTY_STYLE_NAME, mEmptyKeyStyle);
|
||||
}
|
||||
|
||||
private static final class EmptyKeyStyle extends KeyStyle {
|
||||
EmptyKeyStyle(final KeyboardTextsSet textsSet) {
|
||||
EmptyKeyStyle(@Nonnull final KeyboardTextsSet textsSet) {
|
||||
super(textsSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String[] getStringArray(final TypedArray a, final int index) {
|
||||
return parseStringArray(a, index);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getString(final TypedArray a, final int index) {
|
||||
return parseString(a, index);
|
||||
}
|
||||
|
@ -76,14 +85,16 @@ public final class KeyStylesSet {
|
|||
private final String mParentStyleName;
|
||||
private final SparseArray<Object> mStyleAttributes = new SparseArray<>();
|
||||
|
||||
public DeclaredKeyStyle(final String parentStyleName, final KeyboardTextsSet textsSet,
|
||||
final HashMap<String, KeyStyle> styles) {
|
||||
public DeclaredKeyStyle(@Nonnull final String parentStyleName,
|
||||
@Nonnull final KeyboardTextsSet textsSet,
|
||||
@Nonnull final HashMap<String, KeyStyle> styles) {
|
||||
super(textsSet);
|
||||
mParentStyleName = parentStyleName;
|
||||
mStyles = styles;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String[] getStringArray(final TypedArray a, final int index) {
|
||||
if (a.hasValue(index)) {
|
||||
return parseStringArray(a, index);
|
||||
|
@ -98,6 +109,7 @@ public final class KeyStylesSet {
|
|||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getString(final TypedArray a, final int index) {
|
||||
if (a.hasValue(index)) {
|
||||
return parseString(a, index);
|
||||
|
@ -176,37 +188,43 @@ public final class KeyStylesSet {
|
|||
public void parseKeyStyleAttributes(final TypedArray keyStyleAttr, final TypedArray keyAttrs,
|
||||
final XmlPullParser parser) throws XmlPullParserException {
|
||||
final String styleName = keyStyleAttr.getString(R.styleable.Keyboard_KeyStyle_styleName);
|
||||
if (styleName == null) {
|
||||
throw new XmlParseUtils.ParseException(
|
||||
KeyboardBuilder.TAG_KEY_STYLE + " has no styleName attribute", parser);
|
||||
}
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, String.format("<%s styleName=%s />",
|
||||
KeyboardBuilder.TAG_KEY_STYLE, styleName));
|
||||
if (mStyles.containsKey(styleName)) {
|
||||
Log.d(TAG, "key-style " + styleName + " is overridden at "
|
||||
Log.d(TAG, KeyboardBuilder.TAG_KEY_STYLE + " " + styleName + " is overridden at "
|
||||
+ parser.getPositionDescription());
|
||||
}
|
||||
}
|
||||
|
||||
String parentStyleName = EMPTY_STYLE_NAME;
|
||||
if (keyStyleAttr.hasValue(R.styleable.Keyboard_KeyStyle_parentStyle)) {
|
||||
parentStyleName = keyStyleAttr.getString(R.styleable.Keyboard_KeyStyle_parentStyle);
|
||||
if (!mStyles.containsKey(parentStyleName)) {
|
||||
throw new XmlParseUtils.ParseException(
|
||||
"Unknown parentStyle " + parentStyleName, parser);
|
||||
}
|
||||
final String parentStyleInAttr = keyStyleAttr.getString(
|
||||
R.styleable.Keyboard_KeyStyle_parentStyle);
|
||||
if (parentStyleInAttr != null && !mStyles.containsKey(parentStyleInAttr)) {
|
||||
throw new XmlParseUtils.ParseException(
|
||||
"Unknown parentStyle " + parentStyleInAttr, parser);
|
||||
}
|
||||
final String parentStyleName = (parentStyleInAttr == null) ? EMPTY_STYLE_NAME
|
||||
: parentStyleInAttr;
|
||||
final DeclaredKeyStyle style = new DeclaredKeyStyle(parentStyleName, mTextsSet, mStyles);
|
||||
style.readKeyAttributes(keyAttrs);
|
||||
mStyles.put(styleName, style);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public KeyStyle getKeyStyle(final TypedArray keyAttr, final XmlPullParser parser)
|
||||
throws XmlParseUtils.ParseException {
|
||||
if (!keyAttr.hasValue(R.styleable.Keyboard_Key_keyStyle)) {
|
||||
final String styleName = keyAttr.getString(R.styleable.Keyboard_Key_keyStyle);
|
||||
if (styleName == null) {
|
||||
return mEmptyKeyStyle;
|
||||
}
|
||||
final String styleName = keyAttr.getString(R.styleable.Keyboard_Key_keyStyle);
|
||||
if (!mStyles.containsKey(styleName)) {
|
||||
final KeyStyle style = mStyles.get(styleName);
|
||||
if (style == null) {
|
||||
throw new XmlParseUtils.ParseException("Unknown key style: " + styleName, parser);
|
||||
}
|
||||
return mStyles.get(styleName);
|
||||
return style;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,11 @@ import android.util.SparseIntArray;
|
|||
import com.android.inputmethod.latin.R;
|
||||
import com.android.inputmethod.latin.utils.ResourceUtils;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public final class KeyVisualAttributes {
|
||||
@Nullable
|
||||
public final Typeface mTypeface;
|
||||
|
||||
public final float mLetterRatio;
|
||||
|
@ -81,7 +85,8 @@ public final class KeyVisualAttributes {
|
|||
}
|
||||
}
|
||||
|
||||
public static KeyVisualAttributes newInstance(final TypedArray keyAttr) {
|
||||
@Nullable
|
||||
public static KeyVisualAttributes newInstance(@Nonnull final TypedArray keyAttr) {
|
||||
final int indexCount = keyAttr.getIndexCount();
|
||||
for (int i = 0; i < indexCount; i++) {
|
||||
final int attrId = keyAttr.getIndex(i);
|
||||
|
@ -93,7 +98,7 @@ public final class KeyVisualAttributes {
|
|||
return null;
|
||||
}
|
||||
|
||||
private KeyVisualAttributes(final TypedArray keyAttr) {
|
||||
private KeyVisualAttributes(@Nonnull final TypedArray keyAttr) {
|
||||
if (keyAttr.hasValue(R.styleable.Keyboard_Key_keyTypeface)) {
|
||||
mTypeface = Typeface.defaultFromStyle(
|
||||
keyAttr.getInt(R.styleable.Keyboard_Key_keyTypeface, Typeface.NORMAL));
|
||||
|
|
|
@ -139,6 +139,7 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
|
|||
private static final int DEFAULT_KEYBOARD_COLUMNS = 10;
|
||||
private static final int DEFAULT_KEYBOARD_ROWS = 4;
|
||||
|
||||
@Nonnull
|
||||
protected final KP mParams;
|
||||
protected final Context mContext;
|
||||
protected final Resources mResources;
|
||||
|
@ -149,7 +150,7 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
|
|||
private boolean mTopEdge;
|
||||
private Key mRightEdgeKey = null;
|
||||
|
||||
public KeyboardBuilder(final Context context, final KP params) {
|
||||
public KeyboardBuilder(final Context context, @Nonnull final KP params) {
|
||||
mContext = context;
|
||||
final Resources res = context.getResources();
|
||||
mResources = res;
|
||||
|
@ -194,6 +195,7 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
|
|||
mParams.mProximityCharsCorrectionEnabled = enabled;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public Keyboard build() {
|
||||
return new Keyboard(mParams);
|
||||
}
|
||||
|
|
|
@ -26,6 +26,9 @@ import com.android.inputmethod.latin.R;
|
|||
|
||||
import java.util.HashMap;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public final class KeyboardIconsSet {
|
||||
private static final String TAG = KeyboardIconsSet.class.getSimpleName();
|
||||
|
||||
|
@ -127,6 +130,7 @@ public final class KeyboardIconsSet {
|
|||
return iconId >= 0 && iconId < ICON_NAMES.length;
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static String getIconName(final int iconId) {
|
||||
return isValidIconId(iconId) ? ICON_NAMES[iconId] : "unknown<" + iconId + ">";
|
||||
}
|
||||
|
@ -147,6 +151,7 @@ public final class KeyboardIconsSet {
|
|||
throw new RuntimeException("unknown icon name: " + name);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Drawable getIconDrawable(final int iconId) {
|
||||
if (isValidIconId(iconId)) {
|
||||
return mIcons[iconId];
|
||||
|
|
|
@ -49,6 +49,7 @@ public class KeyboardParams {
|
|||
public int mLeftPadding;
|
||||
public int mRightPadding;
|
||||
|
||||
@Nullable
|
||||
public KeyVisualAttributes mKeyVisualAttributes;
|
||||
|
||||
public int mDefaultRowHeight;
|
||||
|
@ -63,14 +64,22 @@ public class KeyboardParams {
|
|||
public int GRID_HEIGHT;
|
||||
|
||||
// Keys are sorted from top-left to bottom-right order.
|
||||
@Nonnull
|
||||
public final SortedSet<Key> mSortedKeys = new TreeSet<>(ROW_COLUMN_COMPARATOR);
|
||||
@Nonnull
|
||||
public final ArrayList<Key> mShiftKeys = new ArrayList<>();
|
||||
@Nonnull
|
||||
public final ArrayList<Key> mAltCodeKeysWhileTyping = new ArrayList<>();
|
||||
@Nonnull
|
||||
public final KeyboardIconsSet mIconsSet = new KeyboardIconsSet();
|
||||
@Nonnull
|
||||
public final KeyboardTextsSet mTextsSet = new KeyboardTextsSet();
|
||||
@Nonnull
|
||||
public final KeyStylesSet mKeyStyles = new KeyStylesSet(mTextsSet);
|
||||
|
||||
@Nullable public KeysCache mKeysCache;
|
||||
// TODO: Make this @Nonnull
|
||||
@Nullable
|
||||
public KeysCache mKeysCache;
|
||||
public boolean mAllowRedundantMoreKeys;
|
||||
|
||||
public int mMostCommonKeyHeight = 0;
|
||||
|
@ -78,6 +87,7 @@ public class KeyboardParams {
|
|||
|
||||
public boolean mProximityCharsCorrectionEnabled;
|
||||
|
||||
@Nonnull
|
||||
public final TouchPositionCorrection mTouchPositionCorrection =
|
||||
new TouchPositionCorrection();
|
||||
|
||||
|
@ -100,7 +110,9 @@ public class KeyboardParams {
|
|||
}
|
||||
|
||||
public void onAddKey(@Nonnull final Key newKey) {
|
||||
final Key key = (mKeysCache != null) ? mKeysCache.get(newKey) : newKey;
|
||||
// To avoid possible null pointer access.
|
||||
final KeysCache keysCache = mKeysCache;
|
||||
final Key key = (keysCache != null) ? keysCache.get(newKey) : newKey;
|
||||
final boolean isSpacer = key.isSpacer();
|
||||
if (isSpacer && key.getWidth() == 0) {
|
||||
// Ignore zero width {@link Spacer}.
|
||||
|
@ -128,12 +140,14 @@ public class KeyboardParams {
|
|||
for (final Key key : mSortedKeys) {
|
||||
lettersOnBaseLayout.addLetter(key);
|
||||
}
|
||||
// To avoid possible null pointer access.
|
||||
final KeysCache keysCache = mKeysCache;
|
||||
final ArrayList<Key> allKeys = new ArrayList<>(mSortedKeys);
|
||||
mSortedKeys.clear();
|
||||
for (final Key key : allKeys) {
|
||||
final Key filteredKey = Key.removeRedundantMoreKeys(key, lettersOnBaseLayout);
|
||||
if (mKeysCache != null) {
|
||||
mKeysCache.replace(key, filteredKey);
|
||||
if (keysCache != null) {
|
||||
keysCache.replace(key, filteredKey);
|
||||
}
|
||||
mSortedKeys.add(filteredKey);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import com.android.inputmethod.keyboard.Key;
|
|||
|
||||
import java.util.HashMap;
|
||||
|
||||
// TODO: Rename more appropriate name.
|
||||
public final class KeysCache {
|
||||
private final HashMap<Key, Key> mMap = new HashMap<>();
|
||||
|
||||
|
@ -27,6 +28,7 @@ public final class KeysCache {
|
|||
mMap.clear();
|
||||
}
|
||||
|
||||
// TODO: Rename more descriptive name.
|
||||
public Key get(final Key key) {
|
||||
final Key existingKey = mMap.get(key);
|
||||
if (existingKey != null) {
|
||||
|
@ -37,6 +39,7 @@ public final class KeysCache {
|
|||
return key;
|
||||
}
|
||||
|
||||
// TODO: Rename more descriptive name.
|
||||
public Key replace(final Key oldKey, final Key newKey) {
|
||||
if (oldKey.equals(newKey)) {
|
||||
return oldKey;
|
||||
|
|
|
@ -24,14 +24,13 @@ import com.android.inputmethod.keyboard.Key;
|
|||
import com.android.inputmethod.latin.common.CollectionUtils;
|
||||
import com.android.inputmethod.latin.common.Constants;
|
||||
import com.android.inputmethod.latin.common.StringUtils;
|
||||
import com.android.inputmethod.latin.define.DebugFlags;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* The more key specification object. The more keys are an array of {@link MoreKeySpec}.
|
||||
|
@ -47,12 +46,15 @@ import javax.annotation.Nonnull;
|
|||
// TODO: Should extend the key specification object.
|
||||
public final class MoreKeySpec {
|
||||
public final int mCode;
|
||||
@Nullable
|
||||
public final String mLabel;
|
||||
@Nullable
|
||||
public final String mOutputText;
|
||||
public final int mIconId;
|
||||
|
||||
public MoreKeySpec(final String moreKeySpec, boolean needsToUpperCase, final Locale locale) {
|
||||
if (TextUtils.isEmpty(moreKeySpec)) {
|
||||
public MoreKeySpec(@Nonnull final String moreKeySpec, boolean needsToUpperCase,
|
||||
@Nonnull final Locale locale) {
|
||||
if (moreKeySpec.isEmpty()) {
|
||||
throw new KeySpecParser.KeySpecParserError("Empty more key spec");
|
||||
}
|
||||
final String label = KeySpecParser.getLabel(moreKeySpec);
|
||||
|
@ -76,7 +78,7 @@ public final class MoreKeySpec {
|
|||
|
||||
@Nonnull
|
||||
public Key buildKey(final int x, final int y, final int labelFlags,
|
||||
final KeyboardParams params) {
|
||||
@Nonnull final KeyboardParams params) {
|
||||
return new Key(mLabel, mIconId, mCode, mOutputText, null /* hintLabel */, labelFlags,
|
||||
Key.BACKGROUND_TYPE_NORMAL, x, y, params.mDefaultKeyWidth, params.mDefaultRowHeight,
|
||||
params.mHorizontalGap, params.mVerticalGap);
|
||||
|
@ -87,14 +89,18 @@ public final class MoreKeySpec {
|
|||
int hashCode = 1;
|
||||
hashCode = 31 + mCode;
|
||||
hashCode = hashCode * 31 + mIconId;
|
||||
hashCode = hashCode * 31 + (mLabel == null ? 0 : mLabel.hashCode());
|
||||
hashCode = hashCode * 31 + (mOutputText == null ? 0 : mOutputText.hashCode());
|
||||
final String label = mLabel;
|
||||
hashCode = hashCode * 31 + (label == null ? 0 : label.hashCode());
|
||||
final String outputText = mOutputText;
|
||||
hashCode = hashCode * 31 + (outputText == null ? 0 : outputText.hashCode());
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o) return true;
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o instanceof MoreKeySpec) {
|
||||
final MoreKeySpec other = (MoreKeySpec)o;
|
||||
return mCode == other.mCode
|
||||
|
@ -121,7 +127,7 @@ public final class MoreKeySpec {
|
|||
private final SparseIntArray mCodes = new SparseIntArray();
|
||||
private final HashSet<String> mTexts = new HashSet<>();
|
||||
|
||||
public void addLetter(final Key key) {
|
||||
public void addLetter(@Nonnull final Key key) {
|
||||
final int code = key.getCode();
|
||||
if (CharacterCompat.isAlphabetic(code)) {
|
||||
mCodes.put(code, 0);
|
||||
|
@ -130,7 +136,7 @@ public final class MoreKeySpec {
|
|||
}
|
||||
}
|
||||
|
||||
public boolean contains(final MoreKeySpec moreKey) {
|
||||
public boolean contains(@Nonnull final MoreKeySpec moreKey) {
|
||||
final int code = moreKey.mCode;
|
||||
if (CharacterCompat.isAlphabetic(code) && mCodes.indexOfKey(code) >= 0) {
|
||||
return true;
|
||||
|
@ -141,8 +147,9 @@ public final class MoreKeySpec {
|
|||
}
|
||||
}
|
||||
|
||||
public static MoreKeySpec[] removeRedundantMoreKeys(final MoreKeySpec[] moreKeys,
|
||||
final LettersOnBaseLayout lettersOnBaseLayout) {
|
||||
@Nullable
|
||||
public static MoreKeySpec[] removeRedundantMoreKeys(@Nullable final MoreKeySpec[] moreKeys,
|
||||
@Nonnull final LettersOnBaseLayout lettersOnBaseLayout) {
|
||||
if (moreKeys == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -162,7 +169,6 @@ public final class MoreKeySpec {
|
|||
return filteredMoreKeys.toArray(new MoreKeySpec[size]);
|
||||
}
|
||||
|
||||
private static final boolean DEBUG = DebugFlags.DEBUG_ENABLED;
|
||||
// Constants for parsing.
|
||||
private static final char COMMA = Constants.CODE_COMMA;
|
||||
private static final char BACKSLASH = Constants.CODE_BACKSLASH;
|
||||
|
@ -180,7 +186,8 @@ public final class MoreKeySpec {
|
|||
* @return an array of key specification text. Null if the specified <code>text</code> is empty
|
||||
* or has no key specifications.
|
||||
*/
|
||||
public static String[] splitKeySpecs(final String text) {
|
||||
@Nullable
|
||||
public static String[] splitKeySpecs(@Nullable final String text) {
|
||||
if (TextUtils.isEmpty(text)) {
|
||||
return null;
|
||||
}
|
||||
|
@ -222,9 +229,11 @@ public final class MoreKeySpec {
|
|||
return list.toArray(new String[list.size()]);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private static final String[] EMPTY_STRING_ARRAY = new String[0];
|
||||
|
||||
private static String[] filterOutEmptyString(final String[] array) {
|
||||
@Nonnull
|
||||
private static String[] filterOutEmptyString(@Nullable final String[] array) {
|
||||
if (array == null) {
|
||||
return EMPTY_STRING_ARRAY;
|
||||
}
|
||||
|
@ -245,8 +254,8 @@ public final class MoreKeySpec {
|
|||
return out.toArray(new String[out.size()]);
|
||||
}
|
||||
|
||||
public static String[] insertAdditionalMoreKeys(final String[] moreKeySpecs,
|
||||
final String[] additionalMoreKeySpecs) {
|
||||
public static String[] insertAdditionalMoreKeys(@Nullable final String[] moreKeySpecs,
|
||||
@Nullable final String[] additionalMoreKeySpecs) {
|
||||
final String[] moreKeys = filterOutEmptyString(moreKeySpecs);
|
||||
final String[] additionalMoreKeys = filterOutEmptyString(additionalMoreKeySpecs);
|
||||
final int moreKeysCount = moreKeys.length;
|
||||
|
@ -280,11 +289,6 @@ public final class MoreKeySpec {
|
|||
if (additionalCount > 0 && additionalIndex == 0) {
|
||||
// No '%' marker is found in more keys.
|
||||
// Insert all additional more keys to the head of more keys.
|
||||
if (DEBUG && out != null) {
|
||||
throw new RuntimeException("Internal logic error:"
|
||||
+ " moreKeys=" + Arrays.toString(moreKeys)
|
||||
+ " additionalMoreKeys=" + Arrays.toString(additionalMoreKeys));
|
||||
}
|
||||
out = CollectionUtils.arrayAsList(additionalMoreKeys, additionalIndex, additionalCount);
|
||||
for (int i = 0; i < moreKeysCount; i++) {
|
||||
out.add(moreKeys[i]);
|
||||
|
@ -292,11 +296,6 @@ public final class MoreKeySpec {
|
|||
} else if (additionalIndex < additionalCount) {
|
||||
// The number of '%' markers are less than additional more keys.
|
||||
// Append remained additional more keys to the tail of more keys.
|
||||
if (DEBUG && out != null) {
|
||||
throw new RuntimeException("Internal logic error:"
|
||||
+ " moreKeys=" + Arrays.toString(moreKeys)
|
||||
+ " additionalMoreKeys=" + Arrays.toString(additionalMoreKeys));
|
||||
}
|
||||
out = CollectionUtils.arrayAsList(moreKeys, 0, moreKeysCount);
|
||||
for (int i = additionalIndex; i < additionalCount; i++) {
|
||||
out.add(additionalMoreKeys[additionalIndex]);
|
||||
|
@ -311,7 +310,7 @@ public final class MoreKeySpec {
|
|||
}
|
||||
}
|
||||
|
||||
public static int getIntValue(final String[] moreKeys, final String key,
|
||||
public static int getIntValue(@Nullable final String[] moreKeys, final String key,
|
||||
final int defaultValue) {
|
||||
if (moreKeys == null) {
|
||||
return defaultValue;
|
||||
|
@ -338,7 +337,7 @@ public final class MoreKeySpec {
|
|||
return value;
|
||||
}
|
||||
|
||||
public static boolean getBooleanValue(final String[] moreKeys, final String key) {
|
||||
public static boolean getBooleanValue(@Nullable final String[] moreKeys, final String key) {
|
||||
if (moreKeys == null) {
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue