refactor: migrate from Hilt to Koin and expand KMP common modules (#4746)

Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
James Rich 2026-03-09 20:19:46 -05:00 committed by GitHub
parent a5390a80e7
commit 875cf1cff2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
440 changed files with 3738 additions and 3508 deletions

View file

@ -22,11 +22,11 @@ import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromStream
import org.koin.core.annotation.Single
import org.meshtastic.core.model.BootloaderOtaQuirk
import javax.inject.Inject
class BootloaderOtaQuirksJsonDataSourceImpl @Inject constructor(private val application: Application) :
BootloaderOtaQuirksJsonDataSource {
@Single
class BootloaderOtaQuirksJsonDataSourceImpl(private val application: Application) : BootloaderOtaQuirksJsonDataSource {
@OptIn(ExperimentalSerializationApi::class)
override fun loadBootloaderOtaQuirksFromJsonAsset(): List<BootloaderOtaQuirk> = runCatching {
val inputStream = application.assets.open("device_bootloader_ota_quirks.json")

View file

@ -20,11 +20,11 @@ import android.app.Application
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromStream
import org.koin.core.annotation.Single
import org.meshtastic.core.model.NetworkDeviceHardware
import javax.inject.Inject
class DeviceHardwareJsonDataSourceImpl @Inject constructor(private val application: Application) :
DeviceHardwareJsonDataSource {
@Single
class DeviceHardwareJsonDataSourceImpl(private val application: Application) : DeviceHardwareJsonDataSource {
// Use a tolerant JSON parser so that additional fields in the bundled asset
// (e.g., "key") do not break deserialization on older app versions.

View file

@ -20,11 +20,11 @@ import android.app.Application
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromStream
import org.koin.core.annotation.Single
import org.meshtastic.core.model.NetworkFirmwareReleases
import javax.inject.Inject
class FirmwareReleaseJsonDataSourceImpl @Inject constructor(private val application: Application) :
FirmwareReleaseJsonDataSource {
@Single
class FirmwareReleaseJsonDataSourceImpl(private val application: Application) : FirmwareReleaseJsonDataSource {
// Match the network client behavior: be tolerant of unknown fields so that
// older app versions can read newer snapshots of firmware_releases.json.

View file

@ -0,0 +1,24 @@
/*
* Copyright (c) 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.data.di
import org.koin.core.annotation.ComponentScan
import org.koin.core.annotation.Module
@Module
@ComponentScan("org.meshtastic.core.data")
class CoreDataAndroidModule

View file

@ -34,19 +34,16 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.callbackFlow
import org.koin.core.annotation.Single
import org.meshtastic.core.di.CoroutineDispatchers
import org.meshtastic.core.repository.Location
import org.meshtastic.core.repository.LocationRepository
import org.meshtastic.core.repository.PlatformAnalytics
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class LocationRepositoryImpl
@Inject
constructor(
@Single
class LocationRepositoryImpl(
private val context: Application,
private val locationManager: dagger.Lazy<LocationManager>,
private val locationManager: Lazy<LocationManager>,
private val analytics: PlatformAnalytics,
private val dispatchers: CoroutineDispatchers,
) : LocationRepository {
@ -125,5 +122,5 @@ constructor(
/** Observable flow for location updates */
@RequiresPermission(anyOf = [ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION])
override fun getLocations(): Flow<Location> = locationManager.get().requestLocationUpdates()
override fun getLocations(): Flow<Location> = locationManager.value.requestLocationUpdates()
}

View file

@ -17,16 +17,15 @@
package org.meshtastic.core.data.datasource
import kotlinx.coroutines.withContext
import org.koin.core.annotation.Single
import org.meshtastic.core.database.DatabaseManager
import org.meshtastic.core.database.entity.DeviceHardwareEntity
import org.meshtastic.core.database.entity.asEntity
import org.meshtastic.core.di.CoroutineDispatchers
import org.meshtastic.core.model.NetworkDeviceHardware
import javax.inject.Inject
class DeviceHardwareLocalDataSource
@Inject
constructor(
@Single
class DeviceHardwareLocalDataSource(
private val dbManager: DatabaseManager,
private val dispatchers: CoroutineDispatchers,
) {

View file

@ -17,6 +17,7 @@
package org.meshtastic.core.data.datasource
import kotlinx.coroutines.withContext
import org.koin.core.annotation.Single
import org.meshtastic.core.database.DatabaseManager
import org.meshtastic.core.database.entity.FirmwareReleaseEntity
import org.meshtastic.core.database.entity.FirmwareReleaseType
@ -24,11 +25,9 @@ import org.meshtastic.core.database.entity.asDeviceVersion
import org.meshtastic.core.database.entity.asEntity
import org.meshtastic.core.di.CoroutineDispatchers
import org.meshtastic.core.model.NetworkFirmwareRelease
import javax.inject.Inject
class FirmwareReleaseLocalDataSource
@Inject
constructor(
@Single
class FirmwareReleaseLocalDataSource(
private val dbManager: DatabaseManager,
private val dispatchers: CoroutineDispatchers,
) {

View file

@ -18,16 +18,14 @@ package org.meshtastic.core.data.datasource
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flatMapLatest
import org.koin.core.annotation.Single
import org.meshtastic.core.database.DatabaseManager
import org.meshtastic.core.database.entity.MyNodeEntity
import org.meshtastic.core.database.entity.NodeEntity
import org.meshtastic.core.database.entity.NodeWithRelations
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class SwitchingNodeInfoReadDataSource @Inject constructor(private val dbManager: DatabaseManager) :
NodeInfoReadDataSource {
@Single
class SwitchingNodeInfoReadDataSource(private val dbManager: DatabaseManager) : NodeInfoReadDataSource {
override fun myNodeInfoFlow(): Flow<MyNodeEntity?> =
dbManager.currentDb.flatMapLatest { db -> db.nodeInfoDao().getMyNodeInfo() }

View file

@ -17,18 +17,15 @@
package org.meshtastic.core.data.datasource
import kotlinx.coroutines.withContext
import org.koin.core.annotation.Single
import org.meshtastic.core.database.DatabaseManager
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.di.CoroutineDispatchers
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class SwitchingNodeInfoWriteDataSource
@Inject
constructor(
@Single
class SwitchingNodeInfoWriteDataSource(
private val dbManager: DatabaseManager,
private val dispatchers: CoroutineDispatchers,
) : NodeInfoWriteDataSource {

View file

@ -0,0 +1,29 @@
/*
* Copyright (c) 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.data.di
import org.koin.core.annotation.ComponentScan
import org.koin.core.annotation.Module
import org.koin.core.annotation.Single
import org.meshtastic.core.model.util.MeshDataMapper
import org.meshtastic.core.model.util.NodeIdLookup
@Module
@ComponentScan("org.meshtastic.core.data")
class CoreDataModule {
@Single fun provideMeshDataMapper(nodeIdLookup: NodeIdLookup): MeshDataMapper = MeshDataMapper(nodeIdLookup)
}

View file

@ -26,6 +26,7 @@ import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import okio.ByteString
import okio.ByteString.Companion.toByteString
import org.koin.core.annotation.Single
import org.meshtastic.core.common.util.nowMillis
import org.meshtastic.core.model.DataPacket
import org.meshtastic.core.model.MessageStatus
@ -46,17 +47,13 @@ import org.meshtastic.proto.Neighbor
import org.meshtastic.proto.NeighborInfo
import org.meshtastic.proto.PortNum
import org.meshtastic.proto.Telemetry
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.math.absoluteValue
import kotlin.random.Random
import kotlin.time.Duration.Companion.hours
@Suppress("TooManyFunctions", "CyclomaticComplexMethod")
@Singleton
class CommandSenderImpl
@Inject
constructor(
@Single
class CommandSenderImpl(
private val packetHandler: PacketHandler,
private val nodeManager: NodeManager,
private val radioConfigRepository: RadioConfigRepository,

View file

@ -16,7 +16,7 @@
*/
package org.meshtastic.core.data.manager
import dagger.Lazy
import org.koin.core.annotation.Single
import org.meshtastic.core.repository.FromRadioPacketHandler
import org.meshtastic.core.repository.MeshRouter
import org.meshtastic.core.repository.MeshServiceNotifications
@ -24,14 +24,10 @@ import org.meshtastic.core.repository.MqttManager
import org.meshtastic.core.repository.PacketHandler
import org.meshtastic.core.repository.ServiceRepository
import org.meshtastic.proto.FromRadio
import javax.inject.Inject
import javax.inject.Singleton
/** Implementation of [FromRadioPacketHandler] that dispatches [FromRadio] variants to specialized handlers. */
@Singleton
class FromRadioPacketHandlerImpl
@Inject
constructor(
@Single
class FromRadioPacketHandlerImpl(
private val serviceRepository: ServiceRepository,
private val router: Lazy<MeshRouter>,
private val mqttManager: MqttManager,
@ -52,18 +48,18 @@ constructor(
val clientNotification = proto.clientNotification
when {
myInfo != null -> router.get().configFlowManager.handleMyInfo(myInfo)
metadata != null -> router.get().configFlowManager.handleLocalMetadata(metadata)
myInfo != null -> router.value.configFlowManager.handleMyInfo(myInfo)
metadata != null -> router.value.configFlowManager.handleLocalMetadata(metadata)
nodeInfo != null -> {
router.get().configFlowManager.handleNodeInfo(nodeInfo)
serviceRepository.setConnectionProgress("Nodes (${router.get().configFlowManager.newNodeCount})")
router.value.configFlowManager.handleNodeInfo(nodeInfo)
serviceRepository.setConnectionProgress("Nodes (${router.value.configFlowManager.newNodeCount})")
}
configCompleteId != null -> router.get().configFlowManager.handleConfigComplete(configCompleteId)
configCompleteId != null -> router.value.configFlowManager.handleConfigComplete(configCompleteId)
mqttProxyMessage != null -> mqttManager.handleMqttProxyMessage(mqttProxyMessage)
queueStatus != null -> packetHandler.handleQueueStatus(queueStatus)
config != null -> router.get().configHandler.handleDeviceConfig(config)
moduleConfig != null -> router.get().configHandler.handleModuleConfig(moduleConfig)
channel != null -> router.get().configHandler.handleChannel(channel)
config != null -> router.value.configHandler.handleDeviceConfig(config)
moduleConfig != null -> router.value.configHandler.handleModuleConfig(moduleConfig)
channel != null -> router.value.configHandler.handleChannel(channel)
clientNotification != null -> {
serviceRepository.setClientNotification(clientNotification)
serviceNotifications.showClientNotification(clientNotification)

View file

@ -18,6 +18,7 @@ package org.meshtastic.core.data.manager
import co.touchlab.kermit.Logger
import okio.ByteString.Companion.toByteString
import org.koin.core.annotation.Single
import org.meshtastic.core.repository.HistoryManager
import org.meshtastic.core.repository.MeshPrefs
import org.meshtastic.core.repository.PacketHandler
@ -26,16 +27,9 @@ import org.meshtastic.proto.MeshPacket
import org.meshtastic.proto.ModuleConfig
import org.meshtastic.proto.PortNum
import org.meshtastic.proto.StoreAndForward
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class HistoryManagerImpl
@Inject
constructor(
private val meshPrefs: MeshPrefs,
private val packetHandler: PacketHandler,
) : HistoryManager {
@Single
class HistoryManagerImpl(private val meshPrefs: MeshPrefs, private val packetHandler: PacketHandler) : HistoryManager {
companion object {
private const val HISTORY_TAG = "HistoryReplay"

View file

@ -16,11 +16,11 @@
*/
package org.meshtastic.core.data.manager
import dagger.Lazy
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import okio.ByteString.Companion.toByteString
import org.koin.core.annotation.Single
import org.meshtastic.core.common.database.DatabaseManager
import org.meshtastic.core.common.util.handledLaunch
import org.meshtastic.core.common.util.ignoreException
@ -49,14 +49,10 @@ import org.meshtastic.proto.ModuleConfig
import org.meshtastic.proto.OTAMode
import org.meshtastic.proto.PortNum
import org.meshtastic.proto.User
import javax.inject.Inject
import javax.inject.Singleton
@Suppress("LongParameterList", "TooManyFunctions", "CyclomaticComplexMethod")
@Singleton
class MeshActionHandlerImpl
@Inject
constructor(
@Single
class MeshActionHandlerImpl(
private val nodeManager: NodeManager,
private val commandSender: CommandSender,
private val packetRepository: Lazy<PacketRepository>,
@ -123,7 +119,7 @@ constructor(
}
}
nodeManager.updateNode(node.num) { it.copy(isIgnored = newIgnoredStatus) }
scope.handledLaunch { packetRepository.get().updateFilteredBySender(node.user.id, newIgnoredStatus) }
scope.handledLaunch { packetRepository.value.updateFilteredBySender(node.user.id, newIgnoredStatus) }
}
private fun handleMute(action: ServiceAction.Mute, myNodeNum: Int) {
@ -177,7 +173,7 @@ constructor(
to = action.contactKey.substring(1),
channel = action.contactKey[0].digitToInt(),
)
packetRepository.get().insertReaction(reaction, myNodeNum)
packetRepository.value.insertReaction(reaction, myNodeNum)
}
}
@ -190,7 +186,7 @@ constructor(
override fun handleSend(p: DataPacket, myNodeNum: Int) {
commandSender.sendData(p)
serviceBroadcasts.broadcastMessageStatus(p.id, p.status ?: MessageStatus.UNKNOWN)
dataHandler.get().rememberDataPacket(p, myNodeNum, false)
dataHandler.value.rememberDataPacket(p, myNodeNum, false)
val bytes = p.bytes ?: okio.ByteString.EMPTY
analytics.track("data_send", DataPair("num_bytes", bytes.size), DataPair("type", p.dataType))
}
@ -348,7 +344,7 @@ constructor(
meshPrefs.setDeviceAddress(deviceAddr)
scope.handledLaunch {
nodeManager.clear()
messageProcessor.get().clearEarlyPackets()
messageProcessor.value.clearEarlyPackets()
databaseManager.switchActiveDatabase(deviceAddr)
serviceNotifications.clearNotifications()
nodeManager.loadCachedNodeDB()

View file

@ -17,12 +17,12 @@
package org.meshtastic.core.data.manager
import co.touchlab.kermit.Logger
import dagger.Lazy
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.delay
import okio.IOException
import org.koin.core.annotation.Single
import org.meshtastic.core.common.util.handledLaunch
import org.meshtastic.core.model.ConnectionState
import org.meshtastic.core.repository.CommandSender
@ -40,16 +40,12 @@ import org.meshtastic.proto.HardwareModel
import org.meshtastic.proto.Heartbeat
import org.meshtastic.proto.NodeInfo
import org.meshtastic.proto.ToRadio
import javax.inject.Inject
import javax.inject.Singleton
import org.meshtastic.core.model.MyNodeInfo as SharedMyNodeInfo
import org.meshtastic.proto.MyNodeInfo as ProtoMyNodeInfo
@Suppress("LongParameterList", "TooManyFunctions")
@Singleton
class MeshConfigFlowManagerImpl
@Inject
constructor(
@Single
class MeshConfigFlowManagerImpl(
private val nodeManager: NodeManager,
private val connectionManager: Lazy<MeshConnectionManager>,
private val nodeRepository: NodeRepository,
@ -101,7 +97,7 @@ constructor(
} else {
myNodeInfo = finalizedInfo
Logger.i { "myNodeInfo committed successfully (nodeNum=${finalizedInfo.myNodeNum})" }
connectionManager.get().onRadioConfigLoaded()
connectionManager.value.onRadioConfigLoaded()
}
scope.handledLaunch {
@ -109,7 +105,7 @@ constructor(
sendHeartbeat()
delay(wantConfigDelay)
Logger.i { "Requesting NodeInfo (Stage 2)" }
connectionManager.get().startNodeInfoOnly()
connectionManager.value.startNodeInfoOnly()
}
}
@ -140,7 +136,7 @@ constructor(
nodeManager.setAllowNodeDbWrites(true)
serviceRepository.setConnectionState(ConnectionState.Connected)
serviceBroadcasts.broadcastConnection()
connectionManager.get().onNodeDbReady()
connectionManager.value.onNodeDbReady()
}
}
@ -172,7 +168,7 @@ constructor(
}
override fun triggerWantConfig() {
connectionManager.get().startConfigOnly()
connectionManager.value.startConfigOnly()
}
private fun regenMyNodeInfo(metadata: DeviceMetadata? = null) {

View file

@ -23,6 +23,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import org.koin.core.annotation.Single
import org.meshtastic.core.common.util.handledLaunch
import org.meshtastic.core.repository.MeshConfigHandler
import org.meshtastic.core.repository.NodeManager
@ -33,13 +34,9 @@ import org.meshtastic.proto.Config
import org.meshtastic.proto.LocalConfig
import org.meshtastic.proto.LocalModuleConfig
import org.meshtastic.proto.ModuleConfig
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class MeshConfigHandlerImpl
@Inject
constructor(
@Single
class MeshConfigHandlerImpl(
private val radioConfigRepository: RadioConfigRepository,
private val serviceRepository: ServiceRepository,
private val nodeManager: NodeManager,

View file

@ -28,6 +28,7 @@ import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import org.koin.core.annotation.Single
import org.meshtastic.core.common.util.handledLaunch
import org.meshtastic.core.common.util.nowMillis
import org.meshtastic.core.common.util.nowSeconds
@ -63,17 +64,13 @@ import org.meshtastic.proto.AdminMessage
import org.meshtastic.proto.Config
import org.meshtastic.proto.Telemetry
import org.meshtastic.proto.ToRadio
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds
import kotlin.time.DurationUnit
@Suppress("LongParameterList", "TooManyFunctions")
@Singleton
class MeshConnectionManagerImpl
@Inject
constructor(
@Single
class MeshConnectionManagerImpl(
private val radioInterfaceService: RadioInterfaceService,
private val serviceRepository: ServiceRepository,
private val serviceBroadcasts: ServiceBroadcasts,

View file

@ -18,7 +18,6 @@ package org.meshtastic.core.data.manager
import co.touchlab.kermit.Logger
import co.touchlab.kermit.Severity
import dagger.Lazy
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
@ -29,6 +28,7 @@ import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import okio.ByteString.Companion.toByteString
import okio.IOException
import org.koin.core.annotation.Single
import org.meshtastic.core.common.util.handledLaunch
import org.meshtastic.core.common.util.nowMillis
import org.meshtastic.core.common.util.nowSeconds
@ -76,8 +76,6 @@ import org.meshtastic.proto.StoreForwardPlusPlus
import org.meshtastic.proto.Telemetry
import org.meshtastic.proto.User
import org.meshtastic.proto.Waypoint
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.time.Duration.Companion.milliseconds
/**
@ -91,10 +89,8 @@ import kotlin.time.Duration.Companion.milliseconds
* 5. Tracking received telemetry for node updates.
*/
@Suppress("LongParameterList", "TooManyFunctions", "LargeClass", "CyclomaticComplexMethod")
@Singleton
class MeshDataHandlerImpl
@Inject
constructor(
@Single
class MeshDataHandlerImpl(
private val nodeManager: NodeManager,
private val packetHandler: PacketHandler,
private val serviceRepository: ServiceRepository,
@ -291,17 +287,15 @@ constructor(
"to=${sfpp.encapsulated_to} myNodeNum=${nodeManager.myNodeNum} status=$status"
}
scope.handledLaunch {
packetRepository
.get()
.updateSFPPStatus(
packetId = sfpp.encapsulated_id,
from = sfpp.encapsulated_from,
to = sfpp.encapsulated_to,
hash = hash,
status = status,
rxTime = sfpp.encapsulated_rxtime.toLong() and 0xFFFFFFFFL,
myNodeNum = nodeManager.myNodeNum ?: 0,
)
packetRepository.value.updateSFPPStatus(
packetId = sfpp.encapsulated_id,
from = sfpp.encapsulated_from,
to = sfpp.encapsulated_to,
hash = hash,
status = status,
rxTime = sfpp.encapsulated_rxtime.toLong() and 0xFFFFFFFFL,
myNodeNum = nodeManager.myNodeNum ?: 0,
)
serviceBroadcasts.broadcastMessageStatus(sfpp.encapsulated_id, status)
}
}
@ -309,13 +303,11 @@ constructor(
StoreForwardPlusPlus.SFPP_message_type.CANON_ANNOUNCE -> {
scope.handledLaunch {
sfpp.message_hash.let {
packetRepository
.get()
.updateSFPPStatusByHash(
hash = it.toByteArray(),
status = MessageStatus.SFPP_CONFIRMED,
rxTime = sfpp.encapsulated_rxtime.toLong() and 0xFFFFFFFFL,
)
packetRepository.value.updateSFPPStatusByHash(
hash = it.toByteArray(),
status = MessageStatus.SFPP_CONFIRMED,
rxTime = sfpp.encapsulated_rxtime.toLong() and 0xFFFFFFFFL,
)
}
}
}
@ -359,20 +351,20 @@ constructor(
val fromNum = packet.from
u.get_module_config_response?.let {
if (fromNum == myNodeNum) {
configHandler.get().handleModuleConfig(it)
configHandler.value.handleModuleConfig(it)
} else {
it.statusmessage?.node_status?.let { nodeManager.updateNodeStatus(fromNum, it) }
}
}
if (fromNum == myNodeNum) {
u.get_config_response?.let { configHandler.get().handleDeviceConfig(it) }
u.get_channel_response?.let { configHandler.get().handleChannel(it) }
u.get_config_response?.let { configHandler.value.handleDeviceConfig(it) }
u.get_channel_response?.let { configHandler.value.handleChannel(it) }
}
u.get_device_metadata_response?.let {
if (fromNum == myNodeNum) {
configFlowManager.get().handleLocalMetadata(it)
configFlowManager.value.handleLocalMetadata(it)
} else {
nodeManager.insertMetadata(fromNum, it)
}
@ -414,7 +406,7 @@ constructor(
val fromNum = packet.from
val isRemote = (fromNum != myNodeNum)
if (!isRemote) {
connectionManager.get().updateTelemetry(t)
connectionManager.value.updateTelemetry(t)
}
nodeManager.updateNode(fromNum) { node: Node ->
@ -508,8 +500,8 @@ constructor(
private fun handleAckNak(requestId: Int, fromId: String, routingError: Int, relayNode: Int?) {
scope.handledLaunch {
val isAck = routingError == Routing.Error.NONE.value
val p = packetRepository.get().getPacketByPacketId(requestId)
val reaction = packetRepository.get().getReactionByPacketId(requestId)
val p = packetRepository.value.getPacketByPacketId(requestId)
val reaction = packetRepository.value.getReactionByPacketId(requestId)
@Suppress("MaxLineLength")
Logger.d {
@ -527,7 +519,7 @@ constructor(
if (p != null && p.status != MessageStatus.RECEIVED) {
val updatedPacket =
p.copy(status = m, relays = if (isAck) p.relays + 1 else p.relays, relayNode = relayNode)
packetRepository.get().update(updatedPacket)
packetRepository.value.update(updatedPacket)
}
reaction?.let { r ->
@ -536,7 +528,7 @@ constructor(
if (isAck) {
updated = updated.copy(relays = updated.relays + 1)
}
packetRepository.get().updateReaction(updated)
packetRepository.value.updateReaction(updated)
}
}
@ -601,7 +593,7 @@ constructor(
val contactKey = "${dataPacket.channel}$contactId"
scope.handledLaunch {
packetRepository.get().apply {
packetRepository.value.apply {
// Check for duplicates before inserting
val existingPackets = findPacketsWithId(dataPacket.id)
if (existingPackets.isNotEmpty()) {
@ -646,7 +638,7 @@ constructor(
contactKey: String,
updateNotification: Boolean,
) {
val conversationMuted = packetRepository.get().getContactSettings(contactKey).isMuted
val conversationMuted = packetRepository.value.getContactSettings(contactKey).isMuted
val nodeMuted = nodeManager.nodeDBbyID[dataPacket.from]?.isMuted == true
val isSilent = conversationMuted || nodeMuted
if (dataPacket.dataType == PortNum.ALERT_APP.value && !isSilent) {
@ -733,7 +725,7 @@ constructor(
)
// Check for duplicates before inserting
val existingReactions = packetRepository.get().findReactionsWithId(packet.id)
val existingReactions = packetRepository.value.findReactionsWithId(packet.id)
if (existingReactions.isNotEmpty()) {
Logger.d {
"Skipping duplicate reaction: packetId=${packet.id} replyId=${decoded.reply_id} " +
@ -742,15 +734,15 @@ constructor(
return@handledLaunch
}
packetRepository.get().insertReaction(reaction, nodeManager.myNodeNum ?: 0)
packetRepository.value.insertReaction(reaction, nodeManager.myNodeNum ?: 0)
// Find the original packet to get the contactKey
packetRepository.get().getPacketByPacketId(decoded.reply_id)?.let { originalPacket ->
packetRepository.value.getPacketByPacketId(decoded.reply_id)?.let { originalPacket ->
// Skip notification if the original message was filtered
val targetId =
if (originalPacket.from == DataPacket.ID_LOCAL) originalPacket.to else originalPacket.from
val contactKey = "${originalPacket.channel}$targetId"
val conversationMuted = packetRepository.get().getContactSettings(contactKey).isMuted
val conversationMuted = packetRepository.value.getContactSettings(contactKey).isMuted
val nodeMuted = nodeManager.nodeDBbyID[fromId]?.isMuted == true
val isSilent = conversationMuted || nodeMuted

View file

@ -17,7 +17,6 @@
package org.meshtastic.core.data.manager
import co.touchlab.kermit.Logger
import dagger.Lazy
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
@ -27,6 +26,7 @@ import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import org.koin.core.annotation.Single
import org.meshtastic.core.common.util.handledLaunch
import org.meshtastic.core.common.util.nowMillis
import org.meshtastic.core.common.util.nowSeconds
@ -43,16 +43,12 @@ import org.meshtastic.proto.FromRadio
import org.meshtastic.proto.LogRecord
import org.meshtastic.proto.MeshPacket
import org.meshtastic.proto.PortNum
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.uuid.Uuid
/** Implementation of [MeshMessageProcessor] that handles raw radio messages and prepares mesh packets for routing. */
@Suppress("TooManyFunctions")
@Singleton
class MeshMessageProcessorImpl
@Inject
constructor(
@Single
class MeshMessageProcessorImpl(
private val nodeManager: NodeManager,
private val serviceRepository: ServiceRepository,
private val meshLogRepository: Lazy<MeshLogRepository>,
@ -246,7 +242,7 @@ constructor(
}
try {
router.get().dataHandler.handleReceivedData(packet, myNum, log.uuid, logJob)
router.value.dataHandler.handleReceivedData(packet, myNum, log.uuid, logJob)
} finally {
scope.launch {
mapsMutex.withLock {
@ -258,5 +254,5 @@ constructor(
}
}
private fun insertMeshLog(log: MeshLog): Job = scope.handledLaunch { meshLogRepository.get().insert(log) }
private fun insertMeshLog(log: MeshLog): Job = scope.handledLaunch { meshLogRepository.value.insert(log) }
}

View file

@ -16,8 +16,8 @@
*/
package org.meshtastic.core.data.manager
import dagger.Lazy
import kotlinx.coroutines.CoroutineScope
import org.koin.core.annotation.Single
import org.meshtastic.core.repository.MeshActionHandler
import org.meshtastic.core.repository.MeshConfigFlowManager
import org.meshtastic.core.repository.MeshConfigHandler
@ -26,15 +26,11 @@ import org.meshtastic.core.repository.MeshRouter
import org.meshtastic.core.repository.MqttManager
import org.meshtastic.core.repository.NeighborInfoHandler
import org.meshtastic.core.repository.TracerouteHandler
import javax.inject.Inject
import javax.inject.Singleton
/** Implementation of [MeshRouter] that orchestrates specialized mesh packet handlers. */
@Suppress("LongParameterList")
@Singleton
class MeshRouterImpl
@Inject
constructor(
@Single
class MeshRouterImpl(
private val dataHandlerLazy: Lazy<MeshDataHandler>,
private val configHandlerLazy: Lazy<MeshConfigHandler>,
private val tracerouteHandlerLazy: Lazy<TracerouteHandler>,
@ -44,25 +40,25 @@ constructor(
private val actionHandlerLazy: Lazy<MeshActionHandler>,
) : MeshRouter {
override val dataHandler: MeshDataHandler
get() = dataHandlerLazy.get()
get() = dataHandlerLazy.value
override val configHandler: MeshConfigHandler
get() = configHandlerLazy.get()
get() = configHandlerLazy.value
override val tracerouteHandler: TracerouteHandler
get() = tracerouteHandlerLazy.get()
get() = tracerouteHandlerLazy.value
override val neighborInfoHandler: NeighborInfoHandler
get() = neighborInfoHandlerLazy.get()
get() = neighborInfoHandlerLazy.value
override val configFlowManager: MeshConfigFlowManager
get() = configFlowManagerLazy.get()
get() = configFlowManagerLazy.value
override val mqttManager: MqttManager
get() = mqttManagerLazy.get()
get() = mqttManagerLazy.value
override val actionHandler: MeshActionHandler
get() = actionHandlerLazy.get()
get() = actionHandlerLazy.value
override fun start(scope: CoroutineScope) {
dataHandler.start(scope)

View file

@ -17,14 +17,13 @@
package org.meshtastic.core.data.manager
import co.touchlab.kermit.Logger
import org.koin.core.annotation.Single
import org.meshtastic.core.repository.FilterPrefs
import org.meshtastic.core.repository.MessageFilter
import javax.inject.Inject
import javax.inject.Singleton
/** Implementation of [MessageFilter] that uses regex and plain text matching. */
@Singleton
class MessageFilterImpl @Inject constructor(private val filterPrefs: FilterPrefs) : MessageFilter {
@Single
class MessageFilterImpl(private val filterPrefs: FilterPrefs) : MessageFilter {
private var compiledPatterns: List<Regex> = emptyList()
init {

View file

@ -25,19 +25,16 @@ import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import org.koin.core.annotation.Single
import org.meshtastic.core.network.repository.MQTTRepository
import org.meshtastic.core.repository.MqttManager
import org.meshtastic.core.repository.PacketHandler
import org.meshtastic.core.repository.ServiceRepository
import org.meshtastic.proto.MqttClientProxyMessage
import org.meshtastic.proto.ToRadio
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class MqttManagerImpl
@Inject
constructor(
@Single
class MqttManagerImpl(
private val mqttRepository: MQTTRepository,
private val packetHandler: PacketHandler,
private val serviceRepository: ServiceRepository,

View file

@ -20,6 +20,7 @@ import co.touchlab.kermit.Logger
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import org.koin.core.annotation.Single
import org.meshtastic.core.common.util.nowMillis
import org.meshtastic.core.repository.CommandSender
import org.meshtastic.core.repository.NeighborInfoHandler
@ -29,13 +30,9 @@ import org.meshtastic.core.repository.ServiceRepository
import org.meshtastic.proto.MeshPacket
import org.meshtastic.proto.NeighborInfo
import java.util.Locale
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class NeighborInfoHandlerImpl
@Inject
constructor(
@Single
class NeighborInfoHandlerImpl(
private val nodeManager: NodeManager,
private val serviceRepository: ServiceRepository,
private val commandSender: CommandSender,

View file

@ -26,6 +26,7 @@ import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.first
import okio.ByteString
import org.koin.core.annotation.Single
import org.meshtastic.core.common.util.handledLaunch
import org.meshtastic.core.model.DataPacket
import org.meshtastic.core.model.DeviceMetrics
@ -35,6 +36,7 @@ import org.meshtastic.core.model.MyNodeInfo
import org.meshtastic.core.model.Node
import org.meshtastic.core.model.NodeInfo
import org.meshtastic.core.model.Position
import org.meshtastic.core.model.util.NodeIdLookup
import org.meshtastic.core.repository.MeshServiceNotifications
import org.meshtastic.core.repository.NodeManager
import org.meshtastic.core.repository.NodeRepository
@ -45,17 +47,13 @@ import org.meshtastic.proto.Paxcount
import org.meshtastic.proto.StatusMessage
import org.meshtastic.proto.Telemetry
import org.meshtastic.proto.User
import javax.inject.Inject
import javax.inject.Singleton
import org.meshtastic.proto.NodeInfo as ProtoNodeInfo
import org.meshtastic.proto.Position as ProtoPosition
/** Implementation of [NodeManager] that maintains an in-memory database of the mesh. */
@Suppress("LongParameterList", "TooManyFunctions", "CyclomaticComplexMethod")
@Singleton
class NodeManagerImpl
@Inject
constructor(
@Single(binds = [NodeManager::class, NodeIdLookup::class])
class NodeManagerImpl(
private val nodeRepository: NodeRepository,
private val serviceBroadcasts: ServiceBroadcasts,
private val serviceNotifications: MeshServiceNotifications,

View file

@ -17,7 +17,6 @@
package org.meshtastic.core.data.manager
import co.touchlab.kermit.Logger
import dagger.Lazy
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@ -29,6 +28,7 @@ import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withTimeout
import kotlinx.coroutines.withTimeoutOrNull
import org.koin.core.annotation.Single
import org.meshtastic.core.common.util.handledLaunch
import org.meshtastic.core.common.util.nowMillis
import org.meshtastic.core.database.entity.MeshLog
@ -48,17 +48,13 @@ import org.meshtastic.proto.FromRadio
import org.meshtastic.proto.MeshPacket
import org.meshtastic.proto.QueueStatus
import org.meshtastic.proto.ToRadio
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds
import kotlin.uuid.Uuid
@Suppress("TooManyFunctions")
@Singleton
class PacketHandlerImpl
@Inject
constructor(
@Single
class PacketHandlerImpl(
private val packetRepository: Lazy<PacketRepository>,
private val serviceBroadcasts: ServiceBroadcasts,
private val radioInterfaceService: RadioInterfaceService,
@ -182,7 +178,7 @@ constructor(
if (packetId != 0) {
getDataPacketById(packetId)?.let { p ->
if (p.status == m) return@handledLaunch
packetRepository.get().updateMessageStatus(p, m)
packetRepository.value.updateMessageStatus(p, m)
serviceBroadcasts.broadcastMessageStatus(packetId, m)
}
}
@ -191,7 +187,7 @@ constructor(
private suspend fun getDataPacketById(packetId: Int): DataPacket? = withTimeoutOrNull(1.seconds) {
var dataPacket: DataPacket? = null
while (dataPacket == null) {
dataPacket = packetRepository.get().getPacketById(packetId)
dataPacket = packetRepository.value.getPacketById(packetId)
if (dataPacket == null) delay(100.milliseconds)
}
dataPacket
@ -222,7 +218,7 @@ constructor(
"insert: ${packetToSave.message_type} = " +
"${packetToSave.raw_message.toOneLineString()} from=${packetToSave.fromNum}"
}
meshLogRepository.get().insert(packetToSave)
meshLogRepository.value.insert(packetToSave)
}
}
}

View file

@ -20,6 +20,7 @@ import co.touchlab.kermit.Logger
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import org.koin.core.annotation.Single
import org.meshtastic.core.common.util.handledLaunch
import org.meshtastic.core.common.util.nowMillis
import org.meshtastic.core.data.repository.TracerouteSnapshotRepository
@ -34,13 +35,9 @@ import org.meshtastic.core.repository.ServiceRepository
import org.meshtastic.core.repository.TracerouteHandler
import org.meshtastic.proto.MeshPacket
import java.util.Locale
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class TracerouteHandlerImpl
@Inject
constructor(
@Single
class TracerouteHandlerImpl(
private val nodeManager: NodeManager,
private val serviceRepository: ServiceRepository,
private val tracerouteSnapshotRepository: TracerouteSnapshotRepository,

View file

@ -18,6 +18,7 @@ package org.meshtastic.core.data.repository
import co.touchlab.kermit.Logger
import kotlinx.coroutines.withContext
import org.koin.core.annotation.Single
import org.meshtastic.core.common.util.nowMillis
import org.meshtastic.core.data.datasource.BootloaderOtaQuirksJsonDataSource
import org.meshtastic.core.data.datasource.DeviceHardwareJsonDataSource
@ -30,14 +31,10 @@ import org.meshtastic.core.model.DeviceHardware
import org.meshtastic.core.model.util.TimeConstants
import org.meshtastic.core.network.DeviceHardwareRemoteDataSource
import org.meshtastic.core.repository.DeviceHardwareRepository
import javax.inject.Inject
import javax.inject.Singleton
// Annotating with Singleton to ensure a single instance manages the cache
@Singleton
class DeviceHardwareRepositoryImpl
@Inject
constructor(
@Single
class DeviceHardwareRepositoryImpl(
private val remoteDataSource: DeviceHardwareRemoteDataSource,
private val localDataSource: DeviceHardwareLocalDataSource,
private val jsonDataSource: DeviceHardwareJsonDataSource,

View file

@ -19,6 +19,7 @@ package org.meshtastic.core.data.repository
import co.touchlab.kermit.Logger
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import org.koin.core.annotation.Single
import org.meshtastic.core.common.util.nowMillis
import org.meshtastic.core.data.datasource.FirmwareReleaseJsonDataSource
import org.meshtastic.core.data.datasource.FirmwareReleaseLocalDataSource
@ -28,13 +29,9 @@ import org.meshtastic.core.database.entity.FirmwareReleaseType
import org.meshtastic.core.database.entity.asExternalModel
import org.meshtastic.core.model.util.TimeConstants
import org.meshtastic.core.network.FirmwareReleaseRemoteDataSource
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class FirmwareReleaseRepository
@Inject
constructor(
@Single
class FirmwareReleaseRepository(
private val remoteDataSource: FirmwareReleaseRemoteDataSource,
private val localDataSource: FirmwareReleaseLocalDataSource,
private val jsonDataSource: FirmwareReleaseJsonDataSource,

View file

@ -25,6 +25,7 @@ import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.withContext
import org.koin.core.annotation.Single
import org.meshtastic.core.common.util.nowMillis
import org.meshtastic.core.data.datasource.NodeInfoReadDataSource
import org.meshtastic.core.database.DatabaseManager
@ -37,8 +38,6 @@ import org.meshtastic.proto.MeshPacket
import org.meshtastic.proto.MyNodeInfo
import org.meshtastic.proto.PortNum
import org.meshtastic.proto.Telemetry
import javax.inject.Inject
import javax.inject.Singleton
/**
* Repository implementation for managing and retrieving logs from the local database.
@ -47,10 +46,8 @@ import javax.inject.Singleton
* telemetry and traceroute data.
*/
@Suppress("TooManyFunctions")
@Singleton
class MeshLogRepositoryImpl
@Inject
constructor(
@Single
class MeshLogRepositoryImpl(
private val dbManager: DatabaseManager,
private val dispatchers: CoroutineDispatchers,
private val meshLogPrefs: MeshLogPrefs,

View file

@ -34,6 +34,8 @@ import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koin.core.annotation.Named
import org.koin.core.annotation.Single
import org.meshtastic.core.data.datasource.NodeInfoReadDataSource
import org.meshtastic.core.data.datasource.NodeInfoWriteDataSource
import org.meshtastic.core.database.entity.MeshLog
@ -42,7 +44,6 @@ import org.meshtastic.core.database.entity.MyNodeEntity
import org.meshtastic.core.database.entity.NodeEntity
import org.meshtastic.core.datastore.LocalStatsDataSource
import org.meshtastic.core.di.CoroutineDispatchers
import org.meshtastic.core.di.ProcessLifecycle
import org.meshtastic.core.model.DataPacket
import org.meshtastic.core.model.MyNodeInfo
import org.meshtastic.core.model.Node
@ -53,16 +54,12 @@ import org.meshtastic.proto.DeviceMetadata
import org.meshtastic.proto.HardwareModel
import org.meshtastic.proto.LocalStats
import org.meshtastic.proto.User
import javax.inject.Inject
import javax.inject.Singleton
/** Repository for managing node-related data, including hardware info, node database, and identity. */
@Singleton
@Single
@Suppress("TooManyFunctions")
class NodeRepositoryImpl
@Inject
constructor(
@ProcessLifecycle private val processLifecycle: Lifecycle,
class NodeRepositoryImpl(
@Named("ProcessLifecycle") private val processLifecycle: Lifecycle,
private val nodeInfoReadDataSource: NodeInfoReadDataSource,
private val nodeInfoWriteDataSource: NodeInfoWriteDataSource,
private val dispatchers: CoroutineDispatchers,

View file

@ -26,6 +26,7 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.withContext
import okio.ByteString.Companion.toByteString
import org.koin.core.annotation.Single
import org.meshtastic.core.database.DatabaseManager
import org.meshtastic.core.database.entity.toReaction
import org.meshtastic.core.di.CoroutineDispatchers
@ -37,19 +38,15 @@ import org.meshtastic.core.model.Node
import org.meshtastic.core.model.Reaction
import org.meshtastic.proto.ChannelSettings
import org.meshtastic.proto.PortNum
import javax.inject.Inject
import org.meshtastic.core.database.entity.ContactSettings as ContactSettingsEntity
import org.meshtastic.core.database.entity.Packet as RoomPacket
import org.meshtastic.core.database.entity.ReactionEntity as RoomReaction
import org.meshtastic.core.repository.PacketRepository as SharedPacketRepository
@Suppress("TooManyFunctions", "LongParameterList")
class PacketRepositoryImpl
@Inject
constructor(
private val dbManager: DatabaseManager,
private val dispatchers: CoroutineDispatchers,
) : SharedPacketRepository {
@Single
class PacketRepositoryImpl(private val dbManager: DatabaseManager, private val dispatchers: CoroutineDispatchers) :
SharedPacketRepository {
override fun getWaypoints(): Flow<List<DataPacket>> = dbManager.currentDb
.flatMapLatest { db -> db.packetDao().getAllWaypointsFlow() }

View file

@ -19,17 +19,13 @@ package org.meshtastic.core.data.repository
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.withContext
import org.koin.core.annotation.Single
import org.meshtastic.core.database.DatabaseManager
import org.meshtastic.core.database.entity.QuickChatAction
import org.meshtastic.core.di.CoroutineDispatchers
import javax.inject.Inject
class QuickChatActionRepository
@Inject
constructor(
private val dbManager: DatabaseManager,
private val dispatchers: CoroutineDispatchers,
) {
@Single
class QuickChatActionRepository(private val dbManager: DatabaseManager, private val dispatchers: CoroutineDispatchers) {
fun getAllActions() = dbManager.currentDb.flatMapLatest { it.quickChatActionDao().getAll() }.flowOn(dispatchers.io)
suspend fun upsert(action: QuickChatAction) =

View file

@ -18,6 +18,7 @@ package org.meshtastic.core.data.repository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import org.koin.core.annotation.Single
import org.meshtastic.core.datastore.ChannelSetDataSource
import org.meshtastic.core.datastore.LocalConfigDataSource
import org.meshtastic.core.datastore.ModuleConfigDataSource
@ -32,15 +33,13 @@ import org.meshtastic.proto.DeviceProfile
import org.meshtastic.proto.LocalConfig
import org.meshtastic.proto.LocalModuleConfig
import org.meshtastic.proto.ModuleConfig
import javax.inject.Inject
/**
* Class responsible for radio configuration data. Combines access to [nodeDB], [ChannelSet], [LocalConfig] &
* [LocalModuleConfig].
*/
open class RadioConfigRepositoryImpl
@Inject
constructor(
@Single
open class RadioConfigRepositoryImpl(
private val nodeDB: NodeRepository,
private val channelSetDataSource: ChannelSetDataSource,
private val localConfigDataSource: LocalConfigDataSource,

View file

@ -23,15 +23,14 @@ import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.withContext
import org.koin.core.annotation.Single
import org.meshtastic.core.database.DatabaseManager
import org.meshtastic.core.database.entity.TracerouteNodePositionEntity
import org.meshtastic.core.di.CoroutineDispatchers
import org.meshtastic.proto.Position
import javax.inject.Inject
class TracerouteSnapshotRepository
@Inject
constructor(
@Single
class TracerouteSnapshotRepository(
private val dbManager: DatabaseManager,
private val dispatchers: CoroutineDispatchers,
) {

View file

@ -46,7 +46,13 @@ class FromRadioPacketHandlerImplTest {
@Before
fun setup() {
handler =
FromRadioPacketHandlerImpl(serviceRepository, { router }, mqttManager, packetHandler, serviceNotifications)
FromRadioPacketHandlerImpl(
serviceRepository,
lazy { router },
mqttManager,
packetHandler,
serviceNotifications,
)
}
@Test

View file

@ -16,7 +16,6 @@
*/
package org.meshtastic.core.data.manager
import dagger.Lazy
import io.mockk.coVerify
import io.mockk.every
import io.mockk.mockk
@ -58,19 +57,19 @@ class MeshDataHandlerTest {
private val packetHandler: PacketHandler = mockk(relaxed = true)
private val serviceRepository: ServiceRepository = mockk(relaxed = true)
private val packetRepository: PacketRepository = mockk(relaxed = true)
private val packetRepositoryLazy: Lazy<PacketRepository> = mockk { every { get() } returns packetRepository }
private val packetRepositoryLazy: Lazy<PacketRepository> = lazy { packetRepository }
private val serviceBroadcasts: ServiceBroadcasts = mockk(relaxed = true)
private val serviceNotifications: MeshServiceNotifications = mockk(relaxed = true)
private val analytics: PlatformAnalytics = mockk(relaxed = true)
private val dataMapper: MeshDataMapper = mockk(relaxed = true)
private val configHandler: MeshConfigHandler = mockk(relaxed = true)
private val configHandlerLazy: Lazy<MeshConfigHandler> = mockk { every { get() } returns configHandler }
private val configHandlerLazy: Lazy<MeshConfigHandler> = lazy { configHandler }
private val configFlowManager: MeshConfigFlowManager = mockk(relaxed = true)
private val configFlowManagerLazy: Lazy<MeshConfigFlowManager> = mockk { every { get() } returns configFlowManager }
private val configFlowManagerLazy: Lazy<MeshConfigFlowManager> = lazy { configFlowManager }
private val commandSender: CommandSender = mockk(relaxed = true)
private val historyManager: HistoryManager = mockk(relaxed = true)
private val connectionManager: MeshConnectionManager = mockk(relaxed = true)
private val connectionManagerLazy: Lazy<MeshConnectionManager> = mockk { every { get() } returns connectionManager }
private val connectionManagerLazy: Lazy<MeshConnectionManager> = lazy { connectionManager }
private val tracerouteHandler: TracerouteHandler = mockk(relaxed = true)
private val neighborInfoHandler: NeighborInfoHandler = mockk(relaxed = true)
private val radioConfigRepository: RadioConfigRepository = mockk(relaxed = true)

View file

@ -60,10 +60,10 @@ class PacketHandlerImplTest {
handler =
PacketHandlerImpl(
{ packetRepository },
lazy { packetRepository },
serviceBroadcasts,
radioInterfaceService,
{ meshLogRepository },
lazy { meshLogRepository },
serviceRepository,
)
handler.start(testScope)