Skip to content

Commit

Permalink
[PBE-2777] Review ringing state and updates sent to StreamCallActivity (
Browse files Browse the repository at this point in the history
#1089)

* Rename timeout flag in updateRingingState

* Change check order in updateRingingState

* Add more logging

* Add reject reason to CallRejectedEvent

* Use reason to differentiate between reject types (timeout or not)

* Run apiDump

---------

Co-authored-by: Aleksandar Apostolov <[email protected]>
  • Loading branch information
liviu-timar and aleksandar-apostolov authored Jun 25, 2024
1 parent 24b30af commit a801a4a
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 34 deletions.
10 changes: 6 additions & 4 deletions stream-video-android-core/api/stream-video-android-core.api
Original file line number Diff line number Diff line change
Expand Up @@ -6973,21 +6973,23 @@ public final class org/openapitools/client/models/CallRecordingStoppedEvent : or
}

public final class org/openapitools/client/models/CallRejectedEvent : org/openapitools/client/models/VideoEvent, org/openapitools/client/models/WSCallEvent {
public fun <init> (Lorg/openapitools/client/models/CallResponse;Ljava/lang/String;Lorg/threeten/bp/OffsetDateTime;Ljava/lang/String;Lorg/openapitools/client/models/UserResponse;)V
public synthetic fun <init> (Lorg/openapitools/client/models/CallResponse;Ljava/lang/String;Lorg/threeten/bp/OffsetDateTime;Ljava/lang/String;Lorg/openapitools/client/models/UserResponse;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun <init> (Lorg/openapitools/client/models/CallResponse;Ljava/lang/String;Lorg/threeten/bp/OffsetDateTime;Ljava/lang/String;Lorg/openapitools/client/models/UserResponse;Ljava/lang/String;)V
public synthetic fun <init> (Lorg/openapitools/client/models/CallResponse;Ljava/lang/String;Lorg/threeten/bp/OffsetDateTime;Ljava/lang/String;Lorg/openapitools/client/models/UserResponse;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Lorg/openapitools/client/models/CallResponse;
public final fun component2 ()Ljava/lang/String;
public final fun component3 ()Lorg/threeten/bp/OffsetDateTime;
public final fun component4 ()Ljava/lang/String;
public final fun component5 ()Lorg/openapitools/client/models/UserResponse;
public final fun copy (Lorg/openapitools/client/models/CallResponse;Ljava/lang/String;Lorg/threeten/bp/OffsetDateTime;Ljava/lang/String;Lorg/openapitools/client/models/UserResponse;)Lorg/openapitools/client/models/CallRejectedEvent;
public static synthetic fun copy$default (Lorg/openapitools/client/models/CallRejectedEvent;Lorg/openapitools/client/models/CallResponse;Ljava/lang/String;Lorg/threeten/bp/OffsetDateTime;Ljava/lang/String;Lorg/openapitools/client/models/UserResponse;ILjava/lang/Object;)Lorg/openapitools/client/models/CallRejectedEvent;
public final fun component6 ()Ljava/lang/String;
public final fun copy (Lorg/openapitools/client/models/CallResponse;Ljava/lang/String;Lorg/threeten/bp/OffsetDateTime;Ljava/lang/String;Lorg/openapitools/client/models/UserResponse;Ljava/lang/String;)Lorg/openapitools/client/models/CallRejectedEvent;
public static synthetic fun copy$default (Lorg/openapitools/client/models/CallRejectedEvent;Lorg/openapitools/client/models/CallResponse;Ljava/lang/String;Lorg/threeten/bp/OffsetDateTime;Ljava/lang/String;Lorg/openapitools/client/models/UserResponse;Ljava/lang/String;ILjava/lang/Object;)Lorg/openapitools/client/models/CallRejectedEvent;
public fun equals (Ljava/lang/Object;)Z
public final fun getCall ()Lorg/openapitools/client/models/CallResponse;
public fun getCallCID ()Ljava/lang/String;
public final fun getCallCid ()Ljava/lang/String;
public final fun getCreatedAt ()Lorg/threeten/bp/OffsetDateTime;
public fun getEventType ()Ljava/lang/String;
public final fun getReason ()Ljava/lang/String;
public final fun getType ()Ljava/lang/String;
public final fun getUser ()Lorg/openapitools/client/models/UserResponse;
public fun hashCode ()I
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import io.getstream.video.android.core.model.Ingress
import io.getstream.video.android.core.model.NetworkQuality
import io.getstream.video.android.core.model.RTMP
import io.getstream.video.android.core.model.Reaction
import io.getstream.video.android.core.model.RejectReason
import io.getstream.video.android.core.model.ScreenSharingSession
import io.getstream.video.android.core.model.VisibilityOnScreenState
import io.getstream.video.android.core.permission.PermissionRequest
Expand Down Expand Up @@ -567,7 +568,22 @@ public class CallState(
val new = _rejectedBy.value.toMutableSet()
new.add(event.user.id)
_rejectedBy.value = new.toSet()
updateRingingState()

Log.d(
"RingingStateDebug",
"CallRejectedEvent. Rejected by: ${event.user.id}. Reason: ${event.reason}. Will call updateRingingState().",
)

updateRingingState(
rejectReason = event.reason?.let {
when (it) {
RejectReason.Busy.alias -> RejectReason.Busy
RejectReason.Cancel.alias -> RejectReason.Cancel
RejectReason.Decline.alias -> RejectReason.Decline
else -> RejectReason.Custom(alias = it)
}
},
)
}

is CallEndedEvent -> {
Expand Down Expand Up @@ -853,48 +869,43 @@ public class CallState(
}
}

private fun updateRingingState(timeout: Boolean = false) {
private fun updateRingingState(rejectReason: RejectReason? = null) {
// this is only true when we are in the session (we have accepted/joined the call)
val userIsParticipant =
_session.value?.participants?.find { it.user.id == client.userId } != null
val outgoingMembersCount = _members.value.filter { it.value.user.id != client.userId }.size
val rejectedBy = _rejectedBy.value
val isRejectedByMe = _rejectedBy.value.contains(client.userId)
val acceptedBy = _acceptedBy.value
val isAcceptedByMe = _acceptedBy.value.contains(client.userId)
val createdBy = _createdBy.value
val members = _members.value
val rejectedByMe = _rejectedBy.value.findLast { it == client.userId }
val acceptedByMe = _acceptedBy.value.findLast { it == client.userId }
val hasActiveCall = client.state.activeCall.value != null
val hasRingingCall = client.state.ringingCall.value != null
val userIsParticipant =
_session.value?.participants?.find { it.user.id == client.userId } != null
val outgoingMembersCount = _members.value.filter { it.value.user.id != client.userId }.size

Log.d("RingingState", "Current: ${_ringingState.value}")
val rejectedByMeBool = !rejectedByMe.isNullOrBlank()
Log.d(
"RingingState",
"Flags: [\n" +
"acceptedByMe: ${!acceptedByMe.isNullOrBlank()},\n" +
"rejectedByMe: $rejectedByMeBool,\n" +
"acceptedByMe: $isAcceptedByMe,\n" +
"rejectedByMe: $isRejectedByMe,\n" +
"rejectReason: $rejectReason,\n" +
"hasActiveCall: $hasActiveCall\n" +
"hasRingingCall: $hasRingingCall\n" +
"userIsParticipant: $userIsParticipant,\n" +
"timeout: $timeout\n" +
"]",
)

// no members - call is empty, we can join
val state: RingingState = if (hasActiveCall) {
cancelTimeout()
RingingState.Active
} else if (rejectedBy.isNotEmpty() && acceptedBy.isEmpty() && rejectedBy.size >= outgoingMembersCount) {
// Call leave same as CallEndedEvent we do not want to receive updates anymore,
// since we or the caller timed-out or the call was rejected.
// We leave the call, we do not depend on the SDK user to call leave()
} else if (rejectedBy.isNotEmpty() && rejectedBy.size >= outgoingMembersCount) {
call.leave()
if (timeout || !rejectedByMeBool) {
cancelTimeout()
cancelTimeout()

if (rejectReason?.alias == REJECT_REASON_TIMEOUT) {
RingingState.TimeoutNoAnswer
} else {
cancelTimeout()
RingingState.RejectedByAll
}
} else if (hasRingingCall && createdBy?.id != client.userId) {
Expand All @@ -904,7 +915,7 @@ public class CallState(
cancelTimeout()
RingingState.Active
} else {
RingingState.Incoming(acceptedByMe = acceptedByMe != null)
RingingState.Incoming(acceptedByMe = isAcceptedByMe)
}
} else if (hasRingingCall && createdBy?.id == client.userId) {
// The call is created by us
Expand All @@ -919,12 +930,6 @@ public class CallState(
cancelTimeout()
RingingState.Active
}
} else if (timeout) {
// It was an outgoing, or incoming call, but timeout was reached
// Call leave same as CallEndedEvent we do not want to receive updates anymore
call.leave()
cancelTimeout()
RingingState.TimeoutNoAnswer
} else {
RingingState.Idle
}
Expand All @@ -944,6 +949,11 @@ public class CallState(
// stop the call ringing timer if it's running
}
Log.d("RingingState", "Update: $state")

Log.d("RingingStateDebug", "updateRingingState 1. Called by: ${getCallingMethod()}")
Log.d("RingingStateDebug", "updateRingingState 2. New state: $state")
Log.d("RingingStateDebug", "-------------------")

_ringingState.value = state
}

Expand Down Expand Up @@ -990,9 +1000,9 @@ public class CallState(

// double check that we are still in Outgoing call state and call is not active
if (_ringingState.value is RingingState.Outgoing || _ringingState.value is RingingState.Incoming && client.state.activeCall.value == null) {
call.reject()
call.leave()
updateRingingState(true)
call.reject(reason = RejectReason.Custom(alias = REJECT_REASON_TIMEOUT))

Log.d("RingingStateDebug", "startRingingTimer. Timeout.")
}
} else {
logger.w { "[startRingingTimer] No autoCancelTimeoutMs set - call ring with no timeout" }
Expand Down Expand Up @@ -1282,3 +1292,17 @@ private fun MemberResponse.toMemberState(): MemberState {
deletedAt = deletedAt,
)
}

private fun getCallingMethod(): String {
val stackTrace = Thread.currentThread().stackTrace

return if (stackTrace.isEmpty()) {
""
} else {
stackTrace[6].let { callingMethod ->
callingMethod.className + "." + callingMethod.methodName
}
}
}

private const val REJECT_REASON_TIMEOUT = "timeout"
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import org.openapitools.client.infrastructure.Serializer
* @param createdAt
* @param type The type of event: \"call.rejected\" in this case
* @param user
* @param reason
*/


Expand All @@ -64,7 +65,10 @@ data class CallRejectedEvent (
val type: kotlin.String = "call.rejected",

@Json(name = "user")
val user: UserResponse
val user: UserResponse,

@Json(name = "reason")
val reason: kotlin.String? = null

) : VideoEvent(), WSCallEvent {

Expand Down

0 comments on commit a801a4a

Please sign in to comment.