From 2ae2d1610faf5e2fed45c6ba604df2e7b126a371 Mon Sep 17 00:00:00 2001 From: Harris Date: Wed, 24 Nov 2021 14:18:15 +1100 Subject: [PATCH] feat: add a hangup via data channel message --- .../securesms/service/WebRtcCallService.kt | 24 +++++++++++------- .../securesms/webrtc/CallManager.kt | 25 ++++++++++++++----- 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/WebRtcCallService.kt b/app/src/main/java/org/thoughtcrime/securesms/service/WebRtcCallService.kt index 38873d6872..b8a34782ef 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/WebRtcCallService.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/service/WebRtcCallService.kt @@ -38,7 +38,7 @@ import java.util.concurrent.TimeUnit import javax.inject.Inject @AndroidEntryPoint -class WebRtcCallService: Service(), PeerConnection.Observer { +class WebRtcCallService: Service(), CallManager.WebRtcListener { companion object { @@ -193,6 +193,19 @@ class WebRtcCallService: Service(), PeerConnection.Observer { override fun onBind(intent: Intent?): IBinder? = null + override fun onHangup() { + serviceExecutor.execute { + callManager.handleRemoteHangup() + + if (callManager.currentConnectionState in arrayOf(STATE_REMOTE_RINGING, STATE_ANSWERING, STATE_LOCAL_RINGING)) { + callManager.recipient?.let { recipient -> + insertMissedCall(recipient, true) + } + } + terminate() + } + } + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { if (intent == null || intent.action == null) return START_NOT_STICKY serviceExecutor.execute { @@ -459,14 +472,7 @@ class WebRtcCallService: Service(), PeerConnection.Observer { return } - callManager.handleRemoteHangup() - - if (callManager.currentConnectionState in arrayOf(STATE_REMOTE_RINGING, STATE_ANSWERING, STATE_LOCAL_RINGING)) { - callManager.recipient?.let { recipient -> - insertMissedCall(recipient, true) - } - } - terminate() + onHangup() } private fun handleSetMuteAudio(intent: Intent) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/webrtc/CallManager.kt b/app/src/main/java/org/thoughtcrime/securesms/webrtc/CallManager.kt index d5db0ab1bc..3f11d10565 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/webrtc/CallManager.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/webrtc/CallManager.kt @@ -5,9 +5,7 @@ import android.telephony.TelephonyManager import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asSharedFlow import kotlinx.serialization.Serializable -import kotlinx.serialization.json.Json -import kotlinx.serialization.json.buildJsonObject -import kotlinx.serialization.json.put +import kotlinx.serialization.json.* import nl.komponents.kovenant.Promise import nl.komponents.kovenant.functional.bind import org.session.libsession.database.StorageProtocol @@ -56,6 +54,7 @@ class CallManager(context: Context, audioManager: AudioManagerCompat, private va val VIDEO_DISABLED_JSON by lazy { buildJsonObject { put("video", false) } } val VIDEO_ENABLED_JSON by lazy { buildJsonObject { put("video", true) } } + val HANGUP_JSON by lazy { buildJsonObject { put("hangup", true) } } private val TAG = Log.tag(CallManager::class.java) val CONNECTED_STATES = arrayOf(CallState.STATE_CONNECTED) @@ -75,13 +74,13 @@ class CallManager(context: Context, audioManager: AudioManagerCompat, private va private val signalAudioManager: SignalAudioManager = SignalAudioManager(context, this, audioManager) - private val peerConnectionObservers = mutableSetOf() + private val peerConnectionObservers = mutableSetOf() - fun registerListener(listener: PeerConnection.Observer) { + fun registerListener(listener: WebRtcListener) { peerConnectionObservers.add(listener) } - fun unregisterListener(listener: PeerConnection.Observer) { + fun unregisterListener(listener: WebRtcListener) { peerConnectionObservers.remove(listener) } @@ -304,6 +303,12 @@ class CallManager(context: Context, audioManager: AudioManagerCompat, private va try { val byteArray = ByteArray(buffer.data.remaining()) { buffer.data[it] } + val json = Json.parseToJsonElement(byteArray.decodeToString()) as JsonObject + if (json.containsKey("video")) { + _remoteVideoEvents.value = VideoEnabled((json["video"] as JsonPrimitive).boolean) + } else if (json.containsKey("hangup")) { + peerConnectionObservers.forEach(WebRtcListener::onHangup) + } val videoEnabled = Json.decodeFromString(VideoEnabledMessage.serializer(), byteArray.decodeToString()) _remoteVideoEvents.value = VideoEnabled(videoEnabled.video) } catch (e: Exception) { @@ -487,6 +492,10 @@ class CallManager(context: Context, audioManager: AudioManagerCompat, private va postViewModelState(CallViewModel.State.CALL_DISCONNECTED) if (sendHangup) { + dataChannel?.let { channel -> + val buffer = DataChannel.Buffer(ByteBuffer.wrap(HANGUP_JSON.toString().encodeToByteArray()), false) + channel.send(buffer) + } MessageSender.sendNonDurably(CallMessage.endCall(callId), recipient.address) } } @@ -643,4 +652,8 @@ class CallManager(context: Context, audioManager: AudioManagerCompat, private va @Serializable data class VideoEnabledMessage(val video: Boolean) + interface WebRtcListener: PeerConnection.Observer { + fun onHangup() + } + } \ No newline at end of file