diff --git a/app/src/main/java/com/termux/app/terminal/io/extrakeys/ExtraKeysInfo.java b/app/src/main/java/com/termux/app/terminal/io/extrakeys/ExtraKeysInfo.java index 26fec3d6a3..98cc6afc4e 100644 --- a/app/src/main/java/com/termux/app/terminal/io/extrakeys/ExtraKeysInfo.java +++ b/app/src/main/java/com/termux/app/terminal/io/extrakeys/ExtraKeysInfo.java @@ -1,5 +1,9 @@ package com.termux.app.terminal.io.extrakeys; +import com.termux.shared.logger.Logger; +import com.termux.shared.settings.properties.TermuxPropertyConstants; +import com.termux.shared.settings.properties.TermuxSharedProperties; + import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -238,6 +242,8 @@ CharDisplayMap getSelectedCharMap() { case "none": return new CharDisplayMap(); default: + if (!TermuxPropertyConstants.DEFAULT_IVALUE_EXTRA_KEYS_STYLE.equals(style)) + Logger.logError(TermuxSharedProperties.LOG_TAG, "The style \"" + style + "\" for the key \"" + TermuxPropertyConstants.KEY_EXTRA_KEYS_STYLE + "\" is invalid. Using default style instead."); return defaultCharDisplay; } } diff --git a/app/src/main/java/com/termux/app/utils/PluginUtils.java b/app/src/main/java/com/termux/app/utils/PluginUtils.java index d1b7dba9c4..b1d5c5db74 100644 --- a/app/src/main/java/com/termux/app/utils/PluginUtils.java +++ b/app/src/main/java/com/termux/app/utils/PluginUtils.java @@ -322,7 +322,7 @@ public static void setupPluginCommandErrorsNotificationChannel(final Context con */ public static String checkIfRunCommandServiceAllowExternalAppsPolicyIsViolated(final Context context) { String errmsg = null; - if (!SharedProperties.isPropertyValueTrue(context, TermuxPropertyConstants.getTermuxPropertiesFile(), TermuxConstants.PROP_ALLOW_EXTERNAL_APPS)) { + if (!SharedProperties.isPropertyValueTrue(context, TermuxPropertyConstants.getTermuxPropertiesFile(), TermuxConstants.PROP_ALLOW_EXTERNAL_APPS, true)) { errmsg = context.getString(R.string.error_run_command_service_allow_external_apps_ungranted); } diff --git a/termux-shared/src/main/java/com/termux/shared/settings/properties/SharedProperties.java b/termux-shared/src/main/java/com/termux/shared/settings/properties/SharedProperties.java index 9c808e93b2..30ec08a5be 100644 --- a/termux-shared/src/main/java/com/termux/shared/settings/properties/SharedProperties.java +++ b/termux-shared/src/main/java/com/termux/shared/settings/properties/SharedProperties.java @@ -3,6 +3,7 @@ import android.content.Context; import android.widget.Toast; +import com.google.common.collect.BiMap; import com.google.common.collect.ImmutableBiMap; import com.google.common.primitives.Primitives; import com.termux.shared.logger.Logger; @@ -289,12 +290,14 @@ public static Object getInternalProperty(Context context, File propertiesFile, S * @param context The {@link Context} for the {@link #getPropertiesFromFile(Context,File)}call. * @param propertiesFile The {@link File} to read the {@link Properties} from. * @param key The key to read. + * @param logErrorOnInvalidValue If {@code true}, then an error will be logged if key value + * was found in {@link Properties} but was invalid. * @return Returns the {@code true} if the {@link Properties} key {@link String} value equals "true", * regardless of case. If the key does not exist in the file or does not equal "true", then * {@code false} will be returned. */ - public static boolean isPropertyValueTrue(Context context, File propertiesFile, String key) { - return (boolean) getBooleanValueForStringValue((String) getProperty(context, propertiesFile, key, null), false); + public static boolean isPropertyValueTrue(Context context, File propertiesFile, String key, boolean logErrorOnInvalidValue) { + return (boolean) getBooleanValueForStringValue(key, (String) getProperty(context, propertiesFile, key, null), false, logErrorOnInvalidValue, LOG_TAG); } /** @@ -304,12 +307,14 @@ public static boolean isPropertyValueTrue(Context context, File propertiesFile, * @param context The {@link Context} for the {@link #getPropertiesFromFile(Context,File)} call. * @param propertiesFile The {@link File} to read the {@link Properties} from. * @param key The key to read. + * @param logErrorOnInvalidValue If {@code true}, then an error will be logged if key value + * was found in {@link Properties} but was invalid. * @return Returns the {@code true} if the {@link Properties} key {@link String} value equals "false", * regardless of case. If the key does not exist in the file or does not equal "false", then * {@code true} will be returned. */ - public static boolean isPropertyValueFalse(Context context, File propertiesFile, String key) { - return (boolean) getInvertedBooleanValueForStringValue((String) getProperty(context, propertiesFile, key, null), true); + public static boolean isPropertyValueFalse(Context context, File propertiesFile, String key, boolean logErrorOnInvalidValue) { + return (boolean) getInvertedBooleanValueForStringValue(key, (String) getProperty(context, propertiesFile, key, null), true, logErrorOnInvalidValue, LOG_TAG); } @@ -413,16 +418,20 @@ public static Map getMapCopy(Map map) { + /** * Get the boolean value for the {@link String} value. * * @param value The {@link String} value to convert. * @param def The default {@link boolean} value to return. + * @param logErrorOnInvalidValue If {@code true}, then an error will be logged if {@code value} + * was not {@code null} and was invalid. + * @param logTag If log tag to use for logging errors. * @return Returns {@code true} or {@code false} if value is the literal string "true" or "false" respectively, * regardless of case. Otherwise returns default value. */ - public static boolean getBooleanValueForStringValue(String value, boolean def) { - return (boolean) getDefaultIfNull(MAP_GENERIC_BOOLEAN.get(toLowerCase(value)), def); + public static boolean getBooleanValueForStringValue(String key, String value, boolean def, boolean logErrorOnInvalidValue, String logTag) { + return (boolean) getDefaultIfNotInMap(key, MAP_GENERIC_BOOLEAN, toLowerCase(value), def, logErrorOnInvalidValue, logTag); } /** @@ -430,11 +439,107 @@ public static boolean getBooleanValueForStringValue(String value, boolean def) { * * @param value The {@link String} value to convert. * @param def The default {@link boolean} value to return. + * @param logErrorOnInvalidValue If {@code true}, then an error will be logged if {@code value} + * was not {@code null} and was invalid. + * @param logTag If log tag to use for logging errors. * @return Returns {@code true} or {@code false} if value is the literal string "false" or "true" respectively, * regardless of case. Otherwise returns default value. */ - public static boolean getInvertedBooleanValueForStringValue(String value, boolean def) { - return (boolean) getDefaultIfNull(MAP_GENERIC_INVERTED_BOOLEAN.get(toLowerCase(value)), def); + public static boolean getInvertedBooleanValueForStringValue(String key, String value, boolean def, boolean logErrorOnInvalidValue, String logTag) { + return (boolean) getDefaultIfNotInMap(key, MAP_GENERIC_INVERTED_BOOLEAN, toLowerCase(value), def, logErrorOnInvalidValue, logTag); + } + + /** + * Get the value for the {@code inputValue} {@link Object} key from a {@link BiMap<>}, otherwise + * default value if key not found in {@code map}. + * + * @param key The shared properties {@link String} key value for which the value is being returned. + * @param map The {@link BiMap<>} value to get the value from. + * @param inputValue The {@link Object} key value of the map. + * @param defaultOutputValue The default {@link boolean} value to return if {@code inputValue} not found in map. + * The default value must exist as a value in the {@link BiMap<>} passed. + * @param logErrorOnInvalidValue If {@code true}, then an error will be logged if {@code inputValue} + * was not {@code null} and was not found in the map. + * @param logTag If log tag to use for logging errors. + * @return Returns the value for the {@code inputValue} key from the map if it exists. Otherwise + * returns default value. + */ + public static Object getDefaultIfNotInMap(String key, @Nonnull BiMap map, Object inputValue, Object defaultOutputValue, boolean logErrorOnInvalidValue, String logTag) { + Object outputValue = map.get(inputValue); + if (outputValue == null) { + Object defaultInputValue = map.inverse().get(defaultOutputValue); + if (defaultInputValue == null) + Logger.logError(LOG_TAG, "The default output value \"" + defaultOutputValue + "\" for the key \"" + key + "\" does not exist as a value in the BiMap passed to getDefaultIfNotInMap(): " + map.values()); + + if (logErrorOnInvalidValue && inputValue != null) { + if (key != null) + Logger.logError(logTag, "The value \"" + inputValue + "\" for the key \"" + key + "\" is invalid. Using default value \"" + defaultInputValue + "\" instead."); + else + Logger.logError(logTag, "The value \"" + inputValue + "\" is invalid. Using default value \"" + defaultInputValue + "\" instead."); + } + + return defaultOutputValue; + } else { + return outputValue; + } + } + + /** + * Get the {@code int} {@code value} as is if between {@code min} and {@code max} (inclusive), otherwise + * return default value. + * + * @param key The shared properties {@link String} key value for which the value is being returned. + * @param value The {@code int} value to check. + * @param def The default {@code int} value if {@code value} not in range. + * @param min The min allowed {@code int} value. + * @param max The max allowed {@code int} value. + * @param logErrorOnInvalidValue If {@code true}, then an error will be logged if {@code value} + * not in range. + * @param ignoreErrorIfValueZero If logging error should be ignored if value equals 0. + * @param logTag If log tag to use for logging errors. + * @return Returns the {@code value} as is if within range. Otherwise returns default value. + */ + public static int getDefaultIfNotInRange(String key, int value, int def, int min, int max, boolean logErrorOnInvalidValue, boolean ignoreErrorIfValueZero, String logTag) { + if (value < min || value > max) { + if (logErrorOnInvalidValue && (!ignoreErrorIfValueZero || value != 0)) { + if (key != null) + Logger.logError(logTag, "The value \"" + value + "\" for the key \"" + key + "\" is not within the range " + min + "-" + max + " (inclusive). Using default value \"" + def + "\" instead."); + else + Logger.logError(logTag, "The value \"" + value + "\" is not within the range " + min + "-" + max + " (inclusive). Using default value \"" + def + "\" instead."); + } + return def; + } else { + return value; + } + } + + /** + * Get the {@code float} {@code value} as is if between {@code min} and {@code max} (inclusive), otherwise + * return default value. + * + * @param key The shared properties {@link String} key value for which the value is being returned. + * @param value The {@code float} value to check. + * @param def The default {@code float} value if {@code value} not in range. + * @param min The min allowed {@code float} value. + * @param max The max allowed {@code float} value. + * @param logErrorOnInvalidValue If {@code true}, then an error will be logged if {@code value} + * not in range. + * @param ignoreErrorIfValueZero If logging error should be ignored if value equals 0. + * @param logTag If log tag to use for logging errors. + * @return Returns the {@code value} as is if within range. Otherwise returns default value. + */ + public static float getDefaultIfNotInRange(String key, float value, float def, float min, float max, boolean logErrorOnInvalidValue, boolean ignoreErrorIfValueZero, String logTag) { + if (value < min || value > max) { + if (logErrorOnInvalidValue && (!ignoreErrorIfValueZero || value != 0)) { + if (key != null) + Logger.logError(logTag, "The value \"" + value + "\" for the key \"" + key + "\" is not within the range " + min + "-" + max + " (inclusive). Using default value \"" + def + "\" instead."); + else + Logger.logError(logTag, "The value \"" + value + "\" is not within the range " + min + "-" + max + " (inclusive). Using default value \"" + def + "\" instead."); + } + return def; + } else { + return value; + } } /** diff --git a/termux-shared/src/main/java/com/termux/shared/settings/properties/TermuxPropertyConstants.java b/termux-shared/src/main/java/com/termux/shared/settings/properties/TermuxPropertyConstants.java index c84a0f38c0..593705c7d8 100644 --- a/termux-shared/src/main/java/com/termux/shared/settings/properties/TermuxPropertyConstants.java +++ b/termux-shared/src/main/java/com/termux/shared/settings/properties/TermuxPropertyConstants.java @@ -10,7 +10,7 @@ import java.util.Set; /* - * Version: v0.9.0 + * Version: v0.10.0 * * Changelog * @@ -45,6 +45,9 @@ * - 0.9.0 (2021-05-14) * - Add `*KEY_TERMINAL_CURSOR_BLINK_RATE*`. * + * - 0.10.0 (2021-05-15) + * - Add `MAP_BACK_KEY_BEHAVIOUR`, `MAP_SOFT_KEYBOARD_TOGGLE_BEHAVIOUR`, `MAP_VOLUME_KEYS_BEHAVIOUR`. + * */ /** @@ -179,6 +182,13 @@ public final class TermuxPropertyConstants { public static final String IVALUE_BACK_KEY_BEHAVIOUR_ESCAPE = "escape"; public static final String DEFAULT_IVALUE_BACK_KEY_BEHAVIOUR = IVALUE_BACK_KEY_BEHAVIOUR_BACK; + /** Defines the bidirectional map for back key behaviour values and their internal values */ + public static final ImmutableBiMap MAP_BACK_KEY_BEHAVIOUR = + new ImmutableBiMap.Builder() + .put(IVALUE_BACK_KEY_BEHAVIOUR_BACK, IVALUE_BACK_KEY_BEHAVIOUR_BACK) + .put(IVALUE_BACK_KEY_BEHAVIOUR_ESCAPE, IVALUE_BACK_KEY_BEHAVIOUR_ESCAPE) + .build(); + /** Defines the key for the default working directory */ @@ -205,6 +215,13 @@ public final class TermuxPropertyConstants { public static final String IVALUE_SOFT_KEYBOARD_TOGGLE_BEHAVIOUR_ENABLE_DISABLE = "enable/disable"; public static final String DEFAULT_IVALUE_SOFT_KEYBOARD_TOGGLE_BEHAVIOUR = IVALUE_SOFT_KEYBOARD_TOGGLE_BEHAVIOUR_SHOW_HIDE; + /** Defines the bidirectional map for toggle soft keyboard behaviour values and their internal values */ + public static final ImmutableBiMap MAP_SOFT_KEYBOARD_TOGGLE_BEHAVIOUR = + new ImmutableBiMap.Builder() + .put(IVALUE_SOFT_KEYBOARD_TOGGLE_BEHAVIOUR_SHOW_HIDE, IVALUE_SOFT_KEYBOARD_TOGGLE_BEHAVIOUR_SHOW_HIDE) + .put(IVALUE_SOFT_KEYBOARD_TOGGLE_BEHAVIOUR_ENABLE_DISABLE, IVALUE_SOFT_KEYBOARD_TOGGLE_BEHAVIOUR_ENABLE_DISABLE) + .build(); + /** Defines the key for whether volume keys will behave as virtual or literal volume keys */ @@ -214,6 +231,13 @@ public final class TermuxPropertyConstants { public static final String IVALUE_VOLUME_KEY_BEHAVIOUR_VOLUME = "volume"; public static final String DEFAULT_IVALUE_VOLUME_KEYS_BEHAVIOUR = IVALUE_VOLUME_KEY_BEHAVIOUR_VIRTUAL; + /** Defines the bidirectional map for volume keys behaviour values and their internal values */ + public static final ImmutableBiMap MAP_VOLUME_KEYS_BEHAVIOUR = + new ImmutableBiMap.Builder() + .put(IVALUE_VOLUME_KEY_BEHAVIOUR_VIRTUAL, IVALUE_VOLUME_KEY_BEHAVIOUR_VIRTUAL) + .put(IVALUE_VOLUME_KEY_BEHAVIOUR_VOLUME, IVALUE_VOLUME_KEY_BEHAVIOUR_VOLUME) + .build(); + diff --git a/termux-shared/src/main/java/com/termux/shared/settings/properties/TermuxSharedProperties.java b/termux-shared/src/main/java/com/termux/shared/settings/properties/TermuxSharedProperties.java index 68acf87278..2532a74eb0 100644 --- a/termux-shared/src/main/java/com/termux/shared/settings/properties/TermuxSharedProperties.java +++ b/termux-shared/src/main/java/com/termux/shared/settings/properties/TermuxSharedProperties.java @@ -19,7 +19,7 @@ public class TermuxSharedProperties implements SharedPropertiesParser { protected final SharedProperties mSharedProperties; protected final File mPropertiesFile; - private static final String LOG_TAG = "TermuxSharedProperties"; + public static final String LOG_TAG = "TermuxSharedProperties"; public TermuxSharedProperties(@Nonnull Context context) { mContext = context; @@ -76,12 +76,14 @@ public String getPropertyValue(String key, String def, boolean cached) { * @param cached If {@code true}, then the value is checked from the the {@link Properties} in-memory cache. * Otherwise the {@link Properties} object is read directly from the file * and value is checked from it. + * @param logErrorOnInvalidValue If {@code true}, then an error will be logged if key value + * was found in {@link Properties} but was invalid. * @return Returns the {@code true} if the {@link Properties} key {@link String} value equals "true", * regardless of case. If the key does not exist in the file or does not equal "true", then * {@code false} will be returned. */ - public boolean isPropertyValueTrue(String key, boolean cached) { - return (boolean) SharedProperties.getBooleanValueForStringValue((String) getPropertyValue(key, null, cached), false); + public boolean isPropertyValueTrue(String key, boolean cached, boolean logErrorOnInvalidValue) { + return (boolean) SharedProperties.getBooleanValueForStringValue(key, (String) getPropertyValue(key, null, cached), false, logErrorOnInvalidValue, LOG_TAG); } /** @@ -92,12 +94,14 @@ public boolean isPropertyValueTrue(String key, boolean cached) { * @param cached If {@code true}, then the value is checked from the the {@link Properties} in-memory cache. * Otherwise the {@link Properties} object is read directly from the file * and value is checked from it. + * @param logErrorOnInvalidValue If {@code true}, then an error will be logged if key value + * was found in {@link Properties} but was invalid. * @return Returns {@code true} if the {@link Properties} key {@link String} value equals "false", * regardless of case. If the key does not exist in the file or does not equal "false", then * {@code true} will be returned. */ - public boolean isPropertyValueFalse(String key, boolean cached) { - return (boolean) SharedProperties.getInvertedBooleanValueForStringValue((String) getPropertyValue(key, null, cached), true); + public boolean isPropertyValueFalse(String key, boolean cached, boolean logErrorOnInvalidValue) { + return (boolean) SharedProperties.getInvertedBooleanValueForStringValue(key, (String) getPropertyValue(key, null, cached), true, logErrorOnInvalidValue, LOG_TAG); } @@ -143,7 +147,7 @@ public Object getInternalPropertyValue(String key, boolean cached) { // A null value can still be returned by // {@link #getInternalPropertyValueFromValue(Context,String,String)} for some keys value = getInternalPropertyValueFromValue(mContext, key, null); - Logger.logWarn(LOG_TAG, "The value for \"" + key + "\" not found in SharedProperties cahce, force returning default value: `" + value + "`"); + Logger.logWarn(LOG_TAG, "The value for \"" + key + "\" not found in SharedProperties cache, force returning default value: `" + value + "`"); return value; } } else { @@ -219,10 +223,10 @@ public static Object getInternalTermuxPropertyValueFromValue(Context context, St default: // default boolean behaviour if (TermuxPropertyConstants.TERMUX_DEFAULT_BOOLEAN_BEHAVIOUR_PROPERTIES_LIST.contains(key)) - return (boolean) SharedProperties.getBooleanValueForStringValue(value, false); + return (boolean) SharedProperties.getBooleanValueForStringValue(key, value, false, true, LOG_TAG); // default inverted boolean behaviour else if (TermuxPropertyConstants.TERMUX_DEFAULT_INVERETED_BOOLEAN_BEHAVIOUR_PROPERTIES_LIST.contains(key)) - return (boolean) SharedProperties.getInvertedBooleanValueForStringValue(value, true); + return (boolean) SharedProperties.getInvertedBooleanValueForStringValue(key, value, true, true, LOG_TAG); // just use String object as is (may be null) else return value; @@ -233,8 +237,6 @@ else if (TermuxPropertyConstants.TERMUX_DEFAULT_INVERETED_BOOLEAN_BEHAVIOUR_PROP - - /** * Returns {@code true} or {@code false} if value is the literal string "true" or "false" respectively regardless of case. * Otherwise returns {@code true} if the night mode is currently enabled in the system. @@ -244,7 +246,7 @@ else if (TermuxPropertyConstants.TERMUX_DEFAULT_INVERETED_BOOLEAN_BEHAVIOUR_PROP */ public static boolean getUseBlackUIInternalPropertyValueFromValue(Context context, String value) { int nightMode = context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; - return SharedProperties.getBooleanValueForStringValue(value, nightMode == Configuration.UI_MODE_NIGHT_YES); + return SharedProperties.getBooleanValueForStringValue(TermuxPropertyConstants.KEY_USE_BLACK_UI, value, nightMode == Configuration.UI_MODE_NIGHT_YES, true, LOG_TAG); } /** @@ -256,7 +258,7 @@ public static boolean getUseBlackUIInternalPropertyValueFromValue(Context contex * @return Returns the internal value for value. */ public static int getBellBehaviourInternalPropertyValueFromValue(String value) { - return SharedProperties.getDefaultIfNull(TermuxPropertyConstants.MAP_BELL_BEHAVIOUR.get(SharedProperties.toLowerCase(value)), TermuxPropertyConstants.DEFAULT_IVALUE_BELL_BEHAVIOUR); + return (int) SharedProperties.getDefaultIfNotInMap(TermuxPropertyConstants.KEY_BELL_BEHAVIOUR, TermuxPropertyConstants.MAP_BELL_BEHAVIOUR, SharedProperties.toLowerCase(value), TermuxPropertyConstants.DEFAULT_IVALUE_BELL_BEHAVIOUR, true, LOG_TAG); } /** @@ -269,23 +271,12 @@ public static int getBellBehaviourInternalPropertyValueFromValue(String value) { * @return Returns the internal value for value. */ public static float getTerminalCursorBlinkRateInternalPropertyValueFromValue(String value) { - return rangeTerminalCursorBlinkRateValue(DataUtils.getIntFromString(value, TermuxPropertyConstants.DEFAULT_IVALUE_TERMINAL_CURSOR_BLINK_RATE)); - } - - /** - * Returns the value itself if it is between - * {@code TermuxPropertyConstants#IVALUE_TERMINAL_CURSOR_BLINK_RATE_MIN} and - * {@code TermuxPropertyConstants#IVALUE_TERMINAL_CURSOR_BLINK_RATE_MAX}, - * otherwise returns {@code TermuxPropertyConstants#DEFAULT_IVALUE_TERMINAL_CURSOR_BLINK_RATE}. - * - * @param value The value to clamp. - * @return Returns the clamped value. - */ - public static int rangeTerminalCursorBlinkRateValue(int value) { - return (int) DataUtils.rangedOrDefault(value, - TermuxPropertyConstants.DEFAULT_IVALUE_TERMINAL_CURSOR_BLINK_RATE, - TermuxPropertyConstants.IVALUE_TERMINAL_CURSOR_BLINK_RATE_MIN, - TermuxPropertyConstants.IVALUE_TERMINAL_CURSOR_BLINK_RATE_MAX); + return SharedProperties.getDefaultIfNotInRange(TermuxPropertyConstants.KEY_TERMINAL_CURSOR_BLINK_RATE, + DataUtils.getIntFromString(value, TermuxPropertyConstants.DEFAULT_IVALUE_TERMINAL_CURSOR_BLINK_RATE), + TermuxPropertyConstants.DEFAULT_IVALUE_TERMINAL_CURSOR_BLINK_RATE, + TermuxPropertyConstants.IVALUE_TERMINAL_CURSOR_BLINK_RATE_MIN, + TermuxPropertyConstants.IVALUE_TERMINAL_CURSOR_BLINK_RATE_MAX, + true, true, LOG_TAG); } /** @@ -298,23 +289,12 @@ public static int rangeTerminalCursorBlinkRateValue(int value) { * @return Returns the internal value for value. */ public static float getTerminalToolbarHeightScaleFactorInternalPropertyValueFromValue(String value) { - return rangeTerminalToolbarHeightScaleFactorValue(DataUtils.getFloatFromString(value, TermuxPropertyConstants.DEFAULT_IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR)); - } - - /** - * Returns the value itself if it is between - * {@code TermuxPropertyConstants#IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR_MIN} and - * {@code TermuxPropertyConstants#IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR_MAX}, - * otherwise returns {@code TermuxPropertyConstants#DEFAULT_IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR}. - * - * @param value The value to clamp. - * @return Returns the clamped value. - */ - public static float rangeTerminalToolbarHeightScaleFactorValue(float value) { - return DataUtils.rangedOrDefault(value, + return SharedProperties.getDefaultIfNotInRange(TermuxPropertyConstants.KEY_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR, + DataUtils.getFloatFromString(value, TermuxPropertyConstants.DEFAULT_IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR), TermuxPropertyConstants.DEFAULT_IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR, TermuxPropertyConstants.IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR_MIN, - TermuxPropertyConstants.IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR_MAX); + TermuxPropertyConstants.IVALUE_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR_MAX, + true, true, LOG_TAG); } /** @@ -356,7 +336,7 @@ public static Integer getCodePointForSessionShortcuts(String key, String value) * @return Returns the internal value for value. */ public static String getBackKeyBehaviourInternalPropertyValueFromValue(String value) { - return SharedProperties.getDefaultIfNull(value, TermuxPropertyConstants.DEFAULT_IVALUE_BACK_KEY_BEHAVIOUR); + return (String) SharedProperties.getDefaultIfNotInMap(TermuxPropertyConstants.KEY_BACK_KEY_BEHAVIOUR, TermuxPropertyConstants.MAP_BACK_KEY_BEHAVIOUR, SharedProperties.toLowerCase(value), TermuxPropertyConstants.DEFAULT_IVALUE_BACK_KEY_BEHAVIOUR, true, LOG_TAG); } /** @@ -370,8 +350,9 @@ public static String getDefaultWorkingDirectoryInternalPropertyValueFromValue(St if (path == null || path.isEmpty()) return TermuxPropertyConstants.DEFAULT_IVALUE_DEFAULT_WORKING_DIRECTORY; File workDir = new File(path); if (!workDir.exists() || !workDir.isDirectory() || !workDir.canRead()) { - // Fallback to default directory if user configured working directory does not exist - // or is not a directory or is not readable. + // Fallback to default directory if user configured working directory does not exist, + // is not a directory or is not readable. + Logger.logError(LOG_TAG, "The path \"" + path + "\" for the key \"" + TermuxPropertyConstants.KEY_DEFAULT_WORKING_DIRECTORY + "\" does not exist, is not a directory or is not readable. Using default value \"" + TermuxPropertyConstants.DEFAULT_IVALUE_DEFAULT_WORKING_DIRECTORY + "\" instead."); return TermuxPropertyConstants.DEFAULT_IVALUE_DEFAULT_WORKING_DIRECTORY; } else { return path; @@ -405,7 +386,7 @@ public static String getExtraKeysStyleInternalPropertyValueFromValue(String valu * @return Returns the internal value for value. */ public static String getSoftKeyboardToggleBehaviourInternalPropertyValueFromValue(String value) { - return SharedProperties.getDefaultIfNull(value, TermuxPropertyConstants.DEFAULT_IVALUE_SOFT_KEYBOARD_TOGGLE_BEHAVIOUR); + return (String) SharedProperties.getDefaultIfNotInMap(TermuxPropertyConstants.KEY_SOFT_KEYBOARD_TOGGLE_BEHAVIOUR, TermuxPropertyConstants.MAP_SOFT_KEYBOARD_TOGGLE_BEHAVIOUR, SharedProperties.toLowerCase(value), TermuxPropertyConstants.DEFAULT_IVALUE_SOFT_KEYBOARD_TOGGLE_BEHAVIOUR, true, LOG_TAG); } /** @@ -415,12 +396,13 @@ public static String getSoftKeyboardToggleBehaviourInternalPropertyValueFromValu * @return Returns the internal value for value. */ public static String getVolumeKeysBehaviourInternalPropertyValueFromValue(String value) { - return SharedProperties.getDefaultIfNull(value, TermuxPropertyConstants.DEFAULT_IVALUE_VOLUME_KEYS_BEHAVIOUR); + return (String) SharedProperties.getDefaultIfNotInMap(TermuxPropertyConstants.KEY_VOLUME_KEYS_BEHAVIOUR, TermuxPropertyConstants.MAP_VOLUME_KEYS_BEHAVIOUR, SharedProperties.toLowerCase(value), TermuxPropertyConstants.DEFAULT_IVALUE_VOLUME_KEYS_BEHAVIOUR, true, LOG_TAG); } + public boolean isEnforcingCharBasedInput() { return (boolean) getInternalPropertyValue(TermuxPropertyConstants.KEY_ENFORCE_CHAR_BASED_INPUT, true); } @@ -450,11 +432,11 @@ public int getBellBehaviour() { } public int getTerminalCursorBlinkRate() { - return rangeTerminalCursorBlinkRateValue((int) getInternalPropertyValue(TermuxPropertyConstants.KEY_TERMINAL_CURSOR_BLINK_RATE, true)); + return (int) getInternalPropertyValue(TermuxPropertyConstants.KEY_TERMINAL_CURSOR_BLINK_RATE, true); } public float getTerminalToolbarHeightScaleFactor() { - return rangeTerminalToolbarHeightScaleFactorValue((float) getInternalPropertyValue(TermuxPropertyConstants.KEY_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR, true)); + return (float) getInternalPropertyValue(TermuxPropertyConstants.KEY_TERMINAL_TOOLBAR_HEIGHT_SCALE_FACTOR, true); } public boolean isBackKeyTheEscapeKey() { @@ -476,6 +458,7 @@ public boolean areVirtualVolumeKeysDisabled() { + public void dumpPropertiesToLog() { Properties properties = getProperties(true); StringBuilder propertiesDump = new StringBuilder();