David Zhao

onMetadataChanged callback on Room

@@ -24,7 +24,7 @@ constructor( @@ -24,7 +24,7 @@ constructor(
24 @Assisted private val connectOptions: ConnectOptions, 24 @Assisted private val connectOptions: ConnectOptions,
25 private val engine: RTCEngine, 25 private val engine: RTCEngine,
26 private val eglBase: EglBase, 26 private val eglBase: EglBase,
27 -) : RTCEngine.Listener { 27 +) : RTCEngine.Listener, RemoteParticipant.Listener, LocalParticipant.Listener {
28 init { 28 init {
29 engine.listener = this 29 engine.listener = this
30 } 30 }
@@ -96,6 +96,7 @@ constructor( @@ -96,6 +96,7 @@ constructor(
96 } else { 96 } else {
97 RemoteParticipant(sid, null) 97 RemoteParticipant(sid, null)
98 } 98 }
  99 + participant.listener = this
99 mutableRemoteParticipants[sid] = participant 100 mutableRemoteParticipants[sid] = participant
100 return participant 101 return participant
101 } 102 }
@@ -152,11 +153,11 @@ constructor( @@ -152,11 +153,11 @@ constructor(
152 fun onFailedToConnect(room: Room, error: Exception) {} 153 fun onFailedToConnect(room: Room, error: Exception) {}
153 fun onReconnecting(room: Room, error: Exception) {} 154 fun onReconnecting(room: Room, error: Exception) {}
154 fun onReconnect(room: Room) {} 155 fun onReconnect(room: Room) {}
155 - fun onStartRecording(room: Room) {}  
156 - fun onStopRecording(room: Room) {} 156 + fun onMetadataChanged(room: Room, Participant: Participant, prevMetadata: String?) {}
157 fun onActiveSpeakersChanged(speakers: List<Participant>, room: Room) {} 157 fun onActiveSpeakersChanged(speakers: List<Participant>, room: Room) {}
158 } 158 }
159 159
  160 + //----------------------------------- RTCEngine.Listener ------------------------------------//
160 /** 161 /**
161 * @suppress 162 * @suppress
162 */ 163 */
@@ -178,7 +179,9 @@ constructor( @@ -178,7 +179,9 @@ constructor(
178 name = response.room.name 179 name = response.room.name
179 180
180 if (response.hasParticipant()) { 181 if (response.hasParticipant()) {
181 - localParticipant = LocalParticipant(response.participant, engine) 182 + val lp = LocalParticipant(response.participant, engine)
  183 + lp.listener = this
  184 + localParticipant = lp
182 } 185 }
183 if (response.otherParticipantsList.isNotEmpty()) { 186 if (response.otherParticipantsList.isNotEmpty()) {
184 response.otherParticipantsList.forEach { 187 response.otherParticipantsList.forEach {
@@ -268,6 +271,15 @@ constructor( @@ -268,6 +271,15 @@ constructor(
268 listener?.onFailedToConnect(this, error) 271 listener?.onFailedToConnect(this, error)
269 } 272 }
270 273
  274 + //------------------------------- RemoteParticipant.Listener --------------------------------//
  275 + /**
  276 + * @suppress
  277 + */
  278 + override fun onMetadataChanged(participant: Participant, prevMetadata: String?) {
  279 + listener?.onMetadataChanged(this, participant, prevMetadata)
  280 + }
  281 +
  282 +
271 /** 283 /**
272 * @suppress 284 * @suppress
273 * // TODO(@dl): can this be moved out of Room/SDK? 285 * // TODO(@dl): can this be moved out of Room/SDK?
@@ -29,17 +29,12 @@ class LocalParticipant(sid: Sid, name: String? = null) : @@ -29,17 +29,12 @@ class LocalParticipant(sid: Sid, name: String? = null) :
29 val localDataTrackPublications 29 val localDataTrackPublications
30 get() = dataTracks.values.toList() 30 get() = dataTracks.values.toList()
31 31
32 - var engine: RTCEngine? = null  
33 - val listener: Listener? = null  
34 -  
35 - /**  
36 - * @suppress  
37 - */  
38 - fun updateFromInfo(info: LivekitModels.ParticipantInfo) {  
39 - sid = Sid(info.sid)  
40 - name = info.identity  
41 - metadata = info.metadata  
42 - } 32 + private var engine: RTCEngine? = null
  33 + var listener: Listener? = null
  34 + set(v) {
  35 + field = v
  36 + participantListener = v
  37 + }
43 38
44 suspend fun publishAudioTrack( 39 suspend fun publishAudioTrack(
45 track: LocalAudioTrack, 40 track: LocalAudioTrack,
@@ -205,13 +200,14 @@ class LocalParticipant(sid: Sid, name: String? = null) : @@ -205,13 +200,14 @@ class LocalParticipant(sid: Sid, name: String? = null) :
205 } 200 }
206 } 201 }
207 202
208 - interface Listener {  
209 - fun onPublishAudioTrack(track: LocalAudioTrack)  
210 - fun onFailToPublishAudioTrack(exception: Exception)  
211 - fun onPublishVideoTrack(track: LocalVideoTrack)  
212 - fun onFailToPublishVideoTrack(exception: Exception)  
213 - fun onPublishDataTrack(track: LocalDataTrack)  
214 - fun onFailToPublishDataTrack(exception: Exception) 203 + interface Listener : Participant.Listener {
  204 + // TODO: can we move these to exceptions? instead of callbacks
  205 + fun onPublishAudioTrack(track: LocalAudioTrack) {}
  206 + fun onFailToPublishAudioTrack(exception: Exception) {}
  207 + fun onPublishVideoTrack(track: LocalVideoTrack) {}
  208 + fun onFailToPublishVideoTrack(exception: Exception) {}
  209 + fun onPublishDataTrack(track: LocalDataTrack) {}
  210 + fun onFailToPublishDataTrack(exception: Exception) {}
215 //fun onNetworkQualityLevelChange 211 //fun onNetworkQualityLevelChange
216 } 212 }
217 } 213 }
1 package io.livekit.android.room.participant 1 package io.livekit.android.room.participant
2 2
3 import io.livekit.android.room.track.* 3 import io.livekit.android.room.track.*
  4 +import livekit.LivekitModels
4 5
5 open class Participant(var sid: Sid, name: String? = null) { 6 open class Participant(var sid: Sid, name: String? = null) {
6 inline class Sid(val sid: String) 7 inline class Sid(val sid: String)
7 8
8 - var metadata: String? = null 9 + var participantInfo: LivekitModels.ParticipantInfo? = null
  10 + private set
9 var name: String? = name 11 var name: String? = name
10 internal set 12 internal set
11 var audioLevel: Float = 0f 13 var audioLevel: Float = 0f
12 internal set 14 internal set
  15 + var metadata: String? = null
  16 + var participantListener: Listener? = null
  17 + val hasInfo
  18 + get() = participantInfo != null
13 19
14 var tracks = mutableMapOf<Track.Sid, TrackPublication>() 20 var tracks = mutableMapOf<Track.Sid, TrackPublication>()
15 var audioTracks = mutableMapOf<Track.Sid, TrackPublication>() 21 var audioTracks = mutableMapOf<Track.Sid, TrackPublication>()
@@ -31,6 +37,22 @@ open class Participant(var sid: Sid, name: String? = null) { @@ -31,6 +37,22 @@ open class Participant(var sid: Sid, name: String? = null) {
31 } 37 }
32 } 38 }
33 39
  40 + /**
  41 + * @suppress
  42 + */
  43 + open fun updateFromInfo(info: LivekitModels.ParticipantInfo) {
  44 + sid = Sid(info.sid)
  45 + name = info.identity
  46 + participantInfo = info
  47 +
  48 + val prevMetadata = metadata
  49 + metadata = info.metadata
  50 +
  51 + if (prevMetadata != metadata) {
  52 + participantListener?.onMetadataChanged(this, prevMetadata)
  53 + }
  54 + }
  55 +
34 override fun equals(other: Any?): Boolean { 56 override fun equals(other: Any?): Boolean {
35 if (this === other) return true 57 if (this === other) return true
36 if (javaClass != other?.javaClass) return false 58 if (javaClass != other?.javaClass) return false
@@ -46,4 +68,7 @@ open class Participant(var sid: Sid, name: String? = null) { @@ -46,4 +68,7 @@ open class Participant(var sid: Sid, name: String? = null) {
46 return sid.hashCode() 68 return sid.hashCode()
47 } 69 }
48 70
  71 + interface Listener {
  72 + fun onMetadataChanged(participant: Participant, prevMetadata: String?) {}
  73 + }
49 } 74 }
@@ -31,11 +31,10 @@ class RemoteParticipant( @@ -31,11 +31,10 @@ class RemoteParticipant(
31 get() = dataTracks.values.toList() 31 get() = dataTracks.values.toList()
32 32
33 var listener: Listener? = null 33 var listener: Listener? = null
34 -  
35 - var participantInfo: LivekitModels.ParticipantInfo? = null  
36 -  
37 - val hasInfo  
38 - get() = participantInfo != null 34 + set(v) {
  35 + field = v
  36 + participantListener = v
  37 + }
39 38
40 private val coroutineScope = CloseableCoroutineScope(SupervisorJob()) 39 private val coroutineScope = CloseableCoroutineScope(SupervisorJob())
41 40
@@ -45,12 +44,9 @@ class RemoteParticipant( @@ -45,12 +44,9 @@ class RemoteParticipant(
45 /** 44 /**
46 * @suppress 45 * @suppress
47 */ 46 */
48 - fun updateFromInfo(info: LivekitModels.ParticipantInfo) { 47 + override fun updateFromInfo(info: LivekitModels.ParticipantInfo) {
49 val hadInfo = hasInfo 48 val hadInfo = hasInfo
50 - sid = Sid(info.sid)  
51 - name = info.identity  
52 - participantInfo = info  
53 - metadata = info.metadata 49 + super.updateFromInfo(info)
54 50
55 val validTrackPublication = mutableMapOf<Track.Sid, RemoteTrackPublication>() 51 val validTrackPublication = mutableMapOf<Track.Sid, RemoteTrackPublication>()
56 val newTrackPublications = mutableMapOf<Track.Sid, RemoteTrackPublication>() 52 val newTrackPublications = mutableMapOf<Track.Sid, RemoteTrackPublication>()
@@ -247,7 +243,7 @@ class RemoteParticipant( @@ -247,7 +243,7 @@ class RemoteParticipant(
247 private const val KIND_VIDEO = "video" 243 private const val KIND_VIDEO = "video"
248 } 244 }
249 245
250 - interface Listener { 246 + interface Listener: Participant.Listener {
251 fun onPublish(audioTrack: RemoteAudioTrackPublication, participant: RemoteParticipant) {} 247 fun onPublish(audioTrack: RemoteAudioTrackPublication, participant: RemoteParticipant) {}
252 fun onUnpublish(audioTrack: RemoteAudioTrackPublication, participant: RemoteParticipant) {} 248 fun onUnpublish(audioTrack: RemoteAudioTrackPublication, participant: RemoteParticipant) {}
253 fun onPublish(videoTrack: RemoteVideoTrackPublication, participant: RemoteParticipant) {} 249 fun onPublish(videoTrack: RemoteVideoTrackPublication, participant: RemoteParticipant) {}
@@ -44,6 +44,7 @@ class LocalVideoTrack( @@ -44,6 +44,7 @@ class LocalVideoTrack(
44 ) 44 )
45 } 45 }
46 46
  47 +
47 private fun createVideoCapturer(context: Context): VideoCapturer? { 48 private fun createVideoCapturer(context: Context): VideoCapturer? {
48 val videoCapturer: VideoCapturer? = if (Camera2Enumerator.isSupported(context)) { 49 val videoCapturer: VideoCapturer? = if (Camera2Enumerator.isSupported(context)) {
49 createCameraCapturer(Camera2Enumerator(context)) 50 createCameraCapturer(Camera2Enumerator(context))
@@ -65,15 +65,16 @@ class CallViewModel( @@ -65,15 +65,16 @@ class CallViewModel(
65 updateParticipants(room) 65 updateParticipants(room)
66 } 66 }
67 67
68 - override fun onStartRecording(room: Room) { 68 + override fun onActiveSpeakersChanged(speakers: List<Participant>, room: Room) {
69 } 69 }
70 70
71 - override fun onStopRecording(room: Room) {  
72 - } 71 + override fun onMetadataChanged(
  72 + room: Room,
  73 + Participant: Participant,
  74 + prevMetadata: String?
  75 + ) {
73 76
74 - override fun onActiveSpeakersChanged(speakers: List<Participant>, room: Room) {  
75 } 77 }
76 -  
77 } 78 }
78 ) 79 )
79 } 80 }