Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for all parameter in leave call endpoint #4386

Merged
merged 24 commits into from
Nov 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
52fd3f9
Add support for all parameter in leave call endpoint
sowjanyakch Oct 25, 2024
ed9fc18
implement long click and short click on hangup button
sowjanyakch Oct 25, 2024
ca0533a
add button for end call for everyone
sowjanyakch Oct 25, 2024
9537a8d
add bundle keys for one-one conversation
sowjanyakch Oct 25, 2024
6e2fdcb
git bundle keys for group conversation
sowjanyakch Oct 25, 2024
3a6a1ed
add short press and long press options to group conversation
sowjanyakch Oct 25, 2024
3d536c2
add short press and long press options to 1:1 conversation
sowjanyakch Oct 25, 2024
bf3ed0e
handle end call button
sowjanyakch Oct 25, 2024
be9bda7
ktlintFormat
sowjanyakch Oct 25, 2024
d523f12
ktlintFormat
sowjanyakch Oct 25, 2024
a25f83c
modify string
sowjanyakch Oct 25, 2024
dff2284
implement material button
sowjanyakch Oct 29, 2024
e5789c0
set bundle keys in CallNotificationActivity
sowjanyakch Oct 29, 2024
de63787
ktlintFormat
sowjanyakch Oct 29, 2024
cfe83dd
remove isGroupConversation variable
sowjanyakch Oct 29, 2024
d09b7b5
remove isGroupConversation variable
sowjanyakch Oct 29, 2024
90628c3
set "all" parameter to false and set to null only before API call
sowjanyakch Nov 8, 2024
0920029
show popup for leaving call in 1:1
sowjanyakch Nov 8, 2024
eda9b94
use touch listeners for hiding popup button
sowjanyakch Nov 8, 2024
121e77b
use white background for popup button and formatting
sowjanyakch Nov 8, 2024
4705d1f
use proper names for popup menu
sowjanyakch Nov 8, 2024
37c3f35
suppress warning string format invalid
sowjanyakch Nov 8, 2024
79a8c16
rename variables and methods
mahibi Nov 12, 2024
49c9b3c
remove to set KEY_ROOM_ONE_TO_ONE twice
mahibi Nov 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 84 additions & 27 deletions app/src/main/java/com/nextcloud/talk/activities/CallActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_PARTICIPANT_PERMISSION_CAN
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_PARTICIPANT_PERMISSION_CAN_PUBLISH_VIDEO
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_RECORDING_STATE
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_ID
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_ONE_TO_ONE
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_START_CALL_AFTER_ROOM_SWITCH
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_SWITCH_TO_ROOM
Expand Down Expand Up @@ -263,15 +264,15 @@ class CallActivity : CallBaseActivity() {

override fun onCallEndedForAll() {
Log.d(TAG, "A moderator ended the call for all.")
hangup(true)
hangup(true, false)
}
}
private var callParticipantList: CallParticipantList? = null
private var switchToRoomToken = ""
private var isBreakoutRoom = false
private val localParticipantMessageListener = LocalParticipantMessageListener { token ->
switchToRoomToken = token
hangup(true)
hangup(true, false)
}
private val offerMessageListener = OfferMessageListener { sessionId, roomType, sdp, nick ->
getOrCreatePeerConnectionWrapperForSessionIdAndType(
Expand Down Expand Up @@ -350,6 +351,7 @@ class CallActivity : CallBaseActivity() {
private var isModerator = false
private var reactionAnimator: ReactionAnimator? = null
private var othersInCall = false
private var isOneToOneConversation = false

private lateinit var micInputAudioRecorder: AudioRecord
private var micInputAudioRecordThread: Thread? = null
Expand Down Expand Up @@ -381,6 +383,8 @@ class CallActivity : CallBaseActivity() {
canPublishAudioStream = extras.getBoolean(KEY_PARTICIPANT_PERMISSION_CAN_PUBLISH_AUDIO)
canPublishVideoStream = extras.getBoolean(KEY_PARTICIPANT_PERMISSION_CAN_PUBLISH_VIDEO)
isModerator = extras.getBoolean(KEY_IS_MODERATOR, false)
isOneToOneConversation = extras.getBoolean(KEY_ROOM_ONE_TO_ONE, false)

if (extras.containsKey(KEY_FROM_NOTIFICATION_START_CALL)) {
isIncomingCallFromNotification = extras.getBoolean(KEY_FROM_NOTIFICATION_START_CALL)
}
Expand Down Expand Up @@ -470,7 +474,7 @@ class CallActivity : CallBaseActivity() {
binding!!.callRecordingIndicator.visibility = View.GONE
}
}
initClickListeners()
initClickListeners(isModerator, isOneToOneConversation)
binding!!.microphoneButton.setOnTouchListener(MicrophoneButtonTouchListener())
pulseAnimation = PulseAnimation.create().with(binding!!.microphoneButton)
.setDuration(310)
Expand Down Expand Up @@ -498,7 +502,7 @@ class CallActivity : CallBaseActivity() {
}
.setNegativeButton(R.string.nc_no) { _, _ ->
recordingConsentGiven = false
hangup(true)
hangup(true, false)
}

viewThemeUtils.dialog.colorMaterialAlertDialogBackground(this, materialAlertDialogBuilder)
Expand Down Expand Up @@ -613,7 +617,8 @@ class CallActivity : CallBaseActivity() {
}
}

private fun initClickListeners() {
@SuppressLint("ClickableViewAccessibility")
private fun initClickListeners(isModerator: Boolean, isOneToOneConversation: Boolean) {
binding!!.pictureInPictureButton.setOnClickListener { enterPipMode() }

binding!!.audioOutputButton.setOnClickListener {
Expand Down Expand Up @@ -663,7 +668,39 @@ class CallActivity : CallBaseActivity() {
).show()
}
}
binding!!.hangupButton.setOnClickListener { hangup(true) }

if (isOneToOneConversation) {
binding!!.hangupButton.setOnLongClickListener {
showLeaveCallPopupMenu()
true
}
binding!!.hangupButton.setOnClickListener {
hangup(true, true)
}
} else {
if (isModerator) {
binding!!.hangupButton.setOnLongClickListener {
showEndCallForAllPopupMenu()
true
}
}
binding!!.hangupButton.setOnClickListener {
hangup(true, false)
}
}

if (!isOneToOneConversation) {
binding!!.endCallPopupMenu.setOnClickListener {
hangup(true, true)
binding!!.endCallPopupMenu.visibility = View.GONE
}
} else {
binding!!.endCallPopupMenu.setOnClickListener {
hangup(true, false)
binding!!.endCallPopupMenu.visibility = View.GONE
}
}

binding!!.switchSelfVideoButton.setOnClickListener { switchCamera() }
binding!!.gridview.onItemClickListener =
AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, _: Int, _: Long ->
Expand All @@ -675,7 +712,7 @@ class CallActivity : CallBaseActivity() {
binding!!.callStates.callStateRelativeLayout.setOnClickListener {
if (currentCallStatus === CallStatus.CALLING_TIMEOUT) {
setCallState(CallStatus.RECONNECTING)
hangupNetworkCalls(false)
hangupNetworkCalls(false, false)
}
}
binding!!.callRecordingIndicator.setOnClickListener {
Expand All @@ -699,6 +736,16 @@ class CallActivity : CallBaseActivity() {
binding!!.lowerHandButton.setOnClickListener { l: View? -> raiseHandViewModel!!.lowerHand() }
}

private fun showEndCallForAllPopupMenu() {
binding!!.endCallPopupMenu.visibility = View.VISIBLE
binding!!.endCallPopupMenu.text = context.getString(R.string.end_call_for_everyone)
}

private fun showLeaveCallPopupMenu() {
binding!!.endCallPopupMenu.visibility = View.VISIBLE
binding!!.endCallPopupMenu.text = context.getString(R.string.leave_call)
}

private fun createCameraEnumerator() {
var camera2EnumeratorIsSupported = false
try {
Expand Down Expand Up @@ -847,13 +894,15 @@ class CallActivity : CallBaseActivity() {
val action = me.actionMasked
if (action == MotionEvent.ACTION_DOWN) {
animateCallControls(true, 0)
binding!!.endCallPopupMenu.visibility = View.GONE
}
false
}
binding!!.conversationRelativeLayout.setOnTouchListener { _, me ->
val action = me.actionMasked
if (action == MotionEvent.ACTION_DOWN) {
animateCallControls(true, 0)
binding!!.endCallPopupMenu.visibility = View.GONE
}
false
}
Expand Down Expand Up @@ -1442,7 +1491,7 @@ class CallActivity : CallBaseActivity() {
Log.d(TAG, "localStream is null")
}
if (currentCallStatus !== CallStatus.LEAVING) {
hangup(true)
hangup(true, false)
}
powerManagerUtils!!.updatePhoneState(PowerManagerUtils.PhoneState.IDLE)
super.onDestroy()
Expand Down Expand Up @@ -1726,7 +1775,7 @@ class CallActivity : CallBaseActivity() {
override fun onError(e: Throwable) {
Log.e(TAG, "Failed to join call", e)
Snackbar.make(binding!!.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show()
hangup(true)
hangup(true, false)
}

override fun onComplete() {
Expand All @@ -1746,7 +1795,8 @@ class CallActivity : CallBaseActivity() {
private fun startCallTimeCounter(callStartTime: Long) {
if (callStartTime != 0L &&
hasSpreedFeatureCapability(
conversationUser!!.capabilities!!.spreedCapability!!, SpreedFeatures.RECORDING_V1
conversationUser!!.capabilities!!.spreedCapability!!,
SpreedFeatures.RECORDING_V1
)
) {
binding!!.callDuration.visibility = View.VISIBLE
Expand Down Expand Up @@ -1877,7 +1927,7 @@ class CallActivity : CallBaseActivity() {
Log.d(TAG, "onMessageEvent 'hello'")
if (!webSocketCommunicationEvent.getHashMap()!!.containsKey("oldResumeId")) {
if (currentCallStatus === CallStatus.RECONNECTING) {
hangup(false)
hangup(false, false)
} else {
setCallState(CallStatus.RECONNECTING)
runOnUiThread { initiateCall() }
Expand Down Expand Up @@ -1953,7 +2003,7 @@ class CallActivity : CallBaseActivity() {
}
}

private fun hangup(shutDownView: Boolean) {
private fun hangup(shutDownView: Boolean, endCallForAll: Boolean) {
Log.d(TAG, "hangup! shutDownView=$shutDownView")
if (shutDownView) {
setCallState(CallStatus.LEAVING)
Expand Down Expand Up @@ -2018,17 +2068,19 @@ class CallActivity : CallBaseActivity() {

ApplicationWideCurrentRoomHolder.getInstance().isInCall = false
ApplicationWideCurrentRoomHolder.getInstance().isDialing = false
hangupNetworkCalls(shutDownView)
hangupNetworkCalls(shutDownView, endCallForAll)
}

private fun hangupNetworkCalls(shutDownView: Boolean) {
private fun hangupNetworkCalls(shutDownView: Boolean, endCallForAll: Boolean) {
Log.d(TAG, "hangupNetworkCalls. shutDownView=$shutDownView")
val apiVersion = ApiUtils.getCallApiVersion(conversationUser, intArrayOf(ApiUtils.API_V4, 1))
if (callParticipantList != null) {
callParticipantList!!.removeObserver(callParticipantListObserver)
callParticipantList!!.destroy()
}
ncApi!!.leaveCall(credentials, ApiUtils.getUrlForCall(apiVersion, baseUrl, roomToken!!))
val endCall: Boolean? = if (endCallForAll) true else null

ncApi!!.leaveCall(credentials, ApiUtils.getUrlForCall(apiVersion, baseUrl, roomToken!!), endCall)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Observer<GenericOverall> {
Expand Down Expand Up @@ -2122,7 +2174,7 @@ class CallActivity : CallBaseActivity() {
ApplicationWideCurrentRoomHolder.getInstance().isInCall
) {
Log.d(TAG, "Most probably a moderator ended the call for all.")
hangup(true)
hangup(true, false)
return
}

Expand Down Expand Up @@ -2188,8 +2240,10 @@ 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 &&
if (hasMCU &&
participantHasAudioOrVideo ||
!hasMCU &&
selfParticipantHasAudioOrVideo &&
(!participantHasAudioOrVideo || sessionId < currentSessionId!!)
) {
getOrCreatePeerConnectionWrapperForSessionIdAndType(sessionId, VIDEO_STREAM_TYPE_VIDEO, false)
Expand All @@ -2212,15 +2266,14 @@ class CallActivity : CallBaseActivity() {
}
}

private fun participantInCallFlagsHaveAudioOrVideo(participant: Participant?): Boolean {
return if (participant == null) {
private fun participantInCallFlagsHaveAudioOrVideo(participant: Participant?): Boolean =
if (participant == null) {
false
} else {
participant.inCall and Participant.InCallFlags.WITH_AUDIO.toLong() > 0 ||
!isVoiceOnlyCall &&
participant.inCall and Participant.InCallFlags.WITH_VIDEO.toLong() > 0
}
}

private fun getPeerConnectionWrapperForSessionIdAndType(sessionId: String?, type: String): PeerConnectionWrapper? {
for (wrapper in peerConnectionWrapperList) {
Expand Down Expand Up @@ -2249,7 +2302,7 @@ class CallActivity : CallBaseActivity() {
context.resources.getString(R.string.nc_common_error_sorry),
Snackbar.LENGTH_LONG
).show()
hangup(true)
hangup(true, false)
return null
}
peerConnectionWrapper = if (hasMCU && publisher) {
Expand Down Expand Up @@ -2468,10 +2521,12 @@ class CallActivity : CallBaseActivity() {
fun onMessageEvent(proximitySensorEvent: ProximitySensorEvent) {
if (!isVoiceOnlyCall) {
val enableVideo = proximitySensorEvent.proximitySensorEventType ==
ProximitySensorEvent.ProximitySensorEventType.SENSOR_FAR && videoOn
ProximitySensorEvent.ProximitySensorEventType.SENSOR_FAR &&
videoOn
if (permissionUtil!!.isCameraPermissionGranted() &&
(currentCallStatus === CallStatus.CONNECTING || isConnectionEstablished) &&
videoOn && enableVideo != localVideoTrack!!.enabled()
videoOn &&
enableVideo != localVideoTrack!!.enabled()
) {
toggleMedia(enableVideo, true)
}
Expand Down Expand Up @@ -2565,7 +2620,7 @@ class CallActivity : CallBaseActivity() {
}

CallStatus.CALLING_TIMEOUT -> handler!!.post {
hangup(false)
hangup(false, false)
binding!!.callStates.callStateTextView.setText(R.string.nc_call_timeout)
binding!!.callModeTextView.text = descriptionForCallType
if (binding!!.callStates.callStateRelativeLayout.visibility != View.VISIBLE) {
Expand Down Expand Up @@ -2835,7 +2890,7 @@ class CallActivity : CallBaseActivity() {
if (iceConnectionState == IceConnectionState.FAILED) {
setCallState(CallStatus.PUBLISHER_FAILED)
webSocketClient!!.clearResumeId()
hangup(false)
hangup(false, false)
}
}
}
Expand Down Expand Up @@ -2868,6 +2923,7 @@ class CallActivity : CallBaseActivity() {
raisedHand = if (callParticipantModel.raisedHand != null) callParticipantModel.raisedHand.state else false
}

@SuppressLint("StringFormatInvalid")
override fun onChange() {
if (callParticipantModel.raisedHand == null || !callParticipantModel.raisedHand.state) {
raisedHand = false
Expand Down Expand Up @@ -3104,7 +3160,8 @@ class CallActivity : CallBaseActivity() {
get() = hasSpreedFeatureCapability(
conversationUser.capabilities!!.spreedCapability!!,
SpreedFeatures.RAISE_HAND
) || isBreakoutRoom
) ||
isBreakoutRoom

private inner class SelfVideoTouchListener : OnTouchListener {
@SuppressLint("ClickableViewAccessibility")
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/java/com/nextcloud/talk/api/NcApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,8 @@ Observable<GenericOverall> joinCall(@Nullable @Header("Authorization") String au
Server URL is: baseUrl + ocsApiVersion + spreedApiVersion + /call/callToken
*/
@DELETE
Observable<GenericOverall> leaveCall(@Nullable @Header("Authorization") String authorization, @Url String url);
Observable<GenericOverall> leaveCall(@Nullable @Header("Authorization") String authorization, @Url String url,
@Nullable @Query("all") Boolean all);

@GET
Observable<SignalingSettingsOverall> getSignalingSettings(@Nullable @Header("Authorization") String authorization,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import com.nextcloud.talk.utils.NotificationUtils
import com.nextcloud.talk.utils.SpreedFeatures
import com.nextcloud.talk.utils.bundle.BundleKeys
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_CALL_VOICE_ONLY
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_ONE_TO_ONE
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
import okhttp3.Cache
import java.io.IOException
Expand Down Expand Up @@ -91,7 +92,7 @@ class CallNotificationActivity : CallBaseActivity() {
notificationTimestamp = extras.getInt(BundleKeys.KEY_NOTIFICATION_TIMESTAMP)
displayName = extras.getString(BundleKeys.KEY_CONVERSATION_DISPLAY_NAME, "")
callFlag = extras.getInt(BundleKeys.KEY_CALL_FLAG)
isOneToOneCall = extras.getBoolean(BundleKeys.KEY_ROOM_ONE_TO_ONE)
isOneToOneCall = extras.getBoolean(KEY_ROOM_ONE_TO_ONE)
conversationName = extras.getString(BundleKeys.KEY_CONVERSATION_NAME, "")
internalUserId = extras.getLong(BundleKeys.KEY_INTERNAL_USER_ID)
}
Expand Down Expand Up @@ -192,13 +193,12 @@ class CallNotificationActivity : CallBaseActivity() {

private fun proceedToCall() {
val callIntent = Intent(this, CallActivity::class.java)
intent.putExtra(KEY_ROOM_ONE_TO_ONE, isOneToOneCall)
callIntent.putExtras(intent.extras!!)
startActivity(callIntent)
}

private fun isInCallWithVideo(callFlag: Int): Boolean {
return (callFlag and Participant.InCallFlags.WITH_VIDEO) > 0
}
private fun isInCallWithVideo(callFlag: Int): Boolean = (callFlag and Participant.InCallFlags.WITH_VIDEO) > 0

override fun onStop() {
val notificationManager = NotificationManagerCompat.from(context)
Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3072,6 +3072,7 @@ class ChatActivity :
BundleKeys.KEY_PARTICIPANT_PERMISSION_CAN_PUBLISH_AUDIO,
participantPermissions.canPublishAudio()
)
bundle.putBoolean(BundleKeys.KEY_ROOM_ONE_TO_ONE, isOneToOneConversation())
bundle.putBoolean(
BundleKeys.KEY_PARTICIPANT_PERMISSION_CAN_PUBLISH_VIDEO,
participantPermissions.canPublishVideo()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
bundle.putLong(KEY_INTERNAL_USER_ID, signatureVerification.user!!.id!!)
bundle.putBoolean(KEY_FROM_NOTIFICATION_START_CALL, true)

val isOneToOneCall = conversation.type === ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL
val isOneToOneCall = conversation.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL

bundle.putBoolean(KEY_ROOM_ONE_TO_ONE, isOneToOneCall) // ggf change in Activity? not necessary????
bundle.putString(BundleKeys.KEY_CONVERSATION_NAME, conversation.name)
Expand Down
Loading
Loading