From f8ccbb4953e835c78a5bdcb170121207b5622d6a Mon Sep 17 00:00:00 2001 From: agnostic-apollo Date: Sun, 16 May 2021 01:31:34 +0500 Subject: [PATCH] Log invalid values stored in termux.properties file during load time All external and internal values were already logged and required log level to be set to "Verbose" in Termux Settings, but now invalid values and the default value used instead will be logged at log level "Normal" as well. The `TermuxPropertyConstants` class has been updated to `v0.10.0`. Check its Changelog sections for info on changes. --- .../terminal/io/extrakeys/ExtraKeysInfo.java | 6 + .../com/termux/app/utils/PluginUtils.java | 2 +- .../settings/properties/SharedProperties.java | 121 ++++++++++++++++-- .../properties/TermuxPropertyConstants.java | 26 +++- .../properties/TermuxSharedProperties.java | 85 +++++------- 5 files changed, 179 insertions(+), 61 deletions(-) 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();