mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-27 12:05:22 +00:00
Merge branch 'dev' into fix/video-call-rotation-and-avatars
This commit is contained in:
commit
2d98da10ee
@ -0,0 +1,46 @@
|
|||||||
|
package org.thoughtcrime.securesms.service
|
||||||
|
|
||||||
|
import android.os.Build
|
||||||
|
import android.telephony.PhoneStateListener
|
||||||
|
import android.telephony.PhoneStateListener.LISTEN_NONE
|
||||||
|
import android.telephony.TelephonyManager
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
|
import org.thoughtcrime.securesms.webrtc.HangUpRtcOnPstnCallAnsweredListener
|
||||||
|
import org.thoughtcrime.securesms.webrtc.HangUpRtcTelephonyCallback
|
||||||
|
import java.util.concurrent.ExecutorService
|
||||||
|
|
||||||
|
internal interface TelephonyHandler {
|
||||||
|
fun register(telephonyManager: TelephonyManager)
|
||||||
|
fun unregister(telephonyManager: TelephonyManager)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun TelephonyHandler(serviceExecutor: ExecutorService, callback: () -> Unit) = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
|
TelephonyHandlerV31(serviceExecutor, callback)
|
||||||
|
} else {
|
||||||
|
TelephonyHandlerV23(callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(Build.VERSION_CODES.S)
|
||||||
|
private class TelephonyHandlerV31(val serviceExecutor: ExecutorService, callback: () -> Unit): TelephonyHandler {
|
||||||
|
private val callback = HangUpRtcTelephonyCallback(callback)
|
||||||
|
|
||||||
|
override fun register(telephonyManager: TelephonyManager) {
|
||||||
|
telephonyManager.registerTelephonyCallback(serviceExecutor, callback)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun unregister(telephonyManager: TelephonyManager) {
|
||||||
|
telephonyManager.unregisterTelephonyCallback(callback)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TelephonyHandlerV23(callback: () -> Unit): TelephonyHandler {
|
||||||
|
val callback = HangUpRtcOnPstnCallAnsweredListener(callback)
|
||||||
|
|
||||||
|
override fun register(telephonyManager: TelephonyManager) {
|
||||||
|
telephonyManager.listen(callback, PhoneStateListener.LISTEN_CALL_STATE)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun unregister(telephonyManager: TelephonyManager) {
|
||||||
|
telephonyManager.listen(callback, LISTEN_NONE)
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,5 @@
|
|||||||
package org.thoughtcrime.securesms.service
|
package org.thoughtcrime.securesms.service
|
||||||
|
|
||||||
import android.app.ForegroundServiceStartNotAllowedException
|
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
@ -10,11 +9,11 @@ import android.content.IntentFilter
|
|||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.media.AudioManager
|
import android.media.AudioManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.IBinder
|
|
||||||
import android.os.ResultReceiver
|
import android.os.ResultReceiver
|
||||||
import android.telephony.PhoneStateListener
|
import android.telephony.PhoneStateListener
|
||||||
import android.telephony.PhoneStateListener.LISTEN_NONE
|
import android.telephony.PhoneStateListener.LISTEN_NONE
|
||||||
import android.telephony.TelephonyManager
|
import android.telephony.TelephonyManager
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.os.bundleOf
|
import androidx.core.os.bundleOf
|
||||||
import androidx.lifecycle.LifecycleService
|
import androidx.lifecycle.LifecycleService
|
||||||
@ -34,14 +33,33 @@ import org.thoughtcrime.securesms.util.CallNotificationBuilder.Companion.TYPE_IN
|
|||||||
import org.thoughtcrime.securesms.util.CallNotificationBuilder.Companion.TYPE_INCOMING_PRE_OFFER
|
import org.thoughtcrime.securesms.util.CallNotificationBuilder.Companion.TYPE_INCOMING_PRE_OFFER
|
||||||
import org.thoughtcrime.securesms.util.CallNotificationBuilder.Companion.TYPE_INCOMING_RINGING
|
import org.thoughtcrime.securesms.util.CallNotificationBuilder.Companion.TYPE_INCOMING_RINGING
|
||||||
import org.thoughtcrime.securesms.util.CallNotificationBuilder.Companion.TYPE_OUTGOING_RINGING
|
import org.thoughtcrime.securesms.util.CallNotificationBuilder.Companion.TYPE_OUTGOING_RINGING
|
||||||
import org.thoughtcrime.securesms.webrtc.*
|
import org.thoughtcrime.securesms.webrtc.AudioManagerCommand
|
||||||
|
import org.thoughtcrime.securesms.webrtc.CallManager
|
||||||
|
import org.thoughtcrime.securesms.webrtc.CallViewModel
|
||||||
|
import org.thoughtcrime.securesms.webrtc.HangUpRtcOnPstnCallAnsweredListener
|
||||||
|
import org.thoughtcrime.securesms.webrtc.HangUpRtcTelephonyCallback
|
||||||
|
import org.thoughtcrime.securesms.webrtc.IncomingPstnCallReceiver
|
||||||
|
import org.thoughtcrime.securesms.webrtc.NetworkChangeReceiver
|
||||||
|
import org.thoughtcrime.securesms.webrtc.PeerConnectionException
|
||||||
|
import org.thoughtcrime.securesms.webrtc.PowerButtonReceiver
|
||||||
|
import org.thoughtcrime.securesms.webrtc.ProximityLockRelease
|
||||||
|
import org.thoughtcrime.securesms.webrtc.UncaughtExceptionHandlerManager
|
||||||
|
import org.thoughtcrime.securesms.webrtc.WiredHeadsetStateReceiver
|
||||||
import org.thoughtcrime.securesms.webrtc.audio.OutgoingRinger
|
import org.thoughtcrime.securesms.webrtc.audio.OutgoingRinger
|
||||||
import org.thoughtcrime.securesms.webrtc.data.Event
|
import org.thoughtcrime.securesms.webrtc.data.Event
|
||||||
import org.thoughtcrime.securesms.webrtc.locks.LockManager
|
import org.thoughtcrime.securesms.webrtc.locks.LockManager
|
||||||
import org.webrtc.*
|
import org.webrtc.DataChannel
|
||||||
import org.webrtc.PeerConnection.IceConnectionState.*
|
import org.webrtc.IceCandidate
|
||||||
import java.util.*
|
import org.webrtc.MediaStream
|
||||||
|
import org.webrtc.PeerConnection
|
||||||
|
import org.webrtc.PeerConnection.IceConnectionState.CONNECTED
|
||||||
|
import org.webrtc.PeerConnection.IceConnectionState.DISCONNECTED
|
||||||
|
import org.webrtc.PeerConnection.IceConnectionState.FAILED
|
||||||
|
import org.webrtc.RtpReceiver
|
||||||
|
import org.webrtc.SessionDescription
|
||||||
|
import java.util.UUID
|
||||||
import java.util.concurrent.ExecutionException
|
import java.util.concurrent.ExecutionException
|
||||||
|
import java.util.concurrent.ExecutorService
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
import java.util.concurrent.ScheduledFuture
|
import java.util.concurrent.ScheduledFuture
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
@ -209,16 +227,11 @@ class WebRtcCallService : LifecycleService(), CallManager.WebRtcListener {
|
|||||||
private val serviceExecutor = Executors.newSingleThreadExecutor()
|
private val serviceExecutor = Executors.newSingleThreadExecutor()
|
||||||
private val timeoutExecutor = Executors.newScheduledThreadPool(1)
|
private val timeoutExecutor = Executors.newScheduledThreadPool(1)
|
||||||
|
|
||||||
private val hangupOnCallAnswered by lazy {
|
private val telephonyHandler = TelephonyHandler(serviceExecutor) {
|
||||||
HangUpRtcOnPstnCallAnsweredListener {
|
ContextCompat.startForegroundService(
|
||||||
ContextCompat.startForegroundService(this, hangupIntent(this))
|
this@WebRtcCallService,
|
||||||
}
|
hangupIntent(this@WebRtcCallService)
|
||||||
}
|
)
|
||||||
|
|
||||||
private val hangupTelephonyCallback by lazy {
|
|
||||||
HangUpRtcTelephonyCallback {
|
|
||||||
ContextCompat.startForegroundService(this, hangupIntent(this))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private var networkChangedReceiver: NetworkChangeReceiver? = null
|
private var networkChangedReceiver: NetworkChangeReceiver? = null
|
||||||
@ -251,17 +264,12 @@ class WebRtcCallService : LifecycleService(), CallManager.WebRtcListener {
|
|||||||
return callManager.callId == expectedCallId
|
return callManager.callId == expectedCallId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun isPreOffer() = callManager.isPreOffer()
|
private fun isPreOffer() = callManager.isPreOffer()
|
||||||
|
|
||||||
private fun isBusy(intent: Intent) = callManager.isBusy(this, getCallId(intent))
|
private fun isBusy(intent: Intent) = callManager.isBusy(this, getCallId(intent))
|
||||||
|
|
||||||
private fun isIdle() = callManager.isIdle()
|
private fun isIdle() = callManager.isIdle()
|
||||||
|
|
||||||
override fun onBind(intent: Intent): IBinder? {
|
|
||||||
return super.onBind(intent)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onHangup() {
|
override fun onHangup() {
|
||||||
serviceExecutor.execute {
|
serviceExecutor.execute {
|
||||||
callManager.handleRemoteHangup()
|
callManager.handleRemoteHangup()
|
||||||
@ -276,38 +284,41 @@ class WebRtcCallService : LifecycleService(), CallManager.WebRtcListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
|
super.onStartCommand(intent, flags, startId)
|
||||||
if (intent == null || intent.action == null) return START_NOT_STICKY
|
if (intent == null || intent.action == null) return START_NOT_STICKY
|
||||||
serviceExecutor.execute {
|
serviceExecutor.execute {
|
||||||
val action = intent.action
|
val action = intent.action
|
||||||
val callId = ((intent.getSerializableExtra(EXTRA_CALL_ID) as? UUID)?.toString() ?: "No callId")
|
val callId = ((intent.getSerializableExtra(EXTRA_CALL_ID) as? UUID)?.toString() ?: "No callId")
|
||||||
Log.i("Loki", "Handling ${intent.action} for call: ${callId}")
|
Log.i("Loki", "Handling ${intent.action} for call: ${callId}")
|
||||||
when {
|
when (action) {
|
||||||
action == ACTION_INCOMING_RING && isSameCall(intent) && callManager.currentConnectionState == CallState.Reconnecting -> handleNewOffer(
|
ACTION_INCOMING_RING -> if (isSameCall(intent) && callManager.currentConnectionState == CallState.Reconnecting) {
|
||||||
intent
|
handleNewOffer(intent)
|
||||||
)
|
}
|
||||||
action == ACTION_PRE_OFFER && isIdle() -> handlePreOffer(intent)
|
ACTION_PRE_OFFER -> if (isIdle()) handlePreOffer(intent)
|
||||||
action == ACTION_INCOMING_RING && isBusy(intent) -> handleBusyCall(intent)
|
ACTION_INCOMING_RING -> when {
|
||||||
action == ACTION_INCOMING_RING && isPreOffer() -> handleIncomingRing(intent)
|
isBusy(intent) -> handleBusyCall(intent)
|
||||||
action == ACTION_OUTGOING_CALL && isIdle() -> handleOutgoingCall(intent)
|
isPreOffer() -> handleIncomingRing(intent)
|
||||||
action == ACTION_ANSWER_CALL -> handleAnswerCall(intent)
|
}
|
||||||
action == ACTION_DENY_CALL -> handleDenyCall(intent)
|
ACTION_OUTGOING_CALL -> if (isIdle()) handleOutgoingCall(intent)
|
||||||
action == ACTION_LOCAL_HANGUP -> handleLocalHangup(intent)
|
ACTION_ANSWER_CALL -> handleAnswerCall(intent)
|
||||||
action == ACTION_REMOTE_HANGUP -> handleRemoteHangup(intent)
|
ACTION_DENY_CALL -> handleDenyCall(intent)
|
||||||
action == ACTION_SET_MUTE_AUDIO -> handleSetMuteAudio(intent)
|
ACTION_LOCAL_HANGUP -> handleLocalHangup(intent)
|
||||||
action == ACTION_SET_MUTE_VIDEO -> handleSetMuteVideo(intent)
|
ACTION_REMOTE_HANGUP -> handleRemoteHangup(intent)
|
||||||
action == ACTION_FLIP_CAMERA -> handleSetCameraFlip(intent)
|
ACTION_SET_MUTE_AUDIO -> handleSetMuteAudio(intent)
|
||||||
action == ACTION_WIRED_HEADSET_CHANGE -> handleWiredHeadsetChanged(intent)
|
ACTION_SET_MUTE_VIDEO -> handleSetMuteVideo(intent)
|
||||||
action == ACTION_SCREEN_OFF -> handleScreenOffChange(intent)
|
ACTION_FLIP_CAMERA -> handleSetCameraFlip(intent)
|
||||||
action == ACTION_RESPONSE_MESSAGE && isSameCall(intent) && callManager.currentConnectionState == CallState.Reconnecting -> handleResponseMessage(
|
ACTION_WIRED_HEADSET_CHANGE -> handleWiredHeadsetChanged(intent)
|
||||||
intent
|
ACTION_SCREEN_OFF -> handleScreenOffChange(intent)
|
||||||
)
|
ACTION_RESPONSE_MESSAGE -> if (isSameCall(intent) && callManager.currentConnectionState == CallState.Reconnecting) {
|
||||||
action == ACTION_RESPONSE_MESSAGE -> handleResponseMessage(intent)
|
handleResponseMessage(intent)
|
||||||
action == ACTION_ICE_MESSAGE -> handleRemoteIceCandidate(intent)
|
}
|
||||||
action == ACTION_ICE_CONNECTED -> handleIceConnected(intent)
|
ACTION_RESPONSE_MESSAGE -> handleResponseMessage(intent)
|
||||||
action == ACTION_CHECK_TIMEOUT -> handleCheckTimeout(intent)
|
ACTION_ICE_MESSAGE -> handleRemoteIceCandidate(intent)
|
||||||
action == ACTION_CHECK_RECONNECT -> handleCheckReconnect(intent)
|
ACTION_ICE_CONNECTED -> handleIceConnected(intent)
|
||||||
action == ACTION_IS_IN_CALL_QUERY -> handleIsInCallQuery(intent)
|
ACTION_CHECK_TIMEOUT -> handleCheckTimeout(intent)
|
||||||
action == ACTION_UPDATE_AUDIO -> handleUpdateAudio(intent)
|
ACTION_CHECK_RECONNECT -> handleCheckReconnect(intent)
|
||||||
|
ACTION_IS_IN_CALL_QUERY -> handleIsInCallQuery(intent)
|
||||||
|
ACTION_UPDATE_AUDIO -> handleUpdateAudio(intent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return START_NOT_STICKY
|
return START_NOT_STICKY
|
||||||
@ -322,13 +333,7 @@ class WebRtcCallService : LifecycleService(), CallManager.WebRtcListener {
|
|||||||
registerWiredHeadsetStateReceiver()
|
registerWiredHeadsetStateReceiver()
|
||||||
registerWantsToAnswerReceiver()
|
registerWantsToAnswerReceiver()
|
||||||
if (checkSelfPermission(android.Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
|
if (checkSelfPermission(android.Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
|
telephonyHandler.register(getSystemService(TelephonyManager::class.java))
|
||||||
getSystemService(TelephonyManager::class.java)
|
|
||||||
.listen(hangupOnCallAnswered, PhoneStateListener.LISTEN_CALL_STATE)
|
|
||||||
} else {
|
|
||||||
getSystemService(TelephonyManager::class.java)
|
|
||||||
.registerTelephonyCallback(serviceExecutor, hangupTelephonyCallback)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
registerUncaughtExceptionHandler()
|
registerUncaughtExceptionHandler()
|
||||||
networkChangedReceiver = NetworkChangeReceiver(::networkChange)
|
networkChangedReceiver = NetworkChangeReceiver(::networkChange)
|
||||||
@ -735,9 +740,8 @@ class WebRtcCallService : LifecycleService(), CallManager.WebRtcListener {
|
|||||||
CallNotificationBuilder.WEBRTC_NOTIFICATION,
|
CallNotificationBuilder.WEBRTC_NOTIFICATION,
|
||||||
CallNotificationBuilder.getCallInProgressNotification(this, type, recipient)
|
CallNotificationBuilder.getCallInProgressNotification(this, type, recipient)
|
||||||
)
|
)
|
||||||
}
|
} catch (e: IllegalStateException) {
|
||||||
catch(e: ForegroundServiceStartNotAllowedException) {
|
Log.e(TAG, "Failed to setCallInProgressNotification as a foreground service for type: ${type}, trying to update instead", e)
|
||||||
Log.e(TAG, "Failed to setCallInProgressNotification as a foreground service for type: ${type}, trying to update instead")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CallNotificationBuilder.areNotificationsEnabled(this) && type == TYPE_INCOMING_PRE_OFFER) {
|
if (!CallNotificationBuilder.areNotificationsEnabled(this) && type == TYPE_INCOMING_PRE_OFFER) {
|
||||||
@ -750,11 +754,7 @@ class WebRtcCallService : LifecycleService(), CallManager.WebRtcListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getOptionalRemoteRecipient(intent: Intent): Recipient? =
|
private fun getOptionalRemoteRecipient(intent: Intent): Recipient? =
|
||||||
if (intent.hasExtra(EXTRA_RECIPIENT_ADDRESS)) {
|
intent.takeIf { it.hasExtra(EXTRA_RECIPIENT_ADDRESS) }?.let(::getRemoteRecipient)
|
||||||
getRemoteRecipient(intent)
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getRemoteRecipient(intent: Intent): Recipient {
|
private fun getRemoteRecipient(intent: Intent): Recipient {
|
||||||
val remoteAddress = intent.getParcelableExtra<Address>(EXTRA_RECIPIENT_ADDRESS)
|
val remoteAddress = intent.getParcelableExtra<Address>(EXTRA_RECIPIENT_ADDRESS)
|
||||||
@ -763,10 +763,9 @@ class WebRtcCallService : LifecycleService(), CallManager.WebRtcListener {
|
|||||||
return Recipient.from(this, remoteAddress, true)
|
return Recipient.from(this, remoteAddress, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getCallId(intent: Intent): UUID {
|
private fun getCallId(intent: Intent): UUID =
|
||||||
return intent.getSerializableExtra(EXTRA_CALL_ID) as? UUID
|
intent.getSerializableExtra(EXTRA_CALL_ID) as? UUID
|
||||||
?: throw AssertionError("No callId in intent!")
|
?: throw AssertionError("No callId in intent!")
|
||||||
}
|
|
||||||
|
|
||||||
private fun insertMissedCall(recipient: Recipient, signal: Boolean) {
|
private fun insertMissedCall(recipient: Recipient, signal: Boolean) {
|
||||||
callManager.insertCallMessage(
|
callManager.insertCallMessage(
|
||||||
@ -788,8 +787,8 @@ class WebRtcCallService : LifecycleService(), CallManager.WebRtcListener {
|
|||||||
callReceiver?.let { receiver ->
|
callReceiver?.let { receiver ->
|
||||||
unregisterReceiver(receiver)
|
unregisterReceiver(receiver)
|
||||||
}
|
}
|
||||||
wiredHeadsetStateReceiver?.let { unregisterReceiver(it) }
|
wiredHeadsetStateReceiver?.let(::unregisterReceiver)
|
||||||
powerButtonReceiver?.let { unregisterReceiver(it) }
|
powerButtonReceiver?.let(::unregisterReceiver)
|
||||||
networkChangedReceiver?.unregister(this)
|
networkChangedReceiver?.unregister(this)
|
||||||
wantsToAnswerReceiver?.let { receiver ->
|
wantsToAnswerReceiver?.let { receiver ->
|
||||||
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver)
|
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver)
|
||||||
@ -804,14 +803,7 @@ class WebRtcCallService : LifecycleService(), CallManager.WebRtcListener {
|
|||||||
currentTimeouts = 0
|
currentTimeouts = 0
|
||||||
isNetworkAvailable = false
|
isNetworkAvailable = false
|
||||||
if (checkSelfPermission(android.Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
|
if (checkSelfPermission(android.Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
|
||||||
val telephonyManager = getSystemService(TelephonyManager::class.java)
|
telephonyHandler.unregister(getSystemService(TelephonyManager::class.java))
|
||||||
with(telephonyManager) {
|
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
|
|
||||||
this.listen(hangupOnCallAnswered, LISTEN_NONE)
|
|
||||||
} else {
|
|
||||||
this.unregisterTelephonyCallback(hangupTelephonyCallback)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
}
|
}
|
||||||
@ -819,13 +811,12 @@ class WebRtcCallService : LifecycleService(), CallManager.WebRtcListener {
|
|||||||
private fun networkChange(networkAvailable: Boolean) {
|
private fun networkChange(networkAvailable: Boolean) {
|
||||||
Log.d("Loki", "flipping network available to $networkAvailable")
|
Log.d("Loki", "flipping network available to $networkAvailable")
|
||||||
isNetworkAvailable = networkAvailable
|
isNetworkAvailable = networkAvailable
|
||||||
if (networkAvailable && !callManager.isReestablishing && callManager.currentConnectionState == CallState.Connected) {
|
if (networkAvailable && callManager.currentConnectionState == CallState.Connected) {
|
||||||
Log.d("Loki", "Should reconnected")
|
Log.d("Loki", "Should reconnected")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CheckReconnectedRunnable(private val callId: UUID, private val context: Context) :
|
private class CheckReconnectedRunnable(private val callId: UUID, private val context: Context) : Runnable {
|
||||||
Runnable {
|
|
||||||
override fun run() {
|
override fun run() {
|
||||||
val intent = Intent(context, WebRtcCallService::class.java)
|
val intent = Intent(context, WebRtcCallService::class.java)
|
||||||
.setAction(ACTION_CHECK_RECONNECT)
|
.setAction(ACTION_CHECK_RECONNECT)
|
||||||
@ -834,18 +825,7 @@ class WebRtcCallService : LifecycleService(), CallManager.WebRtcListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ReconnectTimeoutRunnable(private val callId: UUID, private val context: Context) :
|
private class TimeoutRunnable(private val callId: UUID, private val context: Context) : Runnable {
|
||||||
Runnable {
|
|
||||||
override fun run() {
|
|
||||||
val intent = Intent(context, WebRtcCallService::class.java)
|
|
||||||
.setAction(ACTION_CHECK_RECONNECT_TIMEOUT)
|
|
||||||
.putExtra(EXTRA_CALL_ID, callId)
|
|
||||||
context.startService(intent)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class TimeoutRunnable(private val callId: UUID, private val context: Context) :
|
|
||||||
Runnable {
|
|
||||||
override fun run() {
|
override fun run() {
|
||||||
val intent = Intent(context, WebRtcCallService::class.java)
|
val intent = Intent(context, WebRtcCallService::class.java)
|
||||||
.setAction(ACTION_CHECK_TIMEOUT)
|
.setAction(ACTION_CHECK_TIMEOUT)
|
||||||
|
@ -118,7 +118,7 @@ class CallManager(
|
|||||||
remoteVideoEnabled = false
|
remoteVideoEnabled = false
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
val videoState = _videoState
|
val videoState = _videoState.asStateFlow()
|
||||||
|
|
||||||
private val stateProcessor = StateProcessor(CallState.Idle)
|
private val stateProcessor = StateProcessor(CallState.Idle)
|
||||||
|
|
||||||
@ -137,7 +137,7 @@ class CallManager(
|
|||||||
val currentCallState
|
val currentCallState
|
||||||
get() = _callStateEvents.value
|
get() = _callStateEvents.value
|
||||||
|
|
||||||
var iceState = IceConnectionState.CLOSED
|
private var iceState = IceConnectionState.CLOSED
|
||||||
|
|
||||||
private var eglBase: EglBase? = null
|
private var eglBase: EglBase? = null
|
||||||
|
|
||||||
@ -151,7 +151,6 @@ class CallManager(
|
|||||||
_recipientEvents.value = RecipientUpdate(value)
|
_recipientEvents.value = RecipientUpdate(value)
|
||||||
}
|
}
|
||||||
var callStartTime: Long = -1
|
var callStartTime: Long = -1
|
||||||
var isReestablishing: Boolean = false
|
|
||||||
|
|
||||||
private var peerConnection: PeerConnectionWrapper? = null
|
private var peerConnection: PeerConnectionWrapper? = null
|
||||||
private var dataChannel: DataChannel? = null
|
private var dataChannel: DataChannel? = null
|
||||||
@ -628,12 +627,10 @@ class CallManager(
|
|||||||
|
|
||||||
if (_videoState.value.swapped) {
|
if (_videoState.value.swapped) {
|
||||||
peerConnection?.rotationVideoSink?.setSink(fullscreenRenderer)
|
peerConnection?.rotationVideoSink?.setSink(fullscreenRenderer)
|
||||||
floatingRenderer?.let{remoteRotationSink?.setSink(it) }
|
floatingRenderer?.let { remoteRotationSink?.setSink(it) }
|
||||||
} else {
|
} else {
|
||||||
peerConnection?.rotationVideoSink?.apply {
|
peerConnection?.rotationVideoSink?.setSink(floatingRenderer)
|
||||||
setSink(floatingRenderer)
|
fullscreenRenderer?.let { remoteRotationSink?.setSink(it) }
|
||||||
}
|
|
||||||
fullscreenRenderer?.let{ remoteRotationSink?.setSink(it) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -645,12 +642,12 @@ class CallManager(
|
|||||||
/**
|
/**
|
||||||
* Returns the renderer currently showing the user's video, not the contact's
|
* Returns the renderer currently showing the user's video, not the contact's
|
||||||
*/
|
*/
|
||||||
private fun getUserRenderer() = if(_videoState.value.swapped) fullscreenRenderer else floatingRenderer
|
private fun getUserRenderer() = if (_videoState.value.swapped) fullscreenRenderer else floatingRenderer
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the renderer currently showing the contact's video, not the user's
|
* Returns the renderer currently showing the contact's video, not the user's
|
||||||
*/
|
*/
|
||||||
private fun getRemoteRenderer() = if(_videoState.value.swapped) floatingRenderer else fullscreenRenderer
|
private fun getRemoteRenderer() = if (_videoState.value.swapped) floatingRenderer else fullscreenRenderer
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Makes sure the user's renderer applies mirroring if necessary
|
* Makes sure the user's renderer applies mirroring if necessary
|
||||||
@ -659,12 +656,12 @@ class CallManager(
|
|||||||
val videoState = _videoState.value
|
val videoState = _videoState.value
|
||||||
|
|
||||||
// if we have user video and the camera is front facing, make sure to mirror stream
|
// if we have user video and the camera is front facing, make sure to mirror stream
|
||||||
if(videoState.userVideoEnabled) {
|
if (videoState.userVideoEnabled) {
|
||||||
getUserRenderer()?.setMirror(isCameraFrontFacing())
|
getUserRenderer()?.setMirror(isCameraFrontFacing())
|
||||||
}
|
}
|
||||||
|
|
||||||
// the remote video is never mirrored
|
// the remote video is never mirrored
|
||||||
if(videoState.remoteVideoEnabled){
|
if (videoState.remoteVideoEnabled){
|
||||||
getRemoteRenderer()?.setMirror(false)
|
getRemoteRenderer()?.setMirror(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.webrtc
|
|||||||
|
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.flow.SharedFlow
|
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
@ -32,29 +31,25 @@ class CallViewModel @Inject constructor(private val callManager: CallManager): V
|
|||||||
}
|
}
|
||||||
|
|
||||||
val floatingRenderer: SurfaceViewRenderer?
|
val floatingRenderer: SurfaceViewRenderer?
|
||||||
get() = callManager.floatingRenderer
|
get() = callManager.floatingRenderer
|
||||||
|
|
||||||
val fullscreenRenderer: SurfaceViewRenderer?
|
val fullscreenRenderer: SurfaceViewRenderer?
|
||||||
get() = callManager.fullscreenRenderer
|
get() = callManager.fullscreenRenderer
|
||||||
|
|
||||||
private var _microphoneEnabled: Boolean = true
|
var microphoneEnabled: Boolean = true
|
||||||
|
private set
|
||||||
|
|
||||||
val microphoneEnabled: Boolean
|
var isSpeaker: Boolean = false
|
||||||
get() = _microphoneEnabled
|
private set
|
||||||
|
|
||||||
private var _isSpeaker: Boolean = false
|
|
||||||
val isSpeaker: Boolean
|
|
||||||
get() = _isSpeaker
|
|
||||||
|
|
||||||
val audioDeviceState
|
val audioDeviceState
|
||||||
get() = callManager.audioDeviceEvents
|
get() = callManager.audioDeviceEvents.onEach {
|
||||||
.onEach {
|
isSpeaker = it.selectedDevice == SignalAudioManager.AudioDevice.SPEAKER_PHONE
|
||||||
_isSpeaker = it.selectedDevice == SignalAudioManager.AudioDevice.SPEAKER_PHONE
|
}
|
||||||
}
|
|
||||||
|
|
||||||
val localAudioEnabledState
|
val localAudioEnabledState
|
||||||
get() = callManager.audioEvents.map { it.isEnabled }
|
get() = callManager.audioEvents.map { it.isEnabled }
|
||||||
.onEach { _microphoneEnabled = it }
|
.onEach { microphoneEnabled = it }
|
||||||
|
|
||||||
val videoState: StateFlow<VideoState>
|
val videoState: StateFlow<VideoState>
|
||||||
get() = callManager.videoState
|
get() = callManager.videoState
|
||||||
@ -65,17 +60,10 @@ class CallViewModel @Inject constructor(private val callManager: CallManager): V
|
|||||||
callManager.setDeviceOrientation(value)
|
callManager.setDeviceOrientation(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
val currentCallState
|
val currentCallState get() = callManager.currentCallState
|
||||||
get() = callManager.currentCallState
|
val callState get() = callManager.callStateEvents
|
||||||
|
val recipient get() = callManager.recipientEvents
|
||||||
val callState
|
val callStartTime: Long get() = callManager.callStartTime
|
||||||
get() = callManager.callStateEvents
|
|
||||||
|
|
||||||
val recipient
|
|
||||||
get() = callManager.recipientEvents
|
|
||||||
|
|
||||||
val callStartTime: Long
|
|
||||||
get() = callManager.callStartTime
|
|
||||||
|
|
||||||
fun swapVideos() {
|
fun swapVideos() {
|
||||||
callManager.swapVideos()
|
callManager.swapVideos()
|
||||||
|
Loading…
Reference in New Issue
Block a user