create ChannelSet datastore

This commit is contained in:
andrekir 2022-09-12 19:07:30 -03:00
parent 382535da47
commit 2ed5548abb
11 changed files with 154 additions and 69 deletions

View file

@ -0,0 +1,63 @@
package com.geeksville.mesh.repository.datastore
import androidx.datastore.core.DataStore
import com.geeksville.mesh.android.Logging
import com.geeksville.mesh.AppOnlyProtos.ChannelSet
import com.geeksville.mesh.ChannelProtos
import com.geeksville.mesh.ConfigProtos
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.first
import java.io.IOException
import javax.inject.Inject
/**
* Class that handles saving and retrieving channel settings
*/
class ChannelSetRepository @Inject constructor(
private val channelSetStore: DataStore<ChannelSet>
) : Logging {
val channelSetFlow: Flow<ChannelSet> = channelSetStore.data
.catch { exception ->
// dataStore.data throws an IOException when an error is encountered when reading data
if (exception is IOException) {
errormsg("Error reading DeviceConfig settings: ${exception.message}")
emit(ChannelSet.getDefaultInstance())
} else {
throw exception
}
}
suspend fun clearChannelSet() {
channelSetStore.updateData { preference ->
preference.toBuilder().clear().build()
}
}
suspend fun clearSettings() {
channelSetStore.updateData { preference ->
preference.toBuilder().clearSettings().build()
}
}
suspend fun addSettings(channel: ChannelProtos.Channel) {
channelSetStore.updateData { preference ->
preference.toBuilder().addSettings(channel.index, channel.settings).build()
}
}
suspend fun addAllSettings(channelSet: ChannelSet) {
channelSetStore.updateData { preference ->
preference.toBuilder().addAllSettings(channelSet.settingsList).build()
}
}
suspend fun setLoraConfig(config: ConfigProtos.Config.LoRaConfig) {
channelSetStore.updateData { preference ->
preference.toBuilder().setLoraConfig(config).build()
}
}
suspend fun fetchInitialChannelSet() = channelSetStore.data.first()
}

View file

@ -0,0 +1,26 @@
package com.geeksville.mesh.repository.datastore
import androidx.datastore.core.CorruptionException
import androidx.datastore.core.Serializer
import com.geeksville.mesh.AppOnlyProtos.ChannelSet
import com.google.protobuf.InvalidProtocolBufferException
import java.io.InputStream
import java.io.OutputStream
/**
* Serializer for the [ChannelSet] object defined in apponly.proto.
*/
@Suppress("BlockingMethodInNonBlockingContext")
object ChannelSetSerializer : Serializer<ChannelSet> {
override val defaultValue: ChannelSet = ChannelSet.getDefaultInstance()
override suspend fun readFrom(input: InputStream): ChannelSet {
try {
return ChannelSet.parseFrom(input)
} catch (exception: InvalidProtocolBufferException) {
throw CorruptionException("Cannot read proto.", exception)
}
}
override suspend fun writeTo(t: ChannelSet, output: OutputStream) = t.writeTo(output)
}

View file

@ -5,6 +5,7 @@ import androidx.datastore.core.DataStore
import androidx.datastore.core.DataStoreFactory
import androidx.datastore.core.handlers.ReplaceFileCorruptionHandler
import androidx.datastore.dataStoreFile
import com.geeksville.mesh.AppOnlyProtos.ChannelSet
import com.geeksville.mesh.LocalOnlyProtos.LocalConfig
import dagger.Module
import dagger.Provides
@ -32,4 +33,17 @@ object DataStoreModule {
scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
)
}
@Singleton
@Provides
fun provideChannelSetDataStore(@ApplicationContext appContext: Context): DataStore<ChannelSet> {
return DataStoreFactory.create(
serializer = ChannelSetSerializer,
produceFile = { appContext.dataStoreFile("channel_set.pb") },
corruptionHandler = ReplaceFileCorruptionHandler(
produceNewData = { ChannelSet.getDefaultInstance() }
),
scope = CoroutineScope(Dispatchers.IO + SupervisorJob())
)
}
}

View file

@ -16,7 +16,8 @@ import javax.inject.Inject
* Class that handles saving and retrieving config settings
*/
class LocalConfigRepository @Inject constructor(
private val localConfigStore: DataStore<LocalConfig>
private val localConfigStore: DataStore<LocalConfig>,
private val channelSetRepository: ChannelSetRepository,
) : Logging {
val localConfigFlow: Flow<LocalConfig> = localConfigStore.data
.catch { exception ->
@ -98,6 +99,7 @@ class LocalConfigRepository @Inject constructor(
localConfigStore.updateData { preference ->
preference.toBuilder().setLora(config).build()
}
channelSetRepository.setLoraConfig(config)
}
private suspend fun setBluetoothConfig(config: ConfigProtos.Config.BluetoothConfig) {

View file

@ -10,6 +10,7 @@ import java.io.OutputStream
/**
* Serializer for the [LocalConfig] object defined in localonly.proto.
*/
@Suppress("BlockingMethodInNonBlockingContext")
object LocalConfigSerializer : Serializer<LocalConfig> {
override val defaultValue: LocalConfig = LocalConfig.getDefaultInstance()