mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-05-12 16:55:02 -04:00
refactor: narrow ViewModel injections, add ConnectionAware, delete dead code, integration tests
ViewModel Narrowing: - V1: Created ConnectionAware interface; MessageSender, DeviceAdmin, DeviceControl extend it - V2: Narrowed 6 ViewModels/actions to focused sub-interfaces (DeviceAdmin, MessageSender, DataRequester, DeviceControl) Cleanup: - C1: Deleted dead MeshDataMapper and its DI registration Integration Tests: - T2: SdkStateBridgeTest verifying WentOffline/CameOnline presence handling - Verified Koin resolution, full test suite passes Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -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.model
|
||||
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
/** Provides read-only access to the app's connection state. */
|
||||
interface ConnectionAware {
|
||||
val connectionState: StateFlow<ConnectionState>
|
||||
}
|
||||
@@ -20,7 +20,7 @@ import org.meshtastic.proto.Channel
|
||||
import org.meshtastic.proto.Config
|
||||
|
||||
/** Focused interface for local device configuration and edit sessions. */
|
||||
interface DeviceAdmin {
|
||||
interface DeviceAdmin : ConnectionAware {
|
||||
suspend fun setLocalConfig(config: Config)
|
||||
suspend fun setLocalChannel(channel: Channel)
|
||||
suspend fun beginEditSettings(destNum: Int)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
package org.meshtastic.core.model
|
||||
|
||||
/** Focused interface for device lifecycle control. */
|
||||
interface DeviceControl {
|
||||
interface DeviceControl : ConnectionAware {
|
||||
suspend fun reboot(destNum: Int, packetId: Int)
|
||||
suspend fun rebootToDfu(nodeNum: Int)
|
||||
suspend fun requestRebootOta(requestId: Int, destNum: Int, mode: Int, hash: ByteArray?)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
package org.meshtastic.core.model
|
||||
|
||||
/** Focused interface for sending messages over the mesh. */
|
||||
interface MessageSender {
|
||||
interface MessageSender : ConnectionAware {
|
||||
suspend fun sendMessage(packet: DataPacket)
|
||||
fun getPacketId(): Int
|
||||
}
|
||||
|
||||
@@ -26,18 +26,6 @@ import org.meshtastic.proto.ClientNotification
|
||||
* This super-interface remains for backward compatibility with existing injections.
|
||||
*/
|
||||
interface RadioController : MessageSender, DeviceAdmin, RemoteAdmin, DeviceControl, DataRequester {
|
||||
/**
|
||||
* Canonical app-level connection state, delegated from [ServiceRepository][connectionState].
|
||||
*
|
||||
* This exposes the same single source of truth as `ServiceRepository.connectionState`, surfaced through the
|
||||
* controller interface for convenience in feature modules and ViewModels that depend on [RadioController] rather
|
||||
* than [ServiceRepository] directly.
|
||||
*
|
||||
* This is **not** the transport-level state — it reflects the fully reconciled app-level state including handshake
|
||||
* progress and device sleep policy.
|
||||
*/
|
||||
val connectionState: StateFlow<ConnectionState>
|
||||
|
||||
/**
|
||||
* Flow of notifications from the radio client.
|
||||
*
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
@file:Suppress("MagicNumber")
|
||||
|
||||
package org.meshtastic.core.model.util
|
||||
|
||||
import okio.ByteString.Companion.toByteString
|
||||
import org.meshtastic.core.model.DataPacket
|
||||
import org.meshtastic.proto.MeshPacket
|
||||
|
||||
/**
|
||||
* Utility class to map [MeshPacket] protobufs to [DataPacket] domain models.
|
||||
*
|
||||
* This class is platform-agnostic and can be used in shared logic.
|
||||
*/
|
||||
open class MeshDataMapper(private val nodeIdLookup: NodeIdLookup) {
|
||||
|
||||
/** Maps a [MeshPacket] to a [DataPacket], or returns null if the packet has no decoded data. */
|
||||
open fun toDataPacket(packet: MeshPacket): DataPacket? {
|
||||
val decoded = packet.decoded ?: return null
|
||||
return DataPacket(
|
||||
from = packet.from,
|
||||
to = packet.to,
|
||||
time = packet.rx_time * 1000L,
|
||||
id = packet.id,
|
||||
dataType = decoded.portnum.value,
|
||||
bytes = decoded.payload.toByteArray().toByteString(),
|
||||
hopLimit = packet.hop_limit,
|
||||
channel = if (packet.pki_encrypted == true) DataPacket.PKC_CHANNEL_INDEX else packet.channel,
|
||||
wantAck = packet.want_ack == true,
|
||||
hopStart = packet.hop_start,
|
||||
snr = packet.rx_snr,
|
||||
rssi = packet.rx_rssi,
|
||||
replyId = decoded.reply_id,
|
||||
relayNode = packet.relay_node,
|
||||
viaMqtt = packet.via_mqtt == true,
|
||||
emoji = decoded.emoji,
|
||||
transportMechanism = packet.transport_mechanism.value,
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user