From 4eba3e9daf930689c859b41fc1dbcbea371a1381 Mon Sep 17 00:00:00 2001 From: Phil Oliver <3497406+poliver@users.noreply.github.com> Date: Wed, 24 Sep 2025 11:43:46 -0400 Subject: [PATCH] Modularize more models/utils (#3182) --- .../com/geeksville/mesh/NodeInfoDaoTest.kt | 293 ++++++++++-------- .../java/com/geeksville/mesh/PacketDaoTest.kt | 47 ++- .../mesh/compose/MessageItemTest.kt | 2 +- .../com/geeksville/mesh/ui/map/MapView.kt | 4 +- .../com/geeksville/mesh/ui/map/MapView.kt | 6 +- .../com/geeksville/mesh/IMeshService.aidl | 10 +- .../geeksville/mesh/database/Converters.kt | 2 +- .../mesh/database/NodeRepository.kt | 4 +- .../mesh/database/PacketRepository.kt | 105 +++---- .../geeksville/mesh/database/dao/PacketDao.kt | 70 +++-- .../database/entity/DeviceHardwareEntity.kt | 2 +- .../database/entity/FirmwareReleaseEntity.kt | 4 +- .../mesh/database/entity/MyNodeEntity.kt | 8 +- .../mesh/database/entity/NodeEntity.kt | 12 +- .../geeksville/mesh/database/entity/Packet.kt | 47 +-- .../com/geeksville/mesh/model/BTScanModel.kt | 2 +- .../mesh/model/EnvironmentMetricsState.kt | 2 +- .../java/com/geeksville/mesh/model/Message.kt | 2 +- .../geeksville/mesh/model/MetricsViewModel.kt | 2 +- .../java/com/geeksville/mesh/model/Node.kt | 8 +- .../java/com/geeksville/mesh/model/UIState.kt | 6 +- .../api/DeviceHardwareJsonDataSource.kt | 2 +- .../api/DeviceHardwareLocalDataSource.kt | 2 +- .../api/FirmwareReleaseJsonDataSource.kt | 2 +- .../api/FirmwareReleaseLocalDataSource.kt | 2 +- .../repository/bluetooth/BluetoothState.kt | 12 +- .../repository/radio/BluetoothInterface.kt | 2 +- .../radio/BluetoothInterfaceSpec.kt | 20 +- .../mesh/repository/radio/MockInterface.kt | 4 +- .../repository/radio/RadioInterfaceService.kt | 2 +- .../geeksville/mesh/service/MeshService.kt | 27 +- .../mesh/service/MeshServiceBroadcasts.kt | 6 +- .../mesh/service/MeshServiceNotifications.kt | 2 +- .../geeksville/mesh/service/PacketHandler.kt | 8 +- .../geeksville/mesh/service/ReplyReceiver.kt | 18 +- .../main/java/com/geeksville/mesh/ui/Main.kt | 2 +- .../preview/NodePreviewParameterProvider.kt | 225 +++++++------- .../com/geeksville/mesh/ui/message/Message.kt | 2 +- .../geeksville/mesh/ui/message/MessageList.kt | 2 +- .../ui/message/components/MessageActions.kt | 2 +- .../mesh/ui/message/components/MessageItem.kt | 2 +- .../mesh/ui/metrics/EnvironmentMetrics.kt | 3 +- .../mesh/ui/metrics/HostMetricsLog.kt | 2 +- .../geeksville/mesh/ui/metrics/PaxMetrics.kt | 2 +- .../com/geeksville/mesh/ui/node/NodeDetail.kt | 12 +- .../com/geeksville/mesh/ui/node/NodeScreen.kt | 4 +- .../mesh/ui/node/components/LastHeardInfo.kt | 2 +- .../ui/node/components/LinkedCoordinates.kt | 2 +- .../mesh/ui/settings/SettingsViewModel.kt | 4 +- .../ui/settings/radio/RadioConfigViewModel.kt | 2 +- .../radio/components/ChannelLegend.kt | 2 +- .../components/ChannelSettingsItemList.kt | 2 +- .../components/PositionConfigItemList.kt | 2 +- .../radio/components/UserConfigItemList.kt | 3 +- .../mesh/ui/sharing/ContactSharing.kt | 2 +- .../java/com/geeksville/mesh/NodeInfoTest.kt | 3 + .../java/com/geeksville/mesh/PositionTest.kt | 2 +- .../mesh/model/DeviceVersionTest.kt | 6 +- .../mesh/ui/metrics/EnvironmentMetricsTest.kt | 2 +- core/model/build.gradle.kts | 15 +- .../org/meshtastic/core/model/DataPacket.aidl | 3 + .../org/meshtastic/core/model/MeshUser.aidl | 3 + .../org/meshtastic/core/model/MyNodeInfo.aidl | 3 + .../org/meshtastic/core/model/NodeInfo.aidl | 3 + .../org/meshtastic/core/model/Position.aidl | 3 + .../org/meshtastic/core/model}/DataPacket.kt | 112 ++++--- .../meshtastic/core}/model/DeviceVersion.kt | 34 +- .../org/meshtastic/core/model}/MyNodeInfo.kt | 5 +- .../core}/model/NetworkDeviceHardware.kt | 2 +- .../core}/model/NetworkFirmwareRelease.kt | 2 +- .../org/meshtastic/core/model}/NodeInfo.kt | 20 +- .../core/model}/util/DateTimeUtils.kt | 5 +- .../meshtastic/core/model}/util/Extensions.kt | 5 +- .../core/model}/util/LocationUtils.kt | 8 +- .../core/model}/util/UnitConversions.kt | 10 +- core/network/build.gradle.kts | 1 + .../core/network/di/FDroidNetworkModule.kt | 4 +- .../network/DeviceHardwareRemoteDataSource.kt | 2 +- .../FirmwareReleaseRemoteDataSource.kt | 2 +- .../core/network/service/ApiService.kt | 4 +- 80 files changed, 656 insertions(+), 629 deletions(-) create mode 100644 core/model/src/main/aidl/org/meshtastic/core/model/DataPacket.aidl create mode 100644 core/model/src/main/aidl/org/meshtastic/core/model/MeshUser.aidl create mode 100644 core/model/src/main/aidl/org/meshtastic/core/model/MyNodeInfo.aidl create mode 100644 core/model/src/main/aidl/org/meshtastic/core/model/NodeInfo.aidl create mode 100644 core/model/src/main/aidl/org/meshtastic/core/model/Position.aidl rename {app/src/main/java/com/geeksville/mesh => core/model/src/main/kotlin/org/meshtastic/core/model}/DataPacket.kt (74%) rename {app/src/main/java/com/geeksville/mesh => core/model/src/main/kotlin/org/meshtastic/core}/model/DeviceVersion.kt (65%) rename {app/src/main/java/com/geeksville/mesh => core/model/src/main/kotlin/org/meshtastic/core/model}/MyNodeInfo.kt (93%) rename core/{network/src/main/kotlin/org/meshtastic/core/network => model/src/main/kotlin/org/meshtastic/core}/model/NetworkDeviceHardware.kt (97%) rename core/{network/src/main/kotlin/org/meshtastic/core/network => model/src/main/kotlin/org/meshtastic/core}/model/NetworkFirmwareRelease.kt (97%) rename {app/src/main/java/com/geeksville/mesh => core/model/src/main/kotlin/org/meshtastic/core/model}/NodeInfo.kt (94%) rename {app/src/main/java/com/geeksville/mesh => core/model/src/main/kotlin/org/meshtastic/core/model}/util/DateTimeUtils.kt (97%) rename {app/src/main/java/com/geeksville/mesh => core/model/src/main/kotlin/org/meshtastic/core/model}/util/Extensions.kt (97%) rename {app/src/main/java/com/geeksville/mesh => core/model/src/main/kotlin/org/meshtastic/core/model}/util/LocationUtils.kt (93%) rename {app/src/main/java/com/geeksville/mesh => core/model/src/main/kotlin/org/meshtastic/core/model}/util/UnitConversions.kt (86%) diff --git a/app/src/androidTest/java/com/geeksville/mesh/NodeInfoDaoTest.kt b/app/src/androidTest/java/com/geeksville/mesh/NodeInfoDaoTest.kt index 8111c538e..c90bcc3ac 100644 --- a/app/src/androidTest/java/com/geeksville/mesh/NodeInfoDaoTest.kt +++ b/app/src/androidTest/java/com/geeksville/mesh/NodeInfoDaoTest.kt @@ -26,7 +26,6 @@ import com.geeksville.mesh.database.entity.MyNodeEntity import com.geeksville.mesh.database.entity.NodeEntity import com.geeksville.mesh.model.Node import com.geeksville.mesh.model.NodeSortOption -import com.geeksville.mesh.util.onlineTimeThreshold import com.google.protobuf.ByteString import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.map @@ -38,6 +37,7 @@ import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.meshtastic.core.model.util.onlineTimeThreshold @RunWith(AndroidJUnit4::class) class NodeInfoDaoTest { @@ -48,129 +48,150 @@ class NodeInfoDaoTest { private val offlineNodeLastHeard = onlineThreshold - 30 private val onlineNodeLastHeard = onlineThreshold + 20 - private val unknownNode = NodeEntity( - num = 7, - user = user { - id = "!a1b2c3d4" - longName = "Meshtastic c3d4" - shortName = "c3d4" - hwModel = MeshProtos.HardwareModel.UNSET - }, - longName = "Meshtastic c3d4", - shortName = null // Dao filter for includeUnknown - ) - - private val ourNode = NodeEntity( - num = 8, - user = user { - id = "+16508765308".format(8) - longName = "Kevin Mester" - shortName = "KLO" - hwModel = MeshProtos.HardwareModel.ANDROID_SIM - isLicensed = false - }, - longName = "Kevin Mester", shortName = "KLO", - latitude = 30.267153, longitude = -97.743057, // Austin - hopsAway = 0, - ) - - private val onlineNode = NodeEntity( - num = 9, - user = user { - id = "!25060801" - longName = "Meshtastic 0801" - shortName = "0801" - hwModel = MeshProtos.HardwareModel.ANDROID_SIM - }, - longName = "Meshtastic 0801", - shortName = "0801", - hopsAway = 0, - lastHeard = onlineNodeLastHeard - ) - - private val offlineNode = NodeEntity( - num = 10, - user = user { - id = "!25060802" - longName = "Meshtastic 0802" - shortName = "0802" - hwModel = MeshProtos.HardwareModel.ANDROID_SIM - }, - longName = "Meshtastic 0802", - shortName = "0802", - hopsAway = 0, - lastHeard = offlineNodeLastHeard - ) - - private val directNode = NodeEntity( - num = 11, - user = user { - id = "!25060803" - longName = "Meshtastic 0803" - shortName = "0803" - hwModel = MeshProtos.HardwareModel.ANDROID_SIM - }, - longName = "Meshtastic 0803", - shortName = "0803", - hopsAway = 0, - lastHeard = onlineNodeLastHeard - ) - - private val relayedNode = NodeEntity( - num = 12, - user = user { - id = "!25060804" - longName = "Meshtastic 0804" - shortName = "0804" - hwModel = MeshProtos.HardwareModel.ANDROID_SIM - }, - longName = "Meshtastic 0804", - shortName = "0804", - hopsAway = 3, - lastHeard = onlineNodeLastHeard - ) - - private val myNodeInfo: MyNodeEntity = MyNodeEntity( - myNodeNum = ourNode.num, - model = null, - firmwareVersion = null, - couldUpdate = false, - shouldUpdate = false, - currentPacketId = 1L, - messageTimeoutMsec = 5 * 60 * 1000, - minAppVersion = 1, - maxChannels = 8, - hasWifi = false, - ) - - private val testPositions = arrayOf( - 0.0 to 0.0, - 32.776665 to -96.796989, // Dallas - 32.960758 to -96.733521, // Richardson - 32.912901 to -96.781776, // North Dallas - 29.760427 to -95.369804, // Houston - 33.748997 to -84.387985, // Atlanta - 34.052235 to -118.243683, // Los Angeles - 40.712776 to -74.005974, // New York City - 41.878113 to -87.629799, // Chicago - 39.952583 to -75.165222, // Philadelphia - ) - private val testNodes = listOf(ourNode, unknownNode, onlineNode, offlineNode, directNode, relayedNode) + testPositions.mapIndexed { index, pos -> + private val unknownNode = NodeEntity( - num = 1000 + index, - user = user { - id = "+165087653%02d".format(9 + index) - longName = "Kevin Mester$index" - shortName = "KM$index" + num = 7, + user = + user { + id = "!a1b2c3d4" + longName = "Meshtastic c3d4" + shortName = "c3d4" + hwModel = MeshProtos.HardwareModel.UNSET + }, + longName = "Meshtastic c3d4", + shortName = null, // Dao filter for includeUnknown + ) + + private val ourNode = + NodeEntity( + num = 8, + user = + user { + id = "+16508765308".format(8) + longName = "Kevin Mester" + shortName = "KLO" hwModel = MeshProtos.HardwareModel.ANDROID_SIM isLicensed = false - publicKey = ByteString.copyFrom(ByteArray(32) { index.toByte() }) }, - longName = "Kevin Mester$index", shortName = "KM$index", - latitude = pos.first, longitude = pos.second, - lastHeard = 9 + index, + longName = "Kevin Mester", + shortName = "KLO", + latitude = 30.267153, + longitude = -97.743057, // Austin + hopsAway = 0, ) - } + + private val onlineNode = + NodeEntity( + num = 9, + user = + user { + id = "!25060801" + longName = "Meshtastic 0801" + shortName = "0801" + hwModel = MeshProtos.HardwareModel.ANDROID_SIM + }, + longName = "Meshtastic 0801", + shortName = "0801", + hopsAway = 0, + lastHeard = onlineNodeLastHeard, + ) + + private val offlineNode = + NodeEntity( + num = 10, + user = + user { + id = "!25060802" + longName = "Meshtastic 0802" + shortName = "0802" + hwModel = MeshProtos.HardwareModel.ANDROID_SIM + }, + longName = "Meshtastic 0802", + shortName = "0802", + hopsAway = 0, + lastHeard = offlineNodeLastHeard, + ) + + private val directNode = + NodeEntity( + num = 11, + user = + user { + id = "!25060803" + longName = "Meshtastic 0803" + shortName = "0803" + hwModel = MeshProtos.HardwareModel.ANDROID_SIM + }, + longName = "Meshtastic 0803", + shortName = "0803", + hopsAway = 0, + lastHeard = onlineNodeLastHeard, + ) + + private val relayedNode = + NodeEntity( + num = 12, + user = + user { + id = "!25060804" + longName = "Meshtastic 0804" + shortName = "0804" + hwModel = MeshProtos.HardwareModel.ANDROID_SIM + }, + longName = "Meshtastic 0804", + shortName = "0804", + hopsAway = 3, + lastHeard = onlineNodeLastHeard, + ) + + private val myNodeInfo: MyNodeEntity = + MyNodeEntity( + myNodeNum = ourNode.num, + model = null, + firmwareVersion = null, + couldUpdate = false, + shouldUpdate = false, + currentPacketId = 1L, + messageTimeoutMsec = 5 * 60 * 1000, + minAppVersion = 1, + maxChannels = 8, + hasWifi = false, + ) + + private val testPositions = + arrayOf( + 0.0 to 0.0, + 32.776665 to -96.796989, // Dallas + 32.960758 to -96.733521, // Richardson + 32.912901 to -96.781776, // North Dallas + 29.760427 to -95.369804, // Houston + 33.748997 to -84.387985, // Atlanta + 34.052235 to -118.243683, // Los Angeles + 40.712776 to -74.005974, // New York City + 41.878113 to -87.629799, // Chicago + 39.952583 to -75.165222, // Philadelphia + ) + private val testNodes = + listOf(ourNode, unknownNode, onlineNode, offlineNode, directNode, relayedNode) + + testPositions.mapIndexed { index, pos -> + NodeEntity( + num = 1000 + index, + user = + user { + id = "+165087653%02d".format(9 + index) + longName = "Kevin Mester$index" + shortName = "KM$index" + hwModel = MeshProtos.HardwareModel.ANDROID_SIM + isLicensed = false + publicKey = ByteString.copyFrom(ByteArray(32) { index.toByte() }) + }, + longName = "Kevin Mester$index", + shortName = "KM$index", + latitude = pos.first, + longitude = pos.second, + lastHeard = 9 + index, + ) + } @Before fun createDb(): Unit = runBlocking { @@ -190,8 +211,8 @@ class NodeInfoDaoTest { } /** - * Retrieves a list of nodes based on [sort], [filter] and [includeUnknown] parameters. - * The list excludes [ourNode] to ensure consistency in the results. + * Retrieves a list of nodes based on [sort], [filter] and [includeUnknown] parameters. The list excludes [ourNode] + * to ensure consistency in the results. */ private suspend fun getNodes( sort: NodeSortOption = NodeSortOption.LAST_HEARD, @@ -199,13 +220,17 @@ class NodeInfoDaoTest { includeUnknown: Boolean = true, onlyOnline: Boolean = false, onlyDirect: Boolean = false, - ) = nodeInfoDao.getNodes( - sort = sort.sqlValue, - filter = filter, - includeUnknown = includeUnknown, - hopsAwayMax = if (onlyDirect) 0 else -1, - lastHeardMin = if (onlyOnline) onlineTimeThreshold() else -1, - ).map { list -> list.map { it.toModel() } }.first().filter { it.num != ourNode.num } + ) = nodeInfoDao + .getNodes( + sort = sort.sqlValue, + filter = filter, + includeUnknown = includeUnknown, + hopsAwayMax = if (onlyDirect) 0 else -1, + lastHeardMin = if (onlyOnline) onlineTimeThreshold() else -1, + ) + .map { list -> list.map { it.toModel() } } + .first() + .filter { it.num != ourNode.num } @Test // node list size fun testNodeListSize() = runBlocking { @@ -237,9 +262,10 @@ class NodeInfoDaoTest { fun testSortByDistance() = runBlocking { val nodes = getNodes(sort = NodeSortOption.DISTANCE) fun NodeEntity.toNode() = Node(num = num, user = user, position = position) - val sortedNodes = nodes.sortedWith( // nodes with invalid (null) positions at the end - compareBy { it.validPosition == null }.thenBy { it.distance(ourNode.toNode()) } - ) + val sortedNodes = + nodes.sortedWith( // nodes with invalid (null) positions at the end + compareBy { it.validPosition == null }.thenBy { it.distance(ourNode.toNode()) }, + ) assertEquals(sortedNodes, nodes) } @@ -297,9 +323,8 @@ class NodeInfoDaoTest { @Test fun testPkcMismatch() = runBlocking { - val newNode = testNodes[1].copy(user = testNodes[1].user.copy { - publicKey = ByteString.copyFrom(ByteArray(32) { 99 }) - }) + val newNode = + testNodes[1].copy(user = testNodes[1].user.copy { publicKey = ByteString.copyFrom(ByteArray(32) { 99 }) }) nodeInfoDao.putAll(listOf(newNode)) val nodes = getNodes() val containsMismatchNode = nodes.any { it.mismatchKey } diff --git a/app/src/androidTest/java/com/geeksville/mesh/PacketDaoTest.kt b/app/src/androidTest/java/com/geeksville/mesh/PacketDaoTest.kt index 8385439d0..f2e05090f 100644 --- a/app/src/androidTest/java/com/geeksville/mesh/PacketDaoTest.kt +++ b/app/src/androidTest/java/com/geeksville/mesh/PacketDaoTest.kt @@ -33,6 +33,7 @@ import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.meshtastic.core.model.DataPacket @RunWith(AndroidJUnit4::class) class PacketDaoTest { @@ -40,25 +41,24 @@ class PacketDaoTest { private lateinit var nodeInfoDao: NodeInfoDao private lateinit var packetDao: PacketDao - private val myNodeInfo: MyNodeEntity = MyNodeEntity( - myNodeNum = 42424242, - model = null, - firmwareVersion = null, - couldUpdate = false, - shouldUpdate = false, - currentPacketId = 1L, - messageTimeoutMsec = 5 * 60 * 1000, - minAppVersion = 1, - maxChannels = 8, - hasWifi = false, - ) + private val myNodeInfo: MyNodeEntity = + MyNodeEntity( + myNodeNum = 42424242, + model = null, + firmwareVersion = null, + couldUpdate = false, + shouldUpdate = false, + currentPacketId = 1L, + messageTimeoutMsec = 5 * 60 * 1000, + minAppVersion = 1, + maxChannels = 8, + hasWifi = false, + ) - private val myNodeNum: Int get() = myNodeInfo.myNodeNum + private val myNodeNum: Int + get() = myNodeInfo.myNodeNum - private val testContactKeys = listOf( - "0${DataPacket.ID_BROADCAST}", - "1!test1234", - ) + private val testContactKeys = listOf("0${DataPacket.ID_BROADCAST}", "1!test1234") private fun generateTestPackets(myNodeNum: Int) = testContactKeys.flatMap { contactKey -> List(SAMPLE_SIZE) { @@ -79,14 +79,13 @@ class PacketDaoTest { val context = InstrumentationRegistry.getInstrumentation().targetContext database = Room.inMemoryDatabaseBuilder(context, MeshtasticDatabase::class.java).build() - nodeInfoDao = database.nodeInfoDao().apply { - setMyNodeInfo(myNodeInfo) - } + nodeInfoDao = database.nodeInfoDao().apply { setMyNodeInfo(myNodeInfo) } - packetDao = database.packetDao().apply { - generateTestPackets(42424243).forEach { insert(it) } - generateTestPackets(myNodeNum).forEach { insert(it) } - } + packetDao = + database.packetDao().apply { + generateTestPackets(42424243).forEach { insert(it) } + generateTestPackets(myNodeNum).forEach { insert(it) } + } } @After diff --git a/app/src/androidTest/java/com/geeksville/mesh/compose/MessageItemTest.kt b/app/src/androidTest/java/com/geeksville/mesh/compose/MessageItemTest.kt index dbdba7922..b2833a14a 100644 --- a/app/src/androidTest/java/com/geeksville/mesh/compose/MessageItemTest.kt +++ b/app/src/androidTest/java/com/geeksville/mesh/compose/MessageItemTest.kt @@ -21,13 +21,13 @@ import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.junit4.createComposeRule import androidx.compose.ui.test.onNodeWithContentDescription import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.geeksville.mesh.MessageStatus import com.geeksville.mesh.model.Message import com.geeksville.mesh.ui.common.preview.NodePreviewParameterProvider import com.geeksville.mesh.ui.message.components.MessageItem import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith +import org.meshtastic.core.model.MessageStatus @RunWith(AndroidJUnit4::class) class MessageItemTest { diff --git a/app/src/fdroid/java/com/geeksville/mesh/ui/map/MapView.kt b/app/src/fdroid/java/com/geeksville/mesh/ui/map/MapView.kt index f70f5be94..6e336e564 100644 --- a/app/src/fdroid/java/com/geeksville/mesh/ui/map/MapView.kt +++ b/app/src/fdroid/java/com/geeksville/mesh/ui/map/MapView.kt @@ -62,7 +62,6 @@ import androidx.compose.ui.viewinterop.AndroidView import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.viewmodel.compose.viewModel -import com.geeksville.mesh.DataPacket import com.geeksville.mesh.MeshProtos.Waypoint import com.geeksville.mesh.android.BuildUtils.debug import com.geeksville.mesh.android.gpsDisabled @@ -79,11 +78,12 @@ import com.geeksville.mesh.util.SqlTileWriterExt import com.geeksville.mesh.util.addCopyright import com.geeksville.mesh.util.addScaleBarOverlay import com.geeksville.mesh.util.createLatLongGrid -import com.geeksville.mesh.util.formatAgo import com.geeksville.mesh.waypoint import com.google.accompanist.permissions.ExperimentalPermissionsApi // Added for Accompanist import com.google.accompanist.permissions.rememberMultiplePermissionsState // Added for Accompanist import com.google.android.material.dialog.MaterialAlertDialogBuilder +import org.meshtastic.core.model.DataPacket +import org.meshtastic.core.model.util.formatAgo import org.meshtastic.core.strings.R import org.meshtastic.feature.map.cluster.RadiusMarkerClusterer import org.meshtastic.feature.map.model.CustomTileSource diff --git a/app/src/google/java/com/geeksville/mesh/ui/map/MapView.kt b/app/src/google/java/com/geeksville/mesh/ui/map/MapView.kt index c0f82621d..9fbdfa6fb 100644 --- a/app/src/google/java/com/geeksville/mesh/ui/map/MapView.kt +++ b/app/src/google/java/com/geeksville/mesh/ui/map/MapView.kt @@ -84,10 +84,7 @@ import com.geeksville.mesh.ui.metrics.HEADING_DEG import com.geeksville.mesh.ui.metrics.formatPositionTime import com.geeksville.mesh.ui.node.DEG_D import com.geeksville.mesh.ui.node.components.NodeChip -import com.geeksville.mesh.util.formatAgo import com.geeksville.mesh.util.metersIn -import com.geeksville.mesh.util.mpsToKmph -import com.geeksville.mesh.util.mpsToMph import com.geeksville.mesh.util.toString import com.geeksville.mesh.waypoint import com.google.android.gms.location.LocationCallback @@ -120,6 +117,9 @@ import com.google.maps.android.compose.rememberUpdatedMarkerState import com.google.maps.android.compose.widgets.ScaleBar import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch +import org.meshtastic.core.model.util.formatAgo +import org.meshtastic.core.model.util.mpsToKmph +import org.meshtastic.core.model.util.mpsToMph import org.meshtastic.core.strings.R import timber.log.Timber import java.text.DateFormat diff --git a/app/src/main/aidl/com/geeksville/mesh/IMeshService.aidl b/app/src/main/aidl/com/geeksville/mesh/IMeshService.aidl index 4efffd93b..bf118a33c 100644 --- a/app/src/main/aidl/com/geeksville/mesh/IMeshService.aidl +++ b/app/src/main/aidl/com/geeksville/mesh/IMeshService.aidl @@ -2,11 +2,11 @@ package com.geeksville.mesh; // Declare any non-default types here with import statements -parcelable DataPacket; -parcelable NodeInfo; -parcelable MeshUser; -parcelable Position; -parcelable MyNodeInfo; +import org.meshtastic.core.model.DataPacket; +import org.meshtastic.core.model.NodeInfo; +import org.meshtastic.core.model.MeshUser; +import org.meshtastic.core.model.Position; +import org.meshtastic.core.model.MyNodeInfo; /** This is the public android API for talking to meshtastic radios. diff --git a/app/src/main/java/com/geeksville/mesh/database/Converters.kt b/app/src/main/java/com/geeksville/mesh/database/Converters.kt index 71b39d29c..e5b54db6a 100644 --- a/app/src/main/java/com/geeksville/mesh/database/Converters.kt +++ b/app/src/main/java/com/geeksville/mesh/database/Converters.kt @@ -18,7 +18,6 @@ package com.geeksville.mesh.database import androidx.room.TypeConverter -import com.geeksville.mesh.DataPacket import com.geeksville.mesh.MeshProtos import com.geeksville.mesh.PaxcountProtos import com.geeksville.mesh.TelemetryProtos @@ -26,6 +25,7 @@ import com.geeksville.mesh.android.Logging import com.google.protobuf.ByteString import com.google.protobuf.InvalidProtocolBufferException import kotlinx.serialization.json.Json +import org.meshtastic.core.model.DataPacket @Suppress("TooManyFunctions") class Converters : Logging { diff --git a/app/src/main/java/com/geeksville/mesh/database/NodeRepository.kt b/app/src/main/java/com/geeksville/mesh/database/NodeRepository.kt index 16c737979..460ce6bf3 100644 --- a/app/src/main/java/com/geeksville/mesh/database/NodeRepository.kt +++ b/app/src/main/java/com/geeksville/mesh/database/NodeRepository.kt @@ -20,7 +20,6 @@ package com.geeksville.mesh.database import androidx.lifecycle.Lifecycle import androidx.lifecycle.coroutineScope import com.geeksville.mesh.CoroutineDispatchers -import com.geeksville.mesh.DataPacket import com.geeksville.mesh.MeshProtos import com.geeksville.mesh.database.dao.NodeInfoDao import com.geeksville.mesh.database.entity.MetadataEntity @@ -28,7 +27,6 @@ import com.geeksville.mesh.database.entity.MyNodeEntity import com.geeksville.mesh.database.entity.NodeEntity import com.geeksville.mesh.model.Node import com.geeksville.mesh.model.NodeSortOption -import com.geeksville.mesh.util.onlineTimeThreshold import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted @@ -40,6 +38,8 @@ import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.withContext +import org.meshtastic.core.model.DataPacket +import org.meshtastic.core.model.util.onlineTimeThreshold import javax.inject.Inject import javax.inject.Singleton diff --git a/app/src/main/java/com/geeksville/mesh/database/PacketRepository.kt b/app/src/main/java/com/geeksville/mesh/database/PacketRepository.kt index e805c97a1..733fe6220 100644 --- a/app/src/main/java/com/geeksville/mesh/database/PacketRepository.kt +++ b/app/src/main/java/com/geeksville/mesh/database/PacketRepository.kt @@ -17,8 +17,6 @@ package com.geeksville.mesh.database -import com.geeksville.mesh.DataPacket -import com.geeksville.mesh.MessageStatus import com.geeksville.mesh.Portnums.PortNum import com.geeksville.mesh.database.dao.PacketDao import com.geeksville.mesh.database.entity.ContactSettings @@ -29,66 +27,52 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.withContext +import org.meshtastic.core.model.DataPacket +import org.meshtastic.core.model.MessageStatus import javax.inject.Inject class PacketRepository @Inject constructor(private val packetDaoLazy: dagger.Lazy) { - private val packetDao by lazy { - packetDaoLazy.get() - } + private val packetDao by lazy { packetDaoLazy.get() } fun getWaypoints(): Flow> = packetDao.getAllPackets(PortNum.WAYPOINT_APP_VALUE) fun getContacts(): Flow> = packetDao.getContactKeys() - suspend fun getMessageCount(contact: String): Int = withContext(Dispatchers.IO) { - packetDao.getMessageCount(contact) - } + suspend fun getMessageCount(contact: String): Int = + withContext(Dispatchers.IO) { packetDao.getMessageCount(contact) } - suspend fun getUnreadCount(contact: String): Int = withContext(Dispatchers.IO) { - packetDao.getUnreadCount(contact) - } + suspend fun getUnreadCount(contact: String): Int = withContext(Dispatchers.IO) { packetDao.getUnreadCount(contact) } - suspend fun clearUnreadCount(contact: String, timestamp: Long) = withContext(Dispatchers.IO) { - packetDao.clearUnreadCount(contact, timestamp) - } + suspend fun clearUnreadCount(contact: String, timestamp: Long) = + withContext(Dispatchers.IO) { packetDao.clearUnreadCount(contact, timestamp) } - suspend fun getQueuedPackets(): List? = withContext(Dispatchers.IO) { - packetDao.getQueuedPackets() - } + suspend fun getQueuedPackets(): List? = withContext(Dispatchers.IO) { packetDao.getQueuedPackets() } - suspend fun insert(packet: Packet) = withContext(Dispatchers.IO) { - packetDao.insert(packet) - } + suspend fun insert(packet: Packet) = withContext(Dispatchers.IO) { packetDao.insert(packet) } - suspend fun getMessagesFrom(contact: String, getNode: suspend (String?) -> Node) = - withContext(Dispatchers.IO) { - packetDao.getMessagesFrom(contact).mapLatest { packets -> - packets.map { packet -> - val message = packet.toMessage(getNode) - message.replyId.takeIf { it != null && it != 0 } - ?.let { getPacketByPacketId(it) } - ?.toMessage(getNode) - ?.let { originalMessage -> message.copy(originalMessage = originalMessage) } - ?: message - } + suspend fun getMessagesFrom(contact: String, getNode: suspend (String?) -> Node) = withContext(Dispatchers.IO) { + packetDao.getMessagesFrom(contact).mapLatest { packets -> + packets.map { packet -> + val message = packet.toMessage(getNode) + message.replyId + .takeIf { it != null && it != 0 } + ?.let { getPacketByPacketId(it) } + ?.toMessage(getNode) + ?.let { originalMessage -> message.copy(originalMessage = originalMessage) } ?: message } } - - suspend fun updateMessageStatus(d: DataPacket, m: MessageStatus) = withContext(Dispatchers.IO) { - packetDao.updateMessageStatus(d, m) } - suspend fun updateMessageId(d: DataPacket, id: Int) = withContext(Dispatchers.IO) { - packetDao.updateMessageId(d, id) - } + suspend fun updateMessageStatus(d: DataPacket, m: MessageStatus) = + withContext(Dispatchers.IO) { packetDao.updateMessageStatus(d, m) } - suspend fun getPacketById(requestId: Int) = withContext(Dispatchers.IO) { - packetDao.getPacketById(requestId) - } + suspend fun updateMessageId(d: DataPacket, id: Int) = + withContext(Dispatchers.IO) { packetDao.updateMessageId(d, id) } - suspend fun getPacketByPacketId(packetId: Int) = withContext(Dispatchers.IO) { - packetDao.getPacketByPacketId(packetId) - } + suspend fun getPacketById(requestId: Int) = withContext(Dispatchers.IO) { packetDao.getPacketById(requestId) } + + suspend fun getPacketByPacketId(packetId: Int) = + withContext(Dispatchers.IO) { packetDao.getPacketByPacketId(packetId) } suspend fun deleteMessages(uuidList: List) = withContext(Dispatchers.IO) { for (chunk in uuidList.chunked(500)) { // limit number of UUIDs per query @@ -96,37 +80,24 @@ class PacketRepository @Inject constructor(private val packetDaoLazy: dagger.Laz } } - suspend fun deleteContacts(contactList: List) = withContext(Dispatchers.IO) { - packetDao.deleteContacts(contactList) - } + suspend fun deleteContacts(contactList: List) = + withContext(Dispatchers.IO) { packetDao.deleteContacts(contactList) } - suspend fun deleteWaypoint(id: Int) = withContext(Dispatchers.IO) { - packetDao.deleteWaypoint(id) - } + suspend fun deleteWaypoint(id: Int) = withContext(Dispatchers.IO) { packetDao.deleteWaypoint(id) } - suspend fun delete(packet: Packet) = withContext(Dispatchers.IO) { - packetDao.delete(packet) - } + suspend fun delete(packet: Packet) = withContext(Dispatchers.IO) { packetDao.delete(packet) } - suspend fun update(packet: Packet) = withContext(Dispatchers.IO) { - packetDao.update(packet) - } + suspend fun update(packet: Packet) = withContext(Dispatchers.IO) { packetDao.update(packet) } fun getContactSettings(): Flow> = packetDao.getContactSettings() - suspend fun getContactSettings(contact: String) = withContext(Dispatchers.IO) { - packetDao.getContactSettings(contact) ?: ContactSettings(contact) - } + suspend fun getContactSettings(contact: String) = + withContext(Dispatchers.IO) { packetDao.getContactSettings(contact) ?: ContactSettings(contact) } - suspend fun setMuteUntil(contacts: List, until: Long) = withContext(Dispatchers.IO) { - packetDao.setMuteUntil(contacts, until) - } + suspend fun setMuteUntil(contacts: List, until: Long) = + withContext(Dispatchers.IO) { packetDao.setMuteUntil(contacts, until) } - suspend fun insertReaction(reaction: ReactionEntity) = withContext(Dispatchers.IO) { - packetDao.insert(reaction) - } + suspend fun insertReaction(reaction: ReactionEntity) = withContext(Dispatchers.IO) { packetDao.insert(reaction) } - suspend fun clearPacketDB() = withContext(Dispatchers.IO) { - packetDao.deleteAll() - } + suspend fun clearPacketDB() = withContext(Dispatchers.IO) { packetDao.deleteAll() } } diff --git a/app/src/main/java/com/geeksville/mesh/database/dao/PacketDao.kt b/app/src/main/java/com/geeksville/mesh/database/dao/PacketDao.kt index 94753113e..5bda825b5 100644 --- a/app/src/main/java/com/geeksville/mesh/database/dao/PacketDao.kt +++ b/app/src/main/java/com/geeksville/mesh/database/dao/PacketDao.kt @@ -23,13 +23,13 @@ import androidx.room.Query import androidx.room.Transaction import androidx.room.Update import androidx.room.Upsert -import com.geeksville.mesh.DataPacket -import com.geeksville.mesh.MessageStatus import com.geeksville.mesh.database.entity.ContactSettings import com.geeksville.mesh.database.entity.Packet import com.geeksville.mesh.database.entity.PacketEntity import com.geeksville.mesh.database.entity.ReactionEntity import kotlinx.coroutines.flow.Flow +import org.meshtastic.core.model.DataPacket +import org.meshtastic.core.model.MessageStatus @Dao interface PacketDao { @@ -40,7 +40,7 @@ interface PacketDao { WHERE (myNodeNum = 0 OR myNodeNum = (SELECT myNodeNum FROM my_node)) AND port_num = :portNum ORDER BY received_time ASC - """ + """, ) fun getAllPackets(portNum: Int): Flow> @@ -50,16 +50,22 @@ interface PacketDao { WHERE (myNodeNum = 0 OR myNodeNum = (SELECT myNodeNum FROM my_node)) AND port_num = 1 ORDER BY received_time DESC - """ + """, ) - fun getContactKeys(): Flow> + fun getContactKeys(): Flow< + Map< + @MapColumn(columnName = "contact_key") + String, + Packet, + >, + > @Query( """ SELECT COUNT(*) FROM packet WHERE (myNodeNum = 0 OR myNodeNum = (SELECT myNodeNum FROM my_node)) AND port_num = 1 AND contact_key = :contact - """ + """, ) suspend fun getMessageCount(contact: String): Int @@ -68,7 +74,7 @@ interface PacketDao { SELECT COUNT(*) FROM packet WHERE (myNodeNum = 0 OR myNodeNum = (SELECT myNodeNum FROM my_node)) AND port_num = 1 AND contact_key = :contact AND read = 0 - """ + """, ) suspend fun getUnreadCount(contact: String): Int @@ -78,12 +84,11 @@ interface PacketDao { SET read = 1 WHERE (myNodeNum = 0 OR myNodeNum = (SELECT myNodeNum FROM my_node)) AND port_num = 1 AND contact_key = :contact AND read = 0 AND received_time <= :timestamp - """ + """, ) suspend fun clearUnreadCount(contact: String, timestamp: Long) - @Upsert - suspend fun insert(packet: Packet) + @Upsert suspend fun insert(packet: Packet) @Transaction @Query( @@ -92,7 +97,7 @@ interface PacketDao { WHERE (myNodeNum = 0 OR myNodeNum = (SELECT myNodeNum FROM my_node)) AND port_num = 1 AND contact_key = :contact ORDER BY received_time DESC - """ + """, ) fun getMessagesFrom(contact: String): Flow> @@ -101,7 +106,7 @@ interface PacketDao { SELECT * FROM packet WHERE (myNodeNum = 0 OR myNodeNum = (SELECT myNodeNum FROM my_node)) AND data = :data - """ + """, ) suspend fun findDataPacket(data: DataPacket): Packet? @@ -113,16 +118,16 @@ interface PacketDao { DELETE FROM packet WHERE (myNodeNum = 0 OR myNodeNum = (SELECT myNodeNum FROM my_node)) AND contact_key IN (:contactList) - """ + """, ) suspend fun deleteContacts(contactList: List) @Query("DELETE FROM packet WHERE uuid=:uuid") - suspend fun _delete(uuid: Long) + suspend fun delete(uuid: Long) @Transaction suspend fun delete(packet: Packet) { - _delete(packet.uuid) + delete(packet.uuid) } @Query("SELECT packet_id FROM packet WHERE uuid IN (:uuidList)") @@ -140,8 +145,7 @@ interface PacketDao { deletePackets(uuidList) } - @Update - suspend fun update(packet: Packet) + @Update suspend fun update(packet: Packet) @Transaction suspend fun updateMessageStatus(data: DataPacket, m: MessageStatus) { @@ -160,7 +164,7 @@ interface PacketDao { SELECT data FROM packet WHERE (myNodeNum = 0 OR myNodeNum = (SELECT myNodeNum FROM my_node)) ORDER BY received_time ASC - """ + """, ) suspend fun getDataPackets(): List @@ -171,7 +175,7 @@ interface PacketDao { WHERE (myNodeNum = 0 OR myNodeNum = (SELECT myNodeNum FROM my_node)) AND packet_id = :requestId ORDER BY received_time DESC - """ + """, ) suspend fun getPacketById(requestId: Int): Packet? @@ -180,8 +184,7 @@ interface PacketDao { suspend fun getPacketByPacketId(packetId: Int): PacketEntity? @Transaction - suspend fun getQueuedPackets(): List? = - getDataPackets().filter { it.status == MessageStatus.QUEUED } + suspend fun getQueuedPackets(): List? = getDataPackets().filter { it.status == MessageStatus.QUEUED } @Query( """ @@ -189,7 +192,7 @@ interface PacketDao { WHERE (myNodeNum = 0 OR myNodeNum = (SELECT myNodeNum FROM my_node)) AND port_num = 8 ORDER BY received_time ASC - """ + """, ) suspend fun getAllWaypoints(): List @@ -200,25 +203,30 @@ interface PacketDao { } @Query("SELECT * FROM contact_settings") - fun getContactSettings(): Flow> + fun getContactSettings(): Flow< + Map< + @MapColumn(columnName = "contact_key") + String, + ContactSettings, + >, + > @Query("SELECT * FROM contact_settings WHERE contact_key = :contact") suspend fun getContactSettings(contact: String): ContactSettings? - @Upsert - suspend fun upsertContactSettings(contacts: List) + @Upsert suspend fun upsertContactSettings(contacts: List) @Transaction suspend fun setMuteUntil(contacts: List, until: Long) { - val contactList = contacts.map { contact -> - getContactSettings(contact)?.copy(muteUntil = until) - ?: ContactSettings(contact_key = contact, muteUntil = until) - } + val contactList = + contacts.map { contact -> + getContactSettings(contact)?.copy(muteUntil = until) + ?: ContactSettings(contact_key = contact, muteUntil = until) + } upsertContactSettings(contactList) } - @Upsert - suspend fun insert(reaction: ReactionEntity) + @Upsert suspend fun insert(reaction: ReactionEntity) @Query("DELETE FROM packet") suspend fun deleteAll() diff --git a/app/src/main/java/com/geeksville/mesh/database/entity/DeviceHardwareEntity.kt b/app/src/main/java/com/geeksville/mesh/database/entity/DeviceHardwareEntity.kt index ccaaff4a8..2e1be4c01 100644 --- a/app/src/main/java/com/geeksville/mesh/database/entity/DeviceHardwareEntity.kt +++ b/app/src/main/java/com/geeksville/mesh/database/entity/DeviceHardwareEntity.kt @@ -22,7 +22,7 @@ import androidx.room.Entity import androidx.room.PrimaryKey import kotlinx.serialization.Serializable import org.meshtastic.core.model.DeviceHardware -import org.meshtastic.core.network.model.NetworkDeviceHardware +import org.meshtastic.core.model.NetworkDeviceHardware @Serializable @Entity(tableName = "device_hardware") diff --git a/app/src/main/java/com/geeksville/mesh/database/entity/FirmwareReleaseEntity.kt b/app/src/main/java/com/geeksville/mesh/database/entity/FirmwareReleaseEntity.kt index 72c76b1a6..1a6076393 100644 --- a/app/src/main/java/com/geeksville/mesh/database/entity/FirmwareReleaseEntity.kt +++ b/app/src/main/java/com/geeksville/mesh/database/entity/FirmwareReleaseEntity.kt @@ -20,9 +20,9 @@ package com.geeksville.mesh.database.entity import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey -import com.geeksville.mesh.model.DeviceVersion import kotlinx.serialization.Serializable -import org.meshtastic.core.network.model.NetworkFirmwareRelease +import org.meshtastic.core.model.DeviceVersion +import org.meshtastic.core.model.NetworkFirmwareRelease @Serializable @Entity(tableName = "firmware_release") diff --git a/app/src/main/java/com/geeksville/mesh/database/entity/MyNodeEntity.kt b/app/src/main/java/com/geeksville/mesh/database/entity/MyNodeEntity.kt index f6a99e037..122c58fbe 100644 --- a/app/src/main/java/com/geeksville/mesh/database/entity/MyNodeEntity.kt +++ b/app/src/main/java/com/geeksville/mesh/database/entity/MyNodeEntity.kt @@ -19,12 +19,11 @@ package com.geeksville.mesh.database.entity import androidx.room.Entity import androidx.room.PrimaryKey -import com.geeksville.mesh.MyNodeInfo +import org.meshtastic.core.model.MyNodeInfo @Entity(tableName = "my_node") data class MyNodeEntity( - @PrimaryKey(autoGenerate = false) - val myNodeNum: Int, + @PrimaryKey(autoGenerate = false) val myNodeNum: Int, val model: String?, val firmwareVersion: String?, val couldUpdate: Boolean, // this application contains a software load we _could_ install if you want @@ -37,7 +36,8 @@ data class MyNodeEntity( val deviceId: String? = "unknown", ) { /** A human readable description of the software/hardware version */ - val firmwareString: String get() = "$model $firmwareVersion" + val firmwareString: String + get() = "$model $firmwareVersion" fun toMyNodeInfo() = MyNodeInfo( myNodeNum = myNodeNum, diff --git a/app/src/main/java/com/geeksville/mesh/database/entity/NodeEntity.kt b/app/src/main/java/com/geeksville/mesh/database/entity/NodeEntity.kt index 4cf73cd0e..d83809809 100644 --- a/app/src/main/java/com/geeksville/mesh/database/entity/NodeEntity.kt +++ b/app/src/main/java/com/geeksville/mesh/database/entity/NodeEntity.kt @@ -23,19 +23,19 @@ import androidx.room.Entity import androidx.room.Index import androidx.room.PrimaryKey import androidx.room.Relation -import com.geeksville.mesh.DeviceMetrics -import com.geeksville.mesh.EnvironmentMetrics import com.geeksville.mesh.MeshProtos -import com.geeksville.mesh.MeshUser -import com.geeksville.mesh.NodeInfo import com.geeksville.mesh.PaxcountProtos -import com.geeksville.mesh.Position import com.geeksville.mesh.TelemetryProtos import com.geeksville.mesh.copy import com.geeksville.mesh.model.Node -import com.geeksville.mesh.util.onlineTimeThreshold import com.google.protobuf.ByteString import com.google.protobuf.kotlin.isNotEmpty +import org.meshtastic.core.model.DeviceMetrics +import org.meshtastic.core.model.EnvironmentMetrics +import org.meshtastic.core.model.MeshUser +import org.meshtastic.core.model.NodeInfo +import org.meshtastic.core.model.Position +import org.meshtastic.core.model.util.onlineTimeThreshold data class NodeWithRelations( @Embedded val node: NodeEntity, diff --git a/app/src/main/java/com/geeksville/mesh/database/entity/Packet.kt b/app/src/main/java/com/geeksville/mesh/database/entity/Packet.kt index d1a9e0589..a70d99acf 100644 --- a/app/src/main/java/com/geeksville/mesh/database/entity/Packet.kt +++ b/app/src/main/java/com/geeksville/mesh/database/entity/Packet.kt @@ -23,11 +23,11 @@ import androidx.room.Entity import androidx.room.Index import androidx.room.PrimaryKey import androidx.room.Relation -import com.geeksville.mesh.DataPacket import com.geeksville.mesh.MeshProtos.User import com.geeksville.mesh.model.Message import com.geeksville.mesh.model.Node -import com.geeksville.mesh.util.getShortDateTime +import org.meshtastic.core.model.DataPacket +import org.meshtastic.core.model.util.getShortDateTime data class PacketEntity( @Embedded val packet: Packet, @@ -52,20 +52,15 @@ data class PacketEntity( packetId = packetId, emojis = reactions.toReaction(getNode), replyId = data.replyId, - viaMqtt = node.viaMqtt + viaMqtt = node.viaMqtt, ) } } @Entity( tableName = "packet", - indices = [ - Index(value = ["myNodeNum"]), - Index(value = ["port_num"]), - Index(value = ["contact_key"]), - ] + indices = [Index(value = ["myNodeNum"]), Index(value = ["port_num"]), Index(value = ["contact_key"])], ) - data class Packet( @PrimaryKey(autoGenerate = true) val uuid: Long, @ColumnInfo(name = "myNodeNum", defaultValue = "0") val myNodeNum: Int, @@ -83,26 +78,17 @@ data class Packet( ) @Entity(tableName = "contact_settings") -data class ContactSettings( - @PrimaryKey val contact_key: String, - val muteUntil: Long = 0L, -) { - val isMuted get() = System.currentTimeMillis() <= muteUntil +data class ContactSettings(@PrimaryKey val contact_key: String, val muteUntil: Long = 0L) { + val isMuted + get() = System.currentTimeMillis() <= muteUntil } -data class Reaction( - val replyId: Int, - val user: User, - val emoji: String, - val timestamp: Long, -) +data class Reaction(val replyId: Int, val user: User, val emoji: String, val timestamp: Long) @Entity( tableName = "reactions", primaryKeys = ["reply_id", "user_id", "emoji"], - indices = [ - Index(value = ["reply_id"]), - ], + indices = [Index(value = ["reply_id"])], ) data class ReactionEntity( @ColumnInfo(name = "reply_id") val replyId: Int, @@ -111,15 +97,8 @@ data class ReactionEntity( val timestamp: Long, ) -private suspend fun ReactionEntity.toReaction( - getNode: suspend (userId: String?) -> Node -) = Reaction( - replyId = replyId, - user = getNode(userId).user, - emoji = emoji, - timestamp = timestamp, -) +private suspend fun ReactionEntity.toReaction(getNode: suspend (userId: String?) -> Node) = + Reaction(replyId = replyId, user = getNode(userId).user, emoji = emoji, timestamp = timestamp) -private suspend fun List.toReaction( - getNode: suspend (userId: String?) -> Node -) = this.map { it.toReaction(getNode) } +private suspend fun List.toReaction(getNode: suspend (userId: String?) -> Node) = + this.map { it.toReaction(getNode) } diff --git a/app/src/main/java/com/geeksville/mesh/model/BTScanModel.kt b/app/src/main/java/com/geeksville/mesh/model/BTScanModel.kt index 10e2337de..6f0a3ef83 100644 --- a/app/src/main/java/com/geeksville/mesh/model/BTScanModel.kt +++ b/app/src/main/java/com/geeksville/mesh/model/BTScanModel.kt @@ -35,7 +35,6 @@ import com.geeksville.mesh.repository.radio.RadioInterfaceService import com.geeksville.mesh.repository.usb.UsbRepository import com.geeksville.mesh.service.MeshService import com.geeksville.mesh.service.ServiceRepository -import com.geeksville.mesh.util.anonymize import com.hoho.android.usbserial.driver.UsbSerialDriver import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Job @@ -52,6 +51,7 @@ import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import org.meshtastic.core.datastore.RecentAddressesDataSource import org.meshtastic.core.datastore.model.RecentAddress +import org.meshtastic.core.model.util.anonymize import org.meshtastic.core.strings.R import javax.inject.Inject diff --git a/app/src/main/java/com/geeksville/mesh/model/EnvironmentMetricsState.kt b/app/src/main/java/com/geeksville/mesh/model/EnvironmentMetricsState.kt index 6d9ba13be..98521632a 100644 --- a/app/src/main/java/com/geeksville/mesh/model/EnvironmentMetricsState.kt +++ b/app/src/main/java/com/geeksville/mesh/model/EnvironmentMetricsState.kt @@ -28,7 +28,7 @@ import com.geeksville.mesh.ui.common.theme.GraphColors.Pink import com.geeksville.mesh.ui.common.theme.GraphColors.Purple import com.geeksville.mesh.ui.common.theme.GraphColors.Red import com.geeksville.mesh.ui.common.theme.GraphColors.Yellow -import com.geeksville.mesh.util.UnitConversions +import org.meshtastic.core.model.util.UnitConversions @Suppress("MagicNumber") enum class Environment(val color: Color) { diff --git a/app/src/main/java/com/geeksville/mesh/model/Message.kt b/app/src/main/java/com/geeksville/mesh/model/Message.kt index 7d890fde8..0682b53e0 100644 --- a/app/src/main/java/com/geeksville/mesh/model/Message.kt +++ b/app/src/main/java/com/geeksville/mesh/model/Message.kt @@ -19,8 +19,8 @@ package com.geeksville.mesh.model import androidx.annotation.StringRes import com.geeksville.mesh.MeshProtos.Routing -import com.geeksville.mesh.MessageStatus import com.geeksville.mesh.database.entity.Reaction +import org.meshtastic.core.model.MessageStatus import org.meshtastic.core.strings.R @Suppress("CyclomaticComplexMethod") 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 f72f90cd5..4b300952b 100644 --- a/app/src/main/java/com/geeksville/mesh/model/MetricsViewModel.kt +++ b/app/src/main/java/com/geeksville/mesh/model/MetricsViewModel.kt @@ -28,7 +28,6 @@ import androidx.lifecycle.viewModelScope import androidx.navigation.toRoute import com.geeksville.mesh.ConfigProtos.Config.DisplayConfig.DisplayUnits import com.geeksville.mesh.CoroutineDispatchers -import com.geeksville.mesh.DataPacket import com.geeksville.mesh.MeshProtos import com.geeksville.mesh.MeshProtos.MeshPacket import com.geeksville.mesh.MeshProtos.Position @@ -59,6 +58,7 @@ import kotlinx.coroutines.flow.toList import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import kotlinx.coroutines.withContext +import org.meshtastic.core.model.DataPacket import org.meshtastic.core.model.DeviceHardware import org.meshtastic.core.navigation.NodesRoutes import org.meshtastic.core.prefs.map.MapPrefs diff --git a/app/src/main/java/com/geeksville/mesh/model/Node.kt b/app/src/main/java/com/geeksville/mesh/model/Node.kt index e79d423f9..40d8ac293 100644 --- a/app/src/main/java/com/geeksville/mesh/model/Node.kt +++ b/app/src/main/java/com/geeksville/mesh/model/Node.kt @@ -26,12 +26,12 @@ import com.geeksville.mesh.TelemetryProtos.DeviceMetrics import com.geeksville.mesh.TelemetryProtos.EnvironmentMetrics import com.geeksville.mesh.TelemetryProtos.PowerMetrics import com.geeksville.mesh.database.entity.NodeEntity -import com.geeksville.mesh.util.GPSFormat -import com.geeksville.mesh.util.UnitConversions.celsiusToFahrenheit -import com.geeksville.mesh.util.latLongToMeter import com.geeksville.mesh.util.toDistanceString import com.google.protobuf.ByteString import com.google.protobuf.kotlin.isNotEmpty +import org.meshtastic.core.model.util.GPSFormat +import org.meshtastic.core.model.util.UnitConversions.celsiusToFahrenheit +import org.meshtastic.core.model.util.latLongToMeter @Suppress("MagicNumber") data class Node( @@ -114,7 +114,7 @@ data class Node( // @return bearing to the other position in degrees fun bearing(o: Node?): Int? = when { validPosition == null || o?.validPosition == null -> null - else -> com.geeksville.mesh.util.bearing(latitude, longitude, o.latitude, o.longitude).toInt() + else -> org.meshtastic.core.model.util.bearing(latitude, longitude, o.latitude, o.longitude).toInt() } fun gpsString(): String = GPSFormat.toDec(latitude, longitude) 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 ae904bca8..0786d9316 100644 --- a/app/src/main/java/com/geeksville/mesh/model/UIState.kt +++ b/app/src/main/java/com/geeksville/mesh/model/UIState.kt @@ -32,12 +32,10 @@ import com.geeksville.mesh.AppOnlyProtos import com.geeksville.mesh.ChannelProtos import com.geeksville.mesh.ChannelProtos.ChannelSettings import com.geeksville.mesh.ConfigProtos.Config -import com.geeksville.mesh.DataPacket 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.Position import com.geeksville.mesh.android.Logging import com.geeksville.mesh.channel import com.geeksville.mesh.channelSet @@ -60,7 +58,6 @@ import com.geeksville.mesh.repository.radio.RadioInterfaceService import com.geeksville.mesh.service.MeshServiceNotifications import com.geeksville.mesh.service.ServiceAction import com.geeksville.mesh.ui.node.components.NodeMenuAction -import com.geeksville.mesh.util.getShortDate import com.geeksville.mesh.util.safeNumber import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers @@ -82,7 +79,10 @@ import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import org.meshtastic.core.datastore.UiPreferencesDataSource +import org.meshtastic.core.model.DataPacket import org.meshtastic.core.model.DeviceHardware +import org.meshtastic.core.model.Position +import org.meshtastic.core.model.util.getShortDate import org.meshtastic.core.prefs.ui.UiPrefs import org.meshtastic.core.strings.R import javax.inject.Inject diff --git a/app/src/main/java/com/geeksville/mesh/repository/api/DeviceHardwareJsonDataSource.kt b/app/src/main/java/com/geeksville/mesh/repository/api/DeviceHardwareJsonDataSource.kt index b5f19e1b3..58f2b7245 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/api/DeviceHardwareJsonDataSource.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/api/DeviceHardwareJsonDataSource.kt @@ -21,7 +21,7 @@ import android.app.Application import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.json.Json import kotlinx.serialization.json.decodeFromStream -import org.meshtastic.core.network.model.NetworkDeviceHardware +import org.meshtastic.core.model.NetworkDeviceHardware import javax.inject.Inject class DeviceHardwareJsonDataSource @Inject constructor(private val application: Application) { diff --git a/app/src/main/java/com/geeksville/mesh/repository/api/DeviceHardwareLocalDataSource.kt b/app/src/main/java/com/geeksville/mesh/repository/api/DeviceHardwareLocalDataSource.kt index 87295bcbc..d2d84685e 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/api/DeviceHardwareLocalDataSource.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/api/DeviceHardwareLocalDataSource.kt @@ -22,7 +22,7 @@ import com.geeksville.mesh.database.entity.DeviceHardwareEntity import com.geeksville.mesh.database.entity.asEntity import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -import org.meshtastic.core.network.model.NetworkDeviceHardware +import org.meshtastic.core.model.NetworkDeviceHardware import javax.inject.Inject class DeviceHardwareLocalDataSource diff --git a/app/src/main/java/com/geeksville/mesh/repository/api/FirmwareReleaseJsonDataSource.kt b/app/src/main/java/com/geeksville/mesh/repository/api/FirmwareReleaseJsonDataSource.kt index 6e0a1b603..f2de879a4 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/api/FirmwareReleaseJsonDataSource.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/api/FirmwareReleaseJsonDataSource.kt @@ -21,7 +21,7 @@ import android.app.Application import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.json.Json import kotlinx.serialization.json.decodeFromStream -import org.meshtastic.core.network.model.NetworkFirmwareReleases +import org.meshtastic.core.model.NetworkFirmwareReleases import javax.inject.Inject class FirmwareReleaseJsonDataSource @Inject constructor(private val application: Application) { diff --git a/app/src/main/java/com/geeksville/mesh/repository/api/FirmwareReleaseLocalDataSource.kt b/app/src/main/java/com/geeksville/mesh/repository/api/FirmwareReleaseLocalDataSource.kt index 2776e4c45..2ae85d41f 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/api/FirmwareReleaseLocalDataSource.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/api/FirmwareReleaseLocalDataSource.kt @@ -25,7 +25,7 @@ import com.geeksville.mesh.database.entity.asEntity import dagger.Lazy import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -import org.meshtastic.core.network.model.NetworkFirmwareRelease +import org.meshtastic.core.model.NetworkFirmwareRelease import javax.inject.Inject class FirmwareReleaseLocalDataSource @Inject constructor(private val firmwareReleaseDaoLazy: Lazy) { diff --git a/app/src/main/java/com/geeksville/mesh/repository/bluetooth/BluetoothState.kt b/app/src/main/java/com/geeksville/mesh/repository/bluetooth/BluetoothState.kt index f305f069c..c2b2465d2 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/bluetooth/BluetoothState.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/bluetooth/BluetoothState.kt @@ -18,19 +18,19 @@ package com.geeksville.mesh.repository.bluetooth import android.bluetooth.BluetoothDevice -import com.geeksville.mesh.util.anonymize +import org.meshtastic.core.model.util.anonymize -/** - * A snapshot in time of the state of the bluetooth subsystem. - */ +/** A snapshot in time of the state of the bluetooth subsystem. */ data class BluetoothState( /** Whether we have adequate permissions to query bluetooth state */ val hasPermissions: Boolean = false, /** If we have adequate permissions and bluetooth is enabled */ val enabled: Boolean = false, /** If enabled, a list of the currently bonded devices */ - val bondedDevices: List = emptyList() + val bondedDevices: List = emptyList(), ) { override fun toString(): String = - "BluetoothState(hasPermissions=$hasPermissions, enabled=$enabled, bondedDevices=${bondedDevices.map { it.anonymize }})" + "BluetoothState(hasPermissions=$hasPermissions, enabled=$enabled, bondedDevices=${bondedDevices.map { + it.anonymize + }})" } diff --git a/app/src/main/java/com/geeksville/mesh/repository/radio/BluetoothInterface.kt b/app/src/main/java/com/geeksville/mesh/repository/radio/BluetoothInterface.kt index a4bdfafc6..2c4848f71 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/radio/BluetoothInterface.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/radio/BluetoothInterface.kt @@ -29,7 +29,6 @@ import com.geeksville.mesh.service.BLEConnectionClosing import com.geeksville.mesh.service.BLEException import com.geeksville.mesh.service.RadioNotConnectedException import com.geeksville.mesh.service.SafeBluetooth -import com.geeksville.mesh.util.anonymize import com.geeksville.mesh.util.exceptionReporter import com.geeksville.mesh.util.ignoreException import dagger.assisted.Assisted @@ -37,6 +36,7 @@ import dagger.assisted.AssistedInject import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Job import kotlinx.coroutines.delay +import org.meshtastic.core.model.util.anonymize import java.lang.reflect.Method import java.util.UUID diff --git a/app/src/main/java/com/geeksville/mesh/repository/radio/BluetoothInterfaceSpec.kt b/app/src/main/java/com/geeksville/mesh/repository/radio/BluetoothInterfaceSpec.kt index 645c41418..03cf81231 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/radio/BluetoothInterfaceSpec.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/radio/BluetoothInterfaceSpec.kt @@ -19,24 +19,22 @@ package com.geeksville.mesh.repository.radio import com.geeksville.mesh.android.Logging import com.geeksville.mesh.repository.bluetooth.BluetoothRepository -import com.geeksville.mesh.util.anonymize +import org.meshtastic.core.model.util.anonymize import javax.inject.Inject -/** - * Bluetooth backend implementation. - */ -class BluetoothInterfaceSpec @Inject constructor( +/** Bluetooth backend implementation. */ +class BluetoothInterfaceSpec +@Inject +constructor( private val factory: BluetoothInterfaceFactory, private val bluetoothRepository: BluetoothRepository, -) : InterfaceSpec, Logging { - override fun createInterface(rest: String): BluetoothInterface { - return factory.create(rest) - } +) : InterfaceSpec, + Logging { + override fun createInterface(rest: String): BluetoothInterface = factory.create(rest) /** Return true if this address is still acceptable. For BLE that means, still bonded */ override fun addressValid(rest: String): Boolean { - val allPaired = bluetoothRepository.state.value.bondedDevices - .map { it.address }.toSet() + val allPaired = bluetoothRepository.state.value.bondedDevices.map { it.address }.toSet() return if (!allPaired.contains(rest)) { warn("Ignoring stale bond to ${rest.anonymize}") false diff --git a/app/src/main/java/com/geeksville/mesh/repository/radio/MockInterface.kt b/app/src/main/java/com/geeksville/mesh/repository/radio/MockInterface.kt index a4b19fcf2..cf9644f9d 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/radio/MockInterface.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/radio/MockInterface.kt @@ -21,10 +21,8 @@ import com.geeksville.mesh.AdminProtos import com.geeksville.mesh.ChannelProtos import com.geeksville.mesh.ConfigKt import com.geeksville.mesh.ConfigProtos -import com.geeksville.mesh.DataPacket import com.geeksville.mesh.MeshProtos import com.geeksville.mesh.Portnums -import com.geeksville.mesh.Position import com.geeksville.mesh.TelemetryProtos import com.geeksville.mesh.android.Logging import com.geeksville.mesh.channel @@ -39,6 +37,8 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedInject import kotlinx.coroutines.delay import org.meshtastic.core.model.Channel +import org.meshtastic.core.model.DataPacket +import org.meshtastic.core.model.Position import kotlin.random.Random private val defaultLoRaConfig = diff --git a/app/src/main/java/com/geeksville/mesh/repository/radio/RadioInterfaceService.kt b/app/src/main/java/com/geeksville/mesh/repository/radio/RadioInterfaceService.kt index e448b421f..8b9c10367 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/radio/RadioInterfaceService.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/radio/RadioInterfaceService.kt @@ -31,7 +31,6 @@ import com.geeksville.mesh.concurrent.handledLaunch import com.geeksville.mesh.repository.bluetooth.BluetoothRepository import com.geeksville.mesh.repository.network.NetworkRepository import com.geeksville.mesh.service.ConnectionState -import com.geeksville.mesh.util.anonymize import com.geeksville.mesh.util.ignoreException import com.geeksville.mesh.util.toRemoteExceptions import kotlinx.coroutines.CoroutineScope @@ -48,6 +47,7 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch +import org.meshtastic.core.model.util.anonymize import org.meshtastic.core.prefs.radio.RadioPrefs import javax.inject.Inject import javax.inject.Singleton 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 6d9876769..32424bb79 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -33,7 +33,6 @@ import com.geeksville.mesh.BuildConfig import com.geeksville.mesh.ChannelProtos import com.geeksville.mesh.ConfigProtos import com.geeksville.mesh.CoroutineDispatchers -import com.geeksville.mesh.DataPacket import com.geeksville.mesh.DeviceUIProtos import com.geeksville.mesh.IMeshService import com.geeksville.mesh.LocalOnlyProtos.LocalConfig @@ -42,14 +41,9 @@ import com.geeksville.mesh.MeshProtos import com.geeksville.mesh.MeshProtos.FromRadio.PayloadVariantCase import com.geeksville.mesh.MeshProtos.MeshPacket import com.geeksville.mesh.MeshProtos.ToRadio -import com.geeksville.mesh.MeshUser -import com.geeksville.mesh.MessageStatus import com.geeksville.mesh.ModuleConfigProtos -import com.geeksville.mesh.MyNodeInfo -import com.geeksville.mesh.NodeInfo import com.geeksville.mesh.PaxcountProtos import com.geeksville.mesh.Portnums -import com.geeksville.mesh.Position import com.geeksville.mesh.StoreAndForwardProtos import com.geeksville.mesh.TelemetryProtos import com.geeksville.mesh.TelemetryProtos.LocalStats @@ -68,7 +62,6 @@ import com.geeksville.mesh.database.entity.NodeEntity import com.geeksville.mesh.database.entity.Packet import com.geeksville.mesh.database.entity.ReactionEntity import com.geeksville.mesh.fromRadio -import com.geeksville.mesh.model.DeviceVersion import com.geeksville.mesh.model.NO_DEVICE_SELECTED import com.geeksville.mesh.model.Node import com.geeksville.mesh.position @@ -78,10 +71,7 @@ import com.geeksville.mesh.repository.network.MQTTRepository import com.geeksville.mesh.repository.radio.RadioInterfaceService import com.geeksville.mesh.telemetry import com.geeksville.mesh.user -import com.geeksville.mesh.util.anonymize import com.geeksville.mesh.util.ignoreException -import com.geeksville.mesh.util.toOneLineString -import com.geeksville.mesh.util.toPIIString import com.geeksville.mesh.util.toRemoteExceptions import com.google.protobuf.ByteString import com.google.protobuf.InvalidProtocolBufferException @@ -100,7 +90,17 @@ import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach +import org.meshtastic.core.model.DataPacket +import org.meshtastic.core.model.DeviceVersion +import org.meshtastic.core.model.MeshUser +import org.meshtastic.core.model.MessageStatus +import org.meshtastic.core.model.MyNodeInfo +import org.meshtastic.core.model.NodeInfo +import org.meshtastic.core.model.Position import org.meshtastic.core.model.getFullTracerouteResponse +import org.meshtastic.core.model.util.anonymize +import org.meshtastic.core.model.util.toOneLineString +import org.meshtastic.core.model.util.toPIIString import org.meshtastic.core.prefs.mesh.MeshPrefs import org.meshtastic.core.prefs.ui.UiPrefs import org.meshtastic.core.strings.R @@ -2155,8 +2155,9 @@ class MeshService : toRemoteExceptions { if (p.id == 0) p.id = generatePacketId() + val bytes = p.bytes!! info( - "sendData dest=${p.to}, id=${p.id} <- ${p.bytes!!.size} bytes" + + "sendData dest=${p.to}, id=${p.id} <- ${bytes.size} bytes" + " (connectionState=$connectionState)", ) @@ -2164,7 +2165,7 @@ class MeshService : throw Exception("Port numbers must be non-zero!") // we are now more strict } - if (p.bytes.size >= MeshProtos.Constants.DATA_PAYLOAD_LEN.number) { + if (bytes.size >= MeshProtos.Constants.DATA_PAYLOAD_LEN.number) { p.status = MessageStatus.ERROR throw RemoteException("Message too long") } else { @@ -2188,7 +2189,7 @@ class MeshService : GeeksvilleApplication.analytics.track( "data_send", - DataPair("num_bytes", p.bytes.size), + DataPair("num_bytes", bytes.size), DataPair("type", p.dataType), ) diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshServiceBroadcasts.kt b/app/src/main/java/com/geeksville/mesh/service/MeshServiceBroadcasts.kt index d1ff92ef3..de60aebbe 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshServiceBroadcasts.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshServiceBroadcasts.kt @@ -20,9 +20,9 @@ package com.geeksville.mesh.service import android.content.Context import android.content.Intent import android.os.Parcelable -import com.geeksville.mesh.DataPacket -import com.geeksville.mesh.MessageStatus -import com.geeksville.mesh.NodeInfo +import org.meshtastic.core.model.DataPacket +import org.meshtastic.core.model.MessageStatus +import org.meshtastic.core.model.NodeInfo class MeshServiceBroadcasts( private val context: Context, diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshServiceNotifications.kt b/app/src/main/java/com/geeksville/mesh/service/MeshServiceNotifications.kt index c85b835ec..78b8ca6e2 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshServiceNotifications.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshServiceNotifications.kt @@ -40,7 +40,7 @@ import com.geeksville.mesh.R.raw import com.geeksville.mesh.TelemetryProtos.LocalStats import com.geeksville.mesh.database.entity.NodeEntity import com.geeksville.mesh.service.ReplyReceiver.Companion.KEY_TEXT_REPLY -import com.geeksville.mesh.util.formatUptime +import org.meshtastic.core.model.util.formatUptime import org.meshtastic.core.navigation.DEEP_LINK_BASE_URI import org.meshtastic.core.strings.R diff --git a/app/src/main/java/com/geeksville/mesh/service/PacketHandler.kt b/app/src/main/java/com/geeksville/mesh/service/PacketHandler.kt index 02c5b2b51..4a4572d0e 100644 --- a/app/src/main/java/com/geeksville/mesh/service/PacketHandler.kt +++ b/app/src/main/java/com/geeksville/mesh/service/PacketHandler.kt @@ -17,11 +17,9 @@ package com.geeksville.mesh.service -import com.geeksville.mesh.DataPacket import com.geeksville.mesh.MeshProtos import com.geeksville.mesh.MeshProtos.MeshPacket import com.geeksville.mesh.MeshProtos.ToRadio -import com.geeksville.mesh.MessageStatus import com.geeksville.mesh.android.BuildUtils.debug import com.geeksville.mesh.android.BuildUtils.errormsg import com.geeksville.mesh.android.BuildUtils.info @@ -31,8 +29,6 @@ import com.geeksville.mesh.database.PacketRepository import com.geeksville.mesh.database.entity.MeshLog import com.geeksville.mesh.fromRadio import com.geeksville.mesh.repository.radio.RadioInterfaceService -import com.geeksville.mesh.util.toOneLineString -import com.geeksville.mesh.util.toPIIString import dagger.Lazy import java8.util.concurrent.CompletableFuture import kotlinx.coroutines.CoroutineScope @@ -40,6 +36,10 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.withTimeoutOrNull +import org.meshtastic.core.model.DataPacket +import org.meshtastic.core.model.MessageStatus +import org.meshtastic.core.model.util.toOneLineString +import org.meshtastic.core.model.util.toPIIString import java.util.UUID import java.util.concurrent.ConcurrentLinkedQueue import java.util.concurrent.TimeUnit diff --git a/app/src/main/java/com/geeksville/mesh/service/ReplyReceiver.kt b/app/src/main/java/com/geeksville/mesh/service/ReplyReceiver.kt index a4e70c50b..7b8d4f1d5 100644 --- a/app/src/main/java/com/geeksville/mesh/service/ReplyReceiver.kt +++ b/app/src/main/java/com/geeksville/mesh/service/ReplyReceiver.kt @@ -19,24 +19,22 @@ package com.geeksville.mesh.service import android.content.BroadcastReceiver import androidx.core.app.RemoteInput -import com.geeksville.mesh.DataPacket import dagger.hilt.android.AndroidEntryPoint import jakarta.inject.Inject +import org.meshtastic.core.model.DataPacket /** * A [BroadcastReceiver] that handles inline replies from notifications. * - * This receiver is triggered when a user replies to a message directly from a notification. - * It extracts the reply text and the contact key from the intent, sends the message - * using the [ServiceRepository], and then cancels the original notification. + * This receiver is triggered when a user replies to a message directly from a notification. It extracts the reply text + * and the contact key from the intent, sends the message using the [ServiceRepository], and then cancels the original + * notification. */ @AndroidEntryPoint class ReplyReceiver : BroadcastReceiver() { - @Inject - lateinit var serviceRepository: ServiceRepository + @Inject lateinit var serviceRepository: ServiceRepository - @Inject - lateinit var meshServiceNotifications: MeshServiceNotifications + @Inject lateinit var meshServiceNotifications: MeshServiceNotifications companion object { const val REPLY_ACTION = "com.geeksville.mesh.REPLY_ACTION" @@ -57,9 +55,7 @@ class ReplyReceiver : BroadcastReceiver() { if (remoteInput != null) { val contactKey = intent.getStringExtra(CONTACT_KEY) ?: "" - val message = remoteInput.getCharSequence( - KEY_TEXT_REPLY - )?.toString() ?: "" + val message = remoteInput.getCharSequence(KEY_TEXT_REPLY)?.toString() ?: "" sendMessage(message, contactKey) MeshServiceNotifications(context).cancelMessageNotification(contactKey) } diff --git a/app/src/main/java/com/geeksville/mesh/ui/Main.kt b/app/src/main/java/com/geeksville/mesh/ui/Main.kt index f0a823b27..588ad8723 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/Main.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/Main.kt @@ -80,7 +80,6 @@ import com.geeksville.mesh.android.AddNavigationTracking import com.geeksville.mesh.android.BuildUtils.debug import com.geeksville.mesh.android.setAttributes import com.geeksville.mesh.model.BTScanModel -import com.geeksville.mesh.model.DeviceVersion import com.geeksville.mesh.model.Node import com.geeksville.mesh.model.UIViewModel import com.geeksville.mesh.navigation.channelsGraph @@ -112,6 +111,7 @@ import com.google.accompanist.permissions.isGranted import com.google.accompanist.permissions.rememberPermissionState import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch +import org.meshtastic.core.model.DeviceVersion import org.meshtastic.core.navigation.ConnectionsRoutes import org.meshtastic.core.navigation.ContactsRoutes import org.meshtastic.core.navigation.MapRoutes diff --git a/app/src/main/java/com/geeksville/mesh/ui/common/preview/NodePreviewParameterProvider.kt b/app/src/main/java/com/geeksville/mesh/ui/common/preview/NodePreviewParameterProvider.kt index 3a80ef62f..4b02ce5d0 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/common/preview/NodePreviewParameterProvider.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/common/preview/NodePreviewParameterProvider.kt @@ -19,7 +19,6 @@ package com.geeksville.mesh.ui.common.preview import androidx.compose.ui.tooling.preview.PreviewParameterProvider import com.geeksville.mesh.ConfigProtos -import com.geeksville.mesh.DeviceMetrics.Companion.currentTime import com.geeksville.mesh.MeshProtos import com.geeksville.mesh.deviceMetrics import com.geeksville.mesh.environmentMetrics @@ -28,118 +27,132 @@ import com.geeksville.mesh.paxcount import com.geeksville.mesh.position import com.geeksville.mesh.user import com.google.protobuf.ByteString +import org.meshtastic.core.model.DeviceMetrics.Companion.currentTime import kotlin.random.Random class NodePreviewParameterProvider : PreviewParameterProvider { - val mickeyMouse = Node( - num = 1955, - user = user { - id = "mickeyMouseId" - longName = "Mickey Mouse" - shortName = "MM" - hwModel = MeshProtos.HardwareModel.TBEAM - role = ConfigProtos.Config.DeviceConfig.Role.ROUTER - }, - position = position { - latitudeI = 338125110 - longitudeI = -1179189760 - altitude = 138 - satsInView = 4 - }, - lastHeard = currentTime(), - channel = 0, - snr = 12.5F, - rssi = -42, - deviceMetrics = deviceMetrics { - channelUtilization = 2.4F - airUtilTx = 3.5F - batteryLevel = 85 - voltage = 3.7F - uptimeSeconds = 3600 - }, - isFavorite = true, - hopsAway = 0 - ) + val mickeyMouse = + Node( + num = 1955, + user = + user { + id = "mickeyMouseId" + longName = "Mickey Mouse" + shortName = "MM" + hwModel = MeshProtos.HardwareModel.TBEAM + role = ConfigProtos.Config.DeviceConfig.Role.ROUTER + }, + position = + position { + latitudeI = 338125110 + longitudeI = -1179189760 + altitude = 138 + satsInView = 4 + }, + lastHeard = currentTime(), + channel = 0, + snr = 12.5F, + rssi = -42, + deviceMetrics = + deviceMetrics { + channelUtilization = 2.4F + airUtilTx = 3.5F + batteryLevel = 85 + voltage = 3.7F + uptimeSeconds = 3600 + }, + isFavorite = true, + hopsAway = 0, + ) - val minnieMouse = mickeyMouse.copy( - num = Random.nextInt(), - user = user { - longName = "Minnie Mouse" - shortName = "MiMo" - id = "minnieMouseId" - hwModel = MeshProtos.HardwareModel.HELTEC_V3 - }, - snr = 12.5F, - rssi = -42, - position = position {}, - hopsAway = 1 - ) + val minnieMouse = + mickeyMouse.copy( + num = Random.nextInt(), + user = + user { + longName = "Minnie Mouse" + shortName = "MiMo" + id = "minnieMouseId" + hwModel = MeshProtos.HardwareModel.HELTEC_V3 + }, + snr = 12.5F, + rssi = -42, + position = position {}, + hopsAway = 1, + ) - private val donaldDuck = Node( - num = Random.nextInt(), - position = position { - latitudeI = 338052347 - longitudeI = -1179208460 - altitude = 121 - satsInView = 66 - }, - lastHeard = currentTime() - 300, - channel = 0, - snr = 12.5F, - rssi = -42, - deviceMetrics = deviceMetrics { - channelUtilization = 2.4F - airUtilTx = 3.5F - batteryLevel = 85 - voltage = 3.7F - uptimeSeconds = 3600 - }, - user = user { - id = "donaldDuckId" - longName = "Donald Duck, the Grand Duck of the Ducks" - shortName = "DoDu" - hwModel = MeshProtos.HardwareModel.HELTEC_V3 - publicKey = ByteString.copyFrom(ByteArray(32) { 1 }) - }, - environmentMetrics = environmentMetrics { - temperature = 28.0F - relativeHumidity = 50.0F - barometricPressure = 1013.25F - gasResistance = 0.0F - voltage = 3.7F - current = 0.0F - iaq = 100 - }, - paxcounter = paxcount { - wifi = 30 - ble = 39 - uptime = 420 - }, - isFavorite = true, - hopsAway = 2 - ) + private val donaldDuck = + Node( + num = Random.nextInt(), + position = + position { + latitudeI = 338052347 + longitudeI = -1179208460 + altitude = 121 + satsInView = 66 + }, + lastHeard = currentTime() - 300, + channel = 0, + snr = 12.5F, + rssi = -42, + deviceMetrics = + deviceMetrics { + channelUtilization = 2.4F + airUtilTx = 3.5F + batteryLevel = 85 + voltage = 3.7F + uptimeSeconds = 3600 + }, + user = + user { + id = "donaldDuckId" + longName = "Donald Duck, the Grand Duck of the Ducks" + shortName = "DoDu" + hwModel = MeshProtos.HardwareModel.HELTEC_V3 + publicKey = ByteString.copyFrom(ByteArray(32) { 1 }) + }, + environmentMetrics = + environmentMetrics { + temperature = 28.0F + relativeHumidity = 50.0F + barometricPressure = 1013.25F + gasResistance = 0.0F + voltage = 3.7F + current = 0.0F + iaq = 100 + }, + paxcounter = + paxcount { + wifi = 30 + ble = 39 + uptime = 420 + }, + isFavorite = true, + hopsAway = 2, + ) - private val unknown = donaldDuck.copy( - user = user { - id = "myId" - longName = "Meshtastic myId" - shortName = "myId" - hwModel = MeshProtos.HardwareModel.UNSET - }, - environmentMetrics = environmentMetrics {}, - paxcounter = paxcount {}, - ) + private val unknown = + donaldDuck.copy( + user = + user { + id = "myId" + longName = "Meshtastic myId" + shortName = "myId" + hwModel = MeshProtos.HardwareModel.UNSET + }, + environmentMetrics = environmentMetrics {}, + paxcounter = paxcount {}, + ) - private val almostNothing = Node( - num = Random.nextInt(), - ) + private val almostNothing = Node(num = Random.nextInt()) override val values: Sequence - get() = sequenceOf( - mickeyMouse, // "this" node - unknown, - almostNothing, - minnieMouse, - donaldDuck - ) + get() = + sequenceOf( + mickeyMouse, // "this" node + unknown, + almostNothing, + minnieMouse, + donaldDuck, + ) } diff --git a/app/src/main/java/com/geeksville/mesh/ui/message/Message.kt b/app/src/main/java/com/geeksville/mesh/ui/message/Message.kt index a9cc1c00a..135a47fd0 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/message/Message.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/message/Message.kt @@ -95,7 +95,6 @@ import androidx.compose.ui.unit.dp import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.geeksville.mesh.AppOnlyProtos -import com.geeksville.mesh.DataPacket import com.geeksville.mesh.database.entity.QuickChatAction import com.geeksville.mesh.model.Message import com.geeksville.mesh.model.Node @@ -108,6 +107,7 @@ import com.geeksville.mesh.ui.node.components.NodeMenuAction import com.geeksville.mesh.ui.sharing.SharedContactDialog import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch +import org.meshtastic.core.model.DataPacket import org.meshtastic.core.strings.R import java.nio.charset.StandardCharsets diff --git a/app/src/main/java/com/geeksville/mesh/ui/message/MessageList.kt b/app/src/main/java/com/geeksville/mesh/ui/message/MessageList.kt index f94c09f2a..e0ab6fadc 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/message/MessageList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/message/MessageList.kt @@ -47,7 +47,6 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.geeksville.mesh.MessageStatus import com.geeksville.mesh.database.entity.Reaction import com.geeksville.mesh.model.Message import com.geeksville.mesh.model.UIViewModel @@ -58,6 +57,7 @@ import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.launch +import org.meshtastic.core.model.MessageStatus import org.meshtastic.core.strings.R @Composable diff --git a/app/src/main/java/com/geeksville/mesh/ui/message/components/MessageActions.kt b/app/src/main/java/com/geeksville/mesh/ui/message/components/MessageActions.kt index 45fd15f28..504a05b72 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/message/components/MessageActions.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/message/components/MessageActions.kt @@ -39,8 +39,8 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource -import com.geeksville.mesh.MessageStatus import com.geeksville.mesh.ui.common.components.EmojiPickerDialog +import org.meshtastic.core.model.MessageStatus import org.meshtastic.core.strings.R @Composable diff --git a/app/src/main/java/com/geeksville/mesh/ui/message/components/MessageItem.kt b/app/src/main/java/com/geeksville/mesh/ui/message/components/MessageItem.kt index 0327a49e6..f4ffc2861 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/message/components/MessageItem.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/message/components/MessageItem.kt @@ -49,7 +49,6 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.unit.dp -import com.geeksville.mesh.MessageStatus import com.geeksville.mesh.database.entity.Reaction import com.geeksville.mesh.model.Message import com.geeksville.mesh.model.Node @@ -61,6 +60,7 @@ import com.geeksville.mesh.ui.common.theme.AppTheme import com.geeksville.mesh.ui.common.theme.MessageItemColors import com.geeksville.mesh.ui.node.components.NodeChip import com.geeksville.mesh.ui.node.components.NodeMenuAction +import org.meshtastic.core.model.MessageStatus import org.meshtastic.core.strings.R @Suppress("LongMethod", "CyclomaticComplexMethod") diff --git a/app/src/main/java/com/geeksville/mesh/ui/metrics/EnvironmentMetrics.kt b/app/src/main/java/com/geeksville/mesh/ui/metrics/EnvironmentMetrics.kt index 84605e57c..f40bfeaec 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/metrics/EnvironmentMetrics.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/metrics/EnvironmentMetrics.kt @@ -48,7 +48,6 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.geeksville.mesh.EnvironmentMetrics import com.geeksville.mesh.TelemetryProtos import com.geeksville.mesh.TelemetryProtos.Telemetry import com.geeksville.mesh.copy @@ -60,7 +59,7 @@ import com.geeksville.mesh.ui.common.components.OptionLabel import com.geeksville.mesh.ui.common.components.SlidingSelector import com.geeksville.mesh.ui.metrics.CommonCharts.DATE_TIME_FORMAT import com.geeksville.mesh.ui.metrics.CommonCharts.MS_PER_SEC -import com.geeksville.mesh.util.UnitConversions.celsiusToFahrenheit +import org.meshtastic.core.model.util.UnitConversions.celsiusToFahrenheit import org.meshtastic.core.strings.R @Composable diff --git a/app/src/main/java/com/geeksville/mesh/ui/metrics/HostMetricsLog.kt b/app/src/main/java/com/geeksville/mesh/ui/metrics/HostMetricsLog.kt index b7a90eba0..9b39526c4 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/metrics/HostMetricsLog.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/metrics/HostMetricsLog.kt @@ -57,7 +57,7 @@ import com.geeksville.mesh.TelemetryProtos import com.geeksville.mesh.model.MetricsViewModel import com.geeksville.mesh.ui.common.theme.AppTheme import com.geeksville.mesh.ui.metrics.CommonCharts.DATE_TIME_FORMAT -import com.geeksville.mesh.util.formatUptime +import org.meshtastic.core.model.util.formatUptime import org.meshtastic.core.strings.R import java.text.DecimalFormat diff --git a/app/src/main/java/com/geeksville/mesh/ui/metrics/PaxMetrics.kt b/app/src/main/java/com/geeksville/mesh/ui/metrics/PaxMetrics.kt index 6b9100104..59c4ae12b 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/metrics/PaxMetrics.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/metrics/PaxMetrics.kt @@ -60,7 +60,7 @@ import com.geeksville.mesh.model.MetricsViewModel import com.geeksville.mesh.model.TimeFrame import com.geeksville.mesh.ui.common.components.OptionLabel import com.geeksville.mesh.ui.common.components.SlidingSelector -import com.geeksville.mesh.util.formatUptime +import org.meshtastic.core.model.util.formatUptime import org.meshtastic.core.strings.R import java.text.DateFormat import java.util.Date diff --git a/app/src/main/java/com/geeksville/mesh/ui/node/NodeDetail.kt b/app/src/main/java/com/geeksville/mesh/ui/node/NodeDetail.kt index ee2442095..fda74269f 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/node/NodeDetail.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/node/NodeDetail.kt @@ -122,11 +122,9 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import coil3.compose.AsyncImage import coil3.request.ImageRequest import com.geeksville.mesh.ConfigProtos -import com.geeksville.mesh.DataPacket import com.geeksville.mesh.MeshProtos import com.geeksville.mesh.database.entity.FirmwareRelease import com.geeksville.mesh.database.entity.asDeviceVersion -import com.geeksville.mesh.model.DeviceVersion import com.geeksville.mesh.model.MetricsState import com.geeksville.mesh.model.MetricsViewModel import com.geeksville.mesh.model.Node @@ -148,16 +146,18 @@ import com.geeksville.mesh.ui.settings.components.SettingsItem import com.geeksville.mesh.ui.settings.components.SettingsItemDetail import com.geeksville.mesh.ui.settings.components.SettingsItemSwitch import com.geeksville.mesh.ui.sharing.SharedContactDialog -import com.geeksville.mesh.util.UnitConversions -import com.geeksville.mesh.util.UnitConversions.toTempString -import com.geeksville.mesh.util.formatAgo -import com.geeksville.mesh.util.formatUptime import com.geeksville.mesh.util.thenIf import com.geeksville.mesh.util.toDistanceString import com.geeksville.mesh.util.toSmallDistanceString import com.geeksville.mesh.util.toSpeedString import com.mikepenz.markdown.m3.Markdown +import org.meshtastic.core.model.DataPacket import org.meshtastic.core.model.DeviceHardware +import org.meshtastic.core.model.DeviceVersion +import org.meshtastic.core.model.util.UnitConversions +import org.meshtastic.core.model.util.UnitConversions.toTempString +import org.meshtastic.core.model.util.formatAgo +import org.meshtastic.core.model.util.formatUptime import org.meshtastic.core.navigation.NodeDetailRoutes import org.meshtastic.core.navigation.Route import org.meshtastic.core.navigation.SettingsRoutes diff --git a/app/src/main/java/com/geeksville/mesh/ui/node/NodeScreen.kt b/app/src/main/java/com/geeksville/mesh/ui/node/NodeScreen.kt index 0f0ea8fbe..b70d4ebf2 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/node/NodeScreen.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/node/NodeScreen.kt @@ -46,8 +46,6 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.geeksville.mesh.DataPacket -import com.geeksville.mesh.model.DeviceVersion import com.geeksville.mesh.model.Node import com.geeksville.mesh.model.UIViewModel import com.geeksville.mesh.service.ConnectionState @@ -59,6 +57,8 @@ import com.geeksville.mesh.ui.node.components.NodeMenuAction import com.geeksville.mesh.ui.sharing.AddContactFAB import com.geeksville.mesh.ui.sharing.SharedContactDialog import com.geeksville.mesh.ui.sharing.supportsQrCodeSharing +import org.meshtastic.core.model.DataPacket +import org.meshtastic.core.model.DeviceVersion import org.meshtastic.core.strings.R @OptIn(ExperimentalFoundationApi::class, ExperimentalMaterial3ExpressiveApi::class) diff --git a/app/src/main/java/com/geeksville/mesh/ui/node/components/LastHeardInfo.kt b/app/src/main/java/com/geeksville/mesh/ui/node/components/LastHeardInfo.kt index 7f6db6b8d..c7337256c 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/node/components/LastHeardInfo.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/node/components/LastHeardInfo.kt @@ -32,7 +32,7 @@ import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.unit.dp import com.geeksville.mesh.R import com.geeksville.mesh.ui.common.theme.AppTheme -import com.geeksville.mesh.util.formatAgo +import org.meshtastic.core.model.util.formatAgo @Composable fun LastHeardInfo(modifier: Modifier = Modifier, lastHeard: Int, currentTimeMillis: Long) { diff --git a/app/src/main/java/com/geeksville/mesh/ui/node/components/LinkedCoordinates.kt b/app/src/main/java/com/geeksville/mesh/ui/node/components/LinkedCoordinates.kt index d1a1c0862..da1f71e95 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/node/components/LinkedCoordinates.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/node/components/LinkedCoordinates.kt @@ -43,8 +43,8 @@ import androidx.core.net.toUri import com.geeksville.mesh.android.BuildUtils.debug import com.geeksville.mesh.ui.common.theme.AppTheme import com.geeksville.mesh.ui.common.theme.HyperlinkBlue -import com.geeksville.mesh.util.GPSFormat import kotlinx.coroutines.launch +import org.meshtastic.core.model.util.GPSFormat import java.net.URLEncoder @OptIn(ExperimentalFoundationApi::class) 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 c00517702..5cbc25605 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 @@ -25,14 +25,12 @@ import com.geeksville.mesh.IMeshService import com.geeksville.mesh.LocalOnlyProtos.LocalConfig import com.geeksville.mesh.MeshProtos import com.geeksville.mesh.Portnums -import com.geeksville.mesh.Position import com.geeksville.mesh.android.Logging import com.geeksville.mesh.database.MeshLogRepository import com.geeksville.mesh.database.NodeRepository import com.geeksville.mesh.database.entity.MyNodeEntity import com.geeksville.mesh.model.Node import com.geeksville.mesh.repository.datastore.RadioConfigRepository -import com.geeksville.mesh.util.positionToMeter import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow @@ -48,6 +46,8 @@ import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.meshtastic.core.datastore.UiPreferencesDataSource +import org.meshtastic.core.model.Position +import org.meshtastic.core.model.util.positionToMeter import org.meshtastic.core.prefs.ui.UiPrefs import java.io.BufferedWriter import java.io.FileNotFoundException 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 44569533a..78de37887 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 @@ -41,7 +41,6 @@ import com.geeksville.mesh.IMeshService import com.geeksville.mesh.MeshProtos import com.geeksville.mesh.ModuleConfigProtos import com.geeksville.mesh.Portnums -import com.geeksville.mesh.Position import com.geeksville.mesh.android.GeeksvilleApplication import com.geeksville.mesh.android.Logging import com.geeksville.mesh.android.isAnalyticsAvailable @@ -74,6 +73,7 @@ import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.json.JSONObject +import org.meshtastic.core.model.Position import org.meshtastic.core.navigation.SettingsRoutes import org.meshtastic.core.prefs.analytics.AnalyticsPrefs import org.meshtastic.core.prefs.map.MapConsentPrefs diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/ChannelLegend.kt b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/ChannelLegend.kt index 802dff3da..2e19d3644 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/ChannelLegend.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/ChannelLegend.kt @@ -45,7 +45,7 @@ import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.geeksville.mesh.model.DeviceVersion +import org.meshtastic.core.model.DeviceVersion import org.meshtastic.core.strings.R /** diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/ChannelSettingsItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/ChannelSettingsItemList.kt index b6d0153ee..e76c97a68 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/ChannelSettingsItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/ChannelSettingsItemList.kt @@ -73,7 +73,6 @@ import androidx.navigation.NavController import com.geeksville.mesh.ChannelProtos.ChannelSettings import com.geeksville.mesh.ConfigProtos.Config.LoRaConfig import com.geeksville.mesh.channelSettings -import com.geeksville.mesh.model.DeviceVersion import com.geeksville.mesh.ui.common.components.PreferenceCategory import com.geeksville.mesh.ui.common.components.PreferenceFooter import com.geeksville.mesh.ui.common.components.SecurityIcon @@ -82,6 +81,7 @@ import com.geeksville.mesh.ui.common.components.dragDropItemsIndexed import com.geeksville.mesh.ui.common.components.rememberDragDropState import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel import org.meshtastic.core.model.Channel +import org.meshtastic.core.model.DeviceVersion import org.meshtastic.core.strings.R @Composable diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/PositionConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/PositionConfigItemList.kt index ba5636263..c01292eec 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/PositionConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/PositionConfigItemList.kt @@ -41,7 +41,6 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavController import com.geeksville.mesh.ConfigProtos import com.geeksville.mesh.ConfigProtos.Config.PositionConfig -import com.geeksville.mesh.Position import com.geeksville.mesh.config import com.geeksville.mesh.copy import com.geeksville.mesh.ui.common.components.BitwisePreference @@ -53,6 +52,7 @@ import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel import com.google.accompanist.permissions.ExperimentalPermissionsApi import com.google.accompanist.permissions.rememberPermissionState import kotlinx.coroutines.launch +import org.meshtastic.core.model.Position import org.meshtastic.core.strings.R @OptIn(ExperimentalPermissionsApi::class) diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/UserConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/UserConfigItemList.kt index ebd5703b2..ea574cba3 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/UserConfigItemList.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/UserConfigItemList.kt @@ -30,14 +30,13 @@ import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavController import com.geeksville.mesh.copy -import com.geeksville.mesh.model.DeviceVersion import com.geeksville.mesh.model.isUnmessageableRole import com.geeksville.mesh.ui.common.components.EditTextPreference import com.geeksville.mesh.ui.common.components.PreferenceCategory import com.geeksville.mesh.ui.common.components.RegularPreference import com.geeksville.mesh.ui.common.components.SwitchPreference import com.geeksville.mesh.ui.settings.radio.RadioConfigViewModel -import com.geeksville.mesh.user +import org.meshtastic.core.model.DeviceVersion import org.meshtastic.core.strings.R @Composable diff --git a/app/src/main/java/com/geeksville/mesh/ui/sharing/ContactSharing.kt b/app/src/main/java/com/geeksville/mesh/ui/sharing/ContactSharing.kt index 74ad81186..d0966fd58 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/sharing/ContactSharing.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/sharing/ContactSharing.kt @@ -54,7 +54,6 @@ import com.geeksville.mesh.AdminProtos import com.geeksville.mesh.MeshProtos import com.geeksville.mesh.android.BuildUtils.debug import com.geeksville.mesh.android.BuildUtils.errormsg -import com.geeksville.mesh.model.DeviceVersion import com.geeksville.mesh.model.Node import com.geeksville.mesh.model.UIViewModel import com.geeksville.mesh.ui.common.components.CopyIconButton @@ -70,6 +69,7 @@ import com.google.zxing.WriterException import com.journeyapps.barcodescanner.BarcodeEncoder import com.journeyapps.barcodescanner.ScanContract import com.journeyapps.barcodescanner.ScanOptions +import org.meshtastic.core.model.DeviceVersion import org.meshtastic.core.strings.R import timber.log.Timber import java.net.MalformedURLException diff --git a/app/src/test/java/com/geeksville/mesh/NodeInfoTest.kt b/app/src/test/java/com/geeksville/mesh/NodeInfoTest.kt index d017a6865..80bddce51 100644 --- a/app/src/test/java/com/geeksville/mesh/NodeInfoTest.kt +++ b/app/src/test/java/com/geeksville/mesh/NodeInfoTest.kt @@ -23,6 +23,9 @@ import org.junit.After import org.junit.Assert import org.junit.Before import org.junit.Test +import org.meshtastic.core.model.MeshUser +import org.meshtastic.core.model.NodeInfo +import org.meshtastic.core.model.Position import java.util.Locale class NodeInfoTest { diff --git a/app/src/test/java/com/geeksville/mesh/PositionTest.kt b/app/src/test/java/com/geeksville/mesh/PositionTest.kt index a8c91c8eb..a217f7627 100644 --- a/app/src/test/java/com/geeksville/mesh/PositionTest.kt +++ b/app/src/test/java/com/geeksville/mesh/PositionTest.kt @@ -19,6 +19,7 @@ package com.geeksville.mesh import org.junit.Assert import org.junit.Test +import org.meshtastic.core.model.Position class PositionTest { @Test @@ -35,5 +36,4 @@ class PositionTest { val position = Position(37.1, 121.1, 35) Assert.assertTrue(position.time != 0) } - } diff --git a/app/src/test/java/com/geeksville/mesh/model/DeviceVersionTest.kt b/app/src/test/java/com/geeksville/mesh/model/DeviceVersionTest.kt index 677124135..91d645aac 100644 --- a/app/src/test/java/com/geeksville/mesh/model/DeviceVersionTest.kt +++ b/app/src/test/java/com/geeksville/mesh/model/DeviceVersionTest.kt @@ -17,17 +17,17 @@ package com.geeksville.mesh.model -import org.junit.Assert.* +import org.junit.Assert.assertEquals import org.junit.Test +import org.meshtastic.core.model.DeviceVersion class DeviceVersionTest { /** make sure we match the python and device code behavior */ @Test fun canParse() { - assertEquals(10000, DeviceVersion("1.0.0").asInt) assertEquals(10101, DeviceVersion("1.1.1").asInt) assertEquals(12357, DeviceVersion("1.23.57").asInt) assertEquals(12357, DeviceVersion("1.23.57.abde123").asInt) } -} \ No newline at end of file +} diff --git a/app/src/test/java/com/geeksville/mesh/ui/metrics/EnvironmentMetricsTest.kt b/app/src/test/java/com/geeksville/mesh/ui/metrics/EnvironmentMetricsTest.kt index e9276d79d..2fc378d47 100644 --- a/app/src/test/java/com/geeksville/mesh/ui/metrics/EnvironmentMetricsTest.kt +++ b/app/src/test/java/com/geeksville/mesh/ui/metrics/EnvironmentMetricsTest.kt @@ -19,9 +19,9 @@ package com.geeksville.mesh.ui.metrics import com.geeksville.mesh.TelemetryProtos import com.geeksville.mesh.copy -import com.geeksville.mesh.util.UnitConversions.celsiusToFahrenheit import org.junit.Assert.assertEquals import org.junit.Test +import org.meshtastic.core.model.util.UnitConversions.celsiusToFahrenheit class EnvironmentMetricsTest { diff --git a/core/model/build.gradle.kts b/core/model/build.gradle.kts index 45c560556..725a35c1b 100644 --- a/core/model/build.gradle.kts +++ b/core/model/build.gradle.kts @@ -19,8 +19,19 @@ plugins { alias(libs.plugins.kover) alias(libs.plugins.meshtastic.android.library) alias(libs.plugins.meshtastic.kotlinx.serialization) + alias(libs.plugins.kotlin.parcelize) } -android { namespace = "org.meshtastic.core.model" } +android { + buildFeatures { + buildConfig = true + aidl = true + } + namespace = "org.meshtastic.core.model" +} -dependencies { implementation(projects.core.proto) } +dependencies { + implementation(projects.core.proto) + implementation(projects.core.strings) + implementation(libs.timber) +} diff --git a/core/model/src/main/aidl/org/meshtastic/core/model/DataPacket.aidl b/core/model/src/main/aidl/org/meshtastic/core/model/DataPacket.aidl new file mode 100644 index 000000000..b8a164056 --- /dev/null +++ b/core/model/src/main/aidl/org/meshtastic/core/model/DataPacket.aidl @@ -0,0 +1,3 @@ +package org.meshtastic.core.model; + +parcelable DataPacket; \ No newline at end of file diff --git a/core/model/src/main/aidl/org/meshtastic/core/model/MeshUser.aidl b/core/model/src/main/aidl/org/meshtastic/core/model/MeshUser.aidl new file mode 100644 index 000000000..ba7153973 --- /dev/null +++ b/core/model/src/main/aidl/org/meshtastic/core/model/MeshUser.aidl @@ -0,0 +1,3 @@ +package org.meshtastic.core.model; + +parcelable MeshUser; \ No newline at end of file diff --git a/core/model/src/main/aidl/org/meshtastic/core/model/MyNodeInfo.aidl b/core/model/src/main/aidl/org/meshtastic/core/model/MyNodeInfo.aidl new file mode 100644 index 000000000..1286d7c7f --- /dev/null +++ b/core/model/src/main/aidl/org/meshtastic/core/model/MyNodeInfo.aidl @@ -0,0 +1,3 @@ +package org.meshtastic.core.model; + +parcelable MyNodeInfo; \ No newline at end of file diff --git a/core/model/src/main/aidl/org/meshtastic/core/model/NodeInfo.aidl b/core/model/src/main/aidl/org/meshtastic/core/model/NodeInfo.aidl new file mode 100644 index 000000000..ab7c1c926 --- /dev/null +++ b/core/model/src/main/aidl/org/meshtastic/core/model/NodeInfo.aidl @@ -0,0 +1,3 @@ +package org.meshtastic.core.model; + +parcelable NodeInfo; \ No newline at end of file diff --git a/core/model/src/main/aidl/org/meshtastic/core/model/Position.aidl b/core/model/src/main/aidl/org/meshtastic/core/model/Position.aidl new file mode 100644 index 000000000..be49bd57a --- /dev/null +++ b/core/model/src/main/aidl/org/meshtastic/core/model/Position.aidl @@ -0,0 +1,3 @@ +package org.meshtastic.core.model; + +parcelable Position; \ No newline at end of file diff --git a/app/src/main/java/com/geeksville/mesh/DataPacket.kt b/core/model/src/main/kotlin/org/meshtastic/core/model/DataPacket.kt similarity index 74% rename from app/src/main/java/com/geeksville/mesh/DataPacket.kt rename to core/model/src/main/kotlin/org/meshtastic/core/model/DataPacket.kt index bb387bdf3..aafc8329a 100644 --- a/app/src/main/java/com/geeksville/mesh/DataPacket.kt +++ b/core/model/src/main/kotlin/org/meshtastic/core/model/DataPacket.kt @@ -15,24 +15,23 @@ * along with this program. If not, see . */ -package com.geeksville.mesh +package org.meshtastic.core.model import android.os.Parcel import android.os.Parcelable +import com.geeksville.mesh.MeshProtos +import com.geeksville.mesh.Portnums import kotlinx.parcelize.Parcelize import kotlinx.serialization.Serializable -/** - * Generic [Parcel.readParcelable] Android 13 compatibility extension. - */ -private inline fun Parcel.readParcelableCompat(loader: ClassLoader?): T? { - return if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.TIRAMISU) { +/** Generic [Parcel.readParcelable] Android 13 compatibility extension. */ +private inline fun Parcel.readParcelableCompat(loader: ClassLoader?): T? = + if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.TIRAMISU) { @Suppress("DEPRECATION") readParcelable(loader) } else { readParcelable(loader, T::class.java) } -} @Parcelize enum class MessageStatus : Parcelable { @@ -41,17 +40,16 @@ enum class MessageStatus : Parcelable { QUEUED, // Waiting to send to the mesh as soon as we connect to the device ENROUTE, // Delivered to the radio, but no ACK or NAK received DELIVERED, // We received an ack - ERROR // We received back a nak, message not delivered + ERROR, // We received back a nak, message not delivered } -/** - * A parcelable version of the protobuf MeshPacket + Data subpacket. - */ +/** A parcelable version of the protobuf MeshPacket + Data subpacket. */ @Serializable data class DataPacket( var to: String? = ID_BROADCAST, // a nodeID string, or ID_BROADCAST for broadcast val bytes: ByteArray?, - val dataType: Int, // A port number for this packet (formerly called DataType, see portnums.proto for new usage instructions) + // A port number for this packet (formerly called DataType, see portnums.proto for new usage instructions) + val dataType: Int, var from: String? = ID_LOCAL, // a nodeID string, or ID_LOCAL for localhost var time: Long = System.currentTimeMillis(), // msecs since 1970 var id: Int = 0, // 0 means unassigned @@ -62,62 +60,65 @@ data class DataPacket( var hopStart: Int = 0, var snr: Float = 0f, var rssi: Int = 0, - var replyId: Int? = null // If this is a reply to a previous message, this is the ID of that message + var replyId: Int? = null, // If this is a reply to a previous message, this is the ID of that message ) : Parcelable { - /** - * If there was an error with this message, this string describes what was wrong. - */ + /** If there was an error with this message, this string describes what was wrong. */ var errorMessage: String? = null - /** - * Syntactic sugar to make it easy to create text messages - */ - constructor(to: String?, channel: Int, text: String, replyId: Int? = null) : this( + /** Syntactic sugar to make it easy to create text messages */ + constructor( + to: String?, + channel: Int, + text: String, + replyId: Int? = null, + ) : this( to = to, bytes = text.encodeToByteArray(), dataType = Portnums.PortNum.TEXT_MESSAGE_APP_VALUE, channel = channel, - replyId = replyId ?: 0 + replyId = replyId ?: 0, ) - /** - * If this is a text message, return the string, otherwise null - */ + /** If this is a text message, return the string, otherwise null */ val text: String? - get() = if (dataType == Portnums.PortNum.TEXT_MESSAGE_APP_VALUE) { - bytes?.decodeToString() - } else { - null - } + get() = + if (dataType == Portnums.PortNum.TEXT_MESSAGE_APP_VALUE) { + bytes?.decodeToString() + } else { + null + } val alert: String? - get() = if (dataType == Portnums.PortNum.ALERT_APP_VALUE) { - bytes?.decodeToString() - } else { - null - } + get() = + if (dataType == Portnums.PortNum.ALERT_APP_VALUE) { + bytes?.decodeToString() + } else { + null + } - constructor(to: String?, channel: Int, waypoint: MeshProtos.Waypoint) : this( - to = to, - bytes = waypoint.toByteArray(), - dataType = Portnums.PortNum.WAYPOINT_APP_VALUE, - channel = channel, - ) + constructor( + to: String?, + channel: Int, + waypoint: MeshProtos.Waypoint, + ) : this(to = to, bytes = waypoint.toByteArray(), dataType = Portnums.PortNum.WAYPOINT_APP_VALUE, channel = channel) val waypoint: MeshProtos.Waypoint? - get() = if (dataType == Portnums.PortNum.WAYPOINT_APP_VALUE) { - MeshProtos.Waypoint.parseFrom(bytes) - } else { - null - } + get() = + if (dataType == Portnums.PortNum.WAYPOINT_APP_VALUE) { + MeshProtos.Waypoint.parseFrom(bytes) + } else { + null + } val hopsAway: Int get() = if (hopStart == 0 || hopLimit > hopStart) -1 else hopStart - hopLimit // Autogenerated comparision, because we have a byte array - constructor(parcel: Parcel) : this( + constructor( + parcel: Parcel, + ) : this( parcel.readString(), parcel.createByteArray(), parcel.readInt(), @@ -131,7 +132,7 @@ data class DataPacket( parcel.readInt(), parcel.readFloat(), parcel.readInt(), - parcel.readInt().let { if (it == 0) null else it } + parcel.readInt().let { if (it == 0) null else it }, ) @Suppress("CyclomaticComplexMethod") @@ -194,9 +195,7 @@ data class DataPacket( parcel.writeInt(replyId ?: 0) } - override fun describeContents(): Int { - return 0 - } + override fun describeContents(): Int = 0 // Update our object from our parcel (used for inout parameters fun readFromParcel(parcel: Parcel) { @@ -232,15 +231,12 @@ data class DataPacket( const val PKC_CHANNEL_INDEX = 8 fun nodeNumToDefaultId(n: Int): String = "!%08x".format(n) - fun idToDefaultNodeNum(id: String?): Int? = - runCatching { id?.toLong(16)?.toInt() }.getOrNull() - override fun createFromParcel(parcel: Parcel): DataPacket { - return DataPacket(parcel) - } + @Suppress("MagicNumber") + fun idToDefaultNodeNum(id: String?): Int? = runCatching { id?.toLong(16)?.toInt() }.getOrNull() - override fun newArray(size: Int): Array { - return arrayOfNulls(size) - } + override fun createFromParcel(parcel: Parcel): DataPacket = DataPacket(parcel) + + override fun newArray(size: Int): Array = arrayOfNulls(size) } } diff --git a/app/src/main/java/com/geeksville/mesh/model/DeviceVersion.kt b/core/model/src/main/kotlin/org/meshtastic/core/model/DeviceVersion.kt similarity index 65% rename from app/src/main/java/com/geeksville/mesh/model/DeviceVersion.kt rename to core/model/src/main/kotlin/org/meshtastic/core/model/DeviceVersion.kt index 2cc330bd8..6aeffb8a3 100644 --- a/app/src/main/java/com/geeksville/mesh/model/DeviceVersion.kt +++ b/core/model/src/main/kotlin/org/meshtastic/core/model/DeviceVersion.kt @@ -15,37 +15,35 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.model +package org.meshtastic.core.model -import com.geeksville.mesh.android.Logging +import timber.log.Timber -/** - * Provide structured access to parse and compare device version strings - */ -data class DeviceVersion(val asString: String) : Comparable, Logging { +/** Provide structured access to parse and compare device version strings */ +data class DeviceVersion(val asString: String) : Comparable { + @Suppress("TooGenericExceptionCaught", "SwallowedException") val asInt - get() = try { - verStringToInt(asString) - } catch (e: Exception) { - warn("Exception while parsing version '$asString', assuming version 0") - 0 - } + get() = + try { + verStringToInt(asString) + } catch (e: Exception) { + Timber.w("Exception while parsing version '$asString', assuming version 0") + 0 + } /** - * Convert a version string of the form 1.23.57 to a comparable integer of - * the form 12357. + * Convert a version string of the form 1.23.57 to a comparable integer of the form 12357. * * Or throw an exception if the string can not be parsed */ + @Suppress("TooGenericExceptionThrown", "MagicNumber") private fun verStringToInt(s: String): Int { // Allow 1 to two digits per match - val match = - Regex("(\\d{1,2}).(\\d{1,2}).(\\d{1,2})").find(s) - ?: throw Exception("Can't parse version $s") + val match = Regex("(\\d{1,2}).(\\d{1,2}).(\\d{1,2})").find(s) ?: throw Exception("Can't parse version $s") val (major, minor, build) = match.destructured return major.toInt() * 10000 + minor.toInt() * 100 + build.toInt() } override fun compareTo(other: DeviceVersion): Int = asInt - other.asInt -} \ No newline at end of file +} diff --git a/app/src/main/java/com/geeksville/mesh/MyNodeInfo.kt b/core/model/src/main/kotlin/org/meshtastic/core/model/MyNodeInfo.kt similarity index 93% rename from app/src/main/java/com/geeksville/mesh/MyNodeInfo.kt rename to core/model/src/main/kotlin/org/meshtastic/core/model/MyNodeInfo.kt index 41965a2ec..3cabeeb6f 100644 --- a/app/src/main/java/com/geeksville/mesh/MyNodeInfo.kt +++ b/core/model/src/main/kotlin/org/meshtastic/core/model/MyNodeInfo.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh +package org.meshtastic.core.model import android.os.Parcelable import kotlinx.parcelize.Parcelize @@ -39,5 +39,6 @@ data class MyNodeInfo( val deviceId: String?, ) : Parcelable { /** A human readable description of the software/hardware version */ - val firmwareString: String get() = "$model $firmwareVersion" + val firmwareString: String + get() = "$model $firmwareVersion" } diff --git a/core/network/src/main/kotlin/org/meshtastic/core/network/model/NetworkDeviceHardware.kt b/core/model/src/main/kotlin/org/meshtastic/core/model/NetworkDeviceHardware.kt similarity index 97% rename from core/network/src/main/kotlin/org/meshtastic/core/network/model/NetworkDeviceHardware.kt rename to core/model/src/main/kotlin/org/meshtastic/core/model/NetworkDeviceHardware.kt index 4b36c183c..1f1bf0a81 100644 --- a/core/network/src/main/kotlin/org/meshtastic/core/network/model/NetworkDeviceHardware.kt +++ b/core/model/src/main/kotlin/org/meshtastic/core/model/NetworkDeviceHardware.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package org.meshtastic.core.network.model +package org.meshtastic.core.model import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable diff --git a/core/network/src/main/kotlin/org/meshtastic/core/network/model/NetworkFirmwareRelease.kt b/core/model/src/main/kotlin/org/meshtastic/core/model/NetworkFirmwareRelease.kt similarity index 97% rename from core/network/src/main/kotlin/org/meshtastic/core/network/model/NetworkFirmwareRelease.kt rename to core/model/src/main/kotlin/org/meshtastic/core/model/NetworkFirmwareRelease.kt index a1b746413..33f027673 100644 --- a/core/network/src/main/kotlin/org/meshtastic/core/network/model/NetworkFirmwareRelease.kt +++ b/core/model/src/main/kotlin/org/meshtastic/core/model/NetworkFirmwareRelease.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package org.meshtastic.core.network.model +package org.meshtastic.core.model import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable diff --git a/app/src/main/java/com/geeksville/mesh/NodeInfo.kt b/core/model/src/main/kotlin/org/meshtastic/core/model/NodeInfo.kt similarity index 94% rename from app/src/main/java/com/geeksville/mesh/NodeInfo.kt rename to core/model/src/main/kotlin/org/meshtastic/core/model/NodeInfo.kt index 2aa6f9afa..e86a5fa2b 100644 --- a/app/src/main/java/com/geeksville/mesh/NodeInfo.kt +++ b/core/model/src/main/kotlin/org/meshtastic/core/model/NodeInfo.kt @@ -15,15 +15,18 @@ * along with this program. If not, see . */ -package com.geeksville.mesh +package org.meshtastic.core.model import android.graphics.Color import android.os.Parcelable -import com.geeksville.mesh.util.anonymize -import com.geeksville.mesh.util.bearing -import com.geeksville.mesh.util.latLongToMeter -import com.geeksville.mesh.util.onlineTimeThreshold +import com.geeksville.mesh.ConfigProtos +import com.geeksville.mesh.MeshProtos +import com.geeksville.mesh.TelemetryProtos import kotlinx.parcelize.Parcelize +import org.meshtastic.core.model.util.anonymize +import org.meshtastic.core.model.util.bearing +import org.meshtastic.core.model.util.latLongToMeter +import org.meshtastic.core.model.util.onlineTimeThreshold // // model objects that directly map to the corresponding protobufs @@ -74,6 +77,7 @@ data class Position( val precisionBits: Int = 0, ) : Parcelable { + @Suppress("MagicNumber") companion object { // / Convert to a double representation of degrees fun degD(i: Int) = i * 1e-7 @@ -109,6 +113,7 @@ data class Position( fun bearing(o: Position) = bearing(latitude, longitude, o.latitude, o.longitude) // If GPS gives a crap position don't crash our app + @Suppress("MagicNumber") fun isValid(): Boolean = latitude != 0.0 && longitude != 0.0 && (latitude >= -90 && latitude <= 90.0) && @@ -128,6 +133,7 @@ data class DeviceMetrics( val uptimeSeconds: Int, ) : Parcelable { companion object { + @Suppress("MagicNumber") fun currentTime() = (System.currentTimeMillis() / 1000).toInt() } @@ -153,6 +159,7 @@ data class EnvironmentMetrics( val lux: Float? = null, val uvLux: Float? = null, ) : Parcelable { + @Suppress("MagicNumber") companion object { fun currentTime() = (System.currentTimeMillis() / 1000).toInt() @@ -189,6 +196,7 @@ data class NodeInfo( var hopsAway: Int = 0, ) : Parcelable { + @Suppress("MagicNumber") val colors: Pair get() { // returns foreground and background @ColorInt for each 'num' val r = (num and 0xFF0000) shr 16 @@ -204,6 +212,7 @@ data class NodeInfo( val voltage get() = deviceMetrics?.voltage + @Suppress("ImplicitDefaultLocale") val batteryStr get() = if (batteryLevel in 1..100) String.format("%d%%", batteryLevel) else "" @@ -234,6 +243,7 @@ data class NodeInfo( } // / @return a nice human readable string for the distance, or null for unknown + @Suppress("MagicNumber") fun distanceStr(o: NodeInfo?, prefUnits: Int = 0) = distance(o)?.let { dist -> when { dist == 0 -> null // same point diff --git a/app/src/main/java/com/geeksville/mesh/util/DateTimeUtils.kt b/core/model/src/main/kotlin/org/meshtastic/core/model/util/DateTimeUtils.kt similarity index 97% rename from app/src/main/java/com/geeksville/mesh/util/DateTimeUtils.kt rename to core/model/src/main/kotlin/org/meshtastic/core/model/util/DateTimeUtils.kt index 1c95d1132..f51a97802 100644 --- a/app/src/main/java/com/geeksville/mesh/util/DateTimeUtils.kt +++ b/core/model/src/main/kotlin/org/meshtastic/core/model/util/DateTimeUtils.kt @@ -15,7 +15,7 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.util +package org.meshtastic.core.model.util import java.text.DateFormat import java.util.Date @@ -58,7 +58,8 @@ private fun formatUptime(seconds: Long): String { "${hours}h".takeIf { hours > 0 }, "${minutes}m".takeIf { minutes > 0 }, "${secs}s".takeIf { secs > 0 }, - ).joinToString(" ") + ) + .joinToString(" ") } @Suppress("MagicNumber") diff --git a/app/src/main/java/com/geeksville/mesh/util/Extensions.kt b/core/model/src/main/kotlin/org/meshtastic/core/model/util/Extensions.kt similarity index 97% rename from app/src/main/java/com/geeksville/mesh/util/Extensions.kt rename to core/model/src/main/kotlin/org/meshtastic/core/model/util/Extensions.kt index 9162f740c..9bb047b13 100644 --- a/app/src/main/java/com/geeksville/mesh/util/Extensions.kt +++ b/core/model/src/main/kotlin/org/meshtastic/core/model/util/Extensions.kt @@ -15,12 +15,12 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.util +package org.meshtastic.core.model.util import android.widget.EditText -import com.geeksville.mesh.BuildConfig import com.geeksville.mesh.ConfigProtos import com.geeksville.mesh.MeshProtos +import org.meshtastic.core.model.BuildConfig /** * When printing strings to logs sometimes we want to print useful debugging information about users or positions. But @@ -60,6 +60,7 @@ fun Any.toPIIString() = if (!BuildConfig.DEBUG) { fun ByteArray.toHexString() = joinToString("") { "%02x".format(it) } +@Suppress("MagicNumber") fun formatAgo(lastSeenUnix: Int, currentTimeMillis: Long = System.currentTimeMillis()): String { val currentTime = (currentTimeMillis / 1000).toInt() val diffMin = (currentTime - lastSeenUnix) / 60 diff --git a/app/src/main/java/com/geeksville/mesh/util/LocationUtils.kt b/core/model/src/main/kotlin/org/meshtastic/core/model/util/LocationUtils.kt similarity index 93% rename from app/src/main/java/com/geeksville/mesh/util/LocationUtils.kt rename to core/model/src/main/kotlin/org/meshtastic/core/model/util/LocationUtils.kt index 955d4e013..e2d64e9f1 100644 --- a/app/src/main/java/com/geeksville/mesh/util/LocationUtils.kt +++ b/core/model/src/main/kotlin/org/meshtastic/core/model/util/LocationUtils.kt @@ -15,10 +15,12 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.util +@file:Suppress("MatchingDeclarationName") + +package org.meshtastic.core.model.util import android.annotation.SuppressLint -import com.geeksville.mesh.Position +import org.meshtastic.core.model.Position import java.util.Locale import kotlin.math.asin import kotlin.math.atan2 @@ -52,6 +54,7 @@ fun latLongToMeter(latitudeA: Double, longitudeA: Double, latitudeB: Double, lon } // Same as above, but takes Mesh Position proto. +@Suppress("MagicNumber") fun positionToMeter(a: Position, b: Position): Double = latLongToMeter(a.latitude * 1e-7, a.longitude * 1e-7, b.latitude * 1e-7, b.longitude * 1e-7) @@ -64,6 +67,7 @@ fun positionToMeter(a: Position, b: Position): Double = * @param lon2 Longitude of the second point * @return Bearing between the two points in degrees. A value of 0 means due north. */ +@Suppress("MagicNumber") fun bearing(lat1: Double, lon1: Double, lat2: Double, lon2: Double): Double { val lat1Rad = Math.toRadians(lat1) val lon1Rad = Math.toRadians(lon1) diff --git a/app/src/main/java/com/geeksville/mesh/util/UnitConversions.kt b/core/model/src/main/kotlin/org/meshtastic/core/model/util/UnitConversions.kt similarity index 86% rename from app/src/main/java/com/geeksville/mesh/util/UnitConversions.kt rename to core/model/src/main/kotlin/org/meshtastic/core/model/util/UnitConversions.kt index f2406109f..a372ef2f1 100644 --- a/app/src/main/java/com/geeksville/mesh/util/UnitConversions.kt +++ b/core/model/src/main/kotlin/org/meshtastic/core/model/util/UnitConversions.kt @@ -15,16 +15,14 @@ * along with this program. If not, see . */ -package com.geeksville.mesh.util +package org.meshtastic.core.model.util import kotlin.math.ln object UnitConversions { @Suppress("MagicNumber") - fun celsiusToFahrenheit(celsius: Float): Float { - return (celsius * 1.8F) + 32 - } + fun celsiusToFahrenheit(celsius: Float): Float = (celsius * 1.8F) + 32 fun Float.toTempString(isFahrenheit: Boolean) = if (isFahrenheit) { val fahrenheit = celsiusToFahrenheit(this) @@ -34,8 +32,8 @@ object UnitConversions { } /** - * Calculated the dew point based on the Magnus-Tetens approximation which is a widely used - * formula for calculating dew point temperature. + * Calculated the dew point based on the Magnus-Tetens approximation which is a widely used formula for calculating + * dew point temperature. */ @Suppress("MagicNumber") fun calculateDewPoint(tempCelsius: Float, humidity: Float): Float { diff --git a/core/network/build.gradle.kts b/core/network/build.gradle.kts index 92ebe6f95..6973309f7 100644 --- a/core/network/build.gradle.kts +++ b/core/network/build.gradle.kts @@ -31,6 +31,7 @@ android { } dependencies { + implementation(projects.core.model) implementation(libs.bundles.ktor) implementation(libs.bundles.coil) "googleImplementation"(libs.bundles.datadog) diff --git a/core/network/src/fdroid/kotlin/org/meshtastic/core/network/di/FDroidNetworkModule.kt b/core/network/src/fdroid/kotlin/org/meshtastic/core/network/di/FDroidNetworkModule.kt index aff1f06c2..538400edc 100644 --- a/core/network/src/fdroid/kotlin/org/meshtastic/core/network/di/FDroidNetworkModule.kt +++ b/core/network/src/fdroid/kotlin/org/meshtastic/core/network/di/FDroidNetworkModule.kt @@ -23,9 +23,9 @@ import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor +import org.meshtastic.core.model.NetworkDeviceHardware +import org.meshtastic.core.model.NetworkFirmwareReleases import org.meshtastic.core.network.BuildConfig -import org.meshtastic.core.network.model.NetworkDeviceHardware -import org.meshtastic.core.network.model.NetworkFirmwareReleases import org.meshtastic.core.network.service.ApiService import javax.inject.Singleton diff --git a/core/network/src/main/kotlin/org/meshtastic/core/network/DeviceHardwareRemoteDataSource.kt b/core/network/src/main/kotlin/org/meshtastic/core/network/DeviceHardwareRemoteDataSource.kt index 462294183..1b436fc3f 100644 --- a/core/network/src/main/kotlin/org/meshtastic/core/network/DeviceHardwareRemoteDataSource.kt +++ b/core/network/src/main/kotlin/org/meshtastic/core/network/DeviceHardwareRemoteDataSource.kt @@ -19,7 +19,7 @@ package org.meshtastic.core.network import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -import org.meshtastic.core.network.model.NetworkDeviceHardware +import org.meshtastic.core.model.NetworkDeviceHardware import org.meshtastic.core.network.service.ApiService import javax.inject.Inject diff --git a/core/network/src/main/kotlin/org/meshtastic/core/network/FirmwareReleaseRemoteDataSource.kt b/core/network/src/main/kotlin/org/meshtastic/core/network/FirmwareReleaseRemoteDataSource.kt index 68e0413f0..fa25da247 100644 --- a/core/network/src/main/kotlin/org/meshtastic/core/network/FirmwareReleaseRemoteDataSource.kt +++ b/core/network/src/main/kotlin/org/meshtastic/core/network/FirmwareReleaseRemoteDataSource.kt @@ -19,7 +19,7 @@ package org.meshtastic.core.network import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -import org.meshtastic.core.network.model.NetworkFirmwareReleases +import org.meshtastic.core.model.NetworkFirmwareReleases import org.meshtastic.core.network.service.ApiService import javax.inject.Inject diff --git a/core/network/src/main/kotlin/org/meshtastic/core/network/service/ApiService.kt b/core/network/src/main/kotlin/org/meshtastic/core/network/service/ApiService.kt index a86cd4b4b..5d461c771 100644 --- a/core/network/src/main/kotlin/org/meshtastic/core/network/service/ApiService.kt +++ b/core/network/src/main/kotlin/org/meshtastic/core/network/service/ApiService.kt @@ -18,8 +18,8 @@ package org.meshtastic.core.network.service import de.jensklingenberg.ktorfit.http.GET -import org.meshtastic.core.network.model.NetworkDeviceHardware -import org.meshtastic.core.network.model.NetworkFirmwareReleases +import org.meshtastic.core.model.NetworkDeviceHardware +import org.meshtastic.core.model.NetworkFirmwareReleases interface ApiService { @GET("resource/deviceHardware")