mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
refactor(transport): complete transport architecture overhaul — extract callback, wire BleReconnectPolicy, fix safety issues (#5080)
This commit is contained in:
parent
962c619c4c
commit
e85300531e
64 changed files with 1184 additions and 1018 deletions
|
|
@ -34,16 +34,25 @@ import org.meshtastic.core.model.NetworkFirmwareReleases
|
|||
import org.meshtastic.core.model.RadioController
|
||||
import org.meshtastic.core.network.KermitHttpLogger
|
||||
import org.meshtastic.core.network.repository.MQTTRepository
|
||||
import org.meshtastic.core.network.service.ApiService
|
||||
import org.meshtastic.core.network.service.ApiServiceImpl
|
||||
import org.meshtastic.core.repository.AppWidgetUpdater
|
||||
import org.meshtastic.core.repository.LocationRepository
|
||||
import org.meshtastic.core.repository.MeshLocationManager
|
||||
import org.meshtastic.core.repository.MeshServiceNotifications
|
||||
import org.meshtastic.core.repository.MeshWorkerManager
|
||||
import org.meshtastic.core.repository.MessageQueue
|
||||
import org.meshtastic.core.repository.NotificationManager
|
||||
import org.meshtastic.core.repository.PlatformAnalytics
|
||||
import org.meshtastic.core.repository.RadioTransportFactory
|
||||
import org.meshtastic.core.repository.ServiceBroadcasts
|
||||
import org.meshtastic.core.repository.ServiceRepository
|
||||
import org.meshtastic.core.service.DirectRadioControllerImpl
|
||||
import org.meshtastic.core.service.ServiceRepositoryImpl
|
||||
import org.meshtastic.desktop.DesktopBuildConfig
|
||||
import org.meshtastic.desktop.DesktopNotificationManager
|
||||
import org.meshtastic.desktop.notification.DesktopMeshServiceNotifications
|
||||
import org.meshtastic.desktop.radio.DesktopMessageQueue
|
||||
import org.meshtastic.desktop.radio.DesktopRadioTransportFactory
|
||||
import org.meshtastic.desktop.stub.NoopAppWidgetUpdater
|
||||
import org.meshtastic.desktop.stub.NoopCompassHeadingProvider
|
||||
|
|
@ -55,6 +64,9 @@ import org.meshtastic.desktop.stub.NoopMeshWorkerManager
|
|||
import org.meshtastic.desktop.stub.NoopPhoneLocationProvider
|
||||
import org.meshtastic.desktop.stub.NoopPlatformAnalytics
|
||||
import org.meshtastic.desktop.stub.NoopServiceBroadcasts
|
||||
import org.meshtastic.feature.node.compass.CompassHeadingProvider
|
||||
import org.meshtastic.feature.node.compass.MagneticFieldProvider
|
||||
import org.meshtastic.feature.node.compass.PhoneLocationProvider
|
||||
import org.meshtastic.core.ble.di.module as coreBleModule
|
||||
import org.meshtastic.core.common.di.module as coreCommonModule
|
||||
import org.meshtastic.core.data.di.module as coreDataModule
|
||||
|
|
@ -124,7 +136,7 @@ fun desktopModule() = module {
|
|||
*/
|
||||
@Suppress("LongMethod")
|
||||
private fun desktopPlatformStubsModule() = module {
|
||||
single<ServiceRepository> { org.meshtastic.core.service.ServiceRepositoryImpl() }
|
||||
single<ServiceRepository> { ServiceRepositoryImpl() }
|
||||
single<RadioTransportFactory> {
|
||||
DesktopRadioTransportFactory(
|
||||
dispatchers = get(),
|
||||
|
|
@ -134,7 +146,7 @@ private fun desktopPlatformStubsModule() = module {
|
|||
)
|
||||
}
|
||||
single<RadioController> {
|
||||
org.meshtastic.core.service.DirectRadioControllerImpl(
|
||||
DirectRadioControllerImpl(
|
||||
serviceRepository = get(),
|
||||
nodeRepository = get(),
|
||||
commandSender = get(),
|
||||
|
|
@ -144,37 +156,29 @@ private fun desktopPlatformStubsModule() = module {
|
|||
locationManager = get(),
|
||||
)
|
||||
}
|
||||
single { org.meshtastic.desktop.DesktopNotificationManager(prefs = get()) }
|
||||
single<org.meshtastic.core.repository.NotificationManager> {
|
||||
get<org.meshtastic.desktop.DesktopNotificationManager>()
|
||||
}
|
||||
single<MeshServiceNotifications> {
|
||||
org.meshtastic.desktop.notification.DesktopMeshServiceNotifications(notificationManager = get())
|
||||
}
|
||||
single { DesktopNotificationManager(prefs = get()) }
|
||||
single<NotificationManager> { get<DesktopNotificationManager>() }
|
||||
single<MeshServiceNotifications> { DesktopMeshServiceNotifications(notificationManager = get()) }
|
||||
single<PlatformAnalytics> { NoopPlatformAnalytics() }
|
||||
single<ServiceBroadcasts> { NoopServiceBroadcasts() }
|
||||
single<AppWidgetUpdater> { NoopAppWidgetUpdater() }
|
||||
single<MeshWorkerManager> { NoopMeshWorkerManager() }
|
||||
single<MessageQueue> {
|
||||
org.meshtastic.desktop.radio.DesktopMessageQueue(packetRepository = get(), radioController = get())
|
||||
}
|
||||
single<MessageQueue> { DesktopMessageQueue(packetRepository = get(), radioController = get()) }
|
||||
single<MeshLocationManager> { NoopMeshLocationManager() }
|
||||
single<LocationRepository> { NoopLocationRepository() }
|
||||
single<MQTTRepository> { NoopMQTTRepository() }
|
||||
single<org.meshtastic.feature.node.compass.CompassHeadingProvider> { NoopCompassHeadingProvider() }
|
||||
single<org.meshtastic.feature.node.compass.PhoneLocationProvider> { NoopPhoneLocationProvider() }
|
||||
single<org.meshtastic.feature.node.compass.MagneticFieldProvider> { NoopMagneticFieldProvider() }
|
||||
single<CompassHeadingProvider> { NoopCompassHeadingProvider() }
|
||||
single<PhoneLocationProvider> { NoopPhoneLocationProvider() }
|
||||
single<MagneticFieldProvider> { NoopMagneticFieldProvider() }
|
||||
|
||||
// Desktop uses the real ApiService implementation (no flavor stub needed)
|
||||
single<org.meshtastic.core.network.service.ApiService> {
|
||||
org.meshtastic.core.network.service.ApiServiceImpl(client = get())
|
||||
}
|
||||
single<ApiService> { ApiServiceImpl(client = get()) }
|
||||
|
||||
// Ktor HttpClient for JVM/Desktop (equivalent of CoreNetworkAndroidModule on Android)
|
||||
single<HttpClient> {
|
||||
HttpClient(Java) {
|
||||
install(ContentNegotiation) { json(get<Json>()) }
|
||||
if (org.meshtastic.desktop.DesktopBuildConfig.IS_DEBUG) {
|
||||
if (DesktopBuildConfig.IS_DEBUG) {
|
||||
install(Logging) {
|
||||
logger = KermitHttpLogger
|
||||
level = LogLevel.HEADERS
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import org.meshtastic.core.model.DeviceType
|
|||
import org.meshtastic.core.model.InterfaceId
|
||||
import org.meshtastic.core.network.SerialTransport
|
||||
import org.meshtastic.core.network.radio.BaseRadioTransportFactory
|
||||
import org.meshtastic.core.network.radio.TCPInterface
|
||||
import org.meshtastic.core.network.radio.TcpRadioTransport
|
||||
import org.meshtastic.core.repository.RadioInterfaceService
|
||||
import org.meshtastic.core.repository.RadioTransport
|
||||
import org.meshtastic.core.repository.RadioTransportFactory
|
||||
|
|
@ -45,16 +45,22 @@ class DesktopRadioTransportFactory(
|
|||
|
||||
override val supportedDeviceTypes: List<DeviceType> = listOf(DeviceType.TCP, DeviceType.BLE, DeviceType.USB)
|
||||
|
||||
override fun isMockInterface(): Boolean = false
|
||||
override fun isMockTransport(): Boolean = false
|
||||
|
||||
override fun createPlatformTransport(address: String, service: RadioInterfaceService): RadioTransport = when {
|
||||
address.startsWith(InterfaceId.TCP.id) -> {
|
||||
TCPInterface(service, dispatchers, address.removePrefix(InterfaceId.TCP.id.toString()))
|
||||
TcpRadioTransport(
|
||||
callback = service,
|
||||
scope = service.serviceScope,
|
||||
dispatchers = dispatchers,
|
||||
address = address.removePrefix(InterfaceId.TCP.id.toString()),
|
||||
)
|
||||
}
|
||||
address.startsWith(InterfaceId.SERIAL.id) -> {
|
||||
SerialTransport.open(
|
||||
portName = address.removePrefix(InterfaceId.SERIAL.id.toString()),
|
||||
service = service,
|
||||
callback = service,
|
||||
scope = service.serviceScope,
|
||||
dispatchers = dispatchers,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ package org.meshtastic.desktop.stub
|
|||
|
||||
import co.touchlab.kermit.Logger
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
|
|
@ -27,6 +28,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||
import kotlinx.coroutines.flow.emptyFlow
|
||||
import org.meshtastic.core.model.ConnectionState
|
||||
import org.meshtastic.core.model.DataPacket
|
||||
import org.meshtastic.core.model.DeviceType
|
||||
import org.meshtastic.core.model.InterfaceId
|
||||
import org.meshtastic.core.model.MeshActivity
|
||||
import org.meshtastic.core.model.MessageStatus
|
||||
|
|
@ -37,14 +39,11 @@ import org.meshtastic.core.repository.DataPair
|
|||
import org.meshtastic.core.repository.Location
|
||||
import org.meshtastic.core.repository.LocationRepository
|
||||
import org.meshtastic.core.repository.MeshLocationManager
|
||||
import org.meshtastic.core.repository.MeshServiceNotifications
|
||||
import org.meshtastic.core.repository.MeshWorkerManager
|
||||
import org.meshtastic.core.repository.PlatformAnalytics
|
||||
import org.meshtastic.core.repository.RadioInterfaceService
|
||||
import org.meshtastic.core.repository.ServiceBroadcasts
|
||||
import org.meshtastic.proto.ClientNotification
|
||||
import org.meshtastic.proto.MqttClientProxyMessage
|
||||
import org.meshtastic.proto.Telemetry
|
||||
import org.meshtastic.proto.Position as ProtoPosition
|
||||
|
||||
/**
|
||||
|
|
@ -66,12 +65,12 @@ private fun logWarn(message: String) {
|
|||
// region Transport / Radio Stubs (Android BLE/USB — no commonMain impl)
|
||||
|
||||
class NoopRadioInterfaceService : RadioInterfaceService {
|
||||
override val supportedDeviceTypes: List<org.meshtastic.core.model.DeviceType> = emptyList()
|
||||
override val supportedDeviceTypes: List<DeviceType> = emptyList()
|
||||
|
||||
override val connectionState = MutableStateFlow<ConnectionState>(ConnectionState.Disconnected)
|
||||
override val currentDeviceAddressFlow = MutableStateFlow<String?>(null)
|
||||
|
||||
override fun isMockInterface(): Boolean = false
|
||||
override fun isMockTransport(): Boolean = false
|
||||
|
||||
override val receivedData = MutableSharedFlow<ByteArray>()
|
||||
override val meshActivity = MutableSharedFlow<MeshActivity>()
|
||||
|
|
@ -98,65 +97,13 @@ class NoopRadioInterfaceService : RadioInterfaceService {
|
|||
override fun handleFromRadio(bytes: ByteArray) {}
|
||||
|
||||
@Suppress("InjectDispatcher")
|
||||
override val serviceScope: CoroutineScope = CoroutineScope(SupervisorJob() + kotlinx.coroutines.Dispatchers.Default)
|
||||
override val serviceScope: CoroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Default)
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region Notification / Platform Stubs (Android-only)
|
||||
|
||||
@Suppress("TooManyFunctions")
|
||||
class NoopMeshServiceNotifications : MeshServiceNotifications {
|
||||
override fun clearNotifications() {}
|
||||
|
||||
override fun initChannels() {}
|
||||
|
||||
override fun updateServiceStateNotification(
|
||||
state: org.meshtastic.core.model.ConnectionState,
|
||||
telemetry: Telemetry?,
|
||||
) {}
|
||||
|
||||
override suspend fun updateMessageNotification(
|
||||
contactKey: String,
|
||||
name: String,
|
||||
message: String,
|
||||
isBroadcast: Boolean,
|
||||
channelName: String?,
|
||||
isSilent: Boolean,
|
||||
) {}
|
||||
|
||||
override suspend fun updateWaypointNotification(
|
||||
contactKey: String,
|
||||
name: String,
|
||||
message: String,
|
||||
waypointId: Int,
|
||||
isSilent: Boolean,
|
||||
) {}
|
||||
|
||||
override suspend fun updateReactionNotification(
|
||||
contactKey: String,
|
||||
name: String,
|
||||
emoji: String,
|
||||
isBroadcast: Boolean,
|
||||
channelName: String?,
|
||||
isSilent: Boolean,
|
||||
) {}
|
||||
|
||||
override fun showAlertNotification(contactKey: String, name: String, alert: String) {}
|
||||
|
||||
override fun showNewNodeSeenNotification(node: Node) {}
|
||||
|
||||
override fun showOrUpdateLowBatteryNotification(node: Node, isRemote: Boolean) {}
|
||||
|
||||
override fun showClientNotification(clientNotification: ClientNotification) {}
|
||||
|
||||
override fun cancelMessageNotification(contactKey: String) {}
|
||||
|
||||
override fun cancelLowBatteryNotification(node: Node) {}
|
||||
|
||||
override fun clearClientNotification(notification: ClientNotification) {}
|
||||
}
|
||||
|
||||
class NoopPlatformAnalytics : PlatformAnalytics {
|
||||
override fun track(event: String, vararg properties: DataPair) {}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue