More work on call recording

This commit is contained in:
Juha Heinanen
2023-03-11 06:13:10 +02:00
parent dbec2629ae
commit 84bcfdfa55
6 changed files with 66 additions and 53 deletions
@@ -381,26 +381,11 @@ class BaresipService: Service() {
Config.initialize(applicationContext) Config.initialize(applicationContext)
} }
if (File(filesDir, "history").exists())
File(filesDir, "history").renameTo(File(filesDir, "calls"))
if (!File(filesDir, "tmp").exists()) if (!File(filesDir, "tmp").exists())
File(filesDir, "tmp").mkdir() File(filesDir, "tmp").mkdir()
if (!File(filesDir, "recordings").exists()) if (!File(filesDir, "recordings").exists())
File(filesDir, "recordings").mkdir() File(filesDir, "recordings").mkdir()
else {
File(filesDir, "recordings").walk().forEach { f ->
Log.d(TAG, "***** file ${f.name}")
val recording = f.name.substringBeforeLast("-")
if (recording.startsWith("dump")) {
val time = recording.takeLast(19)
if (!recordings.containsKey(time))
recordings[time] = filesDir.absolutePath + "/recordings/" + recording
}
}
Log.d(TAG, "Recordings $recordings")
}
if (contactsMode != "android") if (contactsMode != "android")
Contact.restoreBaresipContacts() Contact.restoreBaresipContacts()
@@ -897,11 +882,8 @@ class BaresipService: Service() {
val history = CallHistory(aor, call.peerUri, call.dir) val history = CallHistory(aor, call.peerUri, call.dir)
history.startTime = call.startTime history.startTime = call.startTime
history.stopTime = GregorianCalendar() history.stopTime = GregorianCalendar()
if (call.startTime != null && call.dumpfile != "") { if (call.startTime != null && call.dumpfile != "")
val recording = filesDir.absolutePath + "/recordings/" + history.recording = call.dumpfile.substringBeforeLast("-")
call.dumpfile.substringBeforeLast("-")
history.recording = recording
}
CallHistory.add(history) CallHistory.add(history)
CallHistory.save() CallHistory.save()
ua.account.missedCalls = ua.account.missedCalls || missed ua.account.missedCalls = ua.account.missedCalls || missed
@@ -1543,7 +1525,6 @@ class BaresipService: Service() {
var dnsServers = listOf<InetAddress>() var dnsServers = listOf<InetAddress>()
val serviceEvent = MutableLiveData<Event<Long>>() val serviceEvent = MutableLiveData<Event<Long>>()
val serviceEvents = mutableListOf<ServiceEvent>() val serviceEvents = mutableListOf<ServiceEvent>()
val recordings: MutableMap<String, String> = mutableMapOf()
private var audioFocusRequest: AudioFocusRequestCompat? = null private var audioFocusRequest: AudioFocusRequestCompat? = null
private var btAdapter: BluetoothAdapter? = null private var btAdapter: BluetoothAdapter? = null
@@ -18,19 +18,25 @@ class CallHistory(val aor: String, val peerUri: String, val direction: String) :
fun add(history: CallHistory) { fun add(history: CallHistory) {
BaresipService.callHistory.add(history) BaresipService.callHistory.add(history)
if (aorHistorySize(history.aor) > CALL_HISTORY_SIZE) { if (aorHistorySize(history.aor) > CALL_HISTORY_SIZE) {
var i = 0
for (h in BaresipService.callHistory) for (h in BaresipService.callHistory)
if (h.aor == history.aor) if (h.aor == history.aor) {
if (h.recording != "")
deleteRecording(h.recording)
BaresipService.callHistory.remove(h)
break break
else }
i++
BaresipService.callHistory.removeAt(i)
} }
} }
fun clear(aor: String) { fun clear(aor: String) {
val it = BaresipService.callHistory.iterator() for (i in BaresipService.callHistory.indices.reversed()) {
while (it.hasNext()) if (it.next().aor == aor) it.remove() val h = BaresipService.callHistory[i]
if (h.aor == aor) {
if (h.recording != "")
deleteRecording(h.recording)
BaresipService.callHistory.removeAt(i)
}
}
} }
private fun aorHistorySize(aor: String): Int { private fun aorHistorySize(aor: String): Int {
@@ -45,7 +51,7 @@ class CallHistory(val aor: String, val peerUri: String, val direction: String) :
fun save() { fun save() {
Log.d(TAG, "Saving history of ${BaresipService.callHistory.size} calls") Log.d(TAG, "Saving history of ${BaresipService.callHistory.size} calls")
val file = File(BaresipService.filesPath, "history") val file = File(BaresipService.filesPath + "/history")
try { try {
val fos = FileOutputStream(file) val fos = FileOutputStream(file)
val oos = ObjectOutputStream(fos) val oos = ObjectOutputStream(fos)
@@ -56,14 +62,10 @@ class CallHistory(val aor: String, val peerUri: String, val direction: String) :
Log.e(TAG, "OutputStream exception: $e") Log.e(TAG, "OutputStream exception: $e")
e.printStackTrace() e.printStackTrace()
} }
if (file.exists())
Log.d(TAG, "******** file ${BaresipService.filesPath}/history exists")
else
Log.d(TAG, "******** file ${BaresipService.filesPath}/history does NOT exist")
} }
fun restore() { fun restore() {
val file = File(BaresipService.filesPath, "history") val file = File(BaresipService.filesPath + "/history")
if (file.exists()) { if (file.exists()) {
try { try {
val fis = FileInputStream(file) val fis = FileInputStream(file)
@@ -76,11 +78,14 @@ class CallHistory(val aor: String, val peerUri: String, val direction: String) :
} catch (e: Exception) { } catch (e: Exception) {
Log.e(TAG, "InputStream exception: - $e") Log.e(TAG, "InputStream exception: - $e")
} }
} else {
Log.d(TAG, "File ${BaresipService.filesPath}/history does not exist")
} }
} }
fun deleteRecording(recording: String) {
Utils.deleteFile(File("$recording-enc.wav"))
Utils.deleteFile(File("$recording-dec.wav"))
}
@Suppress("UNUSED") @Suppress("UNUSED")
fun print() { fun print() {
for (h in BaresipService.callHistory) for (h in BaresipService.callHistory)
@@ -6,7 +6,7 @@ import kotlin.collections.ArrayList
class CallRow(val aor: String, val peerUri: String, val direction: Int, class CallRow(val aor: String, val peerUri: String, val direction: Int,
startTime: GregorianCalendar?, startTime: GregorianCalendar?,
val stopTime: GregorianCalendar, val stopTime: GregorianCalendar,
private val recording: String) var recording: String)
{ {
@@ -13,6 +13,7 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.tutpro.baresip.databinding.ActivityCallsBinding import com.tutpro.baresip.databinding.ActivityCallsBinding
import java.io.File
class CallsActivity : AppCompatActivity() { class CallsActivity : AppCompatActivity() {
@@ -74,16 +75,21 @@ class CallsActivity : AppCompatActivity() {
i.putExtra("peer", peerUri) i.putExtra("peer", peerUri)
startActivity(i) startActivity(i)
} }
DialogInterface.BUTTON_NEUTRAL -> { DialogInterface.BUTTON_NEUTRAL -> {
} }
} }
} }
if (SystemClock.elapsedRealtime() - lastClick > 1000) { if (SystemClock.elapsedRealtime() - lastClick > 1000) {
lastClick = SystemClock.elapsedRealtime() lastClick = SystemClock.elapsedRealtime()
with (MaterialAlertDialogBuilder(this@CallsActivity, R.style.AlertDialogTheme)) { with(MaterialAlertDialogBuilder(this@CallsActivity, R.style.AlertDialogTheme)) {
setTitle(R.string.confirmation) setTitle(R.string.confirmation)
setMessage(String.format(getString(R.string.calls_call_message_question), setMessage(
peerName)) String.format(
getString(R.string.calls_call_message_question),
peerName
)
)
setNeutralButton(getString(R.string.cancel), dialogClickListener) setNeutralButton(getString(R.string.cancel), dialogClickListener)
setNegativeButton(getString(R.string.call), dialogClickListener) setNegativeButton(getString(R.string.call), dialogClickListener)
setPositiveButton(getString(R.string.send_message), dialogClickListener) setPositiveButton(getString(R.string.send_message), dialogClickListener)
@@ -112,11 +118,13 @@ class CallsActivity : AppCompatActivity() {
i.putExtras(b) i.putExtras(b)
contactRequest.launch(i) contactRequest.launch(i)
} }
DialogInterface.BUTTON_POSITIVE -> { DialogInterface.BUTTON_POSITIVE -> {
removeUaHistoryAt(pos) removeUaHistoryAt(pos)
CallHistory.save() CallHistory.save()
clAdapter.notifyDataSetChanged() clAdapter.notifyDataSetChanged()
} }
DialogInterface.BUTTON_NEUTRAL -> { DialogInterface.BUTTON_NEUTRAL -> {
} }
} }
@@ -127,22 +135,36 @@ class CallsActivity : AppCompatActivity() {
getString(R.string.calls_call) getString(R.string.calls_call)
val builder = MaterialAlertDialogBuilder(this@CallsActivity, R.style.AlertDialogTheme) val builder = MaterialAlertDialogBuilder(this@CallsActivity, R.style.AlertDialogTheme)
if (!Contact.nameExists(peerName, false)) if (!Contact.nameExists(peerName, false))
with (builder) { with(builder) {
setTitle(R.string.confirmation) setTitle(R.string.confirmation)
setMessage(String.format(getString(R.string.calls_add_delete_question), setMessage(
peerName, callText)) String.format(
getString(R.string.calls_add_delete_question),
peerName, callText
)
)
setNeutralButton(getString(R.string.cancel), dialogClickListener) setNeutralButton(getString(R.string.cancel), dialogClickListener)
setPositiveButton(String.format(getString(R.string.delete), callText), dialogClickListener) setPositiveButton(
String.format(getString(R.string.delete), callText),
dialogClickListener
)
setNegativeButton(getString(R.string.add_contact), dialogClickListener) setNegativeButton(getString(R.string.add_contact), dialogClickListener)
show() show()
} }
else else
with (builder) { with(builder) {
setTitle(R.string.confirmation) setTitle(R.string.confirmation)
setMessage(String.format(getString(R.string.calls_delete_question), setMessage(
peerName, callText)) String.format(
getString(R.string.calls_delete_question),
peerName, callText
)
)
setNeutralButton(getString(R.string.cancel), dialogClickListener) setNeutralButton(getString(R.string.cancel), dialogClickListener)
setPositiveButton(String.format(getString(R.string.delete), callText), dialogClickListener) setPositiveButton(
String.format(getString(R.string.delete), callText),
dialogClickListener
)
show() show()
} }
true true
@@ -153,6 +175,9 @@ class CallsActivity : AppCompatActivity() {
onBackPressedDispatcher.addCallback(this, onBackPressedCallback) onBackPressedDispatcher.addCallback(this, onBackPressedCallback)
File("${BaresipService.filesPath}/recordings").walk().forEach { f ->
Log.d(TAG, "***** recording ${f.name}")
}
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun onOptionsItemSelected(item: MenuItem): Boolean {
@@ -254,10 +279,14 @@ class CallsActivity : AppCompatActivity() {
} }
private fun removeUaHistoryAt(i: Int) { private fun removeUaHistoryAt(i: Int) {
for (details in uaHistory[i].details) for (details in uaHistory[i].details) {
if (details.recording != "")
CallHistory.deleteRecording(details.recording)
BaresipService.callHistory.removeAll { BaresipService.callHistory.removeAll {
it.startTime == details.startTime && it.stopTime == details.stopTime it.startTime == details.startTime && it.stopTime == details.stopTime
} }
}
CallHistory.deleteRecording(uaHistory[i].recording)
uaHistory.removeAt(i) uaHistory.removeAt(i)
} }
@@ -1661,7 +1661,7 @@ class MainActivity : AppCompatActivity() {
} }
private fun backup(password: String) { private fun backup(password: String) {
val files = arrayListOf("accounts", "call_history", "config", "contacts", "messages", "uuid", val files = arrayListOf("accounts", "history", "config", "contacts", "messages", "uuid",
"gzrtp.zid", "cert.pem", "ca_cert", "ca_certs.crt") "gzrtp.zid", "cert.pem", "ca_cert", "ca_certs.crt")
File(BaresipService.filesPath).walk().forEach { File(BaresipService.filesPath).walk().forEach {
if (it.name.endsWith(".png")) files.add(it.name) if (it.name.endsWith(".png")) files.add(it.name)
@@ -783,7 +783,7 @@ object Utils {
} }
fun unZip(zipFilePath: String): Boolean { fun unZip(zipFilePath: String): Boolean {
val allFiles = listOf("accounts", "calls", "config", "contacts", "messages", "uuid", val allFiles = listOf("accounts", "history", "config", "contacts", "messages", "uuid",
"gzrtp.zid", "cert.pem", "ca_cert", "ca_certs.crt") "gzrtp.zid", "cert.pem", "ca_cert", "ca_certs.crt")
val zipFiles = mutableListOf<String>() val zipFiles = mutableListOf<String>()
try { try {
@@ -1028,7 +1028,6 @@ object Utils {
val file = "$recording-enc.wav" val file = "$recording-enc.wav"
val encFile = File(file).copyTo(File(BaresipService.filesPath + "/tmp/encode.wav"), true) val encFile = File(file).copyTo(File(BaresipService.filesPath + "/tmp/encode.wav"), true)
val encUri = encFile.toUri() val encUri = encFile.toUri()
Log.d(TAG, "Setting data source $encUri")
setDataSource(ctx, encUri) setDataSource(ctx, encUri)
prepareAsync() prepareAsync()
} catch (e: IllegalArgumentException) { } catch (e: IllegalArgumentException) {
@@ -1049,7 +1048,6 @@ object Utils {
val file = "$recording-dec.wav" val file = "$recording-dec.wav"
val decFile = File(file).copyTo(File(BaresipService.filesPath + "/tmp/decode.wav"), true) val decFile = File(file).copyTo(File(BaresipService.filesPath + "/tmp/decode.wav"), true)
val decUri = decFile.toUri() val decUri = decFile.toUri()
Log.d(TAG, "Setting data source $decUri")
setDataSource(ctx, decUri) setDataSource(ctx, decUri)
prepareAsync() prepareAsync()
} catch (e: IllegalArgumentException) { } catch (e: IllegalArgumentException) {