Merge branch 'missed'

This commit is contained in:
Juha Heinanen
2023-05-13 17:24:34 +03:00
13 changed files with 99 additions and 60 deletions
@@ -59,7 +59,7 @@ class AccountListAdapter(private val cxt: Context, private val rows: ArrayList<A
viewHolder.aorView.text)) viewHolder.aorView.text))
setPositiveButton(cxt.getText(R.string.delete)) { dialog, _ -> setPositiveButton(cxt.getText(R.string.delete)) { dialog, _ ->
Api.ua_destroy(ua.uap) Api.ua_destroy(ua.uap)
CallHistory.clear(ua.account.aor) CallHistoryNew.clear(ua.account.aor)
Message.clear(ua.account.aor) Message.clear(ua.account.aor)
ua.remove() ua.remove()
AccountsActivity.generateAccounts() AccountsActivity.generateAccounts()
@@ -409,17 +409,18 @@ class BaresipService: Service() {
} }
Contact.contactsUpdate() Contact.contactsUpdate()
val history = NewCallHistory.get() val history = CallHistory.get()
if (history.isEmpty()) { if (history.isEmpty()) {
CallHistory.restore() CallHistoryNew.restore()
} else { } else {
for (old in history) { for (old in history) {
val new = CallHistory(old.aor, old.peerUri, old.direction) val new = CallHistoryNew(old.aor, old.peerUri, old.direction)
new.stopTime = old.stopTime new.stopTime = old.stopTime
new.startTime = old.startTime new.startTime = old.startTime
new.recording = old.recording
callHistory.add(new) callHistory.add(new)
} }
CallHistory.save() CallHistoryNew.save()
} }
Message.restore() Message.restore()
@@ -699,8 +700,8 @@ class BaresipService: Service() {
toast(toastMsg) toast(toastMsg)
playUnInterrupted(R.raw.callwaiting, 1) playUnInterrupted(R.raw.callwaiting, 1)
if (ua.account.callHistory) { if (ua.account.callHistory) {
CallHistory.add(CallHistory(aor, peerUri, "in")) CallHistoryNew.add(CallHistoryNew(aor, peerUri, "in"))
CallHistory.save() CallHistoryNew.save()
ua.account.missedCalls = true ua.account.missedCalls = true
} }
return return
@@ -881,22 +882,30 @@ class BaresipService: Service() {
call.onHoldCall = null call.onHoldCall = null
} }
call.remove() call.remove()
if (ev[2] == "busy") { val reason = ev[1]
val tone = ev[2]
if (tone == "busy") {
playBusy() playBusy()
} else if (!Call.inCall()) { } else if (!Call.inCall()) {
resetCallVolume() resetCallVolume()
abandonAudioFocus(applicationContext) abandonAudioFocus(applicationContext)
proximitySensing(false) proximitySensing(false)
} }
val missed = call.startTime == null && call.dir == "in" && !call.rejected if (call.dir == "out")
call.rejected = call.startTime == null &&
!reason.startsWith("408") &&
!reason.startsWith("480") &&
!reason.startsWith("Connection reset by")
val missed = call.dir == "in" && call.startTime == null && !call.rejected
if (ua.account.callHistory) { if (ua.account.callHistory) {
val history = CallHistory(aor, call.peerUri, call.dir) val history = CallHistoryNew(aor, call.peerUri, call.dir)
history.startTime = call.startTime history.startTime = call.startTime
history.stopTime = GregorianCalendar() history.stopTime = GregorianCalendar()
history.rejected = call.rejected
if (call.startTime != null && call.dumpfiles[0] != "") if (call.startTime != null && call.dumpfiles[0] != "")
history.recording = call.dumpfiles history.recording = call.dumpfiles
CallHistory.add(history) CallHistoryNew.add(history)
CallHistory.save() CallHistoryNew.save()
ua.account.missedCalls = ua.account.missedCalls || missed ua.account.missedCalls = ua.account.missedCalls || missed
} }
if (!Utils.isVisible()) { if (!Utils.isVisible()) {
@@ -1495,7 +1504,7 @@ class BaresipService: Service() {
val uas = ArrayList<UserAgent>() val uas = ArrayList<UserAgent>()
val calls = ArrayList<Call>() val calls = ArrayList<Call>()
var callHistory = ArrayList<CallHistory>() var callHistory = ArrayList<CallHistoryNew>()
var messages = ArrayList<Message>() var messages = ArrayList<Message>()
val messageUpdate = MutableLiveData<Long>() val messageUpdate = MutableLiveData<Long>()
val contactUpdate = MutableLiveData<Long>() val contactUpdate = MutableLiveData<Long>()
@@ -10,7 +10,7 @@ class Call(val callp: Long, val ua: UserAgent, val peerUri: String, val dir: Str
var held = false var held = false
var onHoldCall: Call? = null var onHoldCall: Call? = null
var newCall: Call? = null var newCall: Call? = null
var rejected = false var rejected = false // Incoming rejected by user or outgoing fails but not due to 408 or 480
var security = R.drawable.unlocked var security = R.drawable.unlocked
var zid = "" var zid = ""
var startTime: GregorianCalendar? = null // Set when call is established var startTime: GregorianCalendar? = null // Set when call is established
@@ -4,18 +4,19 @@ import java.io.*
import java.util.ArrayList import java.util.ArrayList
import java.util.GregorianCalendar import java.util.GregorianCalendar
class CallHistory(val aor: String, val peerUri: String, val direction: String) : Serializable { class CallHistoryNew(val aor: String, val peerUri: String, val direction: String) : Serializable {
var startTime: GregorianCalendar? = null // Set to time when call is established (if ever) var startTime: GregorianCalendar? = null // Set to time when call is established (if ever)
var stopTime = GregorianCalendar() // Set to time when call is closed var stopTime = GregorianCalendar() // Set to time when call is closed
var rejected = false
var recording = arrayOf("", "") // Encoder and decoder recording files var recording = arrayOf("", "") // Encoder and decoder recording files
companion object { companion object {
private const val serialVersionUID: Long = 2 private const val serialVersionUID: Long = 3
private const val CALL_HISTORY_SIZE = 128 private const val CALL_HISTORY_SIZE = 128
fun add(history: CallHistory) { fun add(history: CallHistoryNew) {
BaresipService.callHistory.add(history) BaresipService.callHistory.add(history)
if (aorHistorySize(history.aor) > CALL_HISTORY_SIZE) { if (aorHistorySize(history.aor) > CALL_HISTORY_SIZE) {
for (h in BaresipService.callHistory) for (h in BaresipService.callHistory)
@@ -42,7 +43,6 @@ class CallHistory(val aor: String, val peerUri: String, val direction: String) :
private fun aorHistorySize(aor: String): Int { private fun aorHistorySize(aor: String): Int {
return BaresipService.callHistory.count { it.aor == aor } return BaresipService.callHistory.count { it.aor == aor }
} }
fun aorLatestPeerUri(aor: String): String? { fun aorLatestPeerUri(aor: String): String? {
for (h in BaresipService.callHistory.reversed()) for (h in BaresipService.callHistory.reversed())
if (h.aor == aor) return h.peerUri if (h.aor == aor) return h.peerUri
@@ -51,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 + "/call_history")
try { try {
val fos = FileOutputStream(file) val fos = FileOutputStream(file)
val oos = ObjectOutputStream(fos) val oos = ObjectOutputStream(fos)
@@ -65,13 +65,13 @@ class CallHistory(val aor: String, val peerUri: String, val direction: String) :
} }
fun restore() { fun restore() {
val file = File(BaresipService.filesPath + "/history") val file = File(BaresipService.filesPath + "/call_history")
if (file.exists()) { if (file.exists()) {
try { try {
val fis = FileInputStream(file) val fis = FileInputStream(file)
val ois = ObjectInputStream(fis) val ois = ObjectInputStream(fis)
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
BaresipService.callHistory = ois.readObject() as ArrayList<CallHistory> BaresipService.callHistory = ois.readObject() as ArrayList<CallHistoryNew>
ois.close() ois.close()
fis.close() fis.close()
Log.d(TAG, "Restored history of ${BaresipService.callHistory.size} calls") Log.d(TAG, "Restored history of ${BaresipService.callHistory.size} calls")
@@ -90,30 +90,31 @@ class CallHistory(val aor: String, val peerUri: String, val direction: String) :
fun print() { fun print() {
for (h in BaresipService.callHistory) for (h in BaresipService.callHistory)
Log.d(TAG, "[${h.aor}, ${h.peerUri}, ${h.direction}, ${h.startTime}," + Log.d(TAG, "[${h.aor}, ${h.peerUri}, ${h.direction}, ${h.startTime}," +
"${h.stopTime}, ${h.recording}") "${h.stopTime}, ${h.rejected}, ${h.recording}")
} }
} }
} }
class NewCallHistory(val aor: String, val peerUri: String, val direction: String) : Serializable { class CallHistory(val aor: String, val peerUri: String, val direction: String) : Serializable {
var startTime: GregorianCalendar? = null var startTime: GregorianCalendar? = null
var stopTime = GregorianCalendar() var stopTime = GregorianCalendar()
var recording = arrayOf("", "")
companion object { companion object {
private const val serialVersionUID: Long = 1 private const val serialVersionUID: Long = 2
fun get(): ArrayList<NewCallHistory> { fun get(): ArrayList<CallHistory> {
val file = File(BaresipService.filesPath, "call_history") val file = File(BaresipService.filesPath, "history")
var result = ArrayList<NewCallHistory>() var result = ArrayList<CallHistory>()
if (file.exists()) { if (file.exists()) {
try { try {
val fis = FileInputStream(file) val fis = FileInputStream(file)
val ois = ObjectInputStream(fis) val ois = ObjectInputStream(fis)
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
result = ois.readObject() as ArrayList<NewCallHistory> result = ois.readObject() as ArrayList<CallHistory>
ois.close() ois.close()
fis.close() fis.close()
Log.d(TAG, "Got history of ${result.size} calls") Log.d(TAG, "Got history of ${result.size} calls")
@@ -3,20 +3,19 @@ package com.tutpro.baresip
import java.util.* import java.util.*
import kotlin.collections.ArrayList 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, val rejected: Boolean,
startTime: GregorianCalendar?, startTime: GregorianCalendar?, val stopTime: GregorianCalendar,
val stopTime: GregorianCalendar,
val recording: Array<String>) val recording: Array<String>)
{ {
class Details(val direction: Int, val startTime: GregorianCalendar?, class Details(val direction: Int, val rejected: Boolean,
val stopTime: GregorianCalendar, val recording: Array<String>) val startTime: GregorianCalendar?, val stopTime: GregorianCalendar,
val recording: Array<String>)
val details = ArrayList<Details>() val details = ArrayList<Details>()
init { init {
details.add(Details(direction, startTime, stopTime, recording)) details.add(Details(direction, rejected, startTime, stopTime, recording))
} }
} }
@@ -120,7 +120,7 @@ class CallsActivity : AppCompatActivity() {
DialogInterface.BUTTON_POSITIVE -> { DialogInterface.BUTTON_POSITIVE -> {
removeUaHistoryAt(pos) removeUaHistoryAt(pos)
CallHistory.save() CallHistoryNew.save()
clAdapter.notifyDataSetChanged() clAdapter.notifyDataSetChanged()
} }
@@ -189,8 +189,8 @@ class CallsActivity : AppCompatActivity() {
setMessage(String.format(getString(R.string.delete_history_alert), setMessage(String.format(getString(R.string.delete_history_alert),
aor.substringAfter(":"))) aor.substringAfter(":")))
setPositiveButton(getText(R.string.delete)) { dialog, _ -> setPositiveButton(getText(R.string.delete)) { dialog, _ ->
CallHistory.clear(aor) CallHistoryNew.clear(aor)
CallHistory.save() CallHistoryNew.save()
aorGenerateHistory(aor) aorGenerateHistory(aor)
clAdapter.notifyDataSetChanged() clAdapter.notifyDataSetChanged()
dialog.dismiss() dialog.dismiss()
@@ -254,21 +254,30 @@ class CallsActivity : AppCompatActivity() {
for (i in BaresipService.callHistory.indices.reversed()) { for (i in BaresipService.callHistory.indices.reversed()) {
val h = BaresipService.callHistory[i] val h = BaresipService.callHistory[i]
if (h.aor == aor) { if (h.aor == aor) {
val direction: Int = if (h.direction == "in") val direction: Int = if (h.direction == "in") {
if (h.startTime != null) if (h.startTime != null) {
R.drawable.call_down_green R.drawable.call_down_green
else } else {
if (h.rejected)
R.drawable.call_down_red R.drawable.call_down_red
else else
if (h.startTime != null) R.drawable.call_missed_in
}
} else {
if (h.startTime != null) {
R.drawable.call_up_green R.drawable.call_up_green
else } else {
if (h.rejected)
R.drawable.call_up_red R.drawable.call_up_red
if (uaHistory.isNotEmpty() && (uaHistory.last().peerUri == h.peerUri))
uaHistory.last().details.add(CallRow.Details(direction, h.startTime,
h.stopTime, h.recording))
else else
uaHistory.add(CallRow(h.aor, h.peerUri, direction, h.startTime, R.drawable.call_missed_out
}
}
if (uaHistory.isNotEmpty() && (uaHistory.last().peerUri == h.peerUri))
uaHistory.last().details.add(CallRow.Details(direction, h.rejected,
h.startTime, h.stopTime, h.recording))
else
uaHistory.add(CallRow(h.aor, h.peerUri, direction, h.rejected, h.startTime,
h.stopTime, h.recording)) h.stopTime, h.recording))
} }
} }
@@ -277,12 +286,12 @@ 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[0] != "") if (details.recording[0] != "")
CallHistory.deleteRecording(details.recording) CallHistoryNew.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) CallHistoryNew.deleteRecording(uaHistory[i].recording)
uaHistory.removeAt(i) uaHistory.removeAt(i)
} }
@@ -384,8 +384,6 @@ class MainActivity : AppCompatActivity() {
val callp = call.callp val callp = call.callp
Log.d(TAG, "AoR $aor hanging up call $callp with ${callUri.text}") Log.d(TAG, "AoR $aor hanging up call $callp with ${callUri.text}")
hangupButton.isEnabled = false hangupButton.isEnabled = false
if (call.status == "answered")
call.rejected = true
Api.ua_hangup(ua.uap, callp, 0, "") Api.ua_hangup(ua.uap, callp, 0, "")
} }
} }
@@ -1907,7 +1905,7 @@ class MainActivity : AppCompatActivity() {
} }
} }
} else { } else {
val latestPeerUri = CallHistory.aorLatestPeerUri(aor) val latestPeerUri = CallHistoryNew.aorLatestPeerUri(aor)
if (latestPeerUri != null) if (latestPeerUri != null)
callUri.setText(Utils.friendlyUri(this, latestPeerUri, ua.account)) callUri.setText(Utils.friendlyUri(this, latestPeerUri, ua.account))
} }
@@ -2,8 +2,9 @@
android:width="20dp" android:width="20dp"
android:height="20dp" android:height="20dp"
android:viewportWidth="960" android:viewportWidth="960"
android:viewportHeight="960" > android:viewportHeight="960"
android:tint="@color/colorTrafficGreen" >
<path <path
android:fillColor="@color/colorTrafficGreen" android:fillColor="@android:color/white"
android:pathData="M232.35,775.65L232.35,428.65L315.35,428.65L315.35,634L714.85,234.5L773.5,293.15L374,692.65L579.35,692.65L579.35,775.65L232.35,775.65Z"/> android:pathData="M232.35,775.65L232.35,428.65L315.35,428.65L315.35,634L714.85,234.5L773.5,293.15L374,692.65L579.35,692.65L579.35,775.65L232.35,775.65Z"/>
</vector> </vector>
+3 -2
View File
@@ -2,8 +2,9 @@
android:width="20dp" android:width="20dp"
android:height="20dp" android:height="20dp"
android:viewportWidth="960" android:viewportWidth="960"
android:viewportHeight="960" > android:viewportHeight="960"
android:tint="@color/colorTrafficRed" >
<path <path
android:fillColor="@color/colorTrafficRed" android:fillColor="@android:color/white"
android:pathData="M232.35,775.65L232.35,428.65L315.35,428.65L315.35,634L714.85,234.5L773.5,293.15L374,692.65L579.35,692.65L579.35,775.65L232.35,775.65Z"/> android:pathData="M232.35,775.65L232.35,428.65L315.35,428.65L315.35,634L714.85,234.5L773.5,293.15L374,692.65L579.35,692.65L579.35,775.65L232.35,775.65Z"/>
</vector> </vector>
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="@color/colorTrafficYellow" >
<path
android:fillColor="@android:color/white"
android:pathData="M232.35,775.65L232.35,428.65L315.35,428.65L315.35,634L714.85,234.5L773.5,293.15L374,692.65L579.35,692.65L579.35,775.65L232.35,775.65Z"/>
</vector>
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="@color/colorTrafficYellow" >
<path
android:fillColor="@android:color/white"
android:pathData="M243,727.65L184.35,669L583.85,269.5L378.5,269.5L378.5,186.5L725.5,186.5L725.5,533.5L642.5,533.5L642.5,328.15L243,727.65Z"/>
</vector>
+2 -1
View File
@@ -1,5 +1,6 @@
<vector android:height="48dp" android:tint="@color/colorAccent" <vector android:height="48dp" android:tint="@color/colorAccent"
android:viewportHeight="24.0" android:viewportWidth="24.0" android:viewportHeight="24.0" android:viewportWidth="24.0"
android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android"> android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M13,3c-4.97,0 -9,4.03 -9,9L1,12l3.89,3.89 0.07,0.14L9,12L6,12c0,-3.87 3.13,-7 7,-7s7,3.13 7,7 -3.13,7 -7,7c-1.93,0 -3.68,-0.79 -4.94,-2.06l-1.42,1.42C8.27,19.99 10.51,21 13,21c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,8v5l4.28,2.54 0.72,-1.21 -3.5,-2.08L13.5,8L12,8z"/> <path android:fillColor="@android:color/white"
android:pathData="M13,3c-4.97,0 -9,4.03 -9,9L1,12l3.89,3.89 0.07,0.14L9,12L6,12c0,-3.87 3.13,-7 7,-7s7,3.13 7,7 -3.13,7 -7,7c-1.93,0 -3.68,-0.79 -4.94,-2.06l-1.42,1.42C8.27,19.99 10.51,21 13,21c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,8v5l4.28,2.54 0.72,-1.21 -3.5,-2.08L13.5,8L12,8z"/>
</vector> </vector>