Skip to content

Commit

Permalink
fix: preferences that are enums can be set either by integer or case-…
Browse files Browse the repository at this point in the history
…insensitive string

fixes #1874
  • Loading branch information
growse committed Oct 6, 2024
1 parent 5925ce3 commit e1508fd
Show file tree
Hide file tree
Showing 36 changed files with 136 additions and 125 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
- Try to not block the main thread when generating an Status Message, which causes an ANR
- Messages that fail to send because the endpoint isn't ready now retry every 10 seconds, not every second
- Import config screen displays JSON config LTR under RTL locales
- setting / importing configuration options that are enums are now case-insensitive
- Fix regression where setting the locatorPriority preference using a number wasn't working (#1874)

## Version 2.5.3

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ class MQTTMessagePublishTests :
private fun setupTestActivity() {
PreferenceManager.getDefaultSharedPreferences(app)
.edit()
.putInt(Preferences::monitoring.name, MonitoringMode.QUIET.value)
.putInt(Preferences::monitoring.name, MonitoringMode.Quiet.value)
.putString(Preferences::reverseGeocodeProvider.name, "None")
.apply()
setNotFirstStartPreferences()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import com.adevinta.android.barista.interaction.BaristaClickInteractions.clickOn
import com.adevinta.android.barista.interaction.BaristaSleepInteractions.sleep
import org.hamcrest.Matchers.allOf

private const val SLEEP_MILLIS = 100L
private const val SLEEP_MILLIS = 10L

fun clickOnDrawerAndWait(text: Int) {
Espresso.onView(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class ContactsActivityTests :
setNotFirstStartPreferences()
getPreferences()
.edit()
.putInt(Preferences::monitoring.name, MonitoringMode.QUIET.value)
.putInt(Preferences::monitoring.name, MonitoringMode.Quiet.value)
.putString(Preferences::reverseGeocodeProvider.name, "None")
.apply()
launchActivity()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ class PreferencesActivityTests :
val expected =
baristaRule.activityTestRule.activity.resources.run {
getStringArray(R.array.geocoders)[
getStringArray(R.array.geocoderValues).indexOfFirst { it == defaultGeocoder.value }]
getStringArray(R.array.geocoderValues).indexOfFirst { it == defaultGeocoder.name }]
}
assertContains(android.R.id.summary, expected)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class DefaultsProviderImpl : DefaultsProvider {
override fun <T> getDefaultValue(preferences: Preferences, property: KProperty<*>): T {
return when (property) {
Preferences::mapLayerStyle -> MapLayerStyle.GoogleMapDefault
Preferences::reverseGeocodeProvider -> ReverseGeocodeProvider.DEVICE
Preferences::reverseGeocodeProvider -> ReverseGeocodeProvider.Device
else -> super.getDefaultValue<T>(preferences, property)
}
as T
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ enum class MapLayerStyle {
@JvmStatic
@FromConfiguration
fun getByValue(value: String): MapLayerStyle =
entries.firstOrNull { it.name == value } ?: GoogleMapDefault
entries.firstOrNull { it.name.equals(value, true) } ?: GoogleMapDefault
}
}

Expand Down
6 changes: 3 additions & 3 deletions project/app/src/main/java/org/owntracks/android/App.kt
Original file line number Diff line number Diff line change
Expand Up @@ -193,9 +193,9 @@ class App :
@MainThread
private fun setThemeFromPreferences() {
when (preferences.theme) {
AppTheme.AUTO -> AppCompatDelegate.setDefaultNightMode(Preferences.SYSTEM_NIGHT_AUTO_MODE)
AppTheme.DARK -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
AppTheme.LIGHT -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
AppTheme.Auto -> AppCompatDelegate.setDefaultNightMode(Preferences.SYSTEM_NIGHT_AUTO_MODE)
AppTheme.Dark -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
AppTheme.Light -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ constructor(
withContext(ioDispatcher) {
geocoder =
when (preferences.reverseGeocodeProvider) {
ReverseGeocodeProvider.OPENCAGE ->
ReverseGeocodeProvider.OpenCage ->
OpenCageGeocoder(preferences.opencageApiKey, httpClient)
ReverseGeocodeProvider.DEVICE -> DeviceGeocoder(context)
ReverseGeocodeProvider.NONE -> GeocoderNone()
ReverseGeocodeProvider.Device -> DeviceGeocoder(context)
ReverseGeocodeProvider.None -> GeocoderNone()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,23 @@ package org.owntracks.android.location

import org.owntracks.android.preferences.types.FromConfiguration

enum class LocatorPriority {
HighAccuracy,
BalancedPowerAccuracy,
LowPower,
NoPower;
enum class LocatorPriority(private val value: Int) {
HighAccuracy(3),
BalancedPowerAccuracy(2),
LowPower(1),
NoPower(0);

companion object {
@JvmStatic
@FromConfiguration
fun getByValue(value: String?): LocatorPriority? =
LocatorPriority.entries.firstOrNull { it.name == value }
fun getByValue(value: Int): LocatorPriority =
LocatorPriority.entries.firstOrNull { it.value == value } ?: BalancedPowerAccuracy

@JvmStatic
@FromConfiguration
fun getByValue(value: String): LocatorPriority =
value.toIntOrNull()?.run(::getByValue)
?: entries.firstOrNull { it.name.equals(value, true) }
?: BalancedPowerAccuracy
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ interface DefaultsProvider {
Preferences::locatorInterval -> 60
Preferences::locatorPriority -> null
Preferences::mode -> ConnectionMode.MQTT
Preferences::monitoring -> MonitoringMode.SIGNIFICANT
Preferences::monitoring -> MonitoringMode.Significant
Preferences::moveModeLocatorInterval -> 10
Preferences::mqttProtocolLevel -> MqttProtocolLevel.MQTT_3_1
Preferences::notificationEvents -> true
Expand All @@ -55,7 +55,7 @@ interface DefaultsProvider {
Preferences::ping -> 15
Preferences::port -> 8883
Preferences::extendedData -> true
Preferences::pubQos -> MqttQos.ONE
Preferences::pubQos -> MqttQos.One
Preferences::pubRetain -> true
Preferences::pubTopicBase -> "owntracks/%u/%d"
Preferences::publishLocationOnConnect -> false
Expand All @@ -64,9 +64,9 @@ interface DefaultsProvider {
Preferences::setupCompleted -> false
Preferences::showRegionsOnMap -> false
Preferences::sub -> true
Preferences::subQos -> MqttQos.TWO
Preferences::subQos -> MqttQos.Two
Preferences::subTopic -> DEFAULT_SUB_TOPIC
Preferences::theme -> AppTheme.AUTO
Preferences::theme -> AppTheme.Auto
Preferences::tls -> true
Preferences::tlsClientCrt -> ""
Preferences::tid ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class PreferenceDataStoreShim @Inject constructor(private val preferences: Prefe
override fun getString(key: String?, defValue: String?): String {
val stringPreferenceValue =
when (val preferenceValue = key?.run(preferences::getPreferenceByName) ?: defValue) {
is ReverseGeocodeProvider -> preferenceValue.value
is ReverseGeocodeProvider -> preferenceValue.name
is StringMaxTwoAlphaNumericChars -> preferenceValue.toString()
else -> preferenceValue
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -330,9 +330,9 @@ constructor(
return pubQos
}

val pubQosWaypoints = MqttQos.ZERO
val pubQosWaypoints = MqttQos.Zero

val pubQosStatus = MqttQos.ZERO
val pubQosStatus = MqttQos.Zero

val pubRetainLocations: Boolean
get() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ abstract class PreferencesStore :
typeOf<AppTheme>() -> AppTheme.getByValue(getInt(property.name, 0))
typeOf<StringMaxTwoAlphaNumericChars>() ->
StringMaxTwoAlphaNumericChars(getString(property.name, "") ?: "")
typeOf<LocatorPriority?>() -> LocatorPriority.getByValue(getString(property.name, ""))
typeOf<LocatorPriority?>() ->
LocatorPriority.getByValue(getString(property.name, "") ?: "")
else ->
throw UnsupportedPreferenceTypeException(
"Trying to get property ${property.name} has type ${property.returnType}")
Expand Down Expand Up @@ -212,7 +213,7 @@ abstract class PreferencesStore :
is Int -> putInt(property.name, coercedValue)
is Float -> putFloat(property.name, coercedValue)
is Set<*> -> putStringSet(property.name, value as Set<String>)
is ReverseGeocodeProvider -> putString(property.name, coercedValue.value)
is ReverseGeocodeProvider -> putString(property.name, coercedValue.name)
is MapLayerStyle -> putString(property.name, coercedValue.name)
is ConnectionMode -> putInt(property.name, coercedValue.value)
is MonitoringMode -> putInt(property.name, coercedValue.value)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
package org.owntracks.android.preferences.types

import com.fasterxml.jackson.annotation.JsonValue

enum class AppTheme(@JsonValue val value: Int) {
LIGHT(0),
DARK(1),
AUTO(2);
enum class AppTheme(val value: Int) {
Light(0),
Dark(1),
Auto(2);

companion object {
@JvmStatic
@FromConfiguration
fun getByValue(value: Int): AppTheme = entries.firstOrNull { it.value == value } ?: LIGHT
fun getByValue(value: Int): AppTheme = entries.firstOrNull { it.value == value } ?: Auto

@JvmStatic
@FromConfiguration
fun getByValue(value: String): AppTheme =
(value.toIntOrNull() ?: Int.MIN_VALUE).run(::getByValue)
value.toIntOrNull()?.run(::getByValue)
?: entries.firstOrNull { it.name.equals(value, true) }
?: Auto
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ enum class ConnectionMode(@JsonValue val value: Int) {
@JvmStatic
@FromConfiguration
fun getByValue(value: String): ConnectionMode =
(value.toIntOrNull() ?: Int.MIN_VALUE).run(::getByValue)
value.toIntOrNull()?.run(::getByValue)
?: entries.firstOrNull { it.name.equals(value, true) }
?: MQTT
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,30 @@ package org.owntracks.android.preferences.types
import com.fasterxml.jackson.annotation.JsonValue

enum class MonitoringMode(@JsonValue val value: Int) {
QUIET(-1),
MANUAL(0),
SIGNIFICANT(1),
MOVE(2);
Quiet(-1),
Manual(0),
Significant(1),
Move(2);

fun next(): MonitoringMode =
when (this) {
QUIET -> MANUAL
MANUAL -> SIGNIFICANT
SIGNIFICANT -> MOVE
MOVE -> QUIET
Quiet -> Manual
Manual -> Significant
Significant -> Move
Move -> Quiet
}

companion object {
@JvmStatic
@FromConfiguration
fun getByValue(value: Int): MonitoringMode =
entries.firstOrNull { it.value == value } ?: SIGNIFICANT
entries.firstOrNull { it.value == value } ?: Significant

@JvmStatic
@FromConfiguration
fun getByValue(value: String): MonitoringMode =
(value.toIntOrNull() ?: Int.MIN_VALUE).run(::getByValue)
value.toIntOrNull()?.run(::getByValue)
?: entries.firstOrNull { it.name.equals(value, true) }
?: Significant
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ enum class MqttProtocolLevel(@JsonValue val value: Int) {
@JvmStatic
@FromConfiguration
fun getByValue(value: String): MqttProtocolLevel =
(value.toIntOrNull() ?: Int.MIN_VALUE).run(::getByValue)
value.toIntOrNull()?.run(::getByValue)
?: entries.firstOrNull { it.name.equals(value, true) }
?: MQTT_3_1
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,20 @@ package org.owntracks.android.preferences.types
import com.fasterxml.jackson.annotation.JsonValue

enum class MqttQos(@JsonValue val value: Int) {
ZERO(0),
ONE(1),
TWO(2);
Zero(0),
One(1),
Two(2);

companion object {
@JvmStatic
@FromConfiguration
fun getByValue(value: Int): MqttQos = entries.firstOrNull { it.value == value } ?: ONE
fun getByValue(value: Int): MqttQos = entries.firstOrNull { it.value == value } ?: One

@JvmStatic
@FromConfiguration
fun getByValue(value: String): MqttQos =
(value.toIntOrNull() ?: Int.MIN_VALUE).run(::getByValue)
value.toIntOrNull()?.run(::getByValue)
?: entries.firstOrNull { it.name.equals(value, true) }
?: One
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
package org.owntracks.android.preferences.types

import com.fasterxml.jackson.annotation.JsonValue

enum class ReverseGeocodeProvider(@JsonValue val value: String) {
NONE("None"),
DEVICE("Device"),
OPENCAGE("OpenCage");
enum class ReverseGeocodeProvider {
None,
Device,
OpenCage;

companion object {
@JvmStatic
@FromConfiguration
fun getByValue(value: String): ReverseGeocodeProvider =
entries.firstOrNull { it.value == value } ?: NONE
entries.firstOrNull { it.name.equals(value, true) } ?: None
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -520,20 +520,20 @@ class BackgroundService : LifecycleService(), Preferences.OnPreferenceChangeList
var smallestDisplacement: Float? = null
val priority: LocatorPriority
when (monitoring) {
MonitoringMode.QUIET,
MonitoringMode.MANUAL -> {
MonitoringMode.Quiet,
MonitoringMode.Manual -> {
interval = Duration.ofSeconds(preferences.locatorInterval.toLong())
smallestDisplacement = preferences.locatorDisplacement.toFloat()
priority = preferences.locatorPriority ?: LocatorPriority.LowPower
}

MonitoringMode.SIGNIFICANT -> {
MonitoringMode.Significant -> {
interval = Duration.ofSeconds(preferences.locatorInterval.toLong())
smallestDisplacement = preferences.locatorDisplacement.toFloat()
priority = preferences.locatorPriority ?: LocatorPriority.BalancedPowerAccuracy
}

MonitoringMode.MOVE -> {
MonitoringMode.Move -> {
interval = Duration.ofSeconds(preferences.moveModeLocatorInterval.toLong())
priority = preferences.locatorPriority ?: LocatorPriority.HighAccuracy
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,12 @@ constructor(
MessageTransition.TRIGGER_LOCATION)
}
}
if (preferences.monitoring === MonitoringMode.QUIET &&
if (preferences.monitoring === MonitoringMode.Quiet &&
MessageLocation.ReportType.USER != trigger) {
Timber.v("message suppressed by monitoring settings: quiet")
return Result.failure(Exception("message suppressed by monitoring settings: quiet"))
}
if (preferences.monitoring === MonitoringMode.MANUAL &&
if (preferences.monitoring === MonitoringMode.Manual &&
MessageLocation.ReportType.USER != trigger &&
MessageLocation.ReportType.CIRCULAR != trigger) {
Timber.v("message suppressed by monitoring settings: manual")
Expand Down Expand Up @@ -189,7 +189,7 @@ constructor(
waypointModel.lastTransition = transition
waypointModel.lastTriggered = Instant.now()
waypointsRepo.update(waypointModel, false)
if (preferences.monitoring === MonitoringMode.QUIET) {
if (preferences.monitoring === MonitoringMode.Quiet) {
Timber.v("message suppressed by monitoring settings: ${preferences.monitoring}")
} else {
publishTransitionMessage(waypointModel, location, transition, trigger)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,10 @@ class OngoingNotification(private val context: Context, private val initialMode:
private fun getMonitoringLabel(monitoringMode: MonitoringMode) =
context.run {
when (monitoringMode) {
MonitoringMode.QUIET -> getString(R.string.monitoring_quiet)
MonitoringMode.MANUAL -> getString(R.string.monitoring_manual)
MonitoringMode.SIGNIFICANT -> getString(R.string.monitoring_significant)
MonitoringMode.MOVE -> getString(R.string.monitoring_move)
MonitoringMode.Quiet -> getString(R.string.monitoring_quiet)
MonitoringMode.Manual -> getString(R.string.monitoring_manual)
MonitoringMode.Significant -> getString(R.string.monitoring_significant)
MonitoringMode.Move -> getString(R.string.monitoring_move)
}
}

Expand Down
Loading

0 comments on commit e1508fd

Please sign in to comment.