Browse Source

Persist the Android call video bitrate range atomically

master
evgeny 6 days ago
parent
commit
f04e3fd995
  1. 19
      tools/chatgui-android/app/src/main/java/com/utun/chat/data/CallVideoBitrateRange.kt
  2. 15
      tools/chatgui-android/app/src/main/java/com/utun/chat/data/ConfigProvider.kt
  3. 20
      tools/chatgui-android/app/src/test/java/com/utun/chat/data/CallVideoBitrateRangeTest.kt

19
tools/chatgui-android/app/src/main/java/com/utun/chat/data/CallVideoBitrateRange.kt

@ -0,0 +1,19 @@
package com.utun.chat.data
/** Обе границы хранятся одной настройкой в десятичных кбит/с. */
data class CallVideoBitrateRange(val minimum: Int = 300, val maximum: Int = 4000) {
init { require(minimum in 300..4000 && maximum in minimum..4000) }
fun encode(): String = "$minimum:$maximum"
companion object {
fun parse(value: String): CallVideoBitrateRange? {
val parts = value.split(':')
if (parts.size != 2 || parts.any { it.isEmpty() || it.any { digit -> digit !in '0'..'9' } }) return null
val minimum = parts[0].toIntOrNull() ?: return null
val maximum = parts[1].toIntOrNull() ?: return null
if (minimum !in 300..4000 || maximum !in minimum..4000) return null
return CallVideoBitrateRange(minimum, maximum)
}
}
}

15
tools/chatgui-android/app/src/main/java/com/utun/chat/data/ConfigProvider.kt

@ -55,6 +55,7 @@ class ConfigProvider(private val context: Context) {
private val chatStorageMaxsizeGb = intPreferencesKey("chat_storage_maxsize_gb") private val chatStorageMaxsizeGb = intPreferencesKey("chat_storage_maxsize_gb")
private val chatOpusCodecPreset = intPreferencesKey("chat_opus_codec_preset") private val chatOpusCodecPreset = intPreferencesKey("chat_opus_codec_preset")
private val callJitterMaxReserveMs = intPreferencesKey("call_jitter_max_reserve_ms") private val callJitterMaxReserveMs = intPreferencesKey("call_jitter_max_reserve_ms")
private val callVideoBitrateRange = stringPreferencesKey("call_video_bitrate_range_kbps")
private val chatCompressorEnabled = intPreferencesKey("chat_compressor_enabled") private val chatCompressorEnabled = intPreferencesKey("chat_compressor_enabled")
private val chatCompressorMaxGainDb = intPreferencesKey("chat_compressor_max_gain_db") private val chatCompressorMaxGainDb = intPreferencesKey("chat_compressor_max_gain_db")
private val chatCompressorRiseRate = intPreferencesKey("chat_compressor_rise_rate") private val chatCompressorRiseRate = intPreferencesKey("chat_compressor_rise_rate")
@ -141,6 +142,19 @@ class ConfigProvider(private val context: Context) {
) )
} }
fun getCallVideoBitrateRange(): CallVideoBitrateRange = runBlocking {
val value = context.dataStore.data.first()[callVideoBitrateRange] ?: return@runBlocking CallVideoBitrateRange()
CallVideoBitrateRange.parse(value) ?: run {
LogManager.addLog("WARN", "CallSettings", "Invalid video bitrate range '$value'; using 300:4000")
CallVideoBitrateRange()
}
}
suspend fun saveCallVideoBitrateRange(range: CallVideoBitrateRange) {
context.dataStore.edit { it[callVideoBitrateRange] = range.encode() }
LogManager.addLog("INFO", "CallSettings", "Video bitrate range saved: ${range.encode()} kbps")
}
fun getString(key: String): String? = runBlocking { fun getString(key: String): String? = runBlocking {
when { when {
key == "node.private_key" -> readKeysFromFile()?.second ?: context.dataStore.data.first()[nodePrivateKey] key == "node.private_key" -> readKeysFromFile()?.second ?: context.dataStore.data.first()[nodePrivateKey]
@ -669,6 +683,7 @@ class ConfigProvider(private val context: Context) {
appendLine("radio_compressor_enabled=$radioCompEnabled") appendLine("radio_compressor_enabled=$radioCompEnabled")
appendLine("radio_compressor_max_gain_db=$radioCompMaxGain") appendLine("radio_compressor_max_gain_db=$radioCompMaxGain")
appendLine("call_jitter_max_reserve_ms=${getInt("chat.call_jitter_max_reserve_ms")}") appendLine("call_jitter_max_reserve_ms=${getInt("chat.call_jitter_max_reserve_ms")}")
appendLine("call_video_bitrate_range_kbps=${getCallVideoBitrateRange().encode()}")
appendLine("compressor_enabled=$chatCompEnabled") appendLine("compressor_enabled=$chatCompEnabled")
appendLine("compressor_max_gain_db=$chatCompMaxGain") appendLine("compressor_max_gain_db=$chatCompMaxGain")
appendLine("compressor_rise_rate=$chatCompRiseRate") appendLine("compressor_rise_rate=$chatCompRiseRate")

20
tools/chatgui-android/app/src/test/java/com/utun/chat/data/CallVideoBitrateRangeTest.kt

@ -0,0 +1,20 @@
package com.utun.chat.data
import org.junit.Assert.*
import org.junit.Test
class CallVideoBitrateRangeTest {
@Test fun defaultsAndRoundTrip() {
assertEquals("300:4000", CallVideoBitrateRange().encode())
for (range in listOf(CallVideoBitrateRange(), CallVideoBitrateRange(500, 1500), CallVideoBitrateRange(300, 300))) {
assertEquals(range, CallVideoBitrateRange.parse(range.encode()))
}
}
@Test fun invalidPersistedRangeIsRejected() {
for (value in listOf("", "299:4000", "300:4001", "4000:300", "300", "300:4000x",
"-300:4000", "300:+4000", "300: 4000", "999999999999999999999999:4000")) {
assertNull(value, CallVideoBitrateRange.parse(value))
}
}
}
Loading…
Cancel
Save