mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
add ModuleConfig settings (#526)
This commit is contained in:
parent
36cb78a332
commit
689e7e7eca
25 changed files with 938 additions and 74 deletions
|
|
@ -7,6 +7,7 @@ import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler
|
|||
import androidx.datastore.dataStoreFile
|
||||
import com.geeksville.mesh.AppOnlyProtos.ChannelSet
|
||||
import com.geeksville.mesh.LocalOnlyProtos.LocalConfig
|
||||
import com.geeksville.mesh.LocalOnlyProtos.LocalModuleConfig
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
|
|
@ -34,6 +35,19 @@ object DataStoreModule {
|
|||
)
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideModuleConfigDataStore(@ApplicationContext appContext: Context): DataStore<LocalModuleConfig> {
|
||||
return DataStoreFactory.create(
|
||||
serializer = ModuleConfigSerializer,
|
||||
produceFile = { appContext.dataStoreFile("module_config.pb") },
|
||||
corruptionHandler = ReplaceFileCorruptionHandler(
|
||||
produceNewData = { LocalModuleConfig.getDefaultInstance() }
|
||||
),
|
||||
scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
|
||||
)
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
fun provideChannelSetDataStore(@ApplicationContext appContext: Context): DataStore<ChannelSet> {
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@ package com.geeksville.mesh.repository.datastore
|
|||
|
||||
import androidx.datastore.core.DataStore
|
||||
import com.geeksville.mesh.android.Logging
|
||||
import com.geeksville.mesh.ConfigProtos
|
||||
import com.geeksville.mesh.ConfigProtos.Config
|
||||
import com.geeksville.mesh.LocalOnlyProtos.LocalConfig
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.asSharedFlow
|
||||
import java.io.IOException
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -30,20 +30,15 @@ class LocalConfigRepository @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private val _sendDeviceConfigFlow = MutableSharedFlow<ConfigProtos.Config>()
|
||||
val sendDeviceConfigFlow = _sendDeviceConfigFlow.asSharedFlow()
|
||||
|
||||
private suspend fun sendDeviceConfig(config: ConfigProtos.Config) {
|
||||
debug("Sending device config!")
|
||||
_sendDeviceConfigFlow.emit(config)
|
||||
}
|
||||
private val _setConfigFlow = MutableSharedFlow<Config>()
|
||||
val setConfigFlow: SharedFlow<Config> = _setConfigFlow
|
||||
|
||||
/**
|
||||
* Update LocalConfig and send ConfigProtos.Config Oneof to the radio
|
||||
*/
|
||||
suspend fun setRadioConfig(config: ConfigProtos.Config) {
|
||||
suspend fun setConfig(config: Config) {
|
||||
setLocalConfig(config)
|
||||
sendDeviceConfig(config)
|
||||
_setConfigFlow.emit(config)
|
||||
}
|
||||
|
||||
suspend fun clearLocalConfig() {
|
||||
|
|
@ -55,7 +50,7 @@ class LocalConfigRepository @Inject constructor(
|
|||
/**
|
||||
* Update LocalConfig from each ConfigProtos.Config Oneof
|
||||
*/
|
||||
suspend fun setLocalConfig(config: ConfigProtos.Config) {
|
||||
suspend fun setLocalConfig(config: Config) {
|
||||
if (config.hasDevice()) setDeviceConfig(config.device)
|
||||
if (config.hasPosition()) setPositionConfig(config.position)
|
||||
if (config.hasPower()) setPowerConfig(config.power)
|
||||
|
|
@ -65,44 +60,44 @@ class LocalConfigRepository @Inject constructor(
|
|||
if (config.hasBluetooth()) setBluetoothConfig(config.bluetooth)
|
||||
}
|
||||
|
||||
private suspend fun setDeviceConfig(config: ConfigProtos.Config.DeviceConfig) {
|
||||
private suspend fun setDeviceConfig(config: Config.DeviceConfig) {
|
||||
localConfigStore.updateData { preference ->
|
||||
preference.toBuilder().setDevice(config).build()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun setPositionConfig(config: ConfigProtos.Config.PositionConfig) {
|
||||
private suspend fun setPositionConfig(config: Config.PositionConfig) {
|
||||
localConfigStore.updateData { preference ->
|
||||
preference.toBuilder().setPosition(config).build()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun setPowerConfig(config: ConfigProtos.Config.PowerConfig) {
|
||||
private suspend fun setPowerConfig(config: Config.PowerConfig) {
|
||||
localConfigStore.updateData { preference ->
|
||||
preference.toBuilder().setPower(config).build()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun setWifiConfig(config: ConfigProtos.Config.NetworkConfig) {
|
||||
private suspend fun setWifiConfig(config: Config.NetworkConfig) {
|
||||
localConfigStore.updateData { preference ->
|
||||
preference.toBuilder().setNetwork(config).build()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun setDisplayConfig(config: ConfigProtos.Config.DisplayConfig) {
|
||||
private suspend fun setDisplayConfig(config: Config.DisplayConfig) {
|
||||
localConfigStore.updateData { preference ->
|
||||
preference.toBuilder().setDisplay(config).build()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun setLoraConfig(config: ConfigProtos.Config.LoRaConfig) {
|
||||
private suspend fun setLoraConfig(config: Config.LoRaConfig) {
|
||||
localConfigStore.updateData { preference ->
|
||||
preference.toBuilder().setLora(config).build()
|
||||
}
|
||||
channelSetRepository.setLoraConfig(config)
|
||||
}
|
||||
|
||||
private suspend fun setBluetoothConfig(config: ConfigProtos.Config.BluetoothConfig) {
|
||||
private suspend fun setBluetoothConfig(config: Config.BluetoothConfig) {
|
||||
localConfigStore.updateData { preference ->
|
||||
preference.toBuilder().setBluetooth(config).build()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,100 @@
|
|||
package com.geeksville.mesh.repository.datastore
|
||||
|
||||
import androidx.datastore.core.DataStore
|
||||
import com.geeksville.mesh.android.Logging
|
||||
import com.geeksville.mesh.ModuleConfigProtos.ModuleConfig
|
||||
import com.geeksville.mesh.LocalOnlyProtos.LocalModuleConfig
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.first
|
||||
import java.io.IOException
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Class that handles saving and retrieving config settings
|
||||
*/
|
||||
class ModuleConfigRepository @Inject constructor(
|
||||
private val moduleConfigStore: DataStore<LocalModuleConfig>,
|
||||
) : Logging {
|
||||
val moduleConfigFlow: Flow<LocalModuleConfig> = moduleConfigStore.data
|
||||
.catch { exception ->
|
||||
// dataStore.data throws an IOException when an error is encountered when reading data
|
||||
if (exception is IOException) {
|
||||
errormsg("Error reading LocalConfig settings: ${exception.message}")
|
||||
emit(LocalModuleConfig.getDefaultInstance())
|
||||
} else {
|
||||
throw exception
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun clearLocalModuleConfig() {
|
||||
moduleConfigStore.updateData { preference ->
|
||||
preference.toBuilder().clear().build()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update LocalModuleConfig from each ModuleConfigProtos.ModuleConfig Oneof
|
||||
*/
|
||||
suspend fun setLocalModuleConfig(config: ModuleConfig) {
|
||||
if (config.hasMqtt()) setMQTTConfig(config.mqtt)
|
||||
if (config.hasSerial()) setSerialConfig(config.serial)
|
||||
if (config.hasExternalNotification()) setExternalNotificationConfig(config.externalNotification)
|
||||
if (config.hasStoreForward()) setStoreForwardConfig(config.storeForward)
|
||||
if (config.hasRangeTest()) setRangeTestConfig(config.rangeTest)
|
||||
if (config.hasTelemetry()) setTelemetryConfig(config.telemetry)
|
||||
if (config.hasCannedMessage()) setCannedMessageConfig(config.cannedMessage)
|
||||
if (config.hasAudio()) setAudioConfig(config.audio)
|
||||
}
|
||||
|
||||
private suspend fun setMQTTConfig(config: ModuleConfig.MQTTConfig) {
|
||||
moduleConfigStore.updateData { preference ->
|
||||
preference.toBuilder().setMqtt(config).build()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun setSerialConfig(config: ModuleConfig.SerialConfig) {
|
||||
moduleConfigStore.updateData { preference ->
|
||||
preference.toBuilder().setSerial(config).build()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun setExternalNotificationConfig(config: ModuleConfig.ExternalNotificationConfig) {
|
||||
moduleConfigStore.updateData { preference ->
|
||||
preference.toBuilder().setExternalNotification(config).build()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun setStoreForwardConfig(config: ModuleConfig.StoreForwardConfig) {
|
||||
moduleConfigStore.updateData { preference ->
|
||||
preference.toBuilder().setStoreForward(config).build()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun setRangeTestConfig(config: ModuleConfig.RangeTestConfig) {
|
||||
moduleConfigStore.updateData { preference ->
|
||||
preference.toBuilder().setRangeTest(config).build()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun setTelemetryConfig(config: ModuleConfig.TelemetryConfig) {
|
||||
moduleConfigStore.updateData { preference ->
|
||||
preference.toBuilder().setTelemetry(config).build()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun setCannedMessageConfig(config: ModuleConfig.CannedMessageConfig) {
|
||||
moduleConfigStore.updateData { preference ->
|
||||
preference.toBuilder().setCannedMessage(config).build()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun setAudioConfig(config: ModuleConfig.AudioConfig) {
|
||||
moduleConfigStore.updateData { preference ->
|
||||
preference.toBuilder().setAudio(config).build()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun fetchInitialModuleConfig() = moduleConfigStore.data.first()
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package com.geeksville.mesh.repository.datastore
|
||||
|
||||
import androidx.datastore.core.CorruptionException
|
||||
import androidx.datastore.core.Serializer
|
||||
import com.geeksville.mesh.LocalOnlyProtos.LocalModuleConfig
|
||||
import com.google.protobuf.InvalidProtocolBufferException
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
|
||||
/**
|
||||
* Serializer for the [LocalModuleConfig] object defined in localonly.proto.
|
||||
*/
|
||||
@Suppress("BlockingMethodInNonBlockingContext")
|
||||
object ModuleConfigSerializer : Serializer<LocalModuleConfig> {
|
||||
override val defaultValue: LocalModuleConfig = LocalModuleConfig.getDefaultInstance()
|
||||
|
||||
override suspend fun readFrom(input: InputStream): LocalModuleConfig {
|
||||
try {
|
||||
return LocalModuleConfig.parseFrom(input)
|
||||
} catch (exception: InvalidProtocolBufferException) {
|
||||
throw CorruptionException("Cannot read proto.", exception)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun writeTo(t: LocalModuleConfig, output: OutputStream) = t.writeTo(output)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue