convert CallActivity to kotlin

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
Marcel Hibbe 2023-07-25 17:42:23 +02:00
parent b5529f869a
commit a941945400

View File

@ -141,7 +141,6 @@ import com.nextcloud.talk.webrtc.PeerConnectionWrapper
import com.nextcloud.talk.webrtc.PeerConnectionWrapper.PeerConnectionObserver
import com.nextcloud.talk.webrtc.WebRtcAudioManager
import com.nextcloud.talk.webrtc.WebRtcAudioManager.AudioDevice
import com.nextcloud.talk.webrtc.WebRtcAudioManager.AudioManagerListener
import com.nextcloud.talk.webrtc.WebSocketConnectionHelper
import com.nextcloud.talk.webrtc.WebSocketInstance
import com.wooplr.spotlight.SpotlightView
@ -183,6 +182,7 @@ import javax.inject.Inject
import kotlin.math.roundToInt
@AutoInjector(NextcloudTalkApplication::class)
@Suppress("TooManyFunctions")
class CallActivity : CallBaseActivity() {
@JvmField
@Inject
@ -348,7 +348,7 @@ class CallActivity : CallBaseActivity() {
}
}
}
if (!rationaleList.isEmpty()) {
if (rationaleList.isNotEmpty()) {
showRationaleDialogForSettings(rationaleList)
}
}
@ -404,7 +404,7 @@ class CallActivity : CallBaseActivity() {
binding!!.lowerHandButton.visibility = View.GONE
raised = false
}
if (isConnectionEstablished && peerConnectionWrapperList != null) {
if (isConnectionEstablished) {
for (peerConnectionWrapper in peerConnectionWrapperList) {
peerConnectionWrapper.raiseHand(raised)
}
@ -436,12 +436,12 @@ class CallActivity : CallBaseActivity() {
val dialogBuilder = MaterialAlertDialogBuilder(this)
.setTitle(R.string.record_stop_confirm_title)
.setMessage(R.string.record_stop_confirm_message)
.setPositiveButton(
R.string.record_stop_description
) { dialog: DialogInterface?, which: Int -> callRecordingViewModel!!.stopRecording() }
.setNegativeButton(
R.string.nc_common_dismiss
) { dialog: DialogInterface?, which: Int -> callRecordingViewModel!!.dismissStopRecording() }
.setPositiveButton(R.string.record_stop_description) { _: DialogInterface?, _: Int ->
callRecordingViewModel!!.stopRecording()
}
.setNegativeButton(R.string.nc_common_dismiss) { _: DialogInterface?, _: Int ->
callRecordingViewModel!!.dismissStopRecording()
}
viewThemeUtils.dialog.colorMaterialAlertDialogBackground(this, dialogBuilder)
val dialog = dialogBuilder.show()
viewThemeUtils.platform.colorTextButtons(
@ -483,7 +483,7 @@ class CallActivity : CallBaseActivity() {
fun sendReaction(emoji: String?) {
addReactionForAnimation(emoji, conversationUser!!.displayName)
if (isConnectionEstablished && peerConnectionWrapperList != null) {
if (isConnectionEstablished) {
for (peerConnectionWrapper in peerConnectionWrapperList) {
peerConnectionWrapper.sendReaction(emoji)
}
@ -521,18 +521,21 @@ class CallActivity : CallBaseActivity() {
}
private fun initClickListeners() {
binding!!.pictureInPictureButton.setOnClickListener { l: View? -> enterPipMode() }
binding!!.audioOutputButton.setOnClickListener { v: View? ->
binding!!.pictureInPictureButton.setOnClickListener { enterPipMode() }
binding!!.audioOutputButton.setOnClickListener {
audioOutputDialog = AudioOutputDialog(this)
audioOutputDialog!!.show()
}
binding!!.moreCallActions.setOnClickListener { v: View? ->
binding!!.moreCallActions.setOnClickListener {
moreCallActionsDialog = MoreCallActionsDialog(this)
moreCallActionsDialog!!.show()
}
if (canPublishAudioStream) {
binding!!.microphoneButton.setOnClickListener { l: View? -> onMicrophoneClick() }
binding!!.microphoneButton.setOnLongClickListener { l: View? ->
binding!!.microphoneButton.setOnClickListener { onMicrophoneClick() }
binding!!.microphoneButton.setOnLongClickListener {
if (!microphoneOn) {
callControlHandler.removeCallbacksAndMessages(null)
callInfosHandler.removeCallbacksAndMessages(null)
@ -547,7 +550,7 @@ class CallActivity : CallBaseActivity() {
true
}
} else {
binding!!.microphoneButton.setOnClickListener { l: View? ->
binding!!.microphoneButton.setOnClickListener {
Toast.makeText(
context,
R.string.nc_not_allowed_to_activate_audio,
@ -555,10 +558,11 @@ class CallActivity : CallBaseActivity() {
).show()
}
}
if (canPublishVideoStream) {
binding!!.cameraButton.setOnClickListener { l: View? -> onCameraClick() }
binding!!.cameraButton.setOnClickListener { onCameraClick() }
} else {
binding!!.cameraButton.setOnClickListener { l: View? ->
binding!!.cameraButton.setOnClickListener {
Toast.makeText(
context,
R.string.nc_not_allowed_to_activate_video,
@ -566,22 +570,22 @@ class CallActivity : CallBaseActivity() {
).show()
}
}
binding!!.hangupButton.setOnClickListener { l: View? -> hangup(true) }
binding!!.switchSelfVideoButton.setOnClickListener { l: View? -> switchCamera() }
binding!!.hangupButton.setOnClickListener { hangup(true) }
binding!!.switchSelfVideoButton.setOnClickListener { switchCamera() }
binding!!.gridview.onItemClickListener =
AdapterView.OnItemClickListener { parent: AdapterView<*>?, view: View?, position: Int, id: Long ->
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, _: Int, _: Long ->
animateCallControls(
true,
0
)
}
binding!!.callStates.callStateRelativeLayout.setOnClickListener { l: View? ->
binding!!.callStates.callStateRelativeLayout.setOnClickListener {
if (currentCallStatus === CallStatus.CALLING_TIMEOUT) {
setCallState(CallStatus.RECONNECTING)
hangupNetworkCalls(false)
}
}
binding!!.callRecordingIndicator.setOnClickListener { l: View? ->
binding!!.callRecordingIndicator.setOnClickListener {
if (isAllowedToStartOrStopRecording) {
if (callRecordingViewModel!!.viewState.value is RecordingStartingState) {
if (moreCallActionsDialog == null) {
@ -644,14 +648,12 @@ class CallActivity : CallBaseActivity() {
// Store existing audio settings and change audio mode to
// MODE_IN_COMMUNICATION for best possible VoIP performance.
Log.d(TAG, "Starting the audio manager...")
audioManager!!.start(
AudioManagerListener { currentDevice: AudioDevice, availableDevices: Set<AudioDevice> ->
onAudioManagerDevicesChanged(
currentDevice,
availableDevices
)
}
)
audioManager!!.start { currentDevice: AudioDevice, availableDevices: Set<AudioDevice> ->
onAudioManagerDevicesChanged(
currentDevice,
availableDevices
)
}
if (isVoiceOnlyCall) {
setAudioOutputChannel(AudioDevice.EARPIECE)
} else {
@ -776,14 +778,14 @@ class CallActivity : CallBaseActivity() {
}
initSelfVideoView()
}
binding!!.gridview.setOnTouchListener { v, me ->
binding!!.gridview.setOnTouchListener { _, me ->
val action = me.actionMasked
if (action == MotionEvent.ACTION_DOWN) {
animateCallControls(true, 0)
}
false
}
binding!!.conversationRelativeLayout.setOnTouchListener { v, me ->
binding!!.conversationRelativeLayout.setOnTouchListener { _, me ->
val action = me.actionMasked
if (action == MotionEvent.ACTION_DOWN) {
animateCallControls(true, 0)
@ -881,7 +883,7 @@ class CallActivity : CallBaseActivity() {
if (!videoOn) {
onCameraClick()
}
if (cameraEnumerator!!.deviceNames.size == 0) {
if (cameraEnumerator!!.deviceNames.isEmpty()) {
binding!!.cameraButton.visibility = View.GONE
}
if (cameraEnumerator!!.deviceNames.size > 1) {
@ -904,8 +906,8 @@ class CallActivity : CallBaseActivity() {
permissionsToRequest.add(Manifest.permission.BLUETOOTH_CONNECT)
}
}
if (!permissionsToRequest.isEmpty()) {
if (!rationaleList.isEmpty()) {
if (permissionsToRequest.isNotEmpty()) {
if (rationaleList.isNotEmpty()) {
showRationaleDialog(permissionsToRequest, rationaleList)
} else {
requestPermissionLauncher.launch(permissionsToRequest.toTypedArray())
@ -932,12 +934,8 @@ class CallActivity : CallBaseActivity() {
val dialogBuilder = MaterialAlertDialogBuilder(this)
.setTitle(R.string.nc_permissions_rationale_dialog_title)
.setMessage(rationalesWithLineBreaks)
.setPositiveButton(
R.string.nc_permissions_ask
) { dialog: DialogInterface?, which: Int ->
requestPermissionLauncher.launch(
permissionsToRequest.toTypedArray()
)
.setPositiveButton(R.string.nc_permissions_ask) { _, _ ->
requestPermissionLauncher.launch(permissionsToRequest.toTypedArray())
}
.setNegativeButton(R.string.nc_common_dismiss, null)
viewThemeUtils.dialog.colorMaterialAlertDialogBackground(this, dialogBuilder)
@ -956,7 +954,7 @@ class CallActivity : CallBaseActivity() {
val dialogBuilder = MaterialAlertDialogBuilder(this)
.setTitle(R.string.nc_permissions_rationale_dialog_title)
.setMessage(rationalesWithLineBreaks)
.setPositiveButton(R.string.nc_permissions_settings) { dialog: DialogInterface?, which: Int ->
.setPositiveButton(R.string.nc_permissions_settings) { _, _ ->
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
intent.data = Uri.fromParts("package", packageName, null)
startActivity(intent)
@ -973,11 +971,7 @@ class CallActivity : CallBaseActivity() {
currentDevice: AudioDevice,
availableDevices: Set<AudioDevice>
) {
Log.d(
TAG,
"onAudioManagerDevicesChanged: " + availableDevices + ", " +
"currentDevice: " + currentDevice
)
Log.d(TAG, "onAudioManagerDevicesChanged: $availableDevices, currentDevice: $currentDevice")
val shouldDisableProximityLock =
currentDevice == AudioDevice.WIRED_HEADSET ||
currentDevice == AudioDevice.SPEAKER_PHONE ||
@ -1065,26 +1059,7 @@ class CallActivity : CallBaseActivity() {
}
if (permissionUtil!!.isMicrophonePermissionGranted()) {
if (!appPreferences.pushToTalkIntroShown) {
val primary = viewThemeUtils.getScheme(binding!!.audioOutputButton.context).primary
spotlightView = SpotlightView.Builder(this)
.introAnimationDuration(300)
.enableRevealAnimation(true)
.performClick(false)
.fadeinTextDuration(400)
.headingTvColor(primary)
.headingTvSize(20)
.headingTvText(resources.getString(R.string.nc_push_to_talk))
.subHeadingTvColor(resources.getColor(R.color.bg_default, null))
.subHeadingTvSize(16)
.subHeadingTvText(resources.getString(R.string.nc_push_to_talk_desc))
.maskColor(Color.parseColor("#dc000000"))
.target(binding!!.microphoneButton)
.lineAnimDuration(400)
.lineAndArcColor(primary)
.enableDismissAfterShown(true)
.dismissOnBackPress(true)
.usageId("pushToTalk")
.show()
spotlightView = getSpotlightView()
appPreferences.pushToTalkIntroShown = true
}
if (!isPushToTalkActive) {
@ -1120,7 +1095,30 @@ class CallActivity : CallBaseActivity() {
}
}
fun onCameraClick() {
private fun getSpotlightView(): SpotlightView? {
val primary = viewThemeUtils.getScheme(binding!!.audioOutputButton.context).primary
return SpotlightView.Builder(this)
.introAnimationDuration(300)
.enableRevealAnimation(true)
.performClick(false)
.fadeinTextDuration(400)
.headingTvColor(primary)
.headingTvSize(20)
.headingTvText(resources.getString(R.string.nc_push_to_talk))
.subHeadingTvColor(resources.getColor(R.color.bg_default, null))
.subHeadingTvSize(16)
.subHeadingTvText(resources.getString(R.string.nc_push_to_talk_desc))
.maskColor(Color.parseColor("#dc000000"))
.target(binding!!.microphoneButton)
.lineAnimDuration(400)
.lineAndArcColor(primary)
.enableDismissAfterShown(true)
.dismissOnBackPress(true)
.usageId("pushToTalk")
.show()
}
private fun onCameraClick() {
if (!canPublishVideoStream) {
videoOn = false
binding!!.cameraButton.setImageResource(R.drawable.ic_videocam_off_white_24px)
@ -1156,7 +1154,9 @@ class CallActivity : CallBaseActivity() {
binding!!.selfVideoRenderer.setMirror(currentCameraIsFront)
}
override fun onCameraSwitchError(s: String) {}
override fun onCameraSwitchError(s: String) {
Log.e(TAG, "Error while switching camera: $s")
}
})
}
@ -1198,7 +1198,7 @@ class CallActivity : CallBaseActivity() {
localStream!!.audioTracks[0].setEnabled(enable)
}
}
if (isConnectionEstablished && peerConnectionWrapperList != null) {
if (isConnectionEstablished) {
if (!hasMCU) {
for (peerConnectionWrapper in peerConnectionWrapperList) {
peerConnectionWrapper.sendChannelData(DataChannelMessage(message))
@ -1348,12 +1348,8 @@ class CallActivity : CallBaseActivity() {
signalingSettingsOverall.ocs!!.settings != null
) {
externalSignalingServer = ExternalSignalingServer()
if (!TextUtils.isEmpty(
signalingSettingsOverall.ocs!!.settings!!.externalSignalingServer
) &&
!TextUtils.isEmpty(
signalingSettingsOverall.ocs!!.settings!!.externalSignalingTicket
)
if (!TextUtils.isEmpty(signalingSettingsOverall.ocs!!.settings!!.externalSignalingServer) &&
!TextUtils.isEmpty(signalingSettingsOverall.ocs!!.settings!!.externalSignalingTicket)
) {
externalSignalingServer = ExternalSignalingServer()
externalSignalingServer!!.externalSignalingServer =
@ -1365,6 +1361,7 @@ class CallActivity : CallBaseActivity() {
hasExternalSignalingServer = false
}
Log.d(TAG, " hasExternalSignalingServer: $hasExternalSignalingServer")
if ("?" != conversationUser!!.userId && conversationUser!!.id != null) {
Log.d(
TAG,
@ -1380,43 +1377,8 @@ class CallActivity : CallBaseActivity() {
} else {
conversationUser!!.externalSignalingServer = externalSignalingServer
}
if (signalingSettingsOverall.ocs!!.settings!!.stunServers != null) {
val stunServers = signalingSettingsOverall.ocs!!.settings!!.stunServers
if (apiVersion == ApiUtils.APIv3) {
for ((_, urls) in stunServers!!) {
if (urls != null) {
for (url in urls) {
Log.d(TAG, " STUN server url: $url")
iceServers!!.add(PeerConnection.IceServer(url))
}
}
}
} else {
if (signalingSettingsOverall.ocs!!.settings!!.stunServers != null) {
for ((url) in stunServers!!) {
Log.d(TAG, " STUN server url: $url")
iceServers!!.add(PeerConnection.IceServer(url))
}
}
}
}
if (signalingSettingsOverall.ocs!!.settings!!.turnServers != null) {
val turnServers = signalingSettingsOverall.ocs!!.settings!!.turnServers
for ((_, urls, username, credential) in turnServers!!) {
if (urls != null) {
for (url in urls) {
Log.d(TAG, " TURN server url: $url")
iceServers!!.add(
PeerConnection.IceServer(
url,
username,
credential
)
)
}
}
}
}
addIceServers(signalingSettingsOverall, apiVersion)
}
checkCapabilities()
}
@ -1431,6 +1393,44 @@ class CallActivity : CallBaseActivity() {
})
}
private fun addIceServers(
signalingSettingsOverall: SignalingSettingsOverall,
apiVersion: Int
) {
if (signalingSettingsOverall.ocs!!.settings!!.stunServers != null) {
val stunServers = signalingSettingsOverall.ocs!!.settings!!.stunServers
if (apiVersion == ApiUtils.APIv3) {
for ((_, urls) in stunServers!!) {
if (urls != null) {
for (url in urls) {
Log.d(TAG, " STUN server url: $url")
iceServers!!.add(PeerConnection.IceServer(url))
}
}
}
} else {
if (signalingSettingsOverall.ocs!!.settings!!.stunServers != null) {
for ((url) in stunServers!!) {
Log.d(TAG, " STUN server url: $url")
iceServers!!.add(PeerConnection.IceServer(url))
}
}
}
}
if (signalingSettingsOverall.ocs!!.settings!!.turnServers != null) {
val turnServers = signalingSettingsOverall.ocs!!.settings!!.turnServers
for ((_, urls, username, credential) in turnServers!!) {
if (urls != null) {
for (url in urls) {
Log.d(TAG, " TURN server url: $url")
iceServers!!.add(PeerConnection.IceServer(url, username, credential))
}
}
}
}
}
private fun checkCapabilities() {
ncApi!!.getCapabilities(credentials, ApiUtils.getUrlForCapabilities(baseUrl))
.retry(3)
@ -1527,6 +1527,7 @@ class CallActivity : CallBaseActivity() {
}
callParticipantList = CallParticipantList(signalingMessageReceiver)
callParticipantList!!.addObserver(callParticipantListObserver)
val apiVersion = ApiUtils.getCallApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1))
ncApi!!.joinCall(
credentials,
@ -1557,55 +1558,7 @@ class CallActivity : CallBaseActivity() {
)
}
if (!hasExternalSignalingServer) {
val signalingApiVersion =
ApiUtils.getSignalingApiVersion(conversationUser, intArrayOf(ApiUtils.APIv3, 2, 1))
val delayOnError = AtomicInteger(0)
ncApi!!.pullSignalingMessages(
credentials,
ApiUtils.getUrlForSignaling(
signalingApiVersion,
baseUrl,
roomToken
)
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.repeatWhen { observable: Observable<Any?>? -> observable }
.takeWhile { isConnectionEstablished }
.doOnNext { delayOnError.set(0) }
.retryWhen { errors: Observable<Throwable?> ->
errors
.flatMap { error: Throwable? ->
if (!isConnectionEstablished) {
return@flatMap Observable.error<Long>(error)
}
if (delayOnError.get() == 0) {
delayOnError.set(1)
} else if (delayOnError.get() < 16) {
delayOnError.set(delayOnError.get() * 2)
}
Observable.timer(delayOnError.get().toLong(), TimeUnit.SECONDS)
}
}
.subscribe(object : Observer<SignalingOverall> {
override fun onSubscribe(d: Disposable) {
signalingDisposable = d
}
override fun onNext(
signalingOverall: SignalingOverall
) {
receivedSignalingMessages(signalingOverall.ocs!!.signalings)
}
override fun onError(e: Throwable) {
dispose(signalingDisposable)
}
override fun onComplete() {
dispose(signalingDisposable)
}
})
pullSignalingMessages()
}
}
}
@ -1620,6 +1573,55 @@ class CallActivity : CallBaseActivity() {
})
}
private fun pullSignalingMessages() {
val signalingApiVersion = ApiUtils.getSignalingApiVersion(conversationUser, intArrayOf(ApiUtils.APIv3, 2, 1))
val delayOnError = AtomicInteger(0)
ncApi!!.pullSignalingMessages(
credentials,
ApiUtils.getUrlForSignaling(
signalingApiVersion,
baseUrl,
roomToken
)
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.repeatWhen { observable: Observable<Any?>? -> observable }
.takeWhile { isConnectionEstablished }
.doOnNext { delayOnError.set(0) }
.retryWhen { errors: Observable<Throwable?> ->
errors.flatMap { error: Throwable? ->
if (!isConnectionEstablished) {
return@flatMap Observable.error<Long>(error)
}
if (delayOnError.get() == 0) {
delayOnError.set(1)
} else if (delayOnError.get() < 16) {
delayOnError.set(delayOnError.get() * 2)
}
Observable.timer(delayOnError.get().toLong(), TimeUnit.SECONDS)
}
}
.subscribe(object : Observer<SignalingOverall> {
override fun onSubscribe(d: Disposable) {
signalingDisposable = d
}
override fun onNext(signalingOverall: SignalingOverall) {
receivedSignalingMessages(signalingOverall.ocs!!.signalings)
}
override fun onError(e: Throwable) {
dispose(signalingDisposable)
}
override fun onComplete() {
dispose(signalingDisposable)
}
})
}
private fun setupAndInitiateWebSocketsConnection() {
if (webSocketConnectionHelper == null) {
webSocketConnectionHelper = WebSocketConnectionHelper()
@ -1722,16 +1724,21 @@ class CallActivity : CallBaseActivity() {
if (!isConnectionEstablished && currentCallStatus !== CallStatus.CONNECTING) {
return
}
if ("usersInRoom" == messageType) {
internalSignalingMessageReceiver.process(signaling.messageWrapper as List<Map<String?, Any?>?>?)
} else if ("message" == messageType) {
val ncSignalingMessage = LoganSquare.parse(
signaling.messageWrapper.toString(),
NCSignalingMessage::class.java
)
internalSignalingMessageReceiver.process(ncSignalingMessage)
} else {
Log.e(TAG, "unexpected message type when receiving signaling message")
when (messageType) {
"usersInRoom" ->
internalSignalingMessageReceiver.process(signaling.messageWrapper as List<Map<String?, Any?>?>?)
"message" -> {
val ncSignalingMessage = LoganSquare.parse(
signaling.messageWrapper.toString(),
NCSignalingMessage::class.java
)
internalSignalingMessageReceiver.process(ncSignalingMessage)
}
else ->
Log.e(TAG, "unexpected message type when receiving signaling message")
}
}
@ -1742,6 +1749,7 @@ class CallActivity : CallBaseActivity() {
}
stopCallingSound()
dispose(null)
if (shutDownView) {
if (videoCapturer != null) {
try {
@ -1775,25 +1783,27 @@ class CallActivity : CallBaseActivity() {
WebSocketConnectionHelper.deleteExternalSignalingInstanceForUserEntity(-1)
}
}
val peerConnectionIdsToEnd: MutableList<String> = ArrayList(
peerConnectionWrapperList!!.size
)
val peerConnectionIdsToEnd: MutableList<String> = ArrayList(peerConnectionWrapperList.size)
for (wrapper in peerConnectionWrapperList) {
peerConnectionIdsToEnd.add(wrapper.sessionId)
}
for (sessionId in peerConnectionIdsToEnd) {
endPeerConnection(sessionId, "video")
endPeerConnection(sessionId, "screen")
}
val callParticipantIdsToEnd: MutableList<String> = ArrayList(
peerConnectionWrapperList.size
)
val callParticipantIdsToEnd: MutableList<String> = ArrayList(peerConnectionWrapperList.size)
for (callParticipant in callParticipants.values) {
callParticipantIdsToEnd.add(callParticipant!!.callParticipantModel.sessionId)
}
for (sessionId in callParticipantIdsToEnd) {
removeCallParticipant(sessionId)
}
ApplicationWideCurrentRoomHolder.getInstance().isInCall = false
ApplicationWideCurrentRoomHolder.getInstance().isDialing = false
hangupNetworkCalls(shutDownView)
@ -1851,6 +1861,7 @@ class CallActivity : CallBaseActivity() {
}
}
@Suppress("Detekt.ComplexMethod")
private fun handleCallParticipantsChanged(
joined: Collection<Participant>,
updated: Collection<Participant>,
@ -1867,12 +1878,15 @@ class CallActivity : CallBaseActivity() {
currentSessionId = webSocketClient!!.sessionId
}
Log.d(TAG, " currentSessionId is $currentSessionId")
val participantsInCall: MutableList<Participant> = ArrayList()
participantsInCall.addAll(joined)
participantsInCall.addAll(updated)
participantsInCall.addAll(unchanged)
var isSelfInCall = false
var selfParticipant: Participant? = null
for (participant in participantsInCall) {
val inCallFlag = participant.inCall
if (participant.sessionId != currentSessionId) {
@ -1889,6 +1903,7 @@ class CallActivity : CallBaseActivity() {
selfParticipant = participant
}
}
if (!isSelfInCall &&
currentCallStatus !== CallStatus.LEAVING &&
ApplicationWideCurrentRoomHolder.getInstance().isInCall
@ -1897,6 +1912,7 @@ class CallActivity : CallBaseActivity() {
hangup(true)
return
}
if (!isSelfInCall) {
Log.d(TAG, "Self not in call, disconnecting from all other sessions")
for ((_, _, _, _, _, _, _, _, _, _, sessionId) in participantsInCall) {
@ -1932,19 +1948,22 @@ class CallActivity : CallBaseActivity() {
}
Log.d(TAG, " newSession joined: $sessionId")
addCallParticipant(sessionId)
val userId = participant.userId
if (userId != null) {
callParticipants[sessionId]!!.setUserId(userId)
}
if (participant.internal != null) {
callParticipants[sessionId]!!.setInternal(participant.internal)
}
var nick: String?
nick = if (hasExternalSignalingServer) {
val nick: String? = if (hasExternalSignalingServer) {
webSocketClient!!.getDisplayNameForSession(sessionId)
} else {
if (offerAnswerNickProviders[sessionId] != null) offerAnswerNickProviders[sessionId]?.nick else ""
}
callParticipants[sessionId]!!.setNick(nick)
val participantHasAudioOrVideo = participantInCallFlagsHaveAudioOrVideo(participant)
@ -1952,16 +1971,14 @@ class CallActivity : CallBaseActivity() {
// remote session ID. However, if the other participant does not have audio nor video that participant
// will not send an offer, so no connection is actually established when the remote participant has a
// higher session ID but is not publishing media.
if (hasMCU && participantHasAudioOrVideo || !hasMCU && selfParticipantHasAudioOrVideo && (
!participantHasAudioOrVideo || sessionId.compareTo(
currentSessionId!!
) < 0
)
if (hasMCU && participantHasAudioOrVideo ||
!hasMCU && selfParticipantHasAudioOrVideo &&
(!participantHasAudioOrVideo || sessionId < currentSessionId!!)
) {
getOrCreatePeerConnectionWrapperForSessionIdAndType(sessionId, VIDEO_STREAM_TYPE_VIDEO, false)
}
}
val othersInCall = if (selfJoined) joined.size > 1 else joined.size > 0
val othersInCall = if (selfJoined) joined.size > 1 else joined.isNotEmpty()
if (othersInCall && currentCallStatus !== CallStatus.IN_CONVERSATION) {
setCallState(CallStatus.IN_CONVERSATION)
}
@ -1984,7 +2001,7 @@ class CallActivity : CallBaseActivity() {
}
private fun getPeerConnectionWrapperForSessionIdAndType(sessionId: String?, type: String): PeerConnectionWrapper? {
for (wrapper in peerConnectionWrapperList!!) {
for (wrapper in peerConnectionWrapperList) {
if (wrapper.sessionId == sessionId && wrapper.videoStreamType == type) {
return wrapper
}
@ -2072,7 +2089,7 @@ class CallActivity : CallBaseActivity() {
)
}
}
peerConnectionWrapperList!!.add(peerConnectionWrapper)
peerConnectionWrapperList.add(peerConnectionWrapper)
if (!publisher) {
var callParticipant = callParticipants[sessionId]
if (callParticipant == null) {
@ -2144,7 +2161,7 @@ class CallActivity : CallBaseActivity() {
}
}
peerConnectionWrapper.removePeerConnection()
peerConnectionWrapperList!!.remove(peerConnectionWrapper)
peerConnectionWrapperList.remove(peerConnectionWrapper)
}
private fun removeCallParticipant(sessionId: String?) {
@ -2202,8 +2219,7 @@ class CallActivity : CallBaseActivity() {
val screenWidthPx = displayMetrics.widthPixels
val screenWidthDp = DisplayUtils.convertPixelToDp(screenWidthPx.toFloat(), applicationContext).toInt()
var newXafterRotate = 0f
val newYafterRotate: Float
newYafterRotate = if (binding!!.callInfosLinearLayout.visibility == View.VISIBLE) {
val newYafterRotate: Float = if (binding!!.callInfosLinearLayout.visibility == View.VISIBLE) {
250f
} else {
20f
@ -2247,7 +2263,7 @@ class CallActivity : CallBaseActivity() {
nickChangedPayload["userid"] = conversationUser!!.userId!!
nickChangedPayload["name"] = conversationUser!!.displayName!!
dataChannelMessage.payloadMap = nickChangedPayload.toMap()
for (peerConnectionWrapper in peerConnectionWrapperList!!) {
for (peerConnectionWrapper in peerConnectionWrapperList) {
if (peerConnectionWrapper.isMCUPublisher) {
Observable
.interval(1, TimeUnit.SECONDS)
@ -2455,14 +2471,12 @@ class CallActivity : CallBaseActivity() {
binding!!.callStates.errorImageView.visibility = View.GONE
}
}
else -> {}
}
}
}
private val descriptionForCallType: String
private get() {
get() {
val appName = resources.getString(R.string.nc_app_product_name)
return if (isVoiceOnlyCall) {
String.format(resources.getString(R.string.nc_call_voice), appName)
@ -2473,14 +2487,10 @@ class CallActivity : CallBaseActivity() {
private fun playCallingSound() {
stopCallingSound()
val ringtoneUri: Uri?
ringtoneUri = if (isIncomingCallFromNotification) {
val ringtoneUri: Uri? = if (isIncomingCallFromNotification) {
getCallRingtoneUri(applicationContext, appPreferences)
} else {
Uri.parse(
"android.resource://" + applicationContext.packageName + "/raw" +
"/tr110_1_kap8_3_freiton1"
)
Uri.parse("android.resource://" + applicationContext.packageName + "/raw/tr110_1_kap8_3_freiton1")
}
if (ringtoneUri != null) {
mediaPlayer = MediaPlayer()
@ -2554,8 +2564,13 @@ class CallActivity : CallBaseActivity() {
onOfferOrAnswer(nick)
}
override fun onCandidate(sdpMid: String, sdpMLineIndex: Int, sdp: String) {}
override fun onEndOfCandidates() {}
override fun onCandidate(sdpMid: String, sdpMLineIndex: Int, sdp: String) {
// unused atm
}
override fun onEndOfCandidates() {
// unused atm
}
}
private fun onOfferOrAnswer(nick: String) {
@ -2568,16 +2583,28 @@ class CallActivity : CallBaseActivity() {
private inner class CallActivityCallParticipantMessageListener(private val sessionId: String?) :
CallParticipantMessageListener {
override fun onRaiseHand(state: Boolean, timestamp: Long) {}
override fun onReaction(reaction: String) {}
override fun onRaiseHand(state: Boolean, timestamp: Long) {
// unused atm
}
override fun onReaction(reaction: String) {
// unused atm
}
override fun onUnshareScreen() {
endPeerConnection(sessionId, "screen")
}
}
private inner class CallActivitySelfPeerConnectionObserver : PeerConnectionObserver {
override fun onStreamAdded(mediaStream: MediaStream) {}
override fun onStreamRemoved(mediaStream: MediaStream) {}
override fun onStreamAdded(mediaStream: MediaStream) {
// unused atm
}
override fun onStreamRemoved(mediaStream: MediaStream) {
// unused atm
}
override fun onIceConnectionStateChanged(iceConnectionState: IceConnectionState) {
runOnUiThread {
updateSelfVideoViewIceConnectionState(iceConnectionState)
@ -2604,7 +2631,9 @@ class CallActivity : CallBaseActivity() {
}
}
override fun onReaction(reaction: String) {}
override fun onReaction(reaction: String) {
// unused atm
}
}
private inner class CallParticipantEventDisplayer(private val callParticipantModel: CallParticipantModel) :
@ -2640,8 +2669,7 @@ class CallActivity : CallBaseActivity() {
private inner class InternalSignalingMessageSender : SignalingMessageSender {
override fun send(ncSignalingMessage: NCSignalingMessage) {
addLocalParticipantNickIfNeeded(ncSignalingMessage)
val serializedNcSignalingMessage: String
serializedNcSignalingMessage = try {
val serializedNcSignalingMessage: String = try {
LoganSquare.serialize(ncSignalingMessage)
} catch (e: IOException) {
Log.e(TAG, "Failed to serialize signaling message", e)
@ -2686,7 +2714,9 @@ class CallActivity : CallBaseActivity() {
Log.e(TAG, "", e)
}
override fun onComplete() {}
override fun onComplete() {
// unused atm
}
})
}
@ -2772,7 +2802,7 @@ class CallActivity : CallBaseActivity() {
}
}
fun updatePictureInPictureActions(
private fun updatePictureInPictureActions(
@DrawableRes iconId: Int,
title: String?,
requestCode: Int
@ -2780,8 +2810,7 @@ class CallActivity : CallBaseActivity() {
if (isGreaterEqualOreo && isPipModePossible) {
val actions = ArrayList<RemoteAction>()
val icon = Icon.createWithResource(this, iconId)
val intentFlag: Int
intentFlag = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
val intentFlag: Int = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
PendingIntent.FLAG_IMMUTABLE
} else {
0
@ -2869,7 +2898,8 @@ class CallActivity : CallBaseActivity() {
companion object {
var active = false
const val VIDEO_STREAM_TYPE_SCREEN = "screen"
// const val VIDEO_STREAM_TYPE_SCREEN = "screen"
const val VIDEO_STREAM_TYPE_VIDEO = "video"
const val TAG = "CallActivity"
private val PERMISSIONS_CAMERA = arrayOf(