mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-04 22:23:47 -04:00
create Room database for DataPacket
This commit is contained in:
33
app/src/main/java/com/geeksville/mesh/database/Converters.kt
Normal file
33
app/src/main/java/com/geeksville/mesh/database/Converters.kt
Normal file
@@ -0,0 +1,33 @@
|
||||
package com.geeksville.mesh.database
|
||||
|
||||
import androidx.room.TypeConverter
|
||||
import com.geeksville.mesh.DataPacket
|
||||
import com.geeksville.mesh.MeshProtos.MeshPacket
|
||||
import com.google.protobuf.TextFormat
|
||||
import kotlinx.serialization.json.Json
|
||||
|
||||
class Converters {
|
||||
@TypeConverter
|
||||
fun dataFromString(value: String): DataPacket {
|
||||
val json = Json { isLenient = true }
|
||||
return json.decodeFromString(DataPacket.serializer(), value)
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun dataToString(value: DataPacket): String {
|
||||
val json = Json { isLenient = true }
|
||||
return json.encodeToString(DataPacket.serializer(), value)
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun protoFromString(value: String): MeshPacket {
|
||||
val builder = MeshPacket.newBuilder()
|
||||
TextFormat.getParser().merge(value, builder)
|
||||
return builder.build()
|
||||
}
|
||||
|
||||
@TypeConverter
|
||||
fun protoToString(value: MeshPacket): String {
|
||||
return value.toString()
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package com.geeksville.mesh.database
|
||||
|
||||
import android.app.Application
|
||||
import com.geeksville.mesh.database.dao.MeshLogDao
|
||||
import com.geeksville.mesh.database.dao.PacketDao
|
||||
import com.geeksville.mesh.database.dao.QuickChatActionDao
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
@@ -17,6 +18,11 @@ class DatabaseModule {
|
||||
fun provideDatabase(app: Application): MeshtasticDatabase =
|
||||
MeshtasticDatabase.getDatabase(app)
|
||||
|
||||
@Provides
|
||||
fun providePacketDao(database: MeshtasticDatabase): PacketDao {
|
||||
return database.packetDao()
|
||||
}
|
||||
|
||||
@Provides
|
||||
fun provideMeshLogDao(database: MeshtasticDatabase): MeshLogDao {
|
||||
return database.meshLogDao()
|
||||
|
||||
@@ -4,13 +4,18 @@ import android.content.Context
|
||||
import androidx.room.Database
|
||||
import androidx.room.Room
|
||||
import androidx.room.RoomDatabase
|
||||
import androidx.room.TypeConverters
|
||||
import com.geeksville.mesh.database.dao.PacketDao
|
||||
import com.geeksville.mesh.database.dao.MeshLogDao
|
||||
import com.geeksville.mesh.database.dao.QuickChatActionDao
|
||||
import com.geeksville.mesh.database.entity.MeshLog
|
||||
import com.geeksville.mesh.database.entity.Packet
|
||||
import com.geeksville.mesh.database.entity.QuickChatAction
|
||||
|
||||
@Database(entities = [MeshLog::class, QuickChatAction::class], version = 3, exportSchema = false)
|
||||
@Database(entities = [Packet::class, MeshLog::class, QuickChatAction::class], version = 3, exportSchema = false)
|
||||
@TypeConverters(Converters::class)
|
||||
abstract class MeshtasticDatabase : RoomDatabase() {
|
||||
abstract fun packetDao(): PacketDao
|
||||
abstract fun meshLogDao(): MeshLogDao
|
||||
abstract fun quickChatActionDao(): QuickChatActionDao
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.geeksville.mesh.database
|
||||
|
||||
import com.geeksville.mesh.database.dao.PacketDao
|
||||
import com.geeksville.mesh.database.entity.Packet
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.withContext
|
||||
import javax.inject.Inject
|
||||
|
||||
class PacketRepository @Inject constructor(private val packetDaoLazy: dagger.Lazy<PacketDao>) {
|
||||
private val packetDao by lazy {
|
||||
packetDaoLazy.get()
|
||||
}
|
||||
|
||||
suspend fun getAll(): Flow<List<Packet>> = withContext(Dispatchers.IO) {
|
||||
packetDao.getAllPackets()
|
||||
}
|
||||
|
||||
suspend fun insert(packet: Packet) = withContext(Dispatchers.IO) {
|
||||
packetDao.insert(packet)
|
||||
}
|
||||
|
||||
suspend fun deleteAll() = withContext(Dispatchers.IO) {
|
||||
packetDao.deleteAll()
|
||||
}
|
||||
|
||||
suspend fun delete(packet: Packet) = withContext(Dispatchers.IO) {
|
||||
packetDao.delete(packet)
|
||||
}
|
||||
|
||||
suspend fun update(packet: Packet) = withContext(Dispatchers.IO) {
|
||||
packetDao.update(packet)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.geeksville.mesh.database.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.Update
|
||||
import androidx.room.Query
|
||||
import androidx.room.Transaction
|
||||
import com.geeksville.mesh.database.entity.Packet
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
@Dao
|
||||
interface PacketDao {
|
||||
|
||||
@Query("Select * from packet order by received_time asc")
|
||||
fun getAllPackets(): Flow<List<Packet>>
|
||||
|
||||
@Insert
|
||||
fun insert(packet: Packet)
|
||||
|
||||
@Query("Delete from packet")
|
||||
fun deleteAll()
|
||||
|
||||
@Query("Delete from packet where uuid=:uuid")
|
||||
fun _delete(uuid: Long)
|
||||
|
||||
@Transaction
|
||||
fun delete(packet: Packet) {
|
||||
_delete(packet.uuid)
|
||||
}
|
||||
|
||||
@Update
|
||||
fun update(packet: Packet)
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.geeksville.mesh.database.entity
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import com.geeksville.mesh.DataPacket
|
||||
import com.geeksville.mesh.MessageStatus
|
||||
|
||||
@Entity(tableName = "packet")
|
||||
data class Packet(
|
||||
@PrimaryKey(autoGenerate = true) val uuid: Long,
|
||||
@ColumnInfo(name = "port_num") val port_num: Int,
|
||||
@ColumnInfo(name = "contact_id") val contact_id: String?,
|
||||
@ColumnInfo(name = "channel") val channel: Int,
|
||||
@ColumnInfo(name = "status") val status: MessageStatus = MessageStatus.UNKNOWN,
|
||||
@ColumnInfo(name = "received_time") val received_time: Long,
|
||||
@ColumnInfo(name = "packet") val packet: DataPacket
|
||||
) {
|
||||
}
|
||||
@@ -16,9 +16,11 @@ import com.geeksville.mesh.*
|
||||
import com.geeksville.mesh.ConfigProtos.Config
|
||||
import com.geeksville.mesh.database.MeshLogRepository
|
||||
import com.geeksville.mesh.database.QuickChatActionRepository
|
||||
import com.geeksville.mesh.database.entity.Packet
|
||||
import com.geeksville.mesh.database.entity.MeshLog
|
||||
import com.geeksville.mesh.database.entity.QuickChatAction
|
||||
import com.geeksville.mesh.LocalOnlyProtos.LocalConfig
|
||||
import com.geeksville.mesh.database.PacketRepository
|
||||
import com.geeksville.mesh.repository.datastore.ChannelSetRepository
|
||||
import com.geeksville.mesh.repository.datastore.LocalConfigRepository
|
||||
import com.geeksville.mesh.service.MeshService
|
||||
@@ -67,6 +69,7 @@ class UIViewModel @Inject constructor(
|
||||
private val app: Application,
|
||||
private val meshLogRepository: MeshLogRepository,
|
||||
private val channelSetRepository: ChannelSetRepository,
|
||||
private val packetRepository: PacketRepository,
|
||||
private val localConfigRepository: LocalConfigRepository,
|
||||
private val quickChatActionRepository: QuickChatActionRepository,
|
||||
private val preferences: SharedPreferences
|
||||
@@ -75,6 +78,9 @@ class UIViewModel @Inject constructor(
|
||||
private val _meshLog = MutableStateFlow<List<MeshLog>>(emptyList())
|
||||
val meshLog: StateFlow<List<MeshLog>> = _meshLog
|
||||
|
||||
private val _packets = MutableStateFlow<List<Packet>>(emptyList())
|
||||
val packets: StateFlow<List<Packet>> = _packets
|
||||
|
||||
private val _localConfig = MutableStateFlow<LocalConfig>(LocalConfig.getDefaultInstance())
|
||||
val localConfig: StateFlow<LocalConfig> = _localConfig
|
||||
val config get() = _localConfig.value
|
||||
@@ -91,6 +97,11 @@ class UIViewModel @Inject constructor(
|
||||
_meshLog.value = logs
|
||||
}
|
||||
}
|
||||
viewModelScope.launch {
|
||||
packetRepository.getAll().collect { meshPackets ->
|
||||
_packets.value = meshPackets
|
||||
}
|
||||
}
|
||||
viewModelScope.launch {
|
||||
localConfigRepository.localConfigFlow.collect { config ->
|
||||
_localConfig.value = config
|
||||
|
||||
@@ -16,7 +16,9 @@ import com.geeksville.mesh.MeshProtos.MeshPacket
|
||||
import com.geeksville.mesh.MeshProtos.ToRadio
|
||||
import com.geeksville.mesh.android.hasBackgroundPermission
|
||||
import com.geeksville.mesh.database.MeshLogRepository
|
||||
import com.geeksville.mesh.database.PacketRepository
|
||||
import com.geeksville.mesh.database.entity.MeshLog
|
||||
import com.geeksville.mesh.database.entity.Packet
|
||||
import com.geeksville.mesh.model.DeviceVersion
|
||||
import com.geeksville.mesh.repository.datastore.ChannelSetRepository
|
||||
import com.geeksville.mesh.repository.datastore.LocalConfigRepository
|
||||
@@ -49,6 +51,9 @@ class MeshService : Service(), Logging {
|
||||
@Inject
|
||||
lateinit var dispatchers: CoroutineDispatchers
|
||||
|
||||
@Inject
|
||||
lateinit var packetRepository: Lazy<PacketRepository>
|
||||
|
||||
@Inject
|
||||
lateinit var meshLogRepository: Lazy<MeshLogRepository>
|
||||
|
||||
@@ -614,7 +619,20 @@ class MeshService : Service(), Logging {
|
||||
private fun rememberDataPacket(dataPacket: DataPacket) {
|
||||
// Now that we use data packets for more things, we need to be choosier about what we keep. Since (currently - in the future less so)
|
||||
// we only care about old text messages, we just store those...
|
||||
if (dataPacket.dataType == Portnums.PortNum.TEXT_MESSAGE_APP_VALUE) {
|
||||
if (dataPacket.dataType == Portnums.PortNum.WAYPOINT_APP_VALUE
|
||||
|| dataPacket.dataType == Portnums.PortNum.TEXT_MESSAGE_APP_VALUE
|
||||
) {
|
||||
val packetToSave = Packet(
|
||||
0L, // autoGenerated
|
||||
dataPacket.dataType,
|
||||
if (dataPacket.from == DataPacket.ID_LOCAL || dataPacket.to == DataPacket.ID_BROADCAST) dataPacket.to else dataPacket.from,
|
||||
dataPacket.channel,
|
||||
MessageStatus.RECEIVED,
|
||||
System.currentTimeMillis(),
|
||||
dataPacket
|
||||
)
|
||||
insertPacket(packetToSave)
|
||||
|
||||
// discard old messages if needed then add the new one
|
||||
while (recentDataPackets.size > 100)
|
||||
recentDataPackets.removeAt(0)
|
||||
@@ -930,6 +948,12 @@ class MeshService : Service(), Logging {
|
||||
}
|
||||
}
|
||||
|
||||
private fun insertPacket(packet: Packet) {
|
||||
serviceScope.handledLaunch {
|
||||
packetRepository.get().insert(packet)
|
||||
}
|
||||
}
|
||||
|
||||
private fun insertMeshLog(packetToSave: MeshLog) {
|
||||
serviceScope.handledLaunch {
|
||||
// Do not log, because might contain PII
|
||||
|
||||
Reference in New Issue
Block a user