feat(service): Introduce fallback worker to ensure service stays alive (#4295)

Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
James Rich 2026-01-24 20:25:09 -06:00 committed by GitHub
parent bd4cb80877
commit 576ae6757f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 144 additions and 26 deletions

View file

@ -57,6 +57,7 @@ import com.google.firebase.crashlytics.setCustomKeys
import com.google.firebase.initialize
import dagger.hilt.android.qualifiers.ApplicationContext
import io.opentelemetry.api.GlobalOpenTelemetry
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import org.meshtastic.core.analytics.BuildConfig
@ -233,16 +234,22 @@ constructor(
override fun log(severity: Severity, message: String, tag: String, throwable: Throwable?) {
if (!Firebase.crashlytics.isCrashlyticsCollectionEnabled) return
Firebase.crashlytics.setCustomKeys {
key(KEY_PRIORITY, severity.ordinal)
key(KEY_TAG, tag)
key(KEY_MESSAGE, message)
}
// Add the log to the Crashlytics log buffer so it appears in reports
Firebase.crashlytics.log("$severity/$tag: $message")
if (throwable == null) {
Firebase.crashlytics.recordException(Exception(message))
} else {
// Filter out normal coroutine cancellations
if (throwable is CancellationException) return
// Only record non-fatal exceptions for actual Errors (or if a throwable is provided)
if (throwable != null) {
Firebase.crashlytics.recordException(throwable)
} else if (severity >= Severity.Error) {
Firebase.crashlytics.setCustomKeys {
key(KEY_PRIORITY, severity.ordinal)
key(KEY_TAG, tag)
key(KEY_MESSAGE, message)
}
Firebase.crashlytics.recordException(Exception(message))
}
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2025 Meshtastic LLC
* Copyright (c) 2025-2026 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -14,7 +14,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package org.meshtastic.core.datastore
import androidx.datastore.core.DataStore
@ -53,7 +52,8 @@ class LocalConfigDataSource @Inject constructor(private val localConfigStore: Da
if (localField != null) {
builder.setField(localField, value)
} else {
Logger.e { "Error writing LocalConfig settings: ${config.payloadVariantCase}" }
// Some fields like SESSIONKEY are not intended to be persisted in LocalConfig
Logger.d { "Skipping non-persistent LocalConfig field: ${field.name}" }
}
}
builder.build()