refactor: combine config data stores into `RadioConfigRepository` (#636)

master
Andre K 2023-05-20 11:42:15 -03:00 zatwierdzone przez GitHub
rodzic a4baa93f4e
commit a2388d1d12
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
6 zmienionych plików z 111 dodań i 70 usunięć

Wyświetl plik

@ -27,9 +27,7 @@ import com.geeksville.mesh.LocalOnlyProtos.LocalConfig
import com.geeksville.mesh.LocalOnlyProtos.LocalModuleConfig import com.geeksville.mesh.LocalOnlyProtos.LocalModuleConfig
import com.geeksville.mesh.MeshProtos.User import com.geeksville.mesh.MeshProtos.User
import com.geeksville.mesh.database.PacketRepository import com.geeksville.mesh.database.PacketRepository
import com.geeksville.mesh.repository.datastore.ChannelSetRepository import com.geeksville.mesh.repository.datastore.RadioConfigRepository
import com.geeksville.mesh.repository.datastore.LocalConfigRepository
import com.geeksville.mesh.repository.datastore.ModuleConfigRepository
import com.geeksville.mesh.service.MeshService import com.geeksville.mesh.service.MeshService
import com.geeksville.mesh.util.GPSFormat import com.geeksville.mesh.util.GPSFormat
import com.geeksville.mesh.util.positionToMeter import com.geeksville.mesh.util.positionToMeter
@ -87,11 +85,9 @@ fun getInitials(nameIn: String): String {
@HiltViewModel @HiltViewModel
class UIViewModel @Inject constructor( class UIViewModel @Inject constructor(
private val app: Application, private val app: Application,
radioConfigRepository: RadioConfigRepository,
private val meshLogRepository: MeshLogRepository, private val meshLogRepository: MeshLogRepository,
private val channelSetRepository: ChannelSetRepository,
private val packetRepository: PacketRepository, private val packetRepository: PacketRepository,
private val localConfigRepository: LocalConfigRepository,
private val moduleConfigRepository: ModuleConfigRepository,
private val quickChatActionRepository: QuickChatActionRepository, private val quickChatActionRepository: QuickChatActionRepository,
private val preferences: SharedPreferences private val preferences: SharedPreferences
) : ViewModel(), Logging { ) : ViewModel(), Logging {
@ -138,10 +134,10 @@ class UIViewModel @Inject constructor(
_packets.value = packets _packets.value = packets
} }
} }
localConfigRepository.localConfigFlow.onEach { config -> radioConfigRepository.localConfigFlow.onEach { config ->
_localConfig.value = config _localConfig.value = config
}.launchIn(viewModelScope) }.launchIn(viewModelScope)
moduleConfigRepository.moduleConfigFlow.onEach { config -> radioConfigRepository.moduleConfigFlow.onEach { config ->
_moduleConfig.value = config _moduleConfig.value = config
}.launchIn(viewModelScope) }.launchIn(viewModelScope)
viewModelScope.launch { viewModelScope.launch {
@ -149,7 +145,7 @@ class UIViewModel @Inject constructor(
_quickChatActions.value = actions _quickChatActions.value = actions
} }
} }
channelSetRepository.channelSetFlow.onEach { channelSet -> radioConfigRepository.channelSetFlow.onEach { channelSet ->
_channels.value = ChannelSet(channelSet) _channels.value = ChannelSet(channelSet)
}.launchIn(viewModelScope) }.launchIn(viewModelScope)
combine(nodeDB.nodes.asFlow(), nodeDB.myId.asFlow()) { nodes, id -> nodes[id] }.onEach { combine(nodeDB.nodes.asFlow(), nodeDB.myId.asFlow()) { nodes, id -> nodes[id] }.onEach {
@ -473,11 +469,6 @@ class UIViewModel @Inject constructor(
meshService?.setChannel(it.toByteArray()) meshService?.setChannel(it.toByteArray())
} }
viewModelScope.launch {
channelSetRepository.clearSettings()
channelSetRepository.addAllSettings(value)
}
val newConfig = config { lora = value.loraConfig } val newConfig = config { lora = value.loraConfig }
if (config.lora != newConfig.lora) setConfig(newConfig) if (config.lora != newConfig.lora) setConfig(newConfig)
} }

Wyświetl plik

@ -3,7 +3,8 @@ package com.geeksville.mesh.repository.datastore
import androidx.datastore.core.DataStore import androidx.datastore.core.DataStore
import com.geeksville.mesh.android.Logging import com.geeksville.mesh.android.Logging
import com.geeksville.mesh.AppOnlyProtos.ChannelSet import com.geeksville.mesh.AppOnlyProtos.ChannelSet
import com.geeksville.mesh.ChannelProtos import com.geeksville.mesh.ChannelProtos.Channel
import com.geeksville.mesh.ChannelProtos.ChannelSettings
import com.geeksville.mesh.ConfigProtos import com.geeksville.mesh.ConfigProtos
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.catch
@ -12,7 +13,7 @@ import java.io.IOException
import javax.inject.Inject import javax.inject.Inject
/** /**
* Class that handles saving and retrieving channel settings * Class that handles saving and retrieving [ChannelSet] data.
*/ */
class ChannelSetRepository @Inject constructor( class ChannelSetRepository @Inject constructor(
private val channelSetStore: DataStore<ChannelSet> private val channelSetStore: DataStore<ChannelSet>
@ -34,20 +35,14 @@ class ChannelSetRepository @Inject constructor(
} }
} }
suspend fun clearSettings() {
channelSetStore.updateData { preference ->
preference.toBuilder().clearSettings().build()
}
}
/** /**
* Updates the ChannelSettings list with the provided channel and returns the index of the * Updates the [ChannelSettings] list with the provided channel and returns the index of the
* admin channel after the update (if not found, returns 0). * admin channel after the update (if not found, returns 0).
*/ */
suspend fun updateChannelSettings(channel: ChannelProtos.Channel): Int { suspend fun updateChannelSettings(channel: Channel): Int {
channelSetStore.updateData { preference -> channelSetStore.updateData { preference ->
if (preference.settingsCount > channel.index) { if (preference.settingsCount > channel.index) {
if (channel.role == ChannelProtos.Channel.Role.DISABLED) { if (channel.role == Channel.Role.DISABLED) {
preference.toBuilder().removeSettings(channel.index).build() preference.toBuilder().removeSettings(channel.index).build()
} else { } else {
preference.toBuilder().setSettings(channel.index, channel.settings).build() preference.toBuilder().setSettings(channel.index, channel.settings).build()
@ -59,12 +54,6 @@ class ChannelSetRepository @Inject constructor(
return getAdminChannel() return getAdminChannel()
} }
suspend fun addAllSettings(channelSet: ChannelSet) {
channelSetStore.updateData { preference ->
preference.toBuilder().addAllSettings(channelSet.settingsList).build()
}
}
suspend fun setLoraConfig(config: ConfigProtos.Config.LoRaConfig) { suspend fun setLoraConfig(config: ConfigProtos.Config.LoRaConfig) {
channelSetStore.updateData { preference -> channelSetStore.updateData { preference ->
preference.toBuilder().setLoraConfig(config).build() preference.toBuilder().setLoraConfig(config).build()

Wyświetl plik

@ -5,19 +5,16 @@ import com.geeksville.mesh.android.Logging
import com.geeksville.mesh.ConfigProtos.Config import com.geeksville.mesh.ConfigProtos.Config
import com.geeksville.mesh.LocalOnlyProtos.LocalConfig import com.geeksville.mesh.LocalOnlyProtos.LocalConfig
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import java.io.IOException import java.io.IOException
import javax.inject.Inject import javax.inject.Inject
/** /**
* Class that handles saving and retrieving config settings * Class that handles saving and retrieving [LocalConfig] data.
*/ */
class LocalConfigRepository @Inject constructor( class LocalConfigRepository @Inject constructor(
private val localConfigStore: DataStore<LocalConfig>, private val localConfigStore: DataStore<LocalConfig>,
private val channelSetRepository: ChannelSetRepository,
) : Logging { ) : Logging {
val localConfigFlow: Flow<LocalConfig> = localConfigStore.data val localConfigFlow: Flow<LocalConfig> = localConfigStore.data
.catch { exception -> .catch { exception ->
@ -30,17 +27,6 @@ class LocalConfigRepository @Inject constructor(
} }
} }
private val _setConfigFlow = MutableSharedFlow<Config>()
val setConfigFlow: SharedFlow<Config> = _setConfigFlow
/**
* Update LocalConfig and send ConfigProtos.Config Oneof to the radio
*/
suspend fun setConfig(config: Config) {
setLocalConfig(config)
_setConfigFlow.emit(config)
}
suspend fun clearLocalConfig() { suspend fun clearLocalConfig() {
localConfigStore.updateData { preference -> localConfigStore.updateData { preference ->
preference.toBuilder().clear().build() preference.toBuilder().clear().build()
@ -48,7 +34,7 @@ class LocalConfigRepository @Inject constructor(
} }
/** /**
* Update LocalConfig from each ConfigProtos.Config Oneof * Updates [LocalConfig] from each [Config] oneOf.
*/ */
suspend fun setLocalConfig(config: Config) { suspend fun setLocalConfig(config: Config) {
if (config.hasDevice()) setDeviceConfig(config.device) if (config.hasDevice()) setDeviceConfig(config.device)
@ -94,7 +80,6 @@ class LocalConfigRepository @Inject constructor(
localConfigStore.updateData { preference -> localConfigStore.updateData { preference ->
preference.toBuilder().setLora(config).build() preference.toBuilder().setLora(config).build()
} }
channelSetRepository.setLoraConfig(config)
} }
private suspend fun setBluetoothConfig(config: Config.BluetoothConfig) { private suspend fun setBluetoothConfig(config: Config.BluetoothConfig) {

Wyświetl plik

@ -11,7 +11,7 @@ import java.io.IOException
import javax.inject.Inject import javax.inject.Inject
/** /**
* Class that handles saving and retrieving config settings * Class that handles saving and retrieving [LocalModuleConfig] data.
*/ */
class ModuleConfigRepository @Inject constructor( class ModuleConfigRepository @Inject constructor(
private val moduleConfigStore: DataStore<LocalModuleConfig>, private val moduleConfigStore: DataStore<LocalModuleConfig>,
@ -34,7 +34,7 @@ class ModuleConfigRepository @Inject constructor(
} }
/** /**
* Update LocalModuleConfig from each ModuleConfigProtos.ModuleConfig Oneof * Updates [LocalModuleConfig] from each [ModuleConfig] oneOf.
*/ */
suspend fun setLocalModuleConfig(config: ModuleConfig) { suspend fun setLocalModuleConfig(config: ModuleConfig) {
if (config.hasMqtt()) setMQTTConfig(config.mqtt) if (config.hasMqtt()) setMQTTConfig(config.mqtt)

Wyświetl plik

@ -0,0 +1,84 @@
package com.geeksville.mesh.repository.datastore
import com.geeksville.mesh.AppOnlyProtos.ChannelSet
import com.geeksville.mesh.ChannelProtos.Channel
import com.geeksville.mesh.ChannelProtos.ChannelSettings
import com.geeksville.mesh.ConfigProtos.Config
import com.geeksville.mesh.LocalOnlyProtos.LocalConfig
import com.geeksville.mesh.LocalOnlyProtos.LocalModuleConfig
import com.geeksville.mesh.ModuleConfigProtos.ModuleConfig
import kotlinx.coroutines.flow.Flow
import javax.inject.Inject
/**
* Class responsible for radio configuration data.
* Combines access to [ChannelSet], [LocalConfig] & [LocalModuleConfig] data stores.
*/
class RadioConfigRepository @Inject constructor(
private val channelSetRepository: ChannelSetRepository,
private val localConfigRepository: LocalConfigRepository,
private val moduleConfigRepository: ModuleConfigRepository,
) {
/**
* Flow representing the [ChannelSet] data store.
*/
val channelSetFlow: Flow<ChannelSet> = channelSetRepository.channelSetFlow
/**
* Clears the [ChannelSet] data in the data store.
*/
suspend fun clearChannelSet() {
channelSetRepository.clearChannelSet()
}
/**
* Updates the [ChannelSettings] list with the provided channel and returns the index of the
* admin channel after the update (if not found, returns 0).
* @param channel The [Channel] provided.
* @return the index of the admin channel after the update (if not found, returns 0).
*/
suspend fun updateChannelSettings(channel: Channel): Int {
return channelSetRepository.updateChannelSettings(channel)
}
/**
* Flow representing the [LocalConfig] data store.
*/
val localConfigFlow: Flow<LocalConfig> = localConfigRepository.localConfigFlow
/**
* Clears the [LocalConfig] data in the data store.
*/
suspend fun clearLocalConfig() {
localConfigRepository.clearLocalConfig()
}
/**
* Updates [LocalConfig] from each [Config] oneOf.
* @param config The [Config] to be set.
*/
suspend fun setLocalConfig(config: Config) {
localConfigRepository.setLocalConfig(config)
if (config.hasLora()) channelSetRepository.setLoraConfig(config.lora)
}
/**
* Flow representing the [LocalModuleConfig] data store.
*/
val moduleConfigFlow: Flow<LocalModuleConfig> = moduleConfigRepository.moduleConfigFlow
/**
* Clears the [LocalModuleConfig] data in the data store.
*/
suspend fun clearLocalModuleConfig() {
moduleConfigRepository.clearLocalModuleConfig()
}
/**
* Updates [LocalModuleConfig] from each [ModuleConfig] oneOf.
* @param config The [ModuleConfig] to be set.
*/
suspend fun setLocalModuleConfig(config: ModuleConfig) {
moduleConfigRepository.setLocalModuleConfig(config)
}
}

Wyświetl plik

@ -21,9 +21,7 @@ import com.geeksville.mesh.database.PacketRepository
import com.geeksville.mesh.database.entity.MeshLog import com.geeksville.mesh.database.entity.MeshLog
import com.geeksville.mesh.database.entity.Packet import com.geeksville.mesh.database.entity.Packet
import com.geeksville.mesh.model.DeviceVersion import com.geeksville.mesh.model.DeviceVersion
import com.geeksville.mesh.repository.datastore.ChannelSetRepository import com.geeksville.mesh.repository.datastore.RadioConfigRepository
import com.geeksville.mesh.repository.datastore.LocalConfigRepository
import com.geeksville.mesh.repository.datastore.ModuleConfigRepository
import com.geeksville.mesh.repository.location.LocationRepository import com.geeksville.mesh.repository.location.LocationRepository
import com.geeksville.mesh.repository.radio.BluetoothInterface import com.geeksville.mesh.repository.radio.BluetoothInterface
import com.geeksville.mesh.repository.radio.RadioInterfaceService import com.geeksville.mesh.repository.radio.RadioInterfaceService
@ -75,13 +73,7 @@ class MeshService : Service(), Logging {
lateinit var locationRepository: LocationRepository lateinit var locationRepository: LocationRepository
@Inject @Inject
lateinit var localConfigRepository: LocalConfigRepository lateinit var radioConfigRepository: RadioConfigRepository
@Inject
lateinit var moduleConfigRepository: ModuleConfigRepository
@Inject
lateinit var channelSetRepository: ChannelSetRepository
companion object : Logging { companion object : Logging {
@ -250,9 +242,9 @@ class MeshService : Service(), Logging {
.launchIn(serviceScope) .launchIn(serviceScope)
radioInterfaceService.receivedData.onEach(::onReceiveFromRadio) radioInterfaceService.receivedData.onEach(::onReceiveFromRadio)
.launchIn(serviceScope) .launchIn(serviceScope)
localConfigRepository.localConfigFlow.onEach { localConfig = it } radioConfigRepository.localConfigFlow.onEach { localConfig = it }
.launchIn(serviceScope) .launchIn(serviceScope)
channelSetRepository.channelSetFlow.onEach { channelSet = it } radioConfigRepository.channelSetFlow.onEach { channelSet = it }
.launchIn(serviceScope) .launchIn(serviceScope)
// the rest of our init will happen once we are in radioConnection.onServiceConnected // the rest of our init will happen once we are in radioConnection.onServiceConnected
@ -948,25 +940,25 @@ class MeshService : Service(), Logging {
private fun setLocalConfig(config: ConfigProtos.Config) { private fun setLocalConfig(config: ConfigProtos.Config) {
serviceScope.handledLaunch { serviceScope.handledLaunch {
localConfigRepository.setLocalConfig(config) radioConfigRepository.setLocalConfig(config)
} }
} }
private fun setLocalModuleConfig(config: ModuleConfigProtos.ModuleConfig) { private fun setLocalModuleConfig(config: ModuleConfigProtos.ModuleConfig) {
serviceScope.handledLaunch { serviceScope.handledLaunch {
moduleConfigRepository.setLocalModuleConfig(config) radioConfigRepository.setLocalModuleConfig(config)
} }
} }
private fun clearLocalConfig() { private fun clearLocalConfig() {
serviceScope.handledLaunch { serviceScope.handledLaunch {
localConfigRepository.clearLocalConfig() radioConfigRepository.clearLocalConfig()
moduleConfigRepository.clearLocalModuleConfig() radioConfigRepository.clearLocalModuleConfig()
} }
} }
private fun updateChannelSettings(ch: ChannelProtos.Channel) = serviceScope.handledLaunch { private fun updateChannelSettings(ch: ChannelProtos.Channel) = serviceScope.handledLaunch {
adminChannelIndex = channelSetRepository.updateChannelSettings(ch) adminChannelIndex = radioConfigRepository.updateChannelSettings(ch)
} }
private fun currentSecond() = (System.currentTimeMillis() / 1000).toInt() private fun currentSecond() = (System.currentTimeMillis() / 1000).toInt()
@ -1338,9 +1330,9 @@ class MeshService : Service(), Logging {
// We'll need to get a new set of channels and settings now // We'll need to get a new set of channels and settings now
serviceScope.handledLaunch { serviceScope.handledLaunch {
channelSetRepository.clearChannelSet() radioConfigRepository.clearChannelSet()
localConfigRepository.clearLocalConfig() radioConfigRepository.clearLocalConfig()
moduleConfigRepository.clearLocalModuleConfig() radioConfigRepository.clearLocalModuleConfig()
} }
} }