Files
2026-08-03 15:32:28 +03:00

154 lines
5.8 KiB
Kotlin

package com.tutpro.baresip
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream
import java.io.IOException
import java.io.ObjectInputStream
import java.io.ObjectOutputStream
import java.util.GregorianCalendar
@Serializable
class CallHistoryNew(val aor: String, val peerUri: String, val direction: String) : java.io.Serializable {
// Set to time when call is established (if ever) or stopTime if call was completed elsewhere
@Serializable(with = Utils.GregorianCalendarSerializer::class)
var startTime: GregorianCalendar? = null
@Serializable(with = Utils.GregorianCalendarSerializer::class)
var stopTime = GregorianCalendar() // Set to time when call is closed
var rejected = false
var recording = arrayOf("", "") // Encoder and decoder recording files, merged file is in [0]
fun add() {
synchronized(BaresipService.callHistory) {
BaresipService.callHistory.add(this)
val aorSpecificHistory = BaresipService.callHistory.filter { it.aor == this.aor }
if (aorSpecificHistory.size > CALL_HISTORY_SIZE) {
val oldestToRemove = aorSpecificHistory.first()
deleteRecordingFiles(oldestToRemove.recording)
BaresipService.callHistory.remove(oldestToRemove)
}
}
save()
}
companion object {
@Suppress("unused")
const val serialVersionUID: Long = 3L
private const val CALL_HISTORY_SIZE = 256
fun aorLatestPeerUri(aor: String): String? {
synchronized(BaresipService.callHistory) {
for (h in BaresipService.callHistory.reversed())
if (h.aor == aor) return h.peerUri
}
return null
}
fun clear(aor: String) {
synchronized(BaresipService.callHistory) {
for (i in BaresipService.callHistory.indices.reversed()) {
val h = BaresipService.callHistory[i]
if (h.aor == aor) {
deleteRecordingFiles(h.recording)
BaresipService.callHistory.removeAt(i)
}
}
}
save()
}
fun remove(startTime: GregorianCalendar?, stopTime: GregorianCalendar) {
synchronized(BaresipService.callHistory) {
val iterator = BaresipService.callHistory.iterator()
while (iterator.hasNext()) {
val h = iterator.next()
if (h.startTime == startTime && h.stopTime == stopTime) {
deleteRecordingFiles(h.recording)
iterator.remove()
}
}
}
save()
}
fun save() {
val historyCopy = synchronized(BaresipService.callHistory) {
ArrayList(BaresipService.callHistory)
}
Log.d(TAG, "Saving history of ${historyCopy.size} calls")
val file = File(BaresipService.filesPath + "/call_history")
try {
val jsonString = Json.encodeToString(historyCopy)
file.writeText(jsonString)
} catch (e: Exception) {
Log.e(TAG, "Serialization exception: $e")
try {
val fos = FileOutputStream(file)
val oos = ObjectOutputStream(fos)
oos.writeObject(historyCopy)
oos.close()
fos.close()
} catch (e2: IOException) {
Log.e(TAG, "OutputStream exception: $e2")
}
}
}
fun restore() {
val file = File(BaresipService.filesPath + "/call_history")
if (file.exists()) {
val content = file.readText()
if (content.startsWith("[")) {
try {
val restoredHistory = Json.decodeFromString<List<CallHistoryNew>>(content)
BaresipService.callHistory = ArrayList(restoredHistory)
Log.d(TAG, "Restored history of ${BaresipService.callHistory.size} calls from JSON")
return
} catch (e: Exception) {
Log.d(TAG, "JSON restore failed, trying Java serialization: $e")
}
}
try {
val fis = FileInputStream(file)
val ois = ObjectInputStream(fis)
@Suppress("UNCHECKED_CAST")
val restoredHistory = ois.readObject() as? List<CallHistoryNew>
if (restoredHistory != null) {
BaresipService.callHistory = ArrayList(restoredHistory)
Log.d(TAG, "Restored history of ${BaresipService.callHistory.size} calls from Java")
save()
}
ois.close()
fis.close()
} catch (e: Exception) {
Log.e(TAG, "InputStream exception: - $e")
}
}
}
fun deleteRecordingFiles(recording: Array<String>) {
Utils.deleteFile(File(recording[0]))
Utils.deleteFile(File(recording[1]))
}
fun clearRecordings() {
synchronized(BaresipService.callHistory) {
for (h in BaresipService.callHistory)
h.recording = arrayOf("", "")
}
}
@Suppress("UNUSED")
fun print() {
for (h in BaresipService.callHistory)
Log.d(TAG, "[${h.aor}, ${h.peerUri}, ${h.direction}, ${h.startTime}," +
"${h.stopTime}, ${h.rejected}, ${h.recording}")
}
}
}