fix: further fixes for fdroid json fallbacks (#3847)

This commit is contained in:
Mac DeCourcy
2025-11-28 18:00:36 -08:00
committed by GitHub
parent 5a413d07e3
commit 923624fbfa
4 changed files with 39 additions and 9 deletions

View File

@@ -31,7 +31,8 @@ import javax.inject.Inject
class FdroidPlatformAnalytics @Inject constructor() : PlatformAnalytics {
init {
// For F-Droid builds we don't initialize external analytics services.
// In debug builds we attach a DebugTree for convenient local logging.
// In debug builds we attach a DebugTree for convenient local logging, but
// release builds rely on system logging only.
if (BuildConfig.DEBUG) {
Timber.plant(Timber.DebugTree())
Timber.i("F-Droid platform no-op analytics initialized (DebugTree planted).")

View File

@@ -25,9 +25,18 @@ import org.meshtastic.core.model.NetworkDeviceHardware
import javax.inject.Inject
class DeviceHardwareJsonDataSource @Inject constructor(private val application: Application) {
// Use a tolerant JSON parser so that additional fields in the bundled asset
// (e.g., "key") do not break deserialization on older app versions.
@OptIn(ExperimentalSerializationApi::class)
fun loadDeviceHardwareFromJsonAsset(): List<NetworkDeviceHardware> {
val inputStream = application.assets.open("device_hardware.json")
return Json.decodeFromStream<List<NetworkDeviceHardware>>(inputStream)
private val json = Json {
ignoreUnknownKeys = true
isLenient = true
}
@OptIn(ExperimentalSerializationApi::class)
fun loadDeviceHardwareFromJsonAsset(): List<NetworkDeviceHardware> =
application.assets.open("device_hardware.json").use { inputStream ->
json.decodeFromStream<List<NetworkDeviceHardware>>(inputStream)
}
}

View File

@@ -25,10 +25,18 @@ import org.meshtastic.core.model.NetworkFirmwareReleases
import javax.inject.Inject
class FirmwareReleaseJsonDataSource @Inject constructor(private val application: Application) {
// Match the network client behavior: be tolerant of unknown fields so that
// older app versions can read newer snapshots of firmware_releases.json.
@OptIn(ExperimentalSerializationApi::class)
fun loadFirmwareReleaseFromJsonAsset(): NetworkFirmwareReleases {
val inputStream = application.assets.open("firmware_releases.json")
val result = inputStream.use { Json.decodeFromStream<NetworkFirmwareReleases>(inputStream) }
return result
private val json = Json {
ignoreUnknownKeys = true
isLenient = true
}
@OptIn(ExperimentalSerializationApi::class)
fun loadFirmwareReleaseFromJsonAsset(): NetworkFirmwareReleases =
application.assets.open("firmware_releases.json").use { inputStream ->
json.decodeFromStream<NetworkFirmwareReleases>(inputStream)
}
}

View File

@@ -123,7 +123,10 @@ constructor(
private suspend fun loadFromBundledJson(hwModel: Int): Result<DeviceHardware?> = runCatching {
Timber.d("DeviceHardwareRepository: loading device hardware from bundled JSON for hwModel=%d", hwModel)
val jsonHardware = jsonDataSource.loadDeviceHardwareFromJsonAsset()
Timber.d("DeviceHardwareRepository: bundled JSON returned %d device hardware entries", jsonHardware.size)
Timber.d(
"DeviceHardwareRepository: bundled JSON returned %d device hardware entries",
jsonHardware.size,
)
localDataSource.insertAllDeviceHardware(jsonHardware)
val fromDb = localDataSource.getByHwModel(hwModel)?.asExternalModel()
@@ -134,6 +137,15 @@ constructor(
)
fromDb
}
.also { result ->
result.exceptionOrNull()?.let { e ->
Timber.e(
e,
"DeviceHardwareRepository: failed to load device hardware from bundled JSON for hwModel=%d",
hwModel,
)
}
}
/** Returns true if the cached entity is missing important fields and should be refreshed. */
private fun DeviceHardwareEntity.isIncomplete(): Boolean =