feat: Add forceEnableAll to Capabilities (#4184)

Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
James Rich 2026-01-10 20:04:07 -06:00 committed by GitHub
parent 75d8c0bdc3
commit c5c7c2b454
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 64 additions and 37 deletions

View file

@ -22,34 +22,37 @@ package org.meshtastic.core.model
* This class provides a centralized way to check if specific features are supported by the connected node's firmware.
* Add new features here to ensure consistency across the app.
*/
data class Capabilities(val firmwareVersion: String?) {
data class Capabilities(val firmwareVersion: String?, internal val forceEnableAll: Boolean = BuildConfig.DEBUG) {
private val version = firmwareVersion?.let { DeviceVersion(it) }
private fun isSupported(minVersion: String): Boolean =
forceEnableAll || (version != null && version >= DeviceVersion(minVersion))
/**
* Ability to mute notifications from specific nodes via admin messages.
*
* Note: This is currently not available in firmware but defined here for future support.
*/
val canMuteNode: Boolean
get() = version != null && version >= DeviceVersion("2.8.0")
get() = isSupported("2.8.0")
/** Ability to request neighbor information from other nodes. Supported since firmware v2.7.15. */
val canRequestNeighborInfo: Boolean
get() = version != null && version >= DeviceVersion("2.7.15")
get() = isSupported("2.7.15")
/** Ability to send verified shared contacts. Supported since firmware v2.7.12. */
val canSendVerifiedContacts: Boolean
get() = version != null && version >= DeviceVersion("2.7.12")
get() = isSupported("2.7.12")
/** Ability to toggle device telemetry globally via module config. Supported since firmware v2.7.12. */
val canToggleTelemetryEnabled: Boolean
get() = version != null && version >= DeviceVersion("2.7.12")
get() = isSupported("2.7.12")
/** Ability to toggle the 'is_unmessageable' flag in user config. Supported since firmware v2.6.9. */
val canToggleUnmessageable: Boolean
get() = version != null && version >= DeviceVersion("2.6.9")
get() = isSupported("2.6.9")
/** Support for sharing contact information via QR codes. Supported since firmware v2.6.8. */
val supportsQrCodeSharing: Boolean
get() = version != null && version >= DeviceVersion("2.6.8")
get() = isSupported("2.6.8")
}

View file

@ -22,65 +22,89 @@ import org.junit.Test
class CapabilitiesTest {
private fun caps(version: String?) = Capabilities(version, forceEnableAll = false)
@Test
fun `canMuteNode requires v2 8 0`() {
assertFalse(Capabilities("2.7.15").canMuteNode)
assertFalse(Capabilities("2.7.99").canMuteNode)
assertTrue(Capabilities("2.8.0").canMuteNode)
assertTrue(Capabilities("2.8.1").canMuteNode)
assertFalse(caps("2.7.15").canMuteNode)
assertFalse(caps("2.7.99").canMuteNode)
assertTrue(caps("2.8.0").canMuteNode)
assertTrue(caps("2.8.1").canMuteNode)
}
@Test
fun `canRequestNeighborInfo requires v2 7 15`() {
assertFalse(Capabilities("2.7.14").canRequestNeighborInfo)
assertTrue(Capabilities("2.7.15").canRequestNeighborInfo)
assertTrue(Capabilities("2.8.0").canRequestNeighborInfo)
assertFalse(caps("2.7.14").canRequestNeighborInfo)
assertTrue(caps("2.7.15").canRequestNeighborInfo)
assertTrue(caps("2.8.0").canRequestNeighborInfo)
}
@Test
fun `canSendVerifiedContacts requires v2 7 12`() {
assertFalse(Capabilities("2.7.11").canSendVerifiedContacts)
assertTrue(Capabilities("2.7.12").canSendVerifiedContacts)
assertTrue(Capabilities("2.7.15").canSendVerifiedContacts)
assertFalse(caps("2.7.11").canSendVerifiedContacts)
assertTrue(caps("2.7.12").canSendVerifiedContacts)
assertTrue(caps("2.7.15").canSendVerifiedContacts)
}
@Test
fun `canToggleTelemetryEnabled requires v2 7 12`() {
assertFalse(Capabilities("2.7.11").canToggleTelemetryEnabled)
assertTrue(Capabilities("2.7.12").canToggleTelemetryEnabled)
assertFalse(caps("2.7.11").canToggleTelemetryEnabled)
assertTrue(caps("2.7.12").canToggleTelemetryEnabled)
}
@Test
fun `canToggleUnmessageable requires v2 6 9`() {
assertFalse(Capabilities("2.6.8").canToggleUnmessageable)
assertTrue(Capabilities("2.6.9").canToggleUnmessageable)
assertFalse(caps("2.6.8").canToggleUnmessageable)
assertTrue(caps("2.6.9").canToggleUnmessageable)
}
@Test
fun `supportsQrCodeSharing requires v2 6 8`() {
assertFalse(Capabilities("2.6.7").supportsQrCodeSharing)
assertTrue(Capabilities("2.6.8").supportsQrCodeSharing)
assertFalse(caps("2.6.7").supportsQrCodeSharing)
assertTrue(caps("2.6.8").supportsQrCodeSharing)
}
@Test
fun `null firmware returns all false`() {
val caps = Capabilities(null)
assertFalse(caps.canMuteNode)
assertFalse(caps.canRequestNeighborInfo)
assertFalse(caps.canSendVerifiedContacts)
assertFalse(caps.canToggleTelemetryEnabled)
assertFalse(caps.canToggleUnmessageable)
assertFalse(caps.supportsQrCodeSharing)
val c = caps(null)
assertFalse(c.canMuteNode)
assertFalse(c.canRequestNeighborInfo)
assertFalse(c.canSendVerifiedContacts)
assertFalse(c.canToggleTelemetryEnabled)
assertFalse(c.canToggleUnmessageable)
assertFalse(c.supportsQrCodeSharing)
}
@Test
fun `invalid firmware returns all false`() {
val caps = Capabilities("invalid")
assertFalse(caps.canMuteNode)
assertFalse(caps.canRequestNeighborInfo)
assertFalse(caps.canSendVerifiedContacts)
assertFalse(caps.canToggleTelemetryEnabled)
assertFalse(caps.canToggleUnmessageable)
assertFalse(caps.supportsQrCodeSharing)
val c = caps("invalid")
assertFalse(c.canMuteNode)
assertFalse(c.canRequestNeighborInfo)
assertFalse(c.canSendVerifiedContacts)
assertFalse(c.canToggleTelemetryEnabled)
assertFalse(c.canToggleUnmessageable)
assertFalse(c.supportsQrCodeSharing)
}
@Test
fun `forceEnableAll returns true for everything regardless of version`() {
val c = Capabilities(firmwareVersion = null, forceEnableAll = true)
assertTrue(c.canMuteNode)
assertTrue(c.canRequestNeighborInfo)
assertTrue(c.canSendVerifiedContacts)
assertTrue(c.canToggleTelemetryEnabled)
assertTrue(c.canToggleUnmessageable)
assertTrue(c.supportsQrCodeSharing)
}
@Test
fun `forceEnableAll returns true even for invalid versions`() {
val c = Capabilities(firmwareVersion = "invalid", forceEnableAll = true)
assertTrue(c.canMuteNode)
assertTrue(c.canRequestNeighborInfo)
assertTrue(c.canSendVerifiedContacts)
assertTrue(c.canToggleTelemetryEnabled)
assertTrue(c.canToggleUnmessageable)
assertTrue(c.supportsQrCodeSharing)
}
}