remove old device-dependent behavior

not updated in 10 years, only few of those are still in use

device-specific default key press volume and vibration duration
and a workaround for bad touch firmware on Motorola Xoom
This commit is contained in:
Helium314 2024-05-26 20:25:13 +02:00
parent fb26eb8e7a
commit b868b583dd
8 changed files with 10 additions and 288 deletions

View file

@ -37,7 +37,6 @@ import helium314.keyboard.latin.define.DebugFlags;
import helium314.keyboard.latin.settings.Settings; import helium314.keyboard.latin.settings.Settings;
import helium314.keyboard.latin.settings.SettingsValues; import helium314.keyboard.latin.settings.SettingsValues;
import helium314.keyboard.latin.utils.Log; import helium314.keyboard.latin.utils.Log;
import helium314.keyboard.latin.utils.ResourceUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Locale; import java.util.Locale;
@ -84,10 +83,6 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
private static final int sPointerStep = (int)TypedValueCompat.dpToPx(10, Resources.getSystem().getDisplayMetrics()); private static final int sPointerStep = (int)TypedValueCompat.dpToPx(10, Resources.getSystem().getDisplayMetrics());
private static GestureStrokeRecognitionParams sGestureStrokeRecognitionParams; private static GestureStrokeRecognitionParams sGestureStrokeRecognitionParams;
private static GestureStrokeDrawingParams sGestureStrokeDrawingParams; private static GestureStrokeDrawingParams sGestureStrokeDrawingParams;
private static boolean sNeedsPhantomSuddenMoveEventHack;
// Move this threshold to resource.
// TODO: Device specific parameter would be better for device specific hack?
private static final float PHANTOM_SUDDEN_MOVE_THRESHOLD = 0.25f; // in keyWidth
private static final ArrayList<PointerTracker> sTrackers = new ArrayList<>(); private static final ArrayList<PointerTracker> sTrackers = new ArrayList<>();
private static final PointerTrackerQueue sPointerTrackerQueue = new PointerTrackerQueue(); private static final PointerTrackerQueue sPointerTrackerQueue = new PointerTrackerQueue();
@ -102,7 +97,6 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
// when new {@link Keyboard} is set by {@link #setKeyDetector(KeyDetector)}. // when new {@link Keyboard} is set by {@link #setKeyDetector(KeyDetector)}.
private KeyDetector mKeyDetector = new KeyDetector(); private KeyDetector mKeyDetector = new KeyDetector();
private Keyboard mKeyboard; private Keyboard mKeyboard;
private int mPhantomSuddenMoveThreshold;
private final BogusMoveEventDetector mBogusMoveEventDetector = new BogusMoveEventDetector(); private final BogusMoveEventDetector mBogusMoveEventDetector = new BogusMoveEventDetector();
private boolean mIsDetectingGesture = false; // per PointerTracker. private boolean mIsDetectingGesture = false; // per PointerTracker.
@ -166,9 +160,6 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
sParams.mSuppressKeyPreviewAfterBatchInputDuration); sParams.mSuppressKeyPreviewAfterBatchInputDuration);
final Resources res = mainKeyboardViewAttr.getResources(); final Resources res = mainKeyboardViewAttr.getResources();
sNeedsPhantomSuddenMoveEventHack = Boolean.parseBoolean(
ResourceUtils.getDeviceOverrideValue(res,
R.array.phantom_sudden_move_event_device_list, Boolean.FALSE.toString()));
BogusMoveEventDetector.init(res); BogusMoveEventDetector.init(res);
sTimerProxy = timerProxy; sTimerProxy = timerProxy;
@ -365,7 +356,6 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
// Keep {@link #mCurrentKey} that comes from previous keyboard. The key preview of // Keep {@link #mCurrentKey} that comes from previous keyboard. The key preview of
// {@link #mCurrentKey} will be dismissed by {@setReleasedKeyGraphics(Key)} via // {@link #mCurrentKey} will be dismissed by {@setReleasedKeyGraphics(Key)} via
// {@link onMoveEventInternal(int,int,long)} or {@link #onUpEventInternal(int,int,long)}. // {@link onMoveEventInternal(int,int,long)} or {@link #onUpEventInternal(int,int,long)}.
mPhantomSuddenMoveThreshold = (int)(keyWidth * PHANTOM_SUDDEN_MOVE_THRESHOLD);
mBogusMoveEventDetector.setKeyboardGeometry(keyWidth, keyHeight); mBogusMoveEventDetector.setKeyboardGeometry(keyWidth, keyHeight);
} }
@ -799,20 +789,6 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
setPressedKeyGraphics(key, eventTime); setPressedKeyGraphics(key, eventTime);
} }
private void processPhantomSuddenMoveHack(final Key key, final int x, final int y,
final long eventTime, final Key oldKey, final int lastX, final int lastY) {
if (DEBUG_MODE) {
Log.w(TAG, String.format(Locale.US, "[%d] onMoveEvent:"
+ " phantom sudden move event (distance=%d) is translated to "
+ "up[%d,%d,%s]/down[%d,%d,%s] events", mPointerId,
getDistance(x, y, lastX, lastY),
lastX, lastY, Constants.printableCode(oldKey.getCode()),
x, y, Constants.printableCode(key.getCode())));
}
onUpEventInternal(x, y, eventTime);
onDownEventInternal(x, y, eventTime);
}
private void processProximateBogusDownMoveUpEventHack(final Key key, final int x, final int y, private void processProximateBogusDownMoveUpEventHack(final Key key, final int x, final int y,
final long eventTime, final Key oldKey, final int lastX, final int lastY) { final long eventTime, final Key oldKey, final int lastX, final int lastY) {
if (DEBUG_MODE) { if (DEBUG_MODE) {
@ -849,14 +825,6 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
if (mIsAllowedDraggingFinger) { if (mIsAllowedDraggingFinger) {
processDraggingFingerInToNewKey(key, x, y, eventTime); processDraggingFingerInToNewKey(key, x, y, eventTime);
} }
// HACK: On some devices, quick successive touches may be reported as a sudden move by
// touch panel firmware. This hack detects such cases and translates the move event to
// successive up and down events.
// TODO: Should find a way to balance gesture detection and this hack.
else if (sNeedsPhantomSuddenMoveEventHack
&& getDistance(x, y, lastX, lastY) >= mPhantomSuddenMoveThreshold) {
processPhantomSuddenMoveHack(key, x, y, eventTime, oldKey, lastX, lastY);
}
// HACK: On some devices, quick successive proximate touches may be reported as a bogus // HACK: On some devices, quick successive proximate touches may be reported as a bogus
// down-move-up event by touch panel firmware. This hack detects such cases and breaks // down-move-up event by touch panel firmware. This hack detects such cases and breaks
// these events into separate up and down events. // these events into separate up and down events.

View file

@ -151,12 +151,12 @@ public final class PreferencesSettingsFragment extends SubScreenFragment {
@Override @Override
public int readValue(final String key) { public int readValue(final String key) {
return Settings.readKeypressVibrationDuration(prefs, res); return Settings.readKeypressVibrationDuration(prefs);
} }
@Override @Override
public int readDefaultValue(final String key) { public int readDefaultValue(final String key) {
return Settings.readDefaultKeypressVibrationDuration(res); return -1;
} }
@Override @Override
@ -206,12 +206,12 @@ public final class PreferencesSettingsFragment extends SubScreenFragment {
@Override @Override
public int readValue(final String key) { public int readValue(final String key) {
return getPercentageFromValue(Settings.readKeypressSoundVolume(prefs, res)); return getPercentageFromValue(Settings.readKeypressSoundVolume(prefs));
} }
@Override @Override
public int readDefaultValue(final String key) { public int readDefaultValue(final String key) {
return getPercentageFromValue(Settings.readDefaultKeypressSoundVolume(res)); return getPercentageFromValue(-1f);
} }
@Override @Override

View file

@ -327,20 +327,8 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
prefs.edit().putString(PREF_ADDITIONAL_SUBTYPES, prefSubtypes).apply(); prefs.edit().putString(PREF_ADDITIONAL_SUBTYPES, prefSubtypes).apply();
} }
public static float readKeypressSoundVolume(final SharedPreferences prefs, final Resources res) { public static float readKeypressSoundVolume(final SharedPreferences prefs) {
final float volume = prefs.getFloat( return prefs.getFloat(PREF_KEYPRESS_SOUND_VOLUME, UNDEFINED_PREFERENCE_VALUE_FLOAT);
PREF_KEYPRESS_SOUND_VOLUME, UNDEFINED_PREFERENCE_VALUE_FLOAT);
return (volume != UNDEFINED_PREFERENCE_VALUE_FLOAT) ? volume
: readDefaultKeypressSoundVolume(res);
}
// Default keypress sound volume for unknown devices.
// The negative value means system default.
private static final String DEFAULT_KEYPRESS_SOUND_VOLUME = Float.toString(-1.0f);
public static float readDefaultKeypressSoundVolume(final Resources res) {
return Float.parseFloat(ResourceUtils.getDeviceOverrideValue(res,
R.array.keypress_volumes, DEFAULT_KEYPRESS_SOUND_VOLUME));
} }
public static int readKeyLongpressTimeout(final SharedPreferences prefs, final Resources res) { public static int readKeyLongpressTimeout(final SharedPreferences prefs, final Resources res) {
@ -354,20 +342,8 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
return res.getInteger(R.integer.config_default_longpress_key_timeout); return res.getInteger(R.integer.config_default_longpress_key_timeout);
} }
public static int readKeypressVibrationDuration(final SharedPreferences prefs, final Resources res) { public static int readKeypressVibrationDuration(final SharedPreferences prefs) {
final int milliseconds = prefs.getInt( return prefs.getInt(PREF_VIBRATION_DURATION_SETTINGS, UNDEFINED_PREFERENCE_VALUE_INT);
PREF_VIBRATION_DURATION_SETTINGS, UNDEFINED_PREFERENCE_VALUE_INT);
return (milliseconds != UNDEFINED_PREFERENCE_VALUE_INT) ? milliseconds
: readDefaultKeypressVibrationDuration(res);
}
// Default keypress vibration duration for unknown devices.
// The negative value means system default.
private static final String DEFAULT_KEYPRESS_VIBRATION_DURATION = Integer.toString(-1);
public static int readDefaultKeypressVibrationDuration(final Resources res) {
return Integer.parseInt(ResourceUtils.getDeviceOverrideValue(res,
R.array.keypress_vibration_durations, DEFAULT_KEYPRESS_VIBRATION_DURATION));
} }
public static boolean readClipboardHistoryEnabled(final SharedPreferences prefs) { public static boolean readClipboardHistoryEnabled(final SharedPreferences prefs) {

View file

@ -185,8 +185,8 @@ public class SettingsValues {
// Compute other readable settings // Compute other readable settings
mKeyLongpressTimeout = Settings.readKeyLongpressTimeout(prefs, res); mKeyLongpressTimeout = Settings.readKeyLongpressTimeout(prefs, res);
mKeypressVibrationDuration = Settings.readKeypressVibrationDuration(prefs, res); mKeypressVibrationDuration = Settings.readKeypressVibrationDuration(prefs);
mKeypressSoundVolume = Settings.readKeypressSoundVolume(prefs, res); mKeypressSoundVolume = Settings.readKeypressSoundVolume(prefs);
mEnableEmojiAltPhysicalKey = prefs.getBoolean(Settings.PREF_ENABLE_EMOJI_ALT_PHYSICAL_KEY, true); mEnableEmojiAltPhysicalKey = prefs.getBoolean(Settings.PREF_ENABLE_EMOJI_ALT_PHYSICAL_KEY, true);
mGestureInputEnabled = Settings.readGestureInputEnabled(prefs); mGestureInputEnabled = Settings.readGestureInputEnabled(prefs);
mGestureTrailEnabled = prefs.getBoolean(Settings.PREF_GESTURE_PREVIEW_TRAIL, true); mGestureTrailEnabled = prefs.getBoolean(Settings.PREF_GESTURE_PREVIEW_TRAIL, true);

View file

@ -9,8 +9,6 @@ package helium314.keyboard.latin.utils;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.os.Build;
import android.text.TextUtils;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.TypedValue; import android.util.TypedValue;
@ -19,12 +17,7 @@ import androidx.core.util.TypedValueCompat;
import helium314.keyboard.latin.R; import helium314.keyboard.latin.R;
import helium314.keyboard.latin.settings.SettingsValues; import helium314.keyboard.latin.settings.SettingsValues;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.regex.PatternSyntaxException;
public final class ResourceUtils { public final class ResourceUtils {
private static final String TAG = ResourceUtils.class.getSimpleName();
public static final float UNDEFINED_RATIO = -1.0f; public static final float UNDEFINED_RATIO = -1.0f;
public static final int UNDEFINED_DIMENSION = -1; public static final int UNDEFINED_DIMENSION = -1;
@ -33,143 +26,6 @@ public final class ResourceUtils {
// This utility class is not publicly instantiable. // This utility class is not publicly instantiable.
} }
private static final HashMap<String, String> sDeviceOverrideValueMap = new HashMap<>();
private static final String[] BUILD_KEYS_AND_VALUES = {
"HARDWARE", Build.HARDWARE,
"MODEL", Build.MODEL,
"BRAND", Build.BRAND,
"MANUFACTURER", Build.MANUFACTURER
};
private static final HashMap<String, String> sBuildKeyValues;
private static final String sBuildKeyValuesDebugString;
static {
sBuildKeyValues = new HashMap<>();
final ArrayList<String> keyValuePairs = new ArrayList<>();
final int keyCount = BUILD_KEYS_AND_VALUES.length / 2;
for (int i = 0; i < keyCount; i++) {
final int index = i * 2;
final String key = BUILD_KEYS_AND_VALUES[index];
final String value = BUILD_KEYS_AND_VALUES[index + 1];
sBuildKeyValues.put(key, value);
keyValuePairs.add(key + '=' + value);
}
sBuildKeyValuesDebugString = "[" + TextUtils.join(" ", keyValuePairs) + "]";
}
public static String getDeviceOverrideValue(final Resources res, final int overrideResId,
final String defaultValue) {
final int orientation = res.getConfiguration().orientation;
final String key = overrideResId + "-" + orientation;
if (sDeviceOverrideValueMap.containsKey(key)) {
return sDeviceOverrideValueMap.get(key);
}
final String[] overrideArray = res.getStringArray(overrideResId);
final String overrideValue = findConstantForKeyValuePairs(sBuildKeyValues, overrideArray);
// The overrideValue might be an empty string.
if (overrideValue != null) {
Log.i(TAG, "Find override value:"
+ " resource="+ res.getResourceEntryName(overrideResId)
+ " build=" + sBuildKeyValuesDebugString
+ " override=" + overrideValue);
sDeviceOverrideValueMap.put(key, overrideValue);
return overrideValue;
}
sDeviceOverrideValueMap.put(key, defaultValue);
return defaultValue;
}
static class DeviceOverridePatternSyntaxError extends Exception {
public DeviceOverridePatternSyntaxError(final String message, final String expression) {
this(message, expression, null);
}
public DeviceOverridePatternSyntaxError(final String message, final String expression,
final Throwable throwable) {
super(message + ": " + expression, throwable);
}
}
/**
* Find the condition that fulfills specified key value pairs from an array of
* "condition,constant", and return the corresponding string constant. A condition is
* "pattern1[:pattern2...] (or an empty string for the default). A pattern is
* "key=regexp_value" string. The condition matches only if all patterns of the condition
* are true for the specified key value pairs.
* <p>
* For example, "condition,constant" has the following format.
* - HARDWARE=mako,constantForNexus4
* - MODEL=Nexus 4:MANUFACTURER=LGE,constantForNexus4
* - ,defaultConstant
*
* @param keyValuePairs attributes to be used to look for a matched condition.
* @param conditionConstantArray an array of "condition,constant" elements to be searched.
* @return the constant part of the matched "condition,constant" element. Returns null if no
* condition matches.
*/
static String findConstantForKeyValuePairs(final HashMap<String, String> keyValuePairs,
final String[] conditionConstantArray) {
if (conditionConstantArray == null || keyValuePairs == null) {
return null;
}
String foundValue = null;
for (final String conditionConstant : conditionConstantArray) {
final int posComma = conditionConstant.indexOf(',');
if (posComma < 0) {
Log.w(TAG, "Array element has no comma: " + conditionConstant);
continue;
}
final String condition = conditionConstant.substring(0, posComma);
if (condition.isEmpty()) {
Log.w(TAG, "Array element has no condition: " + conditionConstant);
continue;
}
try {
if (fulfillsCondition(keyValuePairs, condition)) {
// Take first match
if (foundValue == null) {
foundValue = conditionConstant.substring(posComma + 1);
}
// And continue walking through all conditions.
}
} catch (final DeviceOverridePatternSyntaxError e) {
Log.w(TAG, "Syntax error, ignored", e);
}
}
return foundValue;
}
private static boolean fulfillsCondition(final HashMap<String,String> keyValuePairs,
final String condition) throws DeviceOverridePatternSyntaxError {
final String[] patterns = condition.split(":");
// Check all patterns in a condition are true
boolean matchedAll = true;
for (final String pattern : patterns) {
final int posEqual = pattern.indexOf('=');
if (posEqual < 0) {
throw new DeviceOverridePatternSyntaxError("Pattern has no '='", condition);
}
final String key = pattern.substring(0, posEqual);
final String value = keyValuePairs.get(key);
if (value == null) {
throw new DeviceOverridePatternSyntaxError("Unknown key", condition);
}
final String patternRegexpValue = pattern.substring(posEqual + 1);
try {
if (!value.matches(patternRegexpValue)) {
matchedAll = false;
// And continue walking through all patterns.
}
} catch (final PatternSyntaxException e) {
throw new DeviceOverridePatternSyntaxError("Syntax error", condition, e);
}
}
return matchedAll;
}
public static int getKeyboardWidth(final Resources res, final SettingsValues settingsValues) { public static int getKeyboardWidth(final Resources res, final SettingsValues settingsValues) {
final int defaultKeyboardWidth = getDefaultKeyboardWidth(res); final int defaultKeyboardWidth = getDefaultKeyboardWidth(res);
if (settingsValues.mOneHandedModeEnabled) { if (settingsValues.mOneHandedModeEnabled) {

View file

@ -1,49 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2011 The Android Open Source Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<!-- Build condition,duration_in_milliseconds -->
<string-array name="keypress_vibration_durations" translatable="false">
<!-- Nexus S -->
<item>MODEL=Nexus S:BRAND=google,5</item>
<!-- Galaxy Nexus -->
<item>MODEL=Galaxy Nexus:BRAND=google,5</item>
<!-- Nexus 4 -->
<item>MODEL=Nexus 4:BRAND=google,8</item>
<!-- Nexus 10 -->
<item>MODEL=Nexus 10:BRAND=google,16</item>
<!-- Samsung Galaxy SII -->
<item>MODEL=GT-I(9100[GMPT]?|9108|9210T?):MANUFACTURER=samsung,8</item>
<item>MODEL=SGH-(I9[27]7R?|I927|T989D?):MANUFACTURER=samsung,8</item>
<item>MODEL=SHW-M250[KLS]?|SPH-D710|SCH-R760:MANUFACTURER=samsung,8</item>
<item>MODEL=ISW11SC|SC-02C:MANUFACTURER=samsung,8</item>
<!-- Samsung Galaxy SIII -->
<item>MODEL=(SAMSUNG-)?GT-I(930[05][NT]?|9308):MANUFACTURER=samsung,8</item>
<item>MODEL=(SAMSUNG-)?SGH-(T999[V]?|I747[M]?|N064|N035):MANUFACTURER=samsung,8</item>
<item>MODEL=(SAMSUNG-)?SCH-(J021|R530|I535|I939):MANUFACTURER=samsung,8</item>
<item>MODEL=(SAMSUNG-)?(SCL21|SC-06D|SC-03E):MANUFACTURER=samsung,8</item>
<item>MODEL=(SAMSUNG-)?(SHV-210[KLS]?|SPH-L710):MANUFACTURER=samsung,8</item>
<!-- Samsung Galaxy S4 -->
<item>MODEL=(SAMSUNG-)?GT-I(950[0258][G]?):MANUFACTURER=samsung,7</item>
<item>MODEL=(SAMSUNG-)?SGH-(I337|M919|N045):MANUFACTURER=samsung,7</item>
<item>MODEL=(SAMSUNG-)?SCH-(I545|I959|R970):MANUFACTURER=samsung,7</item>
<item>MODEL=(SAMSUNG-)?SPH-(L720):MANUFACTURER=samsung,7</item>
<item>MODEL=(SAMSUNG-)?(SC-04E):MANUFACTURER=samsung,7</item>
<item>MODEL=(SAMSUNG-)?(SHV-E300[KLS]?):MANUFACTURER=samsung,7</item>
<!-- LG Optimus G -->
<item>MODEL=LG-E97[013]|LS970|L-01E:MANUFACTURER=LGE,15</item>
<!-- HTC One X -->
<item>MODEL=HTC One X:MANUFACTURER=HTC,20</item>
<!-- HTC One -->
<item>MODEL=HTC One:MANUFACTURER=HTC,15</item>
<item>MODEL=HTL22:MANUFACTURER=HTC,15</item>
<!-- Motorola Razor M -->
<item>MODEL=XT907:MANUFACTURER=motorola,30</item>
<!-- Motorola DVX -->
<item>MODEL=XT1035:MANUFACTURER=motorola,18</item>
<!-- Sony Xperia Z, Z Ultra -->
<item>MODEL=C6603|C6806:MANUFACTURER=Sony,35</item>
</string-array>
</resources>

View file

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2011 The Android Open Source Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<!-- Build condition,volume -->
<string-array name="keypress_volumes" translatable="false">
<item>HARDWARE=herring,0.5f</item>
<item>HARDWARE=tuna,0.5f</item>
<item>HARDWARE=stingray,0.4f</item>
<item>HARDWARE=grouper,0.3f</item>
<item>HARDWARE=mako,0.3f</item>
<item>HARDWARE=manta,0.2f</item>
</string-array>
</resources>

View file

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2012 The Android Open Source Project
SPDX-License-Identifier: Apache-2.0
-->
<resources>
<string-array name="phantom_sudden_move_event_device_list" translatable="false">
<!-- "Build condition,true" that needs "phantom sudden move event" hack.
See {@link helium314.keyboard.keyboard.PointerTracker}. -->
<!-- Xoom -->
<item>HARDWARE=stingray,true</item>
</string-array>
</resources>