From 8317b704ea030f834417a7d0e0a2762161d03ee7 Mon Sep 17 00:00:00 2001 From: Phil Oliver <3497406+poliver@users.noreply.github.com> Date: Thu, 25 Sep 2025 09:57:26 -0400 Subject: [PATCH] Redundant methods in `RadioConfigRepository` (#3198) --- .../geeksville/mesh/ui/map/MapViewModel.kt | 6 +- .../geeksville/mesh/ui/map/MapViewModel.kt | 4 +- .../geeksville/mesh/model/DebugViewModel.kt | 6 +- .../geeksville/mesh/model/MetricsViewModel.kt | 12 +- .../java/com/geeksville/mesh/model/UIState.kt | 31 +++--- .../datastore/RadioConfigRepository.kt | 104 ------------------ .../mesh/repository/network/MQTTRepository.kt | 10 +- .../geeksville/mesh/service/MeshService.kt | 49 +++++---- .../ui/connections/ConnectionsViewModel.kt | 4 +- .../mesh/ui/map/BaseMapViewModel.kt | 6 +- .../mesh/ui/settings/SettingsViewModel.kt | 9 +- .../radio/CleanNodeDatabaseViewModel.kt | 6 +- .../ui/settings/radio/RadioConfigViewModel.kt | 21 ++-- 13 files changed, 97 insertions(+), 171 deletions(-) diff --git a/app/src/fdroid/java/com/geeksville/mesh/ui/map/MapViewModel.kt b/app/src/fdroid/java/com/geeksville/mesh/ui/map/MapViewModel.kt index 79060fbc5..a92702834 100644 --- a/app/src/fdroid/java/com/geeksville/mesh/ui/map/MapViewModel.kt +++ b/app/src/fdroid/java/com/geeksville/mesh/ui/map/MapViewModel.kt @@ -19,7 +19,7 @@ package com.geeksville.mesh.ui.map import com.geeksville.mesh.database.NodeRepository import com.geeksville.mesh.database.PacketRepository -import com.geeksville.mesh.repository.datastore.RadioConfigRepository +import com.geeksville.mesh.service.ServiceRepository import dagger.hilt.android.lifecycle.HiltViewModel import org.meshtastic.core.prefs.map.MapPrefs import javax.inject.Inject @@ -31,8 +31,8 @@ constructor( mapPrefs: MapPrefs, packetRepository: PacketRepository, nodeRepository: NodeRepository, - radioConfigRepository: RadioConfigRepository, -) : BaseMapViewModel(mapPrefs, nodeRepository, packetRepository, radioConfigRepository) { + serviceRepository: ServiceRepository, +) : BaseMapViewModel(mapPrefs, nodeRepository, packetRepository, serviceRepository) { var mapStyleId: Int get() = mapPrefs.mapStyle diff --git a/app/src/google/java/com/geeksville/mesh/ui/map/MapViewModel.kt b/app/src/google/java/com/geeksville/mesh/ui/map/MapViewModel.kt index bc8cc637b..880e80fbb 100644 --- a/app/src/google/java/com/geeksville/mesh/ui/map/MapViewModel.kt +++ b/app/src/google/java/com/geeksville/mesh/ui/map/MapViewModel.kt @@ -26,6 +26,7 @@ import com.geeksville.mesh.android.BuildUtils.debug import com.geeksville.mesh.database.NodeRepository import com.geeksville.mesh.database.PacketRepository import com.geeksville.mesh.repository.datastore.RadioConfigRepository +import com.geeksville.mesh.service.ServiceRepository import com.google.android.gms.maps.GoogleMap import com.google.android.gms.maps.model.TileProvider import com.google.android.gms.maps.model.UrlTileProvider @@ -85,8 +86,9 @@ constructor( nodeRepository: NodeRepository, packetRepository: PacketRepository, radioConfigRepository: RadioConfigRepository, + serviceRepository: ServiceRepository, private val customTileProviderRepository: CustomTileProviderRepository, -) : BaseMapViewModel(mapPrefs, nodeRepository, packetRepository, radioConfigRepository) { +) : BaseMapViewModel(mapPrefs, nodeRepository, packetRepository, serviceRepository) { private val _errorFlow = MutableSharedFlow() val errorFlow: SharedFlow = _errorFlow.asSharedFlow() diff --git a/app/src/main/java/com/geeksville/mesh/model/DebugViewModel.kt b/app/src/main/java/com/geeksville/mesh/model/DebugViewModel.kt index dcd5a10f1..8b0d2fcef 100644 --- a/app/src/main/java/com/geeksville/mesh/model/DebugViewModel.kt +++ b/app/src/main/java/com/geeksville/mesh/model/DebugViewModel.kt @@ -28,7 +28,7 @@ import com.geeksville.mesh.StoreAndForwardProtos import com.geeksville.mesh.TelemetryProtos import com.geeksville.mesh.android.Logging import com.geeksville.mesh.database.MeshLogRepository -import com.geeksville.mesh.repository.datastore.RadioConfigRepository +import com.geeksville.mesh.database.NodeRepository import com.geeksville.mesh.ui.debug.FilterMode import com.google.protobuf.InvalidProtocolBufferException import dagger.hilt.android.lifecycle.HiltViewModel @@ -202,7 +202,7 @@ class DebugViewModel @Inject constructor( private val meshLogRepository: MeshLogRepository, - private val radioConfigRepository: RadioConfigRepository, + private val nodeRepository: NodeRepository, ) : ViewModel(), Logging { @@ -345,7 +345,7 @@ constructor( val presetFilters: List get() = buildList { // Our address if available - radioConfigRepository.myNodeInfo.value?.myNodeNum?.let { add("!%08x".format(it)) } + nodeRepository.myNodeInfo.value?.myNodeNum?.let { add("!%08x".format(it)) } // broadcast add("!ffffffff") // decoded diff --git a/app/src/main/java/com/geeksville/mesh/model/MetricsViewModel.kt b/app/src/main/java/com/geeksville/mesh/model/MetricsViewModel.kt index 143573832..5a7e27e8e 100644 --- a/app/src/main/java/com/geeksville/mesh/model/MetricsViewModel.kt +++ b/app/src/main/java/com/geeksville/mesh/model/MetricsViewModel.kt @@ -36,10 +36,12 @@ import com.geeksville.mesh.Portnums.PortNum import com.geeksville.mesh.TelemetryProtos.Telemetry import com.geeksville.mesh.android.Logging import com.geeksville.mesh.database.MeshLogRepository +import com.geeksville.mesh.database.NodeRepository import com.geeksville.mesh.repository.api.DeviceHardwareRepository import com.geeksville.mesh.repository.api.FirmwareReleaseRepository import com.geeksville.mesh.repository.datastore.RadioConfigRepository import com.geeksville.mesh.service.ServiceAction +import com.geeksville.mesh.service.ServiceRepository import com.geeksville.mesh.util.safeNumber import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow @@ -203,7 +205,9 @@ constructor( private val app: Application, private val dispatchers: CoroutineDispatchers, private val meshLogRepository: MeshLogRepository, - private val radioConfigRepository: RadioConfigRepository, + radioConfigRepository: RadioConfigRepository, + private val serviceRepository: ServiceRepository, + private val nodeRepository: NodeRepository, private val deviceHardwareRepository: DeviceHardwareRepository, private val firmwareReleaseRepository: FirmwareReleaseRepository, private val mapPrefs: MapPrefs, @@ -233,7 +237,7 @@ constructor( return Node(num = nodeNum, user = defaultUser) } - fun getUser(nodeNum: Int) = radioConfigRepository.getUser(nodeNum) + fun getUser(nodeNum: Int) = nodeRepository.getUser(nodeNum) val tileSource get() = CustomTileSource.getTileSource(mapPrefs.mapStyle) @@ -244,7 +248,7 @@ constructor( destNum?.let { meshLogRepository.deleteLogs(it, PortNum.POSITION_APP_VALUE) } } - fun onServiceAction(action: ServiceAction) = viewModelScope.launch { radioConfigRepository.onServiceAction(action) } + fun onServiceAction(action: ServiceAction) = viewModelScope.launch { serviceRepository.onServiceAction(action) } private val _state = MutableStateFlow(MetricsState.Empty) val state: StateFlow = _state @@ -257,7 +261,7 @@ constructor( init { if (destNum != null) { - radioConfigRepository.nodeDBbyNum + nodeRepository.nodeDBbyNum .mapLatest { nodes -> nodes[destNum] to nodes.keys.firstOrNull() } .distinctUntilChanged() .onEach { (node, ourNode) -> 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 80ecda051..d646d8c5e 100644 --- a/app/src/main/java/com/geeksville/mesh/model/UIState.kt +++ b/app/src/main/java/com/geeksville/mesh/model/UIState.kt @@ -53,6 +53,7 @@ import com.geeksville.mesh.repository.radio.MeshActivity import com.geeksville.mesh.repository.radio.RadioInterfaceService import com.geeksville.mesh.service.MeshServiceNotifications import com.geeksville.mesh.service.ServiceAction +import com.geeksville.mesh.service.ServiceRepository import com.geeksville.mesh.ui.node.components.NodeMenuAction import com.geeksville.mesh.util.safeNumber import dagger.hilt.android.lifecycle.HiltViewModel @@ -185,6 +186,7 @@ constructor( private val app: Application, private val nodeDB: NodeRepository, private val radioConfigRepository: RadioConfigRepository, + private val serviceRepository: ServiceRepository, radioInterfaceService: RadioInterfaceService, private val meshLogRepository: MeshLogRepository, private val deviceHardwareRepository: DeviceHardwareRepository, @@ -215,10 +217,10 @@ constructor( } .stateIn(scope = viewModelScope, started = SharingStarted.WhileSubscribed(5_000), initialValue = null) - val clientNotification: StateFlow = radioConfigRepository.clientNotification + val clientNotification: StateFlow = serviceRepository.clientNotification fun clearClientNotification(notification: MeshProtos.ClientNotification) { - radioConfigRepository.clearClientNotification() + serviceRepository.clearClientNotification() meshServiceNotifications.clearClientNotification(notification) } @@ -275,7 +277,7 @@ constructor( } val meshService: IMeshService? - get() = radioConfigRepository.meshService + get() = serviceRepository.meshService private val localConfig = MutableStateFlow(LocalConfig.getDefaultInstance()) @@ -447,13 +449,13 @@ constructor( } init { - radioConfigRepository.errorMessage + serviceRepository.errorMessage .filterNotNull() .onEach { showAlert( title = app.getString(R.string.client_notification), message = it, - onConfirm = { radioConfigRepository.clearErrorMessage() }, + onConfirm = { serviceRepository.clearErrorMessage() }, dismissable = false, ) } @@ -590,9 +592,8 @@ constructor( } } - fun sendReaction(emoji: String, replyId: Int, contactKey: String) = viewModelScope.launch { - radioConfigRepository.onServiceAction(ServiceAction.Reaction(emoji, replyId, contactKey)) - } + fun sendReaction(emoji: String, replyId: Int, contactKey: String) = + viewModelScope.launch { serviceRepository.onServiceAction(ServiceAction.Reaction(emoji, replyId, contactKey)) } private val _sharedContactRequested: MutableStateFlow = MutableStateFlow(null) val sharedContactRequested: StateFlow @@ -603,7 +604,7 @@ constructor( } fun addSharedContact(sharedContact: AdminProtos.SharedContact) = - viewModelScope.launch { radioConfigRepository.onServiceAction(ServiceAction.AddSharedContact(sharedContact)) } + viewModelScope.launch { serviceRepository.onServiceAction(ServiceAction.AddSharedContact(sharedContact)) } fun requestTraceroute(destNum: Int) { info("Requesting traceroute for '$destNum'") @@ -663,10 +664,10 @@ constructor( // Connection state to our radio device val connectionState - get() = radioConfigRepository.connectionState + get() = serviceRepository.connectionState val isConnectedStateFlow = - radioConfigRepository.connectionState + serviceRepository.connectionState .map { it.isConnected() } .stateIn(viewModelScope, SharingStarted.Eagerly, false) @@ -701,7 +702,7 @@ constructor( fun favoriteNode(node: Node) = viewModelScope.launch { try { - radioConfigRepository.onServiceAction(ServiceAction.Favorite(node)) + serviceRepository.onServiceAction(ServiceAction.Favorite(node)) } catch (ex: RemoteException) { errormsg("Favorite node error:", ex) } @@ -709,7 +710,7 @@ constructor( fun ignoreNode(node: Node) = viewModelScope.launch { try { - radioConfigRepository.onServiceAction(ServiceAction.Ignore(node)) + serviceRepository.onServiceAction(ServiceAction.Ignore(node)) } catch (ex: RemoteException) { errormsg("Ignore node error:", ex) } @@ -817,10 +818,10 @@ constructor( } val tracerouteResponse: LiveData - get() = radioConfigRepository.tracerouteResponse.asLiveData() + get() = serviceRepository.tracerouteResponse.asLiveData() fun clearTracerouteResponse() { - radioConfigRepository.clearTracerouteResponse() + serviceRepository.clearTracerouteResponse() } fun setNodeFilterText(text: String) { 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 index 6db1f4274..cf5f1f897 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/datastore/RadioConfigRepository.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/datastore/RadioConfigRepository.kt @@ -22,29 +22,14 @@ import com.geeksville.mesh.ChannelProtos.Channel import com.geeksville.mesh.ChannelProtos.ChannelSettings import com.geeksville.mesh.ClientOnlyProtos.DeviceProfile import com.geeksville.mesh.ConfigProtos.Config -import com.geeksville.mesh.IMeshService import com.geeksville.mesh.LocalOnlyProtos.LocalConfig import com.geeksville.mesh.LocalOnlyProtos.LocalModuleConfig -import com.geeksville.mesh.MeshProtos -import com.geeksville.mesh.MeshProtos.DeviceMetadata -import com.geeksville.mesh.MeshProtos.MeshPacket import com.geeksville.mesh.ModuleConfigProtos.ModuleConfig import com.geeksville.mesh.database.NodeRepository import com.geeksville.mesh.deviceProfile import com.geeksville.mesh.model.getChannelUrl -import com.geeksville.mesh.service.ConnectionState -import com.geeksville.mesh.service.ServiceAction -import com.geeksville.mesh.service.ServiceRepository -import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.SharedFlow -import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.first -import org.meshtastic.core.database.entity.MetadataEntity -import org.meshtastic.core.database.entity.MyNodeEntity -import org.meshtastic.core.database.entity.NodeEntity -import org.meshtastic.core.database.model.Node import org.meshtastic.core.datastore.ChannelSetDataSource import org.meshtastic.core.datastore.LocalConfigDataSource import org.meshtastic.core.datastore.ModuleConfigDataSource @@ -57,54 +42,11 @@ import javax.inject.Inject class RadioConfigRepository @Inject constructor( - private val serviceRepository: ServiceRepository, private val nodeDB: NodeRepository, private val channelSetDataSource: ChannelSetDataSource, private val localConfigDataSource: LocalConfigDataSource, private val moduleConfigDataSource: ModuleConfigDataSource, ) { - val meshService: IMeshService? - get() = serviceRepository.meshService - - // Connection state to our radio device - val connectionState - get() = serviceRepository.connectionState - - fun setConnectionState(state: ConnectionState) = serviceRepository.setConnectionState(state) - - /** Flow representing the unique userId of our node. */ - val myId: StateFlow - get() = nodeDB.myId - - /** Flow representing the [MyNodeEntity] database. */ - val myNodeInfo: StateFlow - get() = nodeDB.myNodeInfo - - /** Flow representing the [Node] database. */ - val nodeDBbyNum: StateFlow> - get() = nodeDB.nodeDBbyNum - - fun getUser(nodeNum: Int) = nodeDB.getUser(nodeNum) - - suspend fun getNodeDBbyNum() = nodeDB.getNodeDBbyNum().first() - - suspend fun upsert(node: NodeEntity) = nodeDB.upsert(node) - - suspend fun installMyNodeInfo(mi: MyNodeEntity) { - nodeDB.installMyNodeInfo(mi) - } - - suspend fun installNodeDb(nodes: List) { - nodeDB.installNodeDb(nodes) - } - - suspend fun insertMetadata(fromNum: Int, metadata: DeviceMetadata) { - nodeDB.insertMetadata(MetadataEntity(fromNum, metadata)) - } - - suspend fun clearNodeDB() { - nodeDB.clearNodeDB() - } /** Flow representing the [ChannelSet] data store. */ val channelSetFlow: Flow = channelSetDataSource.channelSetFlow @@ -185,50 +127,4 @@ constructor( } } } - - val clientNotification = serviceRepository.clientNotification - - fun setClientNotification(notification: MeshProtos.ClientNotification?) { - serviceRepository.setClientNotification(notification) - } - - fun clearClientNotification() { - serviceRepository.clearClientNotification() - } - - val errorMessage: StateFlow - get() = serviceRepository.errorMessage - - fun setErrorMessage(text: String) { - serviceRepository.setErrorMessage(text) - } - - fun clearErrorMessage() { - serviceRepository.clearErrorMessage() - } - - fun setStatusMessage(text: String) { - serviceRepository.setStatusMessage(text) - } - - val meshPacketFlow: SharedFlow - get() = serviceRepository.meshPacketFlow - - suspend fun emitMeshPacket(packet: MeshPacket) = coroutineScope { serviceRepository.emitMeshPacket(packet) } - - val serviceAction: Flow - get() = serviceRepository.serviceAction - - suspend fun onServiceAction(action: ServiceAction) = coroutineScope { serviceRepository.onServiceAction(action) } - - val tracerouteResponse: StateFlow - get() = serviceRepository.tracerouteResponse - - fun setTracerouteResponse(value: String?) { - serviceRepository.setTracerouteResponse(value) - } - - fun clearTracerouteResponse() { - setTracerouteResponse(null) - } } diff --git a/app/src/main/java/com/geeksville/mesh/repository/network/MQTTRepository.kt b/app/src/main/java/com/geeksville/mesh/repository/network/MQTTRepository.kt index 56a6a8c8e..f1d88fcd0 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/network/MQTTRepository.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/network/MQTTRepository.kt @@ -19,6 +19,7 @@ package com.geeksville.mesh.repository.network import com.geeksville.mesh.MeshProtos.MqttClientProxyMessage import com.geeksville.mesh.android.Logging +import com.geeksville.mesh.database.NodeRepository import com.geeksville.mesh.model.subscribeList import com.geeksville.mesh.mqttClientProxyMessage import com.geeksville.mesh.repository.datastore.RadioConfigRepository @@ -44,7 +45,12 @@ import javax.net.ssl.SSLContext import javax.net.ssl.TrustManager @Singleton -class MQTTRepository @Inject constructor(private val radioConfigRepository: RadioConfigRepository) : Logging { +class MQTTRepository +@Inject +constructor( + private val radioConfigRepository: RadioConfigRepository, + private val nodeRepository: NodeRepository, +) : Logging { companion object { /** @@ -73,7 +79,7 @@ class MQTTRepository @Inject constructor(private val radioConfigRepository: Radi } val proxyMessageFlow: Flow = callbackFlow { - val ownerId = "MeshtasticAndroidMqttProxy-${radioConfigRepository.myId.value ?: generateClientId()}" + val ownerId = "MeshtasticAndroidMqttProxy-${nodeRepository.myId.value ?: generateClientId()}" val channelSet = radioConfigRepository.channelSetFlow.first() val mqttConfig = radioConfigRepository.moduleConfigFlow.first().mqtt 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 d22729a5a..45b921235 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -55,6 +55,7 @@ import com.geeksville.mesh.android.hasLocationPermission import com.geeksville.mesh.concurrent.handledLaunch import com.geeksville.mesh.copy import com.geeksville.mesh.database.MeshLogRepository +import com.geeksville.mesh.database.NodeRepository import com.geeksville.mesh.database.PacketRepository import com.geeksville.mesh.fromRadio import com.geeksville.mesh.model.NO_DEVICE_SELECTED @@ -80,11 +81,13 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import org.meshtastic.core.database.entity.MeshLog +import org.meshtastic.core.database.entity.MetadataEntity import org.meshtastic.core.database.entity.MyNodeEntity import org.meshtastic.core.database.entity.NodeEntity import org.meshtastic.core.database.entity.Packet @@ -144,6 +147,10 @@ class MeshService : @Inject lateinit var radioConfigRepository: RadioConfigRepository + @Inject lateinit var serviceRepository: ServiceRepository + + @Inject lateinit var nodeRepository: NodeRepository + @Inject lateinit var mqttRepository: MQTTRepository @Inject lateinit var serviceNotifications: MeshServiceNotifications @@ -215,7 +222,7 @@ class MeshService : private val clientPackages = mutableMapOf() private val serviceBroadcasts = MeshServiceBroadcasts(this, clientPackages) { - connectionState.also { radioConfigRepository.setConnectionState(it) } + connectionState.also { serviceRepository.setConnectionState(it) } } private val packetHandler: PacketHandler by lazy { PacketHandler( @@ -338,8 +345,8 @@ class MeshService : radioConfigRepository.localConfigFlow.onEach { localConfig = it }.launchIn(serviceScope) radioConfigRepository.moduleConfigFlow.onEach { moduleConfig = it }.launchIn(serviceScope) radioConfigRepository.channelSetFlow.onEach { channelSet = it }.launchIn(serviceScope) - radioConfigRepository.serviceAction.onEach(::onServiceAction).launchIn(serviceScope) - radioConfigRepository.myNodeInfo + serviceRepository.serviceAction.onEach(::onServiceAction).launchIn(serviceScope) + nodeRepository.myNodeInfo .flatMapLatest { myNodeEntity -> // When myNodeInfo changes, set up emissions for the "provide-location-nodeNum" pref. if (myNodeEntity == null) { @@ -443,8 +450,8 @@ class MeshService : private fun loadSettings() = serviceScope.handledLaunch { discardNodeDB() // Get rid of any old state - myNodeInfo = radioConfigRepository.myNodeInfo.value - nodeDBbyNodeNum.putAll(radioConfigRepository.getNodeDBbyNum()) + myNodeInfo = nodeRepository.myNodeInfo.value + nodeDBbyNodeNum.putAll(nodeRepository.getNodeDBbyNum().first()) // Note: we do not haveNodeDB = true because that means we've got a valid db from a real // device (rather than // this possibly stale hint) @@ -543,7 +550,7 @@ class MeshService : } } - private fun getUserName(num: Int): String = with(radioConfigRepository.getUser(num)) { "$longName ($shortName)" } + private fun getUserName(num: Int): String = with(nodeRepository.getUser(num)) { "$longName ($shortName)" } private val numNodes get() = nodeDBbyNodeNum.size @@ -569,7 +576,7 @@ class MeshService : updateFn(info) if (info.user.id.isNotEmpty() && haveNodeDB) { - serviceScope.handledLaunch { radioConfigRepository.upsert(info) } + serviceScope.handledLaunch { nodeRepository.upsert(info) } } if (withBroadcast) { @@ -834,7 +841,7 @@ class MeshService : val u = MeshProtos.Routing.parseFrom(data.payload) if (u.errorReason == MeshProtos.Routing.Error.DUTY_CYCLE_LIMIT) { - radioConfigRepository.setErrorMessage(getString(R.string.error_duty_cycle)) + serviceRepository.setErrorMessage(getString(R.string.error_duty_cycle)) } handleAckNak(data.requestId, fromId, u.errorReasonValue) @@ -884,7 +891,7 @@ class MeshService : } else { full } - radioConfigRepository.setTracerouteResponse(response) + serviceRepository.setTracerouteResponse(response) } } @@ -934,7 +941,7 @@ class MeshService : AdminProtos.AdminMessage.PayloadVariantCase.GET_DEVICE_METADATA_RESPONSE -> { debug("Admin: received DeviceMetadata from $fromNodeNum") serviceScope.handledLaunch { - radioConfigRepository.insertMetadata(fromNodeNum, a.getDeviceMetadataResponse) + nodeRepository.insertMetadata(MetadataEntity(fromNodeNum, a.getDeviceMetadataResponse)) } } @@ -1188,7 +1195,7 @@ class MeshService : ) insertMeshLog(packetToSave) - serviceScope.handledLaunch { radioConfigRepository.emitMeshPacket(packet) } + serviceScope.handledLaunch { serviceRepository.emitMeshPacket(packet) } // Update last seen for the node that sent the packet, but also for _our node_ because // anytime a packet @@ -1488,7 +1495,7 @@ class MeshService : insertMeshLog(packetToSave) setLocalConfig(config) val configCount = localConfig.allFields.size - radioConfigRepository.setStatusMessage("Device config ($configCount / $configTotal)") + serviceRepository.setStatusMessage("Device config ($configCount / $configTotal)") } private fun handleModuleConfig(config: ModuleConfigProtos.ModuleConfig) { @@ -1504,7 +1511,7 @@ class MeshService : insertMeshLog(packetToSave) setLocalModuleConfig(config) val moduleCount = moduleConfig.allFields.size - radioConfigRepository.setStatusMessage("Module config ($moduleCount / $moduleTotal)") + serviceRepository.setStatusMessage("Module config ($moduleCount / $moduleTotal)") } private fun handleChannel(ch: ChannelProtos.Channel) { @@ -1520,7 +1527,7 @@ class MeshService : insertMeshLog(packetToSave) if (ch.role != ChannelProtos.Channel.Role.DISABLED) updateChannelSettings(ch) val maxChannels = myNodeInfo?.maxChannels ?: 8 - radioConfigRepository.setStatusMessage("Channels (${ch.index + 1} / $maxChannels)") + serviceRepository.setStatusMessage("Channels (${ch.index + 1} / $maxChannels)") } /** Convert a protobuf NodeInfo into our model objects and update our node DB */ @@ -1584,7 +1591,7 @@ class MeshService : insertMeshLog(packetToSave) newNodes.add(info) - radioConfigRepository.setStatusMessage("Nodes (${newNodes.size})") + serviceRepository.setStatusMessage("Nodes (${newNodes.size})") } private var rawMyNodeInfo: MeshProtos.MyNodeInfo? = null @@ -1619,7 +1626,7 @@ class MeshService : deviceId = deviceId.toStringUtf8(), ) } - serviceScope.handledLaunch { radioConfigRepository.insertMetadata(mi.myNodeNum, metadata) } + serviceScope.handledLaunch { nodeRepository.insertMetadata(MetadataEntity(mi.myNodeNum, metadata)) } newMyNodeInfo = mi } } @@ -1693,7 +1700,7 @@ class MeshService : private fun handleClientNotification(notification: MeshProtos.ClientNotification) { debug("Received clientNotification ${notification.toOneLineString()}") - radioConfigRepository.setClientNotification(notification) + serviceRepository.setClientNotification(notification) serviceNotifications.showClientNotification(notification) // if the future for the originating request is still in the queue, complete as unsuccessful // for now @@ -1774,7 +1781,7 @@ class MeshService : .onEach { message -> packetHandler.sendToRadio(ToRadio.newBuilder().apply { mqttClientProxyMessage = message }) } - .catch { throwable -> radioConfigRepository.setErrorMessage("MqttClientProxy failed: $throwable") } + .catch { throwable -> serviceRepository.setErrorMessage("MqttClientProxy failed: $throwable") } .launchIn(serviceScope) } } @@ -1857,8 +1864,8 @@ class MeshService : newNodes.clear() // Just to save RAM ;-) serviceScope.handledLaunch { - radioConfigRepository.installMyNodeInfo(myNodeInfo!!) - radioConfigRepository.installNodeDb(nodeDBbyNodeNum.values.toList()) + nodeRepository.installMyNodeInfo(myNodeInfo!!) + nodeRepository.installNodeDb(nodeDBbyNodeNum.values.toList()) } haveNodeDB = true // we now have nodes from real hardware @@ -2058,7 +2065,7 @@ class MeshService : fun clearDatabases() = serviceScope.handledLaunch { debug("Clearing nodeDB") - radioConfigRepository.clearNodeDB() + nodeRepository.clearNodeDB() } private fun updateLastAddress(deviceAddr: String?) { diff --git a/app/src/main/java/com/geeksville/mesh/ui/connections/ConnectionsViewModel.kt b/app/src/main/java/com/geeksville/mesh/ui/connections/ConnectionsViewModel.kt index 1a41aa0bf..0f59f85b3 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/connections/ConnectionsViewModel.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/connections/ConnectionsViewModel.kt @@ -23,6 +23,7 @@ import com.geeksville.mesh.LocalOnlyProtos.LocalConfig import com.geeksville.mesh.database.NodeRepository import com.geeksville.mesh.repository.bluetooth.BluetoothRepository import com.geeksville.mesh.repository.datastore.RadioConfigRepository +import com.geeksville.mesh.service.ServiceRepository import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted @@ -39,6 +40,7 @@ class ConnectionsViewModel @Inject constructor( radioConfigRepository: RadioConfigRepository, + serviceRepository: ServiceRepository, nodeRepository: NodeRepository, bluetoothRepository: BluetoothRepository, private val uiPrefs: UiPrefs, @@ -50,7 +52,7 @@ constructor( LocalConfig.getDefaultInstance(), ) - val connectionState = radioConfigRepository.connectionState + val connectionState = serviceRepository.connectionState val myNodeInfo: StateFlow = nodeRepository.myNodeInfo diff --git a/app/src/main/java/com/geeksville/mesh/ui/map/BaseMapViewModel.kt b/app/src/main/java/com/geeksville/mesh/ui/map/BaseMapViewModel.kt index c0e4d33e2..4434cf07d 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/map/BaseMapViewModel.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/map/BaseMapViewModel.kt @@ -21,7 +21,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.geeksville.mesh.database.NodeRepository import com.geeksville.mesh.database.PacketRepository -import com.geeksville.mesh.repository.datastore.RadioConfigRepository +import com.geeksville.mesh.service.ServiceRepository import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow @@ -38,7 +38,7 @@ abstract class BaseMapViewModel( protected val mapPrefs: MapPrefs, nodeRepository: NodeRepository, packetRepository: PacketRepository, - radioConfigRepository: RadioConfigRepository, + serviceRepository: ServiceRepository, ) : ViewModel() { val nodes: StateFlow> = @@ -72,7 +72,7 @@ abstract class BaseMapViewModel( val ourNodeInfo: StateFlow = nodeRepository.ourNodeInfo val isConnected = - radioConfigRepository.connectionState + serviceRepository.connectionState .map { it.isConnected() } .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000), false) diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/SettingsViewModel.kt b/app/src/main/java/com/geeksville/mesh/ui/settings/SettingsViewModel.kt index 36c469331..9fbdaa75a 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/settings/SettingsViewModel.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/settings/SettingsViewModel.kt @@ -29,6 +29,7 @@ import com.geeksville.mesh.android.Logging import com.geeksville.mesh.database.MeshLogRepository import com.geeksville.mesh.database.NodeRepository import com.geeksville.mesh.repository.datastore.RadioConfigRepository +import com.geeksville.mesh.service.ServiceRepository import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow @@ -57,12 +58,14 @@ import java.util.Locale import javax.inject.Inject import kotlin.math.roundToInt +@Suppress("LongParameterList") @HiltViewModel class SettingsViewModel @Inject constructor( private val app: Application, - private val radioConfigRepository: RadioConfigRepository, + radioConfigRepository: RadioConfigRepository, + private val serviceRepository: ServiceRepository, private val nodeRepository: NodeRepository, private val meshLogRepository: MeshLogRepository, private val uiPrefs: UiPrefs, @@ -77,7 +80,7 @@ constructor( val ourNodeInfo: StateFlow = nodeRepository.ourNodeInfo val isConnected = - radioConfigRepository.connectionState + serviceRepository.connectionState .map { it.isConnected() } .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000L), false) @@ -89,7 +92,7 @@ constructor( ) val meshService: IMeshService? - get() = radioConfigRepository.meshService + get() = serviceRepository.meshService val provideLocation: StateFlow = myNodeInfo diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/CleanNodeDatabaseViewModel.kt b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/CleanNodeDatabaseViewModel.kt index 2a75b3242..ce74b45b9 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/CleanNodeDatabaseViewModel.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/CleanNodeDatabaseViewModel.kt @@ -20,7 +20,7 @@ package com.geeksville.mesh.ui.settings.radio import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.geeksville.mesh.database.NodeRepository -import com.geeksville.mesh.repository.datastore.RadioConfigRepository +import com.geeksville.mesh.service.ServiceRepository import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow @@ -41,7 +41,7 @@ class CleanNodeDatabaseViewModel @Inject constructor( private val nodeRepository: NodeRepository, - private val radioConfigRepository: RadioConfigRepository, + private val serviceRepository: ServiceRepository, ) : ViewModel() { private val _olderThanDays = MutableStateFlow(30f) val olderThanDays = _olderThanDays.asStateFlow() @@ -110,7 +110,7 @@ constructor( if (nodeNums.isNotEmpty()) { nodeRepository.deleteNodes(nodeNums) - val service = radioConfigRepository.meshService + val service = serviceRepository.meshService if (service != null) { for (nodeNum in nodeNums) { service.removeByNodenum(service.packetId, nodeNum) diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/RadioConfigViewModel.kt b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/RadioConfigViewModel.kt index 1cf4a7792..dbd87b8be 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/RadioConfigViewModel.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/RadioConfigViewModel.kt @@ -45,6 +45,7 @@ import com.geeksville.mesh.android.GeeksvilleApplication import com.geeksville.mesh.android.Logging import com.geeksville.mesh.android.isAnalyticsAvailable import com.geeksville.mesh.config +import com.geeksville.mesh.database.NodeRepository import com.geeksville.mesh.deviceProfile import com.geeksville.mesh.model.getChannelList import com.geeksville.mesh.model.toChannelSet @@ -54,6 +55,7 @@ import com.geeksville.mesh.navigation.ModuleRoute import com.geeksville.mesh.repository.datastore.RadioConfigRepository import com.geeksville.mesh.repository.location.LocationRepository import com.geeksville.mesh.service.ConnectionState +import com.geeksville.mesh.service.ServiceRepository import com.geeksville.mesh.util.UiText import com.google.protobuf.MessageLite import dagger.hilt.android.lifecycle.HiltViewModel @@ -98,6 +100,7 @@ data class RadioConfigState( val analyticsEnabled: Boolean = false, ) +@Suppress("LongParameterList") @HiltViewModel class RadioConfigViewModel @Inject @@ -105,13 +108,15 @@ constructor( savedStateHandle: SavedStateHandle, private val app: Application, private val radioConfigRepository: RadioConfigRepository, + private val serviceRepository: ServiceRepository, + private val nodeRepository: NodeRepository, private val locationRepository: LocationRepository, private val mapConsentPrefs: MapConsentPrefs, private val analyticsPrefs: AnalyticsPrefs, ) : ViewModel(), Logging { private val meshService: IMeshService? - get() = radioConfigRepository.meshService + get() = serviceRepository.meshService private val destNum = savedStateHandle.toRoute().destNum private val _destNode = MutableStateFlow(null) @@ -137,7 +142,7 @@ constructor( } init { - radioConfigRepository.nodeDBbyNum + nodeRepository.nodeDBbyNum .mapLatest { nodes -> nodes[destNum] ?: nodes.values.firstOrNull() } .distinctUntilChanged() .onEach { @@ -148,9 +153,9 @@ constructor( radioConfigRepository.deviceProfileFlow.onEach { _currentDeviceProfile.value = it }.launchIn(viewModelScope) - radioConfigRepository.meshPacketFlow.onEach(::processPacketResponse).launchIn(viewModelScope) + serviceRepository.meshPacketFlow.onEach(::processPacketResponse).launchIn(viewModelScope) - combine(radioConfigRepository.connectionState, radioConfigState) { connState, configState -> + combine(serviceRepository.connectionState, radioConfigState) { connState, configState -> _radioConfigState.update { it.copy(connected = connState == ConnectionState.CONNECTED) } if (connState == ConnectionState.DISCONNECTED && configState.responseState.isWaiting()) { sendError(R.string.disconnected) @@ -158,7 +163,7 @@ constructor( } .launchIn(viewModelScope) - radioConfigRepository.myNodeInfo + nodeRepository.myNodeInfo .onEach { ni -> _radioConfigState.update { it.copy(isLocal = destNum == null || destNum == ni?.myNodeNum) } } @@ -170,7 +175,7 @@ constructor( } private val myNodeInfo: StateFlow - get() = radioConfigRepository.myNodeInfo + get() = nodeRepository.myNodeInfo val myNodeNum get() = myNodeInfo.value?.myNodeNum @@ -342,7 +347,7 @@ constructor( "Request factory reset error", ) if (destNum == myNodeNum) { - viewModelScope.launch { radioConfigRepository.clearNodeDB() } + viewModelScope.launch { nodeRepository.clearNodeDB() } } } @@ -353,7 +358,7 @@ constructor( "Request NodeDB reset error", ) if (destNum == myNodeNum) { - viewModelScope.launch { radioConfigRepository.clearNodeDB() } + viewModelScope.launch { nodeRepository.clearNodeDB() } } }