Merge "Pass the touch position correction flag from KeyboardSwitcher."
This commit is contained in:
commit
a25dd3b5c3
6 changed files with 104 additions and 84 deletions
|
@ -138,8 +138,7 @@ public class Keyboard {
|
||||||
|
|
||||||
mProximityInfo = new ProximityInfo(
|
mProximityInfo = new ProximityInfo(
|
||||||
params.GRID_WIDTH, params.GRID_HEIGHT, mOccupiedWidth, mOccupiedHeight,
|
params.GRID_WIDTH, params.GRID_HEIGHT, mOccupiedWidth, mOccupiedHeight,
|
||||||
mMostCommonKeyWidth, mMostCommonKeyHeight, mKeys, params.mTouchPositionCorrectionXs,
|
mMostCommonKeyWidth, mMostCommonKeyHeight, mKeys, params.mTouchPositionCorrection);
|
||||||
params.mTouchPositionCorrectionYs, params.mTouchPositionCorrectionRadii);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProximityInfo getProximityInfo() {
|
public ProximityInfo getProximityInfo() {
|
||||||
|
|
|
@ -264,7 +264,12 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
|
||||||
if (keyboard == null) {
|
if (keyboard == null) {
|
||||||
final Locale savedLocale = LocaleUtils.setSystemLocale(mResources, id.mLocale);
|
final Locale savedLocale = LocaleUtils.setSystemLocale(mResources, id.mLocale);
|
||||||
try {
|
try {
|
||||||
keyboard = new LatinKeyboard.Builder(mThemeContext).load(id).build();
|
final LatinKeyboard.Builder builder = new LatinKeyboard.Builder(mThemeContext);
|
||||||
|
builder.load(id);
|
||||||
|
builder.setTouchPositionCorrectionEnabled(
|
||||||
|
mSubtypeSwitcher.currentSubtypeContainsExtraValueKey(
|
||||||
|
LatinIME.SUBTYPE_EXTRA_VALUE_SUPPORT_TOUCH_POSITION_CORRECTION));
|
||||||
|
keyboard = builder.build();
|
||||||
} finally {
|
} finally {
|
||||||
LocaleUtils.setSystemLocale(mResources, savedLocale);
|
LocaleUtils.setSystemLocale(mResources, savedLocale);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ package com.android.inputmethod.keyboard;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
|
|
||||||
import com.android.inputmethod.keyboard.Key;
|
import com.android.inputmethod.keyboard.Key;
|
||||||
|
import com.android.inputmethod.keyboard.internal.KeyboardParams.TouchPositionCorrection;
|
||||||
import com.android.inputmethod.latin.SubtypeSwitcher;
|
import com.android.inputmethod.latin.SubtypeSwitcher;
|
||||||
import com.android.inputmethod.latin.Utils;
|
import com.android.inputmethod.latin.Utils;
|
||||||
import com.android.inputmethod.latin.spellcheck.SpellCheckerProximityInfo;
|
import com.android.inputmethod.latin.spellcheck.SpellCheckerProximityInfo;
|
||||||
|
@ -32,8 +33,6 @@ public class ProximityInfo {
|
||||||
/** Number of key widths from current touch point to search for nearest keys. */
|
/** Number of key widths from current touch point to search for nearest keys. */
|
||||||
private static float SEARCH_DISTANCE = 1.2f;
|
private static float SEARCH_DISTANCE = 1.2f;
|
||||||
private static final int[] EMPTY_INT_ARRAY = new int[0];
|
private static final int[] EMPTY_INT_ARRAY = new int[0];
|
||||||
private static final String SUPPORT_TOUCH_POSITION_CORRECTION =
|
|
||||||
"SupportTouchPositionCorrection";
|
|
||||||
|
|
||||||
private final int mKeyHeight;
|
private final int mKeyHeight;
|
||||||
private final int mGridWidth;
|
private final int mGridWidth;
|
||||||
|
@ -46,13 +45,8 @@ public class ProximityInfo {
|
||||||
private final int mKeyboardHeight;
|
private final int mKeyboardHeight;
|
||||||
private final int[][] mGridNeighbors;
|
private final int[][] mGridNeighbors;
|
||||||
|
|
||||||
private final float[] mTouchPositionCorrectionXs;
|
|
||||||
private final float[] mTouchPositionCorrectionYs;
|
|
||||||
private final float[] mTouchPositionCorrectionRadii;
|
|
||||||
|
|
||||||
ProximityInfo(int gridWidth, int gridHeight, int minWidth, int height, int keyWidth,
|
ProximityInfo(int gridWidth, int gridHeight, int minWidth, int height, int keyWidth,
|
||||||
int keyHeight, List<Key> keys, float[] touchPositionCorrectionXs,
|
int keyHeight, List<Key> keys, TouchPositionCorrection touchPositionCorrection) {
|
||||||
float[] touchPositionCorrectionYs, float[] touchPositionCorrectionRadii) {
|
|
||||||
mGridWidth = gridWidth;
|
mGridWidth = gridWidth;
|
||||||
mGridHeight = gridHeight;
|
mGridHeight = gridHeight;
|
||||||
mGridSize = mGridWidth * mGridHeight;
|
mGridSize = mGridWidth * mGridHeight;
|
||||||
|
@ -61,19 +55,16 @@ public class ProximityInfo {
|
||||||
mKeyboardMinWidth = minWidth;
|
mKeyboardMinWidth = minWidth;
|
||||||
mKeyboardHeight = height;
|
mKeyboardHeight = height;
|
||||||
mKeyHeight = keyHeight;
|
mKeyHeight = keyHeight;
|
||||||
mTouchPositionCorrectionXs = touchPositionCorrectionXs;
|
|
||||||
mTouchPositionCorrectionYs = touchPositionCorrectionYs;
|
|
||||||
mTouchPositionCorrectionRadii = touchPositionCorrectionRadii;
|
|
||||||
mGridNeighbors = new int[mGridSize][];
|
mGridNeighbors = new int[mGridSize][];
|
||||||
if (minWidth == 0 || height == 0) {
|
if (minWidth == 0 || height == 0) {
|
||||||
// No proximity required. Keyboard might be mini keyboard.
|
// No proximity required. Keyboard might be mini keyboard.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
computeNearestNeighbors(keyWidth, keys);
|
computeNearestNeighbors(keyWidth, keys, touchPositionCorrection);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ProximityInfo createDummyProximityInfo() {
|
public static ProximityInfo createDummyProximityInfo() {
|
||||||
return new ProximityInfo(1, 1, 1, 1, 1, 1, Collections.<Key>emptyList(), null, null, null);
|
return new ProximityInfo(1, 1, 1, 1, 1, 1, Collections.<Key>emptyList(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ProximityInfo createSpellCheckerProximityInfo() {
|
public static ProximityInfo createSpellCheckerProximityInfo() {
|
||||||
|
@ -98,7 +89,8 @@ public class ProximityInfo {
|
||||||
private native void releaseProximityInfoNative(int nativeProximityInfo);
|
private native void releaseProximityInfoNative(int nativeProximityInfo);
|
||||||
|
|
||||||
private final void setProximityInfo(int[][] gridNeighborKeyIndexes, int keyboardWidth,
|
private final void setProximityInfo(int[][] gridNeighborKeyIndexes, int keyboardWidth,
|
||||||
int keyboardHeight, List<Key> keys) {
|
int keyboardHeight, List<Key> keys,
|
||||||
|
TouchPositionCorrection touchPositionCorrection) {
|
||||||
int[] proximityCharsArray = new int[mGridSize * MAX_PROXIMITY_CHARS_SIZE];
|
int[] proximityCharsArray = new int[mGridSize * MAX_PROXIMITY_CHARS_SIZE];
|
||||||
Arrays.fill(proximityCharsArray, KeyDetector.NOT_A_CODE);
|
Arrays.fill(proximityCharsArray, KeyDetector.NOT_A_CODE);
|
||||||
for (int i = 0; i < mGridSize; ++i) {
|
for (int i = 0; i < mGridSize; ++i) {
|
||||||
|
@ -123,23 +115,16 @@ public class ProximityInfo {
|
||||||
keyCharCodes[i] = key.mCode;
|
keyCharCodes[i] = key.mCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
final SubtypeSwitcher switcher = SubtypeSwitcher.getInstance();
|
float[] sweetSpotCenterXs = null;
|
||||||
final boolean hasTouchPositionCorrectionData =
|
float[] sweetSpotCenterYs = null;
|
||||||
switcher.currentSubtypeContainsExtraValueKey(SUPPORT_TOUCH_POSITION_CORRECTION)
|
float[] sweetSpotRadii = null;
|
||||||
&& mTouchPositionCorrectionXs != null
|
|
||||||
&& mTouchPositionCorrectionYs != null
|
if (touchPositionCorrection != null && touchPositionCorrection.isValid()) {
|
||||||
&& mTouchPositionCorrectionRadii != null
|
sweetSpotCenterXs = new float[keyCount];
|
||||||
&& mTouchPositionCorrectionXs.length > 0
|
sweetSpotCenterYs = new float[keyCount];
|
||||||
&& mTouchPositionCorrectionYs.length > 0
|
sweetSpotRadii = new float[keyCount];
|
||||||
&& mTouchPositionCorrectionRadii.length > 0;
|
calculateSweetSpot(keys, touchPositionCorrection,
|
||||||
final float[] sweetSpotCenterXs =
|
sweetSpotCenterXs, sweetSpotCenterYs, sweetSpotRadii);
|
||||||
hasTouchPositionCorrectionData ? new float[keyCount] : null;
|
|
||||||
final float[] sweetSpotCenterYs =
|
|
||||||
hasTouchPositionCorrectionData ? new float[keyCount] : null;
|
|
||||||
final float[] sweetSpotRadii =
|
|
||||||
hasTouchPositionCorrectionData ? new float[keyCount] : null;
|
|
||||||
if (hasTouchPositionCorrectionData) {
|
|
||||||
calculateSweetSpot(keys, sweetSpotCenterXs, sweetSpotCenterYs, sweetSpotRadii);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mNativeProximityInfo = setProximityInfoNative(MAX_PROXIMITY_CHARS_SIZE,
|
mNativeProximityInfo = setProximityInfoNative(MAX_PROXIMITY_CHARS_SIZE,
|
||||||
|
@ -148,21 +133,24 @@ public class ProximityInfo {
|
||||||
sweetSpotCenterXs, sweetSpotCenterYs, sweetSpotRadii);
|
sweetSpotCenterXs, sweetSpotCenterYs, sweetSpotRadii);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void calculateSweetSpot(List<Key> keys, float[] sweetSpotCenterXs,
|
private void calculateSweetSpot(List<Key> keys, TouchPositionCorrection touchPositionCorrection,
|
||||||
float[] sweetSpotCenterYs, float[] sweetSpotRadii) {
|
float[] sweetSpotCenterXs, float[] sweetSpotCenterYs, float[] sweetSpotRadii) {
|
||||||
final int keyCount = keys.size();
|
final int keyCount = keys.size();
|
||||||
|
final float[] xs = touchPositionCorrection.mXs;
|
||||||
|
final float[] ys = touchPositionCorrection.mYs;
|
||||||
|
final float[] radii = touchPositionCorrection.mRadii;
|
||||||
for (int i = 0; i < keyCount; ++i) {
|
for (int i = 0; i < keyCount; ++i) {
|
||||||
final Key key = keys.get(i);
|
final Key key = keys.get(i);
|
||||||
final Rect hitBox = key.mHitBox;
|
final Rect hitBox = key.mHitBox;
|
||||||
final int row = hitBox.top / mKeyHeight;
|
final int row = hitBox.top / mKeyHeight;
|
||||||
if (row < mTouchPositionCorrectionRadii.length) {
|
if (row < radii.length) {
|
||||||
final float hitBoxCenterX = (hitBox.left + hitBox.right) * 0.5f;
|
final float hitBoxCenterX = (hitBox.left + hitBox.right) * 0.5f;
|
||||||
final float hitBoxCenterY = (hitBox.top + hitBox.bottom) * 0.5f;
|
final float hitBoxCenterY = (hitBox.top + hitBox.bottom) * 0.5f;
|
||||||
final float hitBoxWidth = hitBox.right - hitBox.left;
|
final float hitBoxWidth = hitBox.right - hitBox.left;
|
||||||
final float hitBoxHeight = hitBox.bottom - hitBox.top;
|
final float hitBoxHeight = hitBox.bottom - hitBox.top;
|
||||||
final float x = mTouchPositionCorrectionXs[row];
|
final float x = xs[row];
|
||||||
final float y = mTouchPositionCorrectionYs[row];
|
final float y = ys[row];
|
||||||
final float radius = mTouchPositionCorrectionRadii[row];
|
final float radius = radii[row];
|
||||||
sweetSpotCenterXs[i] = hitBoxCenterX + x * hitBoxWidth;
|
sweetSpotCenterXs[i] = hitBoxCenterX + x * hitBoxWidth;
|
||||||
sweetSpotCenterYs[i] = hitBoxCenterY + y * hitBoxHeight;
|
sweetSpotCenterYs[i] = hitBoxCenterY + y * hitBoxHeight;
|
||||||
sweetSpotRadii[i] = radius
|
sweetSpotRadii[i] = radius
|
||||||
|
@ -187,7 +175,8 @@ public class ProximityInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void computeNearestNeighbors(int defaultWidth, List<Key> keys) {
|
private void computeNearestNeighbors(int defaultWidth, List<Key> keys,
|
||||||
|
TouchPositionCorrection touchPositionCorrection) {
|
||||||
final int thresholdBase = (int) (defaultWidth * SEARCH_DISTANCE);
|
final int thresholdBase = (int) (defaultWidth * SEARCH_DISTANCE);
|
||||||
final int threshold = thresholdBase * thresholdBase;
|
final int threshold = thresholdBase * thresholdBase;
|
||||||
// Round-up so we don't have any pixels outside the grid
|
// Round-up so we don't have any pixels outside the grid
|
||||||
|
@ -210,7 +199,8 @@ public class ProximityInfo {
|
||||||
mGridNeighbors[(y / mCellHeight) * mGridWidth + (x / mCellWidth)] = cell;
|
mGridNeighbors[(y / mCellHeight) * mGridWidth + (x / mCellWidth)] = cell;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setProximityInfo(mGridNeighbors, mKeyboardMinWidth, mKeyboardHeight, keys);
|
setProximityInfo(mGridNeighbors, mKeyboardMinWidth, mKeyboardHeight, keys,
|
||||||
|
touchPositionCorrection);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getNearestKeys(int x, int y) {
|
public int[] getNearestKeys(int x, int y) {
|
||||||
|
|
|
@ -127,8 +127,6 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
|
||||||
private static final int DEFAULT_KEYBOARD_COLUMNS = 10;
|
private static final int DEFAULT_KEYBOARD_COLUMNS = 10;
|
||||||
private static final int DEFAULT_KEYBOARD_ROWS = 4;
|
private static final int DEFAULT_KEYBOARD_ROWS = 4;
|
||||||
|
|
||||||
private static final int TOUCH_POSITION_CORRECTION_RECORD_SIZE = 3;
|
|
||||||
|
|
||||||
protected final KP mParams;
|
protected final KP mParams;
|
||||||
protected final Context mContext;
|
protected final Context mContext;
|
||||||
protected final Resources mResources;
|
protected final Resources mResources;
|
||||||
|
@ -254,10 +252,6 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setTouchPositionCorrectionData(Context context, KeyboardParams params) {
|
private static void setTouchPositionCorrectionData(Context context, KeyboardParams params) {
|
||||||
params.mTouchPositionCorrectionXs = null;
|
|
||||||
params.mTouchPositionCorrectionYs = null;
|
|
||||||
params.mTouchPositionCorrectionRadii = null;
|
|
||||||
|
|
||||||
final TypedArray a = context.obtainStyledAttributes(
|
final TypedArray a = context.obtainStyledAttributes(
|
||||||
null, R.styleable.Keyboard, R.attr.keyboardStyle, 0);
|
null, R.styleable.Keyboard, R.attr.keyboardStyle, 0);
|
||||||
params.mThemeId = a.getInt(R.styleable.Keyboard_themeId, 0);
|
params.mThemeId = a.getInt(R.styleable.Keyboard_themeId, 0);
|
||||||
|
@ -270,39 +264,7 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
|
||||||
}
|
}
|
||||||
|
|
||||||
final String[] data = context.getResources().getStringArray(resourceId);
|
final String[] data = context.getResources().getStringArray(resourceId);
|
||||||
final int dataLength = data.length;
|
params.mTouchPositionCorrection.load(data);
|
||||||
if (dataLength % TOUCH_POSITION_CORRECTION_RECORD_SIZE != 0) {
|
|
||||||
if (LatinImeLogger.sDBG)
|
|
||||||
throw new RuntimeException("the size of touch position correction data is invalid");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final int length = dataLength / TOUCH_POSITION_CORRECTION_RECORD_SIZE;
|
|
||||||
params.mTouchPositionCorrectionXs = new float[length];
|
|
||||||
params.mTouchPositionCorrectionYs = new float[length];
|
|
||||||
params.mTouchPositionCorrectionRadii = new float[length];
|
|
||||||
try {
|
|
||||||
for (int i = 0; i < dataLength; ++i) {
|
|
||||||
final int type = i % TOUCH_POSITION_CORRECTION_RECORD_SIZE;
|
|
||||||
final int index = i / TOUCH_POSITION_CORRECTION_RECORD_SIZE;
|
|
||||||
final float value = Float.parseFloat(data[i]);
|
|
||||||
if (type == 0) {
|
|
||||||
params.mTouchPositionCorrectionXs[index] = value;
|
|
||||||
} else if (type == 1) {
|
|
||||||
params.mTouchPositionCorrectionYs[index] = value;
|
|
||||||
} else {
|
|
||||||
params.mTouchPositionCorrectionRadii[index] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
if (LatinImeLogger.sDBG) {
|
|
||||||
throw new RuntimeException(
|
|
||||||
"the number format for touch position correction data is invalid");
|
|
||||||
}
|
|
||||||
params.mTouchPositionCorrectionXs = null;
|
|
||||||
params.mTouchPositionCorrectionYs = null;
|
|
||||||
params.mTouchPositionCorrectionRadii = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public KeyboardBuilder<KP> load(KeyboardId id) {
|
public KeyboardBuilder<KP> load(KeyboardId id) {
|
||||||
|
@ -319,6 +281,10 @@ public class KeyboardBuilder<KP extends KeyboardParams> {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setTouchPositionCorrectionEnabled(boolean enabled) {
|
||||||
|
mParams.mTouchPositionCorrection.setEnabled(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
public Keyboard build() {
|
public Keyboard build() {
|
||||||
return new Keyboard(mParams);
|
return new Keyboard(mParams);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import android.graphics.drawable.Drawable;
|
||||||
import com.android.inputmethod.keyboard.Key;
|
import com.android.inputmethod.keyboard.Key;
|
||||||
import com.android.inputmethod.keyboard.Keyboard;
|
import com.android.inputmethod.keyboard.Keyboard;
|
||||||
import com.android.inputmethod.keyboard.KeyboardId;
|
import com.android.inputmethod.keyboard.KeyboardId;
|
||||||
|
import com.android.inputmethod.latin.LatinImeLogger;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -68,9 +69,62 @@ public class KeyboardParams {
|
||||||
public int mMostCommonKeyHeight = 0;
|
public int mMostCommonKeyHeight = 0;
|
||||||
public int mMostCommonKeyWidth = 0;
|
public int mMostCommonKeyWidth = 0;
|
||||||
|
|
||||||
public float[] mTouchPositionCorrectionXs;
|
public final TouchPositionCorrection mTouchPositionCorrection = new TouchPositionCorrection();
|
||||||
public float[] mTouchPositionCorrectionYs;
|
|
||||||
public float[] mTouchPositionCorrectionRadii;
|
public static class TouchPositionCorrection {
|
||||||
|
private static final int TOUCH_POSITION_CORRECTION_RECORD_SIZE = 3;
|
||||||
|
|
||||||
|
public boolean mEnabled;
|
||||||
|
public float[] mXs;
|
||||||
|
public float[] mYs;
|
||||||
|
public float[] mRadii;
|
||||||
|
|
||||||
|
public void load(String[] data) {
|
||||||
|
final int dataLength = data.length;
|
||||||
|
if (dataLength % TOUCH_POSITION_CORRECTION_RECORD_SIZE != 0) {
|
||||||
|
if (LatinImeLogger.sDBG)
|
||||||
|
throw new RuntimeException(
|
||||||
|
"the size of touch position correction data is invalid");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final int length = dataLength / TOUCH_POSITION_CORRECTION_RECORD_SIZE;
|
||||||
|
mXs = new float[length];
|
||||||
|
mYs = new float[length];
|
||||||
|
mRadii = new float[length];
|
||||||
|
try {
|
||||||
|
for (int i = 0; i < dataLength; ++i) {
|
||||||
|
final int type = i % TOUCH_POSITION_CORRECTION_RECORD_SIZE;
|
||||||
|
final int index = i / TOUCH_POSITION_CORRECTION_RECORD_SIZE;
|
||||||
|
final float value = Float.parseFloat(data[i]);
|
||||||
|
if (type == 0) {
|
||||||
|
mXs[index] = value;
|
||||||
|
} else if (type == 1) {
|
||||||
|
mYs[index] = value;
|
||||||
|
} else {
|
||||||
|
mRadii[index] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
if (LatinImeLogger.sDBG) {
|
||||||
|
throw new RuntimeException(
|
||||||
|
"the number format for touch position correction data is invalid");
|
||||||
|
}
|
||||||
|
mXs = null;
|
||||||
|
mYs = null;
|
||||||
|
mRadii = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEnabled(boolean enabled) {
|
||||||
|
mEnabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isValid() {
|
||||||
|
return mEnabled && mXs != null && mYs != null && mRadii != null
|
||||||
|
&& mXs.length > 0 && mYs.length > 0 && mRadii.length > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void clearKeys() {
|
protected void clearKeys() {
|
||||||
mKeys.clear();
|
mKeys.clear();
|
||||||
|
|
|
@ -117,6 +117,12 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
|
||||||
*/
|
*/
|
||||||
public static final String SUBTYPE_EXTRA_VALUE_ASCII_CAPABLE = "AsciiCapable";
|
public static final String SUBTYPE_EXTRA_VALUE_ASCII_CAPABLE = "AsciiCapable";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The subtype extra value used to indicate that the subtype keyboard layout supports touch
|
||||||
|
* position correction.
|
||||||
|
*/
|
||||||
|
public static final String SUBTYPE_EXTRA_VALUE_SUPPORT_TOUCH_POSITION_CORRECTION =
|
||||||
|
"SupportTouchPositionCorrection";
|
||||||
/**
|
/**
|
||||||
* The subtype extra value used to indicate that the subtype keyboard layout should be loaded
|
* The subtype extra value used to indicate that the subtype keyboard layout should be loaded
|
||||||
* from the specified locale.
|
* from the specified locale.
|
||||||
|
|
Loading…
Reference in a new issue