Skip to content

Commit 0cc8c6e

Browse files
authored
[AND-338] Audio-only call improvements (#1302)
* Show only remote user info & other improvements * Show all avatars with the same size * Fix build * Remove unnecessary logs * Enable video track only if video is enabled in call settings * Add dedicated audio call controls * Refactor audio call components * Refactor calls UI * Add user capability check to camera enable * Fix test * Update KDocs * Add snapshot tests * Restore timeout
1 parent 832d9d8 commit 0cc8c6e

File tree

27 files changed

+361
-199
lines changed

27 files changed

+361
-199
lines changed

stream-video-android-core/api/stream-video-android-core.api

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9297,20 +9297,20 @@ public final class io/getstream/video/android/core/model/CallRecordingData {
92979297
public abstract interface class io/getstream/video/android/core/model/CallStatus {
92989298
}
92999299

9300-
public final class io/getstream/video/android/core/model/CallStatus$Calling : io/getstream/video/android/core/model/CallStatus {
9301-
public fun <init> (Ljava/lang/String;)V
9302-
public final fun component1 ()Ljava/lang/String;
9303-
public final fun copy (Ljava/lang/String;)Lio/getstream/video/android/core/model/CallStatus$Calling;
9304-
public static synthetic fun copy$default (Lio/getstream/video/android/core/model/CallStatus$Calling;Ljava/lang/String;ILjava/lang/Object;)Lio/getstream/video/android/core/model/CallStatus$Calling;
9300+
public final class io/getstream/video/android/core/model/CallStatus$Incoming : io/getstream/video/android/core/model/CallStatus {
9301+
public static final field INSTANCE Lio/getstream/video/android/core/model/CallStatus$Incoming;
93059302
public fun equals (Ljava/lang/Object;)Z
9306-
public final fun getDuration ()Ljava/lang/String;
93079303
public fun hashCode ()I
93089304
public fun toString ()Ljava/lang/String;
93099305
}
93109306

9311-
public final class io/getstream/video/android/core/model/CallStatus$Incoming : io/getstream/video/android/core/model/CallStatus {
9312-
public static final field INSTANCE Lio/getstream/video/android/core/model/CallStatus$Incoming;
9307+
public final class io/getstream/video/android/core/model/CallStatus$Ongoing : io/getstream/video/android/core/model/CallStatus {
9308+
public fun <init> (Ljava/lang/String;)V
9309+
public final fun component1 ()Ljava/lang/String;
9310+
public final fun copy (Ljava/lang/String;)Lio/getstream/video/android/core/model/CallStatus$Ongoing;
9311+
public static synthetic fun copy$default (Lio/getstream/video/android/core/model/CallStatus$Ongoing;Ljava/lang/String;ILjava/lang/Object;)Lio/getstream/video/android/core/model/CallStatus$Ongoing;
93139312
public fun equals (Ljava/lang/Object;)Z
9313+
public final fun getDuration ()Ljava/lang/String;
93149314
public fun hashCode ()I
93159315
public fun toString ()Ljava/lang/String;
93169316
}
@@ -9323,18 +9323,19 @@ public final class io/getstream/video/android/core/model/CallStatus$Outgoing : i
93239323
}
93249324

93259325
public final class io/getstream/video/android/core/model/CallUser : java/io/Serializable {
9326-
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Lio/getstream/video/android/core/model/CallUserState;Ljava/util/Date;Ljava/util/Date;)V
9327-
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Lio/getstream/video/android/core/model/CallUserState;Ljava/util/Date;Ljava/util/Date;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
9326+
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/List;Lio/getstream/video/android/core/model/CallUserState;Ljava/util/Date;Ljava/util/Date;)V
9327+
public synthetic fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/List;Lio/getstream/video/android/core/model/CallUserState;Ljava/util/Date;Ljava/util/Date;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
93289328
public final fun component1 ()Ljava/lang/String;
93299329
public final fun component2 ()Ljava/lang/String;
93309330
public final fun component3 ()Ljava/lang/String;
93319331
public final fun component4 ()Ljava/lang/String;
9332-
public final fun component5 ()Ljava/util/List;
9333-
public final fun component6 ()Lio/getstream/video/android/core/model/CallUserState;
9334-
public final fun component7 ()Ljava/util/Date;
9332+
public final fun component5 ()Ljava/lang/Boolean;
9333+
public final fun component6 ()Ljava/util/List;
9334+
public final fun component7 ()Lio/getstream/video/android/core/model/CallUserState;
93359335
public final fun component8 ()Ljava/util/Date;
9336-
public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Lio/getstream/video/android/core/model/CallUserState;Ljava/util/Date;Ljava/util/Date;)Lio/getstream/video/android/core/model/CallUser;
9337-
public static synthetic fun copy$default (Lio/getstream/video/android/core/model/CallUser;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;Lio/getstream/video/android/core/model/CallUserState;Ljava/util/Date;Ljava/util/Date;ILjava/lang/Object;)Lio/getstream/video/android/core/model/CallUser;
9336+
public final fun component9 ()Ljava/util/Date;
9337+
public final fun copy (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/List;Lio/getstream/video/android/core/model/CallUserState;Ljava/util/Date;Ljava/util/Date;)Lio/getstream/video/android/core/model/CallUser;
9338+
public static synthetic fun copy$default (Lio/getstream/video/android/core/model/CallUser;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;Ljava/util/List;Lio/getstream/video/android/core/model/CallUserState;Ljava/util/Date;Ljava/util/Date;ILjava/lang/Object;)Lio/getstream/video/android/core/model/CallUser;
93389339
public fun equals (Ljava/lang/Object;)Z
93399340
public final fun getCreatedAt ()Ljava/util/Date;
93409341
public final fun getId ()Ljava/lang/String;
@@ -9345,6 +9346,7 @@ public final class io/getstream/video/android/core/model/CallUser : java/io/Seri
93459346
public final fun getTeams ()Ljava/util/List;
93469347
public final fun getUpdatedAt ()Ljava/util/Date;
93479348
public fun hashCode ()I
9349+
public final fun isLocalUser ()Ljava/lang/Boolean;
93489350
public fun toString ()Ljava/lang/String;
93499351
}
93509352

@@ -9829,6 +9831,7 @@ public final class io/getstream/video/android/core/model/VideoCodec : java/lang/
98299831
}
98309832

98319833
public final class io/getstream/video/android/core/model/VideoModelKt {
9834+
public static final fun getUserNameOrId (Lio/getstream/video/android/core/model/CallUser;)Ljava/lang/String;
98329835
public static final fun merge (Lio/getstream/video/android/core/model/CallUser;Lio/getstream/video/android/core/model/CallUser;)Lio/getstream/video/android/core/model/CallUser;
98339836
public static final fun merge (Lio/getstream/video/android/core/model/CallUserState;Lio/getstream/video/android/core/model/CallUserState;)Lio/getstream/video/android/core/model/CallUserState;
98349837
public static final fun merge (Ljava/util/Map;Lio/getstream/video/android/core/model/CallUser;)Ljava/util/Map;
@@ -12331,6 +12334,7 @@ public final class io/getstream/video/android/model/User$$serializer : kotlinx/s
1233112334
public final class io/getstream/video/android/model/User$Companion {
1233212335
public final fun anonymous ()Lio/getstream/video/android/model/User;
1233312336
public final fun isAnonymous (Lio/getstream/video/android/model/User;)Z
12337+
public final fun isLocalUser (Lio/getstream/video/android/model/User;)Z
1233412338
public final fun serializer ()Lkotlinx/serialization/KSerializer;
1233512339
}
1233612340

stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/CallState.kt

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -662,11 +662,6 @@ public class CallState(
662662
new.add(event.user.id)
663663
_rejectedBy.value = new.toSet()
664664

665-
Log.d(
666-
"RingingStateDebug",
667-
"CallRejectedEvent. Rejected by: ${event.user.id}. Reason: ${event.reason}. Will call updateRingingState().",
668-
)
669-
670665
updateRingingState(
671666
rejectReason = event.reason?.let {
672667
when (it) {
@@ -1090,10 +1085,6 @@ public class CallState(
10901085
}
10911086
Log.d("RingingState", "Update: $state")
10921087

1093-
Log.d("RingingStateDebug", "updateRingingState 1. Called by: ${getCallingMethod()}")
1094-
Log.d("RingingStateDebug", "updateRingingState 2. New state: $state")
1095-
Log.d("RingingStateDebug", "-------------------")
1096-
10971088
_ringingState.value = state
10981089
}
10991090

@@ -1154,8 +1145,6 @@ public class CallState(
11541145
// double check that we are still in Outgoing call state and call is not active
11551146
if (_ringingState.value is RingingState.Outgoing || _ringingState.value is RingingState.Incoming && client.state.activeCall.value == null) {
11561147
call.reject(reason = RejectReason.Custom(alias = REJECT_REASON_TIMEOUT))
1157-
1158-
Log.d("RingingStateDebug", "startRingingTimer. Timeout.")
11591148
}
11601149
} else {
11611150
logger.w { "[startRingingTimer] No autoCancelTimeoutMs set - call ring with no timeout" }

stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/MediaManager.kt

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import android.os.Build
2929
import android.os.IBinder
3030
import androidx.core.content.ContextCompat
3131
import androidx.core.content.getSystemService
32+
import io.getstream.android.video.generated.models.OwnCapability
3233
import io.getstream.android.video.generated.models.VideoSettingsResponse
3334
import io.getstream.log.taggedLogger
3435
import io.getstream.video.android.core.audio.AudioHandler
@@ -555,15 +556,21 @@ public class CameraManager(
555556
}
556557

557558
internal fun enable(fromUser: Boolean = true) {
558-
setup()
559-
// 1. update our local state
560-
// 2. update the track enabled status
561-
// 3. Rtc listens and sends the update mute state request
562-
if (fromUser) {
563-
_status.value = DeviceStatus.Enabled
559+
val (isCallVideoEnabled, canUserSendVideo) = with(mediaManager.call.state) {
560+
(settings.value?.video?.enabled == true) to ownCapabilities.value.contains(OwnCapability.SendVideo)
561+
}
562+
563+
if (isCallVideoEnabled && canUserSendVideo) {
564+
setup()
565+
// 1. update our local state
566+
// 2. update the track enabled status
567+
// 3. Rtc listens and sends the update mute state request
568+
if (fromUser) {
569+
_status.value = DeviceStatus.Enabled
570+
}
571+
mediaManager.videoTrack.trySetEnabled(true)
572+
startCapture()
564573
}
565-
mediaManager.videoTrack.trySetEnabled(true)
566-
startCapture()
567574
}
568575

569576
fun pause(fromUser: Boolean = true) {

stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/model/CallStatus.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,5 @@ public sealed interface CallStatus {
2828
public data object Outgoing : CallStatus
2929

3030
@Stable
31-
public data class Calling(public val duration: String) : CallStatus
31+
public data class Ongoing(public val duration: String) : CallStatus
3232
}

stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/model/VideoModel.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public data class CallUser(
3030
val name: String? = null,
3131
val role: String? = null,
3232
val imageUrl: String? = null,
33+
val isLocalUser: Boolean? = null,
3334
val teams: List<String>? = null,
3435
val state: CallUserState?,
3536
val createdAt: Date?,
@@ -80,6 +81,9 @@ public data class CallEgress(
8081
val recordEgress: String,
8182
)
8283

84+
val CallUser.userNameOrId: String
85+
get() = name.takeUnless { it.isNullOrBlank() } ?: id
86+
8387
internal fun List<MemberResponse>.toCallUsers(): Map<String, CallUser> =
8488
associate { it.userId to it.toCallUser() }
8589

stream-video-android-core/src/main/kotlin/io/getstream/video/android/core/utils/DomainUtils.kt

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import io.getstream.android.video.generated.models.QueryCallsResponse
2525
import io.getstream.android.video.generated.models.ReactionResponse
2626
import io.getstream.android.video.generated.models.UserResponse
2727
import io.getstream.video.android.core.MemberState
28+
import io.getstream.video.android.core.ParticipantState
2829
import io.getstream.video.android.core.internal.InternalStreamVideoApi
2930
import io.getstream.video.android.core.model.CallData
3031
import io.getstream.video.android.core.model.CallRecordingData
@@ -37,6 +38,7 @@ import io.getstream.video.android.core.model.QueriedMembers
3738
import io.getstream.video.android.core.model.ReactionData
3839
import io.getstream.video.android.core.model.toCallInfo
3940
import io.getstream.video.android.model.User
41+
import io.getstream.video.android.model.User.Companion.isLocalUser
4042
import stream.video.sfu.models.Participant
4143
import stream.video.sfu.models.TrackType
4244
import java.util.Date
@@ -61,9 +63,23 @@ public fun MemberState.toCallUser(): CallUser {
6163
return CallUser(
6264
id = user.id,
6365
name = user.name,
66+
role = user.role,
6467
imageUrl = user.image,
68+
isLocalUser = user.isLocalUser(),
6569
teams = user.teams,
66-
role = user.role,
70+
state = null,
71+
createdAt = null,
72+
updatedAt = null,
73+
)
74+
}
75+
76+
@JvmSynthetic
77+
@InternalStreamVideoApi
78+
public fun ParticipantState.toCallUser(): CallUser {
79+
return CallUser(
80+
id = userId.value,
81+
name = userNameOrId.value,
82+
imageUrl = image.value,
6783
state = null,
6884
createdAt = null,
6985
updatedAt = null,
@@ -179,7 +195,3 @@ internal fun EdgeResponse.toEdge(): EdgeData {
179195
red = red,
180196
)
181197
}
182-
183-
@JvmSynthetic
184-
@InternalStreamVideoApi
185-
fun CallUser.getNameOrId(): String = name.takeUnless { it.isNullOrBlank() } ?: id

stream-video-android-core/src/main/kotlin/io/getstream/video/android/model/User.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
package io.getstream.video.android.model
2020

2121
import androidx.compose.runtime.Immutable
22+
import io.getstream.video.android.core.StreamVideo
2223
import kotlinx.serialization.ExperimentalSerializationApi
2324
import kotlinx.serialization.KSerializer
2425
import kotlinx.serialization.Serializable
@@ -91,6 +92,9 @@ public data class User(
9192
inline get() = name.takeUnless { it.isNullOrBlank() } ?: id
9293

9394
companion object {
95+
/** Check if user is the local SDK user */
96+
fun User.isLocalUser(): Boolean = StreamVideo.instanceOrNull()?.userId == id
97+
9498
/** Check if user is anonymous. */
9599
fun User.isAnonymous(): Boolean = id == "!anon"
96100

stream-video-android-ui-compose/api/stream-video-android-ui-compose.api

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,7 +1041,9 @@ public final class io/getstream/video/android/compose/ui/components/call/Composa
10411041
}
10421042

10431043
public final class io/getstream/video/android/compose/ui/components/call/activecall/AudioCallContentKt {
1044-
public static final fun AudioCallContent (Landroidx/compose/ui/Modifier;Lio/getstream/video/android/core/Call;ZLio/getstream/video/android/compose/permission/VideoPermissionsState;Lkotlin/jvm/functions/Function1;Ljava/lang/String;ZLkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function5;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;III)V
1044+
public static final fun AudioCallContent (Landroidx/compose/ui/Modifier;Lio/getstream/video/android/core/Call;ZLio/getstream/video/android/compose/permission/VideoPermissionsState;ZLkotlin/jvm/functions/Function3;Ljava/lang/String;Lkotlin/jvm/functions/Function5;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;Landroidx/compose/runtime/Composer;III)V
1045+
public static final fun AudioCallControls (Landroidx/compose/ui/Modifier;ZLkotlin/jvm/functions/Function1;Landroidx/compose/runtime/Composer;I)V
1046+
public static final fun AudioCallDetails (Landroidx/compose/ui/Modifier;Ljava/lang/String;Ljava/util/List;Landroidx/compose/runtime/Composer;II)V
10451047
}
10461048

10471049
public final class io/getstream/video/android/compose/ui/components/call/activecall/CallContentKt {
@@ -1816,7 +1818,7 @@ public final class io/getstream/video/android/compose/ui/components/participants
18161818
}
18171819

18181820
public final class io/getstream/video/android/compose/ui/components/participants/ParticipantAvatarsKt {
1819-
public static final fun ParticipantAvatars (Ljava/util/List;Landroidx/compose/runtime/Composer;I)V
1821+
public static final fun ParticipantAvatars (Ljava/util/List;Ljava/util/List;Landroidx/compose/runtime/Composer;II)V
18201822
}
18211823

18221824
public final class io/getstream/video/android/compose/ui/components/participants/internal/ComposableSingletons$CallParticipantListAppBarKt {
@@ -1859,7 +1861,7 @@ public final class io/getstream/video/android/compose/ui/components/participants
18591861
}
18601862

18611863
public final class io/getstream/video/android/compose/ui/components/participants/internal/ParticipantInformationKt {
1862-
public static final fun ParticipantInformation (Lio/getstream/video/android/core/model/CallStatus;Ljava/util/List;ZLandroidx/compose/runtime/Composer;II)V
1864+
public static final fun ParticipantInformation (Lio/getstream/video/android/core/model/CallStatus;Ljava/util/List;Ljava/util/List;ZLandroidx/compose/runtime/Composer;II)V
18631865
}
18641866

18651867
public final class io/getstream/video/android/compose/ui/components/video/ComposableSingletons$VideoRendererKt {

stream-video-android-ui-compose/src/main/kotlin/io/getstream/video/android/compose/ui/StreamCallActivityComposeDelegate.kt

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -281,18 +281,12 @@ public open class StreamCallActivityComposeDelegate : StreamCallActivityComposeU
281281
@Composable
282282
override fun StreamCallActivity.AudioCallContent(call: Call) {
283283
val micEnabled by call.microphone.isEnabled.collectAsStateWithLifecycle()
284-
val duration by call.state.durationInDateFormat.collectAsStateWithLifecycle()
284+
285285
io.getstream.video.android.compose.ui.components.call.activecall.AudioCallContent(
286-
onBackPressed = {
287-
onBackPressed(call)
288-
},
289286
call = call,
290287
isMicrophoneEnabled = micEnabled,
291-
onCallAction = {
292-
onCallAction(call, it)
293-
},
294-
durationPlaceholder = duration
295-
?: "...",
288+
onCallAction = { onCallAction(call, it) },
289+
onBackPressed = { onBackPressed(call) },
296290
)
297291
}
298292

0 commit comments

Comments
 (0)