VoIP: fix a bunch of issues
This commit is contained in:
parent
05361c13f1
commit
88e18a8640
|
@ -126,7 +126,16 @@ internal class CallSignalingHandler @Inject constructor(private val activeCallHa
|
|||
private fun handleCallRejectEvent(event: Event) {
|
||||
val content = event.getClearContent().toModel<CallRejectContent>() ?: return
|
||||
val call = content.getCall() ?: return
|
||||
if (call.ourPartyId == content.partyId) {
|
||||
// Ignore remote echo
|
||||
return
|
||||
}
|
||||
activeCallHandler.removeCall(content.callId)
|
||||
if (event.senderId == userId) {
|
||||
// discard current call, it's rejected by another of my session
|
||||
callListenersDispatcher.onCallManagedByOtherSession(content.callId)
|
||||
return
|
||||
}
|
||||
// No need to check party_id for reject because if we'd received either
|
||||
// an answer or reject, we wouldn't be in state InviteSent
|
||||
if (call.state != CallState.Dialing) {
|
||||
|
@ -177,6 +186,7 @@ internal class CallSignalingHandler @Inject constructor(private val activeCallHa
|
|||
}
|
||||
if (event.senderId == userId) {
|
||||
// discard current call, it's answered by another of my session
|
||||
activeCallHandler.removeCall(call.callId)
|
||||
callListenersDispatcher.onCallManagedByOtherSession(content.callId)
|
||||
} else {
|
||||
if (call.opponentPartyId != null) {
|
||||
|
|
|
@ -161,7 +161,7 @@ Formatter\.formatShortFileSize===1
|
|||
# android\.text\.TextUtils
|
||||
|
||||
### This is not a rule, but a warning: the number of "enum class" has changed. For Json classes, it is mandatory that they have `@JsonClass(generateAdapter = false)`. If the enum is not used as a Json class, change the value in file forbidden_strings_in_code.txt
|
||||
enum class===87
|
||||
enum class===88
|
||||
|
||||
### Do not import temporary legacy classes
|
||||
import org.matrix.android.sdk.internal.legacy.riot===3
|
||||
|
|
|
@ -16,33 +16,76 @@
|
|||
|
||||
package im.vector.app.core.services
|
||||
|
||||
import android.app.NotificationChannel
|
||||
import android.content.Context
|
||||
import android.media.Ringtone
|
||||
import android.media.RingtoneManager
|
||||
import android.media.AudioAttributes
|
||||
import android.media.AudioManager
|
||||
import android.media.MediaPlayer
|
||||
import android.media.Ringtone
|
||||
import android.media.RingtoneManager
|
||||
import android.os.Build
|
||||
import android.os.VibrationEffect
|
||||
import android.os.Vibrator
|
||||
import androidx.core.content.getSystemService
|
||||
import im.vector.app.R
|
||||
import im.vector.app.features.notifications.NotificationUtils
|
||||
import org.matrix.android.sdk.api.extensions.orFalse
|
||||
import timber.log.Timber
|
||||
|
||||
class CallRingPlayerIncoming(
|
||||
context: Context
|
||||
context: Context,
|
||||
private val notificationUtils: NotificationUtils
|
||||
) {
|
||||
|
||||
private val applicationContext = context.applicationContext
|
||||
private var r: Ringtone? = null
|
||||
private var ringtone: Ringtone? = null
|
||||
private var vibrator: Vibrator? = null
|
||||
|
||||
fun start() {
|
||||
val notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)
|
||||
r = RingtoneManager.getRingtone(applicationContext, notification)
|
||||
Timber.v("## VOIP Starting ringing incomming")
|
||||
r?.play()
|
||||
private val VIBRATE_PATTERN = longArrayOf(0, 400, 600)
|
||||
|
||||
fun start(fromBg: Boolean) {
|
||||
val audioManager = applicationContext.getSystemService<AudioManager>()
|
||||
val incomingCallChannel = notificationUtils.getChannelForIncomingCall(fromBg)
|
||||
val ringerMode = audioManager?.ringerMode
|
||||
if (ringerMode == AudioManager.RINGER_MODE_NORMAL) {
|
||||
playRingtoneIfNeeded(incomingCallChannel)
|
||||
} else if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
|
||||
vibrateIfNeeded(incomingCallChannel)
|
||||
}
|
||||
}
|
||||
|
||||
private fun playRingtoneIfNeeded(incomingCallChannel: NotificationChannel?) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && incomingCallChannel?.sound != null) {
|
||||
Timber.v("Ringtone already configured by notification channel")
|
||||
return
|
||||
}
|
||||
val ringtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)
|
||||
ringtone = RingtoneManager.getRingtone(applicationContext, ringtoneUri)
|
||||
Timber.v("Play ringtone for incoming call")
|
||||
ringtone?.play()
|
||||
}
|
||||
|
||||
private fun vibrateIfNeeded(incomingCallChannel: NotificationChannel?) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && incomingCallChannel?.shouldVibrate().orFalse()) {
|
||||
Timber.v("## Vibration already configured by notification channel")
|
||||
return
|
||||
}
|
||||
vibrator = applicationContext.getSystemService()
|
||||
Timber.v("Vibrate for incoming call")
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val vibrationEffect = VibrationEffect.createWaveform(VIBRATE_PATTERN, 0)
|
||||
vibrator?.vibrate(vibrationEffect)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
vibrator?.vibrate(VIBRATE_PATTERN, 0)
|
||||
}
|
||||
}
|
||||
|
||||
fun stop() {
|
||||
r?.stop()
|
||||
ringtone?.stop()
|
||||
ringtone = null
|
||||
vibrator?.cancel()
|
||||
vibrator = null
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,12 +98,12 @@ class CallRingPlayerOutgoing(
|
|||
private var player: MediaPlayer? = null
|
||||
|
||||
fun start() {
|
||||
val audioManager = applicationContext.getSystemService<AudioManager>()!!
|
||||
val audioManager: AudioManager? = applicationContext.getSystemService()
|
||||
player?.release()
|
||||
player = createPlayer()
|
||||
|
||||
// Check if sound is enabled
|
||||
val ringerMode = audioManager.ringerMode
|
||||
val ringerMode = audioManager?.ringerMode
|
||||
if (player != null && ringerMode == AudioManager.RINGER_MODE_NORMAL) {
|
||||
try {
|
||||
if (player?.isPlaying == false) {
|
||||
|
@ -89,14 +132,14 @@ class CallRingPlayerOutgoing(
|
|||
|
||||
mediaPlayer.setOnErrorListener(MediaPlayerErrorListener())
|
||||
mediaPlayer.isLooping = true
|
||||
if (Build.VERSION.SDK_INT <= 21) {
|
||||
@Suppress("DEPRECATION")
|
||||
mediaPlayer.setAudioStreamType(AudioManager.STREAM_RING)
|
||||
} else {
|
||||
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
|
||||
mediaPlayer.setAudioAttributes(AudioAttributes.Builder()
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
|
||||
.setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
|
||||
.build())
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
mediaPlayer.setAudioStreamType(AudioManager.STREAM_RING)
|
||||
}
|
||||
return mediaPlayer
|
||||
} catch (failure: Throwable) {
|
||||
|
|
|
@ -79,7 +79,7 @@ class CallService : VectorService() {
|
|||
callManager = vectorComponent().webRtcCallManager()
|
||||
avatarRenderer = vectorComponent().avatarRenderer()
|
||||
alertManager = vectorComponent().alertManager()
|
||||
callRingPlayerIncoming = CallRingPlayerIncoming(applicationContext)
|
||||
callRingPlayerIncoming = CallRingPlayerIncoming(applicationContext, notificationUtils)
|
||||
callRingPlayerOutgoing = CallRingPlayerOutgoing(applicationContext)
|
||||
}
|
||||
|
||||
|
@ -98,21 +98,17 @@ class CallService : VectorService() {
|
|||
setCallback(mediaSessionButtonCallback)
|
||||
}
|
||||
}
|
||||
if (intent == null) {
|
||||
// Service started again by the system.
|
||||
// TODO What do we do here?
|
||||
return START_STICKY
|
||||
}
|
||||
mediaSession?.let {
|
||||
// This ensures that the correct callbacks to MediaSessionCompat.Callback
|
||||
// will be triggered based on the incoming KeyEvent.
|
||||
MediaButtonReceiver.handleIntent(it, intent)
|
||||
}
|
||||
|
||||
when (intent.action) {
|
||||
when (intent?.action) {
|
||||
ACTION_INCOMING_RINGING_CALL -> {
|
||||
mediaSession?.isActive = true
|
||||
callRingPlayerIncoming?.start()
|
||||
val fromBg = intent.getBooleanExtra(EXTRA_IS_IN_BG, false)
|
||||
callRingPlayerIncoming?.start(fromBg)
|
||||
displayIncomingCallNotification(intent)
|
||||
}
|
||||
ACTION_OUTGOING_RINGING_CALL -> {
|
||||
|
@ -136,15 +132,12 @@ class CallService : VectorService() {
|
|||
handleCallTerminated(intent)
|
||||
}
|
||||
else -> {
|
||||
// Should not happen
|
||||
callRingPlayerIncoming?.stop()
|
||||
callRingPlayerOutgoing?.stop()
|
||||
myStopSelf()
|
||||
handleUnexpectedState(null)
|
||||
}
|
||||
}
|
||||
|
||||
// We want the system to restore the service if killed
|
||||
return START_STICKY
|
||||
return START_REDELIVER_INTENT
|
||||
}
|
||||
|
||||
// ================================================================================
|
||||
|
@ -158,10 +151,8 @@ class CallService : VectorService() {
|
|||
private fun displayIncomingCallNotification(intent: Intent) {
|
||||
Timber.v("## VOIP displayIncomingCallNotification $intent")
|
||||
val callId = intent.getStringExtra(EXTRA_CALL_ID) ?: ""
|
||||
val call = callManager.getCallById(callId) ?: return
|
||||
if (knownCalls.contains(callId)) {
|
||||
Timber.v("Call already notified $callId$")
|
||||
return
|
||||
val call = callManager.getCallById(callId) ?: return Unit.also {
|
||||
handleUnexpectedState(callId)
|
||||
}
|
||||
val isVideoCall = call.mxCall.isVideoCall
|
||||
val fromBg = intent.getBooleanExtra(EXTRA_IS_IN_BG, false)
|
||||
|
@ -202,13 +193,14 @@ class CallService : VectorService() {
|
|||
|
||||
private fun handleCallTerminated(intent: Intent) {
|
||||
val callId = intent.getStringExtra(EXTRA_CALL_ID) ?: ""
|
||||
alertManager.cancelAlert(callId)
|
||||
if (!knownCalls.remove(callId)) {
|
||||
Timber.v("Call terminated for unknown call $callId$")
|
||||
handleUnexpectedState(callId)
|
||||
return
|
||||
}
|
||||
val notification = notificationUtils.buildCallEndedNotification()
|
||||
notificationManager.notify(callId.hashCode(), notification)
|
||||
alertManager.cancelAlert(callId)
|
||||
if (knownCalls.isEmpty()) {
|
||||
mediaSession?.isActive = false
|
||||
myStopSelf()
|
||||
|
@ -225,11 +217,9 @@ class CallService : VectorService() {
|
|||
}
|
||||
|
||||
private fun displayOutgoingRingingCallNotification(intent: Intent) {
|
||||
val callId = intent.getStringExtra(EXTRA_CALL_ID) ?: return
|
||||
val call = callManager.getCallById(callId) ?: return
|
||||
if (knownCalls.contains(callId)) {
|
||||
Timber.v("Call already notified $callId$")
|
||||
return
|
||||
val callId = intent.getStringExtra(EXTRA_CALL_ID) ?: ""
|
||||
val call = callManager.getCallById(callId) ?: return Unit.also {
|
||||
handleUnexpectedState(callId)
|
||||
}
|
||||
val opponentMatrixItem = getOpponentMatrixItem(call)
|
||||
Timber.v("displayOutgoingCallNotification : display the dedicated notification")
|
||||
|
@ -251,10 +241,8 @@ class CallService : VectorService() {
|
|||
private fun displayCallInProgressNotification(intent: Intent) {
|
||||
Timber.v("## VOIP displayCallInProgressNotification")
|
||||
val callId = intent.getStringExtra(EXTRA_CALL_ID) ?: ""
|
||||
val call = callManager.getCallById(callId) ?: return
|
||||
if (!knownCalls.contains(callId)) {
|
||||
Timber.v("Call in progress for unknown call $callId$")
|
||||
return
|
||||
val call = callManager.getCallById(callId) ?: return Unit.also {
|
||||
handleUnexpectedState(callId)
|
||||
}
|
||||
val opponentMatrixItem = getOpponentMatrixItem(call)
|
||||
alertManager.cancelAlert(callId)
|
||||
|
@ -262,8 +250,28 @@ class CallService : VectorService() {
|
|||
mxCall = call.mxCall,
|
||||
title = opponentMatrixItem?.getBestName() ?: call.mxCall.opponentUserId
|
||||
)
|
||||
if (knownCalls.isEmpty()) {
|
||||
startForeground(callId.hashCode(), notification)
|
||||
} else {
|
||||
notificationManager.notify(callId.hashCode(), notification)
|
||||
}
|
||||
knownCalls.add(callId)
|
||||
}
|
||||
|
||||
private fun handleUnexpectedState(callId: String?) {
|
||||
Timber.v("Fallback to clear everything")
|
||||
callRingPlayerIncoming?.stop()
|
||||
callRingPlayerOutgoing?.stop()
|
||||
if (callId != null) {
|
||||
notificationManager.cancel(callId.hashCode())
|
||||
}
|
||||
val notification = notificationUtils.buildCallEndedNotification()
|
||||
startForeground(DEFAULT_NOTIFICATION_ID, notification)
|
||||
if (knownCalls.isEmpty()) {
|
||||
mediaSession?.isActive = false
|
||||
myStopSelf()
|
||||
}
|
||||
}
|
||||
|
||||
fun addConnection(callConnection: CallConnection) {
|
||||
connections[callConnection.callId] = callConnection
|
||||
|
@ -274,7 +282,7 @@ class CallService : VectorService() {
|
|||
}
|
||||
|
||||
companion object {
|
||||
private const val NOTIFICATION_ID = 6480
|
||||
private const val DEFAULT_NOTIFICATION_ID = 6480
|
||||
|
||||
private const val ACTION_INCOMING_RINGING_CALL = "im.vector.app.core.services.CallService.ACTION_INCOMING_RINGING_CALL"
|
||||
private const val ACTION_OUTGOING_RINGING_CALL = "im.vector.app.core.services.CallService.ACTION_OUTGOING_RINGING_CALL"
|
||||
|
|
|
@ -20,7 +20,6 @@ import android.content.Context
|
|||
import android.content.res.ColorStateList
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.widget.FrameLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.withStyledAttributes
|
||||
|
|
|
@ -21,11 +21,7 @@ import android.bluetooth.BluetoothAdapter
|
|||
import android.bluetooth.BluetoothManager
|
||||
import android.bluetooth.BluetoothProfile
|
||||
import android.content.Context
|
||||
import android.media.AudioDeviceCallback
|
||||
import android.media.AudioDeviceInfo
|
||||
import android.media.AudioManager
|
||||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.content.getSystemService
|
||||
import im.vector.app.core.services.BluetoothHeadsetReceiver
|
||||
import im.vector.app.core.services.WiredHeadsetStateReceiver
|
||||
|
@ -61,7 +57,6 @@ internal class API21AudioDeviceDetector(private val context: Context,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private fun isWiredHeadsetOn(): Boolean {
|
||||
return audioManager.isWiredHeadsetOn
|
||||
}
|
||||
|
@ -82,7 +77,6 @@ internal class API21AudioDeviceDetector(private val context: Context,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper method to trigger an audio route update when devices change. It
|
||||
* makes sure the operation is performed on the audio thread.
|
||||
|
@ -119,7 +113,6 @@ internal class API21AudioDeviceDetector(private val context: Context,
|
|||
onAudioDeviceChange()
|
||||
}
|
||||
|
||||
|
||||
override fun stop() {
|
||||
Timber.i("Stop using $this as the audio device handler")
|
||||
wiredHeadsetStateReceiver?.let { WiredHeadsetStateReceiver.unRegister(context, it) }
|
||||
|
|
|
@ -30,7 +30,7 @@ internal class API23AudioDeviceDetector(private val audioManager: AudioManager,
|
|||
|
||||
private val onAudioDeviceChangeRunner = Runnable {
|
||||
val devices: MutableSet<CallAudioManager.Device> = HashSet()
|
||||
val deviceInfos = audioManager.getDevices(AudioManager.GET_DEVICES_ALL)
|
||||
val deviceInfos = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS)
|
||||
for (info in deviceInfos) {
|
||||
when (info.type) {
|
||||
AudioDeviceInfo.TYPE_BLUETOOTH_SCO -> devices.add(CallAudioManager.Device.WIRELESS_HEADSET)
|
||||
|
|
|
@ -18,6 +18,8 @@ package im.vector.app.features.call.audio
|
|||
|
||||
import android.content.Context
|
||||
import android.media.AudioManager
|
||||
import android.os.Build
|
||||
import androidx.core.content.getSystemService
|
||||
import org.matrix.android.sdk.api.extensions.orFalse
|
||||
import timber.log.Timber
|
||||
import java.util.HashSet
|
||||
|
@ -25,7 +27,7 @@ import java.util.concurrent.Executors
|
|||
|
||||
class CallAudioManager(private val context: Context, val configChange: (() -> Unit)?) {
|
||||
|
||||
private val audioManager = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||
private val audioManager: AudioManager? = context.getSystemService()
|
||||
private var audioDeviceDetector: AudioDeviceDetector? = null
|
||||
private var audioDeviceRouter: AudioDeviceRouter? = null
|
||||
|
||||
|
@ -56,8 +58,11 @@ class CallAudioManager(private val context: Context, val configChange: (() -> Un
|
|||
}
|
||||
|
||||
private fun setup() {
|
||||
if (audioManager == null) {
|
||||
return
|
||||
}
|
||||
audioDeviceDetector?.stop()
|
||||
audioDeviceDetector = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
|
||||
audioDeviceDetector = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
API23AudioDeviceDetector(audioManager, this)
|
||||
} else {
|
||||
API21AudioDeviceDetector(context, audioManager, this)
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
package im.vector.app.features.call.webrtc
|
||||
|
||||
import im.vector.app.features.call.audio.CallAudioManager
|
||||
import org.matrix.android.sdk.api.session.call.CallState
|
||||
import org.matrix.android.sdk.api.session.call.MxPeerConnectionState
|
||||
import org.webrtc.DataChannel
|
||||
|
|
|
@ -21,7 +21,6 @@ import android.hardware.camera2.CameraManager
|
|||
import androidx.core.content.getSystemService
|
||||
import im.vector.app.core.services.CallService
|
||||
import im.vector.app.core.utils.CountUpTimer
|
||||
import im.vector.app.features.call.audio.CallAudioManager
|
||||
import im.vector.app.features.call.CameraEventsHandlerAdapter
|
||||
import im.vector.app.features.call.CameraProxy
|
||||
import im.vector.app.features.call.CameraType
|
||||
|
@ -92,7 +91,7 @@ class WebRtcCall(val mxCall: MxCall,
|
|||
private val sessionProvider: Provider<Session?>,
|
||||
private val peerConnectionFactoryProvider: Provider<PeerConnectionFactory?>,
|
||||
private val onCallBecomeActive: (WebRtcCall) -> Unit,
|
||||
private val onCallEnded: (WebRtcCall) -> Unit) : MxCall.StateListener {
|
||||
private val onCallEnded: (String) -> Unit) : MxCall.StateListener {
|
||||
|
||||
interface Listener : MxCall.StateListener {
|
||||
fun onCaptureStateChanged() {}
|
||||
|
@ -725,7 +724,7 @@ class WebRtcCall(val mxCall: MxCall,
|
|||
GlobalScope.launch(dispatcher) {
|
||||
release()
|
||||
}
|
||||
onCallEnded(this)
|
||||
onCallEnded(callId)
|
||||
if (originatedByMe) {
|
||||
if (wasRinging) {
|
||||
mxCall.reject()
|
||||
|
|
|
@ -21,9 +21,7 @@ import androidx.lifecycle.Lifecycle
|
|||
import androidx.lifecycle.LifecycleObserver
|
||||
import androidx.lifecycle.OnLifecycleEvent
|
||||
import im.vector.app.ActiveSessionDataSource
|
||||
import im.vector.app.core.services.BluetoothHeadsetReceiver
|
||||
import im.vector.app.core.services.CallService
|
||||
import im.vector.app.core.services.WiredHeadsetStateReceiver
|
||||
import im.vector.app.features.call.VectorCallActivity
|
||||
import im.vector.app.features.call.audio.CallAudioManager
|
||||
import im.vector.app.features.call.utils.EglUtils
|
||||
|
@ -186,22 +184,34 @@ class WebRtcCallManager @Inject constructor(
|
|||
this.currentCall.setAndNotify(call)
|
||||
}
|
||||
|
||||
private fun onCallEnded(call: WebRtcCall) {
|
||||
Timber.v("## VOIP WebRtcPeerConnectionManager onCall ended: ${call.mxCall.callId}")
|
||||
CallService.onCallTerminated(context, call.callId)
|
||||
callsByCallId.remove(call.mxCall.callId)
|
||||
callsByRoomId[call.mxCall.roomId]?.remove(call)
|
||||
if (getCurrentCall() == call) {
|
||||
private fun onCallEnded(callId: String) {
|
||||
Timber.v("## VOIP WebRtcPeerConnectionManager onCall ended: $callId")
|
||||
val webRtcCall = callsByCallId.remove(callId) ?: return Unit.also {
|
||||
Timber.v("On call ended for unknown call $callId")
|
||||
}
|
||||
CallService.onCallTerminated(context, callId)
|
||||
callsByRoomId[webRtcCall.roomId]?.remove(webRtcCall)
|
||||
if (getCurrentCall()?.callId == callId) {
|
||||
val otherCall = getCalls().lastOrNull()
|
||||
currentCall.setAndNotify(otherCall)
|
||||
}
|
||||
// This must be done in this thread
|
||||
executor.execute {
|
||||
// There is no active calls
|
||||
if (getCurrentCall() == null) {
|
||||
Timber.v("## VOIP Dispose peerConnectionFactory as there is no need to keep one")
|
||||
peerConnectionFactory?.dispose()
|
||||
peerConnectionFactory = null
|
||||
audioManager.setMode(CallAudioManager.Mode.DEFAULT)
|
||||
// did we start background sync? so we should stop it
|
||||
if (isInBackground) {
|
||||
if (FcmHelper.isPushSupported()) {
|
||||
currentSession?.stopAnyBackgroundSync()
|
||||
} else {
|
||||
// for fdroid we should not stop, it should continue syncing
|
||||
// maybe we should restore default timeout/delay though?
|
||||
}
|
||||
}
|
||||
}
|
||||
Timber.v("## VOIP WebRtcPeerConnectionManager close() executor done")
|
||||
}
|
||||
|
@ -225,7 +235,6 @@ class WebRtcCallManager @Inject constructor(
|
|||
val mxCall = currentSession?.callSignalingService()?.createOutgoingCall(signalingRoomId, otherUserId, isVideoCall) ?: return
|
||||
val webRtcCall = createWebRtcCall(mxCall)
|
||||
currentCall.setAndNotify(webRtcCall)
|
||||
//callAudioManager.startForCall(mxCall)
|
||||
|
||||
CallService.onOutgoingCallRinging(
|
||||
context = context.applicationContext,
|
||||
|
@ -261,6 +270,9 @@ class WebRtcCallManager @Inject constructor(
|
|||
callsByCallId[mxCall.callId] = webRtcCall
|
||||
callsByRoomId.getOrPut(mxCall.roomId) { ArrayList(1) }
|
||||
.add(webRtcCall)
|
||||
if (getCurrentCall() == null) {
|
||||
currentCall.setAndNotify(webRtcCall)
|
||||
}
|
||||
return webRtcCall
|
||||
}
|
||||
|
||||
|
@ -268,18 +280,6 @@ class WebRtcCallManager @Inject constructor(
|
|||
callsByRoomId[roomId]?.forEach { it.endCall(originatedByMe) }
|
||||
}
|
||||
|
||||
fun onWiredDeviceEvent(event: WiredHeadsetStateReceiver.HeadsetPlugEvent) {
|
||||
Timber.v("## VOIP onWiredDeviceEvent $event")
|
||||
getCurrentCall() ?: return
|
||||
// sometimes we received un-wanted unplugged...
|
||||
//callAudioManager.wiredStateChange(event)
|
||||
}
|
||||
|
||||
fun onWirelessDeviceEvent(event: BluetoothHeadsetReceiver.BTHeadsetPlugEvent) {
|
||||
Timber.v("## VOIP onWirelessDeviceEvent $event")
|
||||
//callAudioManager.bluetoothStateChange(event.plugged)
|
||||
}
|
||||
|
||||
override fun onCallInviteReceived(mxCall: MxCall, callInviteContent: CallInviteContent) {
|
||||
Timber.v("## VOIP onCallInviteReceived callId ${mxCall.callId}")
|
||||
if (getCallsByRoomId(mxCall.roomId).isNotEmpty()) {
|
||||
|
@ -294,7 +294,6 @@ class WebRtcCallManager @Inject constructor(
|
|||
createWebRtcCall(mxCall).apply {
|
||||
offerSdp = callInviteContent.offer
|
||||
}
|
||||
//callAudioManager.startForCall(mxCall)
|
||||
// Start background service with notification
|
||||
CallService.onIncomingCallRinging(
|
||||
context = context,
|
||||
|
@ -367,21 +366,6 @@ class WebRtcCallManager @Inject constructor(
|
|||
|
||||
override fun onCallManagedByOtherSession(callId: String) {
|
||||
Timber.v("## VOIP onCallManagedByOtherSession: $callId")
|
||||
val webRtcCall = callsByCallId.remove(callId)
|
||||
if (webRtcCall != null) {
|
||||
callsByRoomId[webRtcCall.mxCall.roomId]?.remove(webRtcCall)
|
||||
}
|
||||
// TODO: handle this properly
|
||||
CallService.onCallTerminated(context, callId)
|
||||
|
||||
// did we start background sync? so we should stop it
|
||||
if (isInBackground) {
|
||||
if (FcmHelper.isPushSupported()) {
|
||||
currentSession?.stopAnyBackgroundSync()
|
||||
} else {
|
||||
// for fdroid we should not stop, it should continue syncing
|
||||
// maybe we should restore default timeout/delay though?
|
||||
}
|
||||
}
|
||||
onCallEnded(callId)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -208,6 +208,10 @@ class NotificationUtils @Inject constructor(private val context: Context,
|
|||
})
|
||||
}
|
||||
|
||||
fun getChannel(channelId: String): NotificationChannel? {
|
||||
return notificationManager.getNotificationChannel(channelId)
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a polling thread listener notification
|
||||
*
|
||||
|
@ -266,6 +270,11 @@ class NotificationUtils @Inject constructor(private val context: Context,
|
|||
return notification
|
||||
}
|
||||
|
||||
fun getChannelForIncomingCall(fromBg: Boolean): NotificationChannel? {
|
||||
val notificationChannel = if (fromBg) CALL_NOTIFICATION_CHANNEL_ID else SILENT_NOTIFICATION_CHANNEL_ID
|
||||
return getChannel(notificationChannel)
|
||||
}
|
||||
|
||||
/**
|
||||
* Build an incoming call notification.
|
||||
* This notification starts the VectorHomeActivity which is in charge of centralizing the incoming call flow.
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
android:textSize="16sp"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintBottom_toTopOf="@+id/bottomSheetActionSubTitle"
|
||||
app:layout_constraintEnd_toStartOf="@+id/itemVerificationActionIcon"
|
||||
app:layout_constraintEnd_toStartOf="@+id/bottomSheetActionIcon"
|
||||
app:layout_constraintStart_toEndOf="@+id/bottomSheetActionLeftIcon"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_chainStyle="packed"
|
||||
|
|
Loading…
Reference in New Issue