switch between two calls

This commit is contained in:
Mysochenko Yuriy
2022-05-15 09:12:23 +03:00
parent a2bff29d59
commit 445e13389e
6 changed files with 297 additions and 59 deletions

View File

@ -5,6 +5,7 @@ import android.net.Uri
import android.telecom.Call
import android.telecom.InCallService
import android.telecom.VideoProfile
import android.util.Log
import com.simplemobiletools.commons.extensions.getMyContactsCursor
import com.simplemobiletools.commons.extensions.getPhoneNumberTypeText
import com.simplemobiletools.commons.helpers.MyContactsContentProvider
@ -12,12 +13,64 @@ import com.simplemobiletools.commons.helpers.SimpleContactsHelper
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
import com.simplemobiletools.dialer.extensions.getStateCompat
import com.simplemobiletools.dialer.models.CallContact
import java.util.concurrent.CopyOnWriteArraySet
const val TAG = "SimpleDialer:CallManager"
// inspired by https://github.com/Chooloo/call_manage
class CallManager {
companion object {
var call: Call? = null
var inCallService: InCallService? = null
val calls = mutableListOf<Call>()
private val listeners = CopyOnWriteArraySet<CallManagerListener>()
fun onCallAdded(call: Call) {
this.call = call
calls.add(call)
call.registerCallback(object : Call.Callback() {
override fun onStateChanged(call: Call, state: Int) {
Log.d(TAG, "onStateChanged: $call")
for (listener in listeners) {
listener.onStateChanged(call, state)
}
if (state == Call.STATE_HOLDING && calls.size > 1) {
for (listener in listeners) {
listener.onCallPutOnHold(call)
}
}
if (state == Call.STATE_ACTIVE && calls.size == 1) {
for (listener in listeners) {
listener.onCallPutOnHold(null)
}
}
if ((state == Call.STATE_CONNECTING || state == Call.STATE_DIALING || state == Call.STATE_ACTIVE) && calls.size > 1) {
if (CallManager.call != call) {
CallManager.call = call
Log.d(TAG, "onCallsChanged")
for (listener in listeners) {
listener.onCallsChanged(call, getSecondaryCall())
}
}
}
}
})
}
fun onCallRemoved(call: Call) {
calls.remove(call)
}
fun getPrimaryCall(): Call? {
return call
}
fun getSecondaryCall(): Call? {
if (calls.size == 1) {
return null
}
return calls.find { it.getStateCompat() == Call.STATE_HOLDING }
}
fun accept() {
call?.answer(VideoProfile.STATE_AUDIO_ONLY)
@ -43,27 +96,33 @@ class CallManager {
return !isOnHold
}
fun swap() {
val isConference: Boolean
get() = call?.details?.hasProperty(Call.Details.PROPERTY_CONFERENCE) ?: false
fun swap() {
getSecondaryCall()?.unhold()
}
fun merge() {
// val conferenceableCalls = call!!.conferenceableCalls
// if (conferenceableCalls.isNotEmpty()) {
// call!!.conference(conferenceableCalls.first())
// } else {
// if (call!!.hasCapability(Call.Details.CAPABILITY_MERGE_CONFERENCE)) {
// call!!.mergeConference()
// }
// }
}
fun registerCallback(callback: Call.Callback) {
call?.registerCallback(callback)
fun addListener(listener: CallManagerListener) {
listeners.add(listener)
}
fun unregisterCallback(callback: Call.Callback) {
call?.unregisterCallback(callback)
fun removeListener(listener: CallManagerListener) {
listeners.remove(listener)
}
fun getState() = if (call == null) {
Call.STATE_DISCONNECTED
} else {
call!!.getStateCompat()
}
fun getState() = getPrimaryCall()?.getStateCompat()
fun keypad(c: Char) {
call?.playDtmfTone(c)
@ -71,6 +130,10 @@ class CallManager {
}
fun getCallContact(context: Context, callback: (CallContact?) -> Unit) {
return getCallContact(context, call, callback)
}
fun getCallContact(context: Context, call: Call?, callback: (CallContact) -> Unit) {
val privateCursor = context.getMyContactsCursor(false, true)
ensureBackgroundThread {
val callContact = CallContact("", "", "", "")
@ -126,10 +189,20 @@ class CallManager {
fun getCallDuration(): Int {
return if (call != null) {
((System.currentTimeMillis() - call!!.details.connectTimeMillis) / 1000).toInt()
val connectTimeMillis = call!!.details.connectTimeMillis
if (connectTimeMillis == 0L) {
return 0
}
((System.currentTimeMillis() - connectTimeMillis) / 1000).toInt()
} else {
0
}
}
}
}
interface CallManagerListener {
fun onStateChanged(call: Call, state: Int)
fun onCallPutOnHold(call: Call?)
fun onCallsChanged(active: Call, onHold: Call?)
}