fix(aprs): keep enabled switch consistent with actual service state

AprsForegroundService refuses to run when callsign is blank and calls
stopSelf(), but it never writes enabled=false back to AprsStore. AprsCard did
the opposite: toggling Enable first persisted enabled=true, then started the
service. On a fresh install with no callsign this produced a permanent lie:

  UI switch: ON   SharedPreferences: enabled=true   service: stopped

Leaving and reopening settings still showed ON even though APRS had never sent
a packet. Startup/restore code could then repeatedly try to launch a service
that immediately stops itself.

There were two entry paths with the same root cause:
1. Turning the switch on before entering a callsign.
2. Erasing an existing callsign in the dialog while APRS was already enabled.

The switch now opens the configuration dialog without persisting or starting
anything when callsign is blank. Saving the dialog also forces enabled=false
when the callsign was erased.

State-machine simulation: old state ends ON/stopped; both fixed paths end in a
consistent OFF/stopped state. :feature:settings:compileReleaseKotlin and full
:core:domain:test BUILD SUCCESSFUL.
This commit is contained in:
mckero committed 2026-08-14 16:10:18 +00:00
1 parent d5230b3bc6
commit a7a6d70d40
1 file changed
+13
@@ -82,6 +82,14 @@ fun AprsCard() {
}
// Enable switch
AprsSwitchRow(R.string.prefs_aprs_enable, config.enabled) { enabled ->
// The service refuses to run without a callsign (it toasts and
// calls stopSelf), but it never writes enabled=false back. Saving
// enabled=true here would leave the switch stuck on while nothing
// is reporting, so send the user to the settings dialog instead.
if (enabled && config.callsign.isBlank()) {
showDialog = true
return@AprsSwitchRow
}
config = config.copy(enabled = enabled)
AprsStore.saveConfig(context, config)
if (enabled) requestNotifPermissionIfNeeded()
@@ -283,6 +291,11 @@ private fun AprsSettingsDialog(
TextButton(onClick = {
onSave(
config.copy(
// A configuration with no callsign cannot be enabled:
// AprsForegroundService rejects it immediately. Persisting
// enabled=true here would recreate the same "switch on,
// service stopped" state when an existing callsign is erased.
enabled = config.enabled && callsign.trim().isNotBlank(),
server = server.ifBlank { "euro.aprs2.net" },
port = port.toIntOrNull() ?: 14580,
callsign = callsign.trim().uppercase(),