diff --git a/app/src/main/java/com/geeksville/mesh/model/UIState.kt b/app/src/main/java/com/geeksville/mesh/model/UIState.kt index 67d56e0a..3c95963b 100644 --- a/app/src/main/java/com/geeksville/mesh/model/UIState.kt +++ b/app/src/main/java/com/geeksville/mesh/model/UIState.kt @@ -27,9 +27,7 @@ import com.geeksville.mesh.LocalOnlyProtos.LocalConfig import com.geeksville.mesh.LocalOnlyProtos.LocalModuleConfig import com.geeksville.mesh.MeshProtos.User import com.geeksville.mesh.database.PacketRepository -import com.geeksville.mesh.repository.datastore.ChannelSetRepository -import com.geeksville.mesh.repository.datastore.LocalConfigRepository -import com.geeksville.mesh.repository.datastore.ModuleConfigRepository +import com.geeksville.mesh.repository.datastore.RadioConfigRepository import com.geeksville.mesh.service.MeshService import com.geeksville.mesh.util.GPSFormat import com.geeksville.mesh.util.positionToMeter @@ -87,11 +85,9 @@ fun getInitials(nameIn: String): String { @HiltViewModel class UIViewModel @Inject constructor( private val app: Application, + radioConfigRepository: RadioConfigRepository, private val meshLogRepository: MeshLogRepository, - private val channelSetRepository: ChannelSetRepository, private val packetRepository: PacketRepository, - private val localConfigRepository: LocalConfigRepository, - private val moduleConfigRepository: ModuleConfigRepository, private val quickChatActionRepository: QuickChatActionRepository, private val preferences: SharedPreferences ) : ViewModel(), Logging { @@ -138,10 +134,10 @@ class UIViewModel @Inject constructor( _packets.value = packets } } - localConfigRepository.localConfigFlow.onEach { config -> + radioConfigRepository.localConfigFlow.onEach { config -> _localConfig.value = config }.launchIn(viewModelScope) - moduleConfigRepository.moduleConfigFlow.onEach { config -> + radioConfigRepository.moduleConfigFlow.onEach { config -> _moduleConfig.value = config }.launchIn(viewModelScope) viewModelScope.launch { @@ -149,7 +145,7 @@ class UIViewModel @Inject constructor( _quickChatActions.value = actions } } - channelSetRepository.channelSetFlow.onEach { channelSet -> + radioConfigRepository.channelSetFlow.onEach { channelSet -> _channels.value = ChannelSet(channelSet) }.launchIn(viewModelScope) combine(nodeDB.nodes.asFlow(), nodeDB.myId.asFlow()) { nodes, id -> nodes[id] }.onEach { @@ -473,11 +469,6 @@ class UIViewModel @Inject constructor( meshService?.setChannel(it.toByteArray()) } - viewModelScope.launch { - channelSetRepository.clearSettings() - channelSetRepository.addAllSettings(value) - } - val newConfig = config { lora = value.loraConfig } if (config.lora != newConfig.lora) setConfig(newConfig) } diff --git a/app/src/main/java/com/geeksville/mesh/repository/datastore/ChannelSetRepository.kt b/app/src/main/java/com/geeksville/mesh/repository/datastore/ChannelSetRepository.kt index 746fdca2..0f588ad3 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/datastore/ChannelSetRepository.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/datastore/ChannelSetRepository.kt @@ -3,7 +3,8 @@ package com.geeksville.mesh.repository.datastore import androidx.datastore.core.DataStore import com.geeksville.mesh.android.Logging 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 kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.catch @@ -12,7 +13,7 @@ import java.io.IOException import javax.inject.Inject /** - * Class that handles saving and retrieving channel settings + * Class that handles saving and retrieving [ChannelSet] data. */ class ChannelSetRepository @Inject constructor( private val channelSetStore: DataStore @@ -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). */ - suspend fun updateChannelSettings(channel: ChannelProtos.Channel): Int { + suspend fun updateChannelSettings(channel: Channel): Int { channelSetStore.updateData { preference -> if (preference.settingsCount > channel.index) { - if (channel.role == ChannelProtos.Channel.Role.DISABLED) { + if (channel.role == Channel.Role.DISABLED) { preference.toBuilder().removeSettings(channel.index).build() } else { preference.toBuilder().setSettings(channel.index, channel.settings).build() @@ -59,12 +54,6 @@ class ChannelSetRepository @Inject constructor( return getAdminChannel() } - suspend fun addAllSettings(channelSet: ChannelSet) { - channelSetStore.updateData { preference -> - preference.toBuilder().addAllSettings(channelSet.settingsList).build() - } - } - suspend fun setLoraConfig(config: ConfigProtos.Config.LoRaConfig) { channelSetStore.updateData { preference -> preference.toBuilder().setLoraConfig(config).build() diff --git a/app/src/main/java/com/geeksville/mesh/repository/datastore/LocalConfigRepository.kt b/app/src/main/java/com/geeksville/mesh/repository/datastore/LocalConfigRepository.kt index 16fb9231..ab4d3564 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/datastore/LocalConfigRepository.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/datastore/LocalConfigRepository.kt @@ -5,19 +5,16 @@ import com.geeksville.mesh.android.Logging 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 java.io.IOException import javax.inject.Inject /** - * Class that handles saving and retrieving config settings + * Class that handles saving and retrieving [LocalConfig] data. */ class LocalConfigRepository @Inject constructor( private val localConfigStore: DataStore, - private val channelSetRepository: ChannelSetRepository, ) : Logging { val localConfigFlow: Flow = localConfigStore.data .catch { exception -> @@ -30,17 +27,6 @@ class LocalConfigRepository @Inject constructor( } } - private val _setConfigFlow = MutableSharedFlow() - val setConfigFlow: SharedFlow = _setConfigFlow - - /** - * Update LocalConfig and send ConfigProtos.Config Oneof to the radio - */ - suspend fun setConfig(config: Config) { - setLocalConfig(config) - _setConfigFlow.emit(config) - } - suspend fun clearLocalConfig() { localConfigStore.updateData { preference -> 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) { if (config.hasDevice()) setDeviceConfig(config.device) @@ -94,7 +80,6 @@ class LocalConfigRepository @Inject constructor( localConfigStore.updateData { preference -> preference.toBuilder().setLora(config).build() } - channelSetRepository.setLoraConfig(config) } private suspend fun setBluetoothConfig(config: Config.BluetoothConfig) { diff --git a/app/src/main/java/com/geeksville/mesh/repository/datastore/ModuleConfigRepository.kt b/app/src/main/java/com/geeksville/mesh/repository/datastore/ModuleConfigRepository.kt index d98103c0..33a3f819 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/datastore/ModuleConfigRepository.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/datastore/ModuleConfigRepository.kt @@ -11,7 +11,7 @@ import java.io.IOException import javax.inject.Inject /** - * Class that handles saving and retrieving config settings + * Class that handles saving and retrieving [LocalModuleConfig] data. */ class ModuleConfigRepository @Inject constructor( private val moduleConfigStore: DataStore, @@ -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) { if (config.hasMqtt()) setMQTTConfig(config.mqtt) diff --git a/app/src/main/java/com/geeksville/mesh/repository/datastore/RadioConfigRepository.kt b/app/src/main/java/com/geeksville/mesh/repository/datastore/RadioConfigRepository.kt new file mode 100644 index 00000000..2cd0810b --- /dev/null +++ b/app/src/main/java/com/geeksville/mesh/repository/datastore/RadioConfigRepository.kt @@ -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 = 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 = 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 = 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) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt index fbfbf723..4af5664c 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -21,9 +21,7 @@ import com.geeksville.mesh.database.PacketRepository import com.geeksville.mesh.database.entity.MeshLog import com.geeksville.mesh.database.entity.Packet import com.geeksville.mesh.model.DeviceVersion -import com.geeksville.mesh.repository.datastore.ChannelSetRepository -import com.geeksville.mesh.repository.datastore.LocalConfigRepository -import com.geeksville.mesh.repository.datastore.ModuleConfigRepository +import com.geeksville.mesh.repository.datastore.RadioConfigRepository import com.geeksville.mesh.repository.location.LocationRepository import com.geeksville.mesh.repository.radio.BluetoothInterface import com.geeksville.mesh.repository.radio.RadioInterfaceService @@ -75,13 +73,7 @@ class MeshService : Service(), Logging { lateinit var locationRepository: LocationRepository @Inject - lateinit var localConfigRepository: LocalConfigRepository - - @Inject - lateinit var moduleConfigRepository: ModuleConfigRepository - - @Inject - lateinit var channelSetRepository: ChannelSetRepository + lateinit var radioConfigRepository: RadioConfigRepository companion object : Logging { @@ -250,9 +242,9 @@ class MeshService : Service(), Logging { .launchIn(serviceScope) radioInterfaceService.receivedData.onEach(::onReceiveFromRadio) .launchIn(serviceScope) - localConfigRepository.localConfigFlow.onEach { localConfig = it } + radioConfigRepository.localConfigFlow.onEach { localConfig = it } .launchIn(serviceScope) - channelSetRepository.channelSetFlow.onEach { channelSet = it } + radioConfigRepository.channelSetFlow.onEach { channelSet = it } .launchIn(serviceScope) // 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) { serviceScope.handledLaunch { - localConfigRepository.setLocalConfig(config) + radioConfigRepository.setLocalConfig(config) } } private fun setLocalModuleConfig(config: ModuleConfigProtos.ModuleConfig) { serviceScope.handledLaunch { - moduleConfigRepository.setLocalModuleConfig(config) + radioConfigRepository.setLocalModuleConfig(config) } } private fun clearLocalConfig() { serviceScope.handledLaunch { - localConfigRepository.clearLocalConfig() - moduleConfigRepository.clearLocalModuleConfig() + radioConfigRepository.clearLocalConfig() + radioConfigRepository.clearLocalModuleConfig() } } private fun updateChannelSettings(ch: ChannelProtos.Channel) = serviceScope.handledLaunch { - adminChannelIndex = channelSetRepository.updateChannelSettings(ch) + adminChannelIndex = radioConfigRepository.updateChannelSettings(ch) } 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 serviceScope.handledLaunch { - channelSetRepository.clearChannelSet() - localConfigRepository.clearLocalConfig() - moduleConfigRepository.clearLocalModuleConfig() + radioConfigRepository.clearChannelSet() + radioConfigRepository.clearLocalConfig() + radioConfigRepository.clearLocalModuleConfig() } }