mirror of
https://github.com/nextcloud/talk-android
synced 2025-06-19 11:39:42 +01:00
convert CallActivity to kotlin
Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
parent
b5529f869a
commit
a941945400
@ -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(
|
||||
|
Loading…
Reference in New Issue
Block a user