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 0dee0470..d2efd0b4 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 @@ -9,6 +9,8 @@ import androidx.annotation.Nullable; import com.google.common.collect.BiMap; import com.google.common.collect.ImmutableBiMap; import com.google.common.primitives.Primitives; +import com.termux.shared.file.FileUtils; +import com.termux.shared.file.filesystem.FileType; import com.termux.shared.logger.Logger; import java.io.File; @@ -16,6 +18,7 @@ import java.io.FileInputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; @@ -253,6 +256,38 @@ public class SharedProperties { return properties; } + /** Returns the first {@link File} found in + * {@code propertiesFilePaths} from which app properties can be loaded. If the {@link File} found + * is not a regular file or is not readable, then {@code null} is returned. Symlinks **will not** + * be followed for potential security reasons. + * + * @param propertiesFilePaths The {@link List} containing properties file paths. + * @param logTag If log tag to use for logging errors. + * @return Returns the {@link File} object for Termux:Float app properties. + */ + public static File getPropertiesFileFromList(List propertiesFilePaths, @NonNull String logTag) { + if (propertiesFilePaths == null || propertiesFilePaths.size() == 0) + return null; + + for(String propertiesFilePath : propertiesFilePaths) { + File propertiesFile = new File(propertiesFilePath); + + // Symlinks **will not** be followed. + FileType fileType = FileUtils.getFileType(propertiesFilePath, false); + if (fileType == FileType.REGULAR) { + if (propertiesFile.canRead()) + return propertiesFile; + else + Logger.logWarn(logTag, "Ignoring properties file at \"" + propertiesFilePath + "\" since it is not readable"); + } else if (fileType != FileType.NO_EXIST) { + Logger.logWarn(logTag, "Ignoring properties file at \"" + propertiesFilePath + "\" of type: \"" + fileType.getName() + "\""); + } + } + + Logger.logDebug(logTag, "No readable properties file found at: " + propertiesFilePaths); + return null; + } + public static String getProperty(Context context, File propertiesFile, String key, String def) { diff --git a/termux-shared/src/main/java/com/termux/shared/termux/settings/properties/TermuxAppSharedProperties.java b/termux-shared/src/main/java/com/termux/shared/termux/settings/properties/TermuxAppSharedProperties.java index a0189c96..7faf5f8b 100644 --- a/termux-shared/src/main/java/com/termux/shared/termux/settings/properties/TermuxAppSharedProperties.java +++ b/termux-shared/src/main/java/com/termux/shared/termux/settings/properties/TermuxAppSharedProperties.java @@ -13,7 +13,7 @@ public class TermuxAppSharedProperties extends TermuxSharedProperties { private TermuxAppSharedProperties(@NonNull Context context) { super(context, TermuxConstants.TERMUX_APP_NAME, - TermuxPropertyConstants.getTermuxPropertiesFile(), TermuxPropertyConstants.TERMUX_APP_PROPERTIES_LIST, + TermuxConstants.TERMUX_PROPERTIES_FILE_PATHS_LIST, TermuxPropertyConstants.TERMUX_APP_PROPERTIES_LIST, new TermuxSharedProperties.SharedPropertiesParserClient()); } diff --git a/termux-shared/src/main/java/com/termux/shared/termux/settings/properties/TermuxPropertyConstants.java b/termux-shared/src/main/java/com/termux/shared/termux/settings/properties/TermuxPropertyConstants.java index 8fcbf629..dd935f3a 100644 --- a/termux-shared/src/main/java/com/termux/shared/termux/settings/properties/TermuxPropertyConstants.java +++ b/termux-shared/src/main/java/com/termux/shared/termux/settings/properties/TermuxPropertyConstants.java @@ -478,58 +478,4 @@ public final class TermuxPropertyConstants { public static final Set TERMUX_DEFAULT_INVERETED_TRUE_BOOLEAN_BEHAVIOUR_PROPERTIES_LIST = new HashSet<>(Arrays.asList( )); - - - - - /** Returns the first {@link File} found in - * {@link TermuxConstants#TERMUX_PROPERTIES_FILE_PATHS_LIST} via a call to - * {@link #getPropertiesFile(List)}. - * - * @return Returns the {@link File} object for Termux app properties. - */ - public static File getTermuxPropertiesFile() { - return getPropertiesFile(TermuxConstants.TERMUX_PROPERTIES_FILE_PATHS_LIST); - } - - /** Returns the first {@link File} found in - * {@link TermuxConstants#TERMUX_FLOAT_PROPERTIES_FILE_PATHS_LIST} via a call to - * {@link #getPropertiesFile(List)}. - * - * @return Returns the {@link File} object for Termux:Float app properties. - */ - public static File getTermuxFloatPropertiesFile() { - return getPropertiesFile(TermuxConstants.TERMUX_FLOAT_PROPERTIES_FILE_PATHS_LIST); - } - - /** Returns the first {@link File} found in - * {@code propertiesFilePaths} from which app properties can be loaded. If the {@link File} found - * is not a regular file or is not readable, then {@code null} is returned. Symlinks **will not** - * be followed for potential security reasons. - * - * @return Returns the {@link File} object for Termux:Float app properties. - */ - public static File getPropertiesFile(List propertiesFilePaths) { - if (propertiesFilePaths == null || propertiesFilePaths.size() == 0) - return null; - - for(String propertiesFilePath : propertiesFilePaths) { - File propertiesFile = new File(propertiesFilePath); - - // Symlinks **will not** be followed. - FileType fileType = FileUtils.getFileType(propertiesFilePath, false); - if (fileType == FileType.REGULAR) { - if (propertiesFile.canRead()) - return propertiesFile; - else - Logger.logWarn(LOG_TAG, "Ignoring properties file at \"" + propertiesFilePath + "\" since it is not readable"); - } else if (fileType != FileType.NO_EXIST) { - Logger.logWarn(LOG_TAG, "Ignoring properties file at \"" + propertiesFilePath + "\" of type: \"" + fileType.getName() + "\""); - } - } - - Logger.logDebug(LOG_TAG, "No readable properties file found at: " + propertiesFilePaths); - return null; - } - } diff --git a/termux-shared/src/main/java/com/termux/shared/termux/settings/properties/TermuxSharedProperties.java b/termux-shared/src/main/java/com/termux/shared/termux/settings/properties/TermuxSharedProperties.java index cd1d0ec0..e277f450 100644 --- a/termux-shared/src/main/java/com/termux/shared/termux/settings/properties/TermuxSharedProperties.java +++ b/termux-shared/src/main/java/com/termux/shared/termux/settings/properties/TermuxSharedProperties.java @@ -12,6 +12,7 @@ import com.termux.shared.termux.TermuxConstants; import java.io.File; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; @@ -20,24 +21,35 @@ public abstract class TermuxSharedProperties { protected final Context mContext; protected final String mLabel; - protected final File mPropertiesFile; - protected final SharedProperties mSharedProperties; + protected final List mPropertiesFilePaths; + protected final Set mPropertiesList; + protected final SharedPropertiesParser mSharedPropertiesParser; + protected File mPropertiesFile; + protected SharedProperties mSharedProperties; public static final String LOG_TAG = "TermuxSharedProperties"; - public TermuxSharedProperties(@NonNull Context context, @NonNull String label, File propertiesFile, + public TermuxSharedProperties(@NonNull Context context, @NonNull String label, List propertiesFilePaths, @NonNull Set propertiesList, @NonNull SharedPropertiesParser sharedPropertiesParser) { mContext = context.getApplicationContext(); mLabel = label; - mPropertiesFile = propertiesFile; - mSharedProperties = new SharedProperties(context, mPropertiesFile, propertiesList, sharedPropertiesParser); + mPropertiesFilePaths = propertiesFilePaths; + mPropertiesList = propertiesList; + mSharedPropertiesParser = sharedPropertiesParser; loadTermuxPropertiesFromDisk(); } /** * Reload the termux properties from disk into an in-memory cache. */ - public void loadTermuxPropertiesFromDisk() { + public synchronized void loadTermuxPropertiesFromDisk() { + // Properties files must be searched everytime since no file may exist when constructor is + // called or a higher priority file may have been created afterward. Otherwise, if no file + // was found, then default props would keep loading, since mSharedProperties would be null. #2836 + mPropertiesFile = SharedProperties.getPropertiesFileFromList(mPropertiesFilePaths, LOG_TAG); + mSharedProperties = null; + mSharedProperties = new SharedProperties(mContext, mPropertiesFile, mPropertiesList, mSharedPropertiesParser); + mSharedProperties.loadPropertiesFromDisk(); dumpPropertiesToLog(); dumpInternalPropertiesToLog(); @@ -167,8 +179,8 @@ public abstract class TermuxSharedProperties { /** - * Get the internal {@link Object} value for the key passed from the file returned by - * {@link TermuxPropertyConstants#getTermuxPropertiesFile()}. The {@link Properties} object is + * Get the internal {@link Object} value for the key passed from the first file found in + * {@link TermuxConstants#TERMUX_PROPERTIES_FILE_PATHS_LIST}. The {@link Properties} object is * read directly from the file and internal value is returned for the property value against the key. * * @param context The context for operations. @@ -177,7 +189,9 @@ public abstract class TermuxSharedProperties { * the object stored against the key is {@code null}. */ public static Object getTermuxInternalPropertyValue(Context context, String key) { - return SharedProperties.getInternalProperty(context, TermuxPropertyConstants.getTermuxPropertiesFile(), key, new SharedPropertiesParserClient()); + return SharedProperties.getInternalProperty(context, + SharedProperties.getPropertiesFileFromList(TermuxConstants.TERMUX_PROPERTIES_FILE_PATHS_LIST, LOG_TAG), + key, new SharedPropertiesParserClient()); } /**