participant.rs

  1use crate::{
  2    AudioStream, ConnectionQuality, LocalAudioTrack, LocalTrackPublication, LocalVideoTrack,
  3    Participant, ParticipantIdentity, RemoteTrack, RemoteTrackPublication, TrackSid,
  4    test::{Room, WeakRoom},
  5};
  6use anyhow::Result;
  7use collections::HashMap;
  8use gpui::{
  9    AsyncApp, DevicePixels, ScreenCaptureSource, ScreenCaptureStream, SourceMetadata, size,
 10};
 11use std::sync::{Arc, atomic::AtomicU64};
 12
 13#[derive(Clone, Debug)]
 14pub struct LocalParticipant {
 15    pub(crate) identity: ParticipantIdentity,
 16    pub(crate) room: Room,
 17}
 18
 19#[derive(Clone, Debug)]
 20pub struct RemoteParticipant {
 21    pub(crate) identity: ParticipantIdentity,
 22    pub(crate) room: WeakRoom,
 23}
 24
 25impl Participant {
 26    pub fn identity(&self) -> ParticipantIdentity {
 27        match self {
 28            Participant::Local(participant) => participant.identity.clone(),
 29            Participant::Remote(participant) => participant.identity.clone(),
 30        }
 31    }
 32
 33    pub fn connection_quality(&self) -> ConnectionQuality {
 34        match self {
 35            Participant::Local(p) => p.connection_quality(),
 36            Participant::Remote(p) => p.connection_quality(),
 37        }
 38    }
 39
 40    pub fn audio_level(&self) -> f32 {
 41        match self {
 42            Participant::Local(p) => p.audio_level(),
 43            Participant::Remote(p) => p.audio_level(),
 44        }
 45    }
 46}
 47
 48impl LocalParticipant {
 49    pub fn connection_quality(&self) -> ConnectionQuality {
 50        ConnectionQuality::Excellent
 51    }
 52
 53    pub fn audio_level(&self) -> f32 {
 54        0.0
 55    }
 56
 57    pub async fn unpublish_track(&self, track: TrackSid, _cx: &AsyncApp) -> Result<()> {
 58        self.room
 59            .test_server()
 60            .unpublish_track(self.room.token(), &track)
 61            .await
 62    }
 63
 64    pub(crate) async fn publish_microphone_track(
 65        &self,
 66        _cx: &AsyncApp,
 67    ) -> Result<(LocalTrackPublication, AudioStream, Arc<AtomicU64>)> {
 68        let this = self.clone();
 69        let server = this.room.test_server();
 70        let sid = server
 71            .publish_audio_track(this.room.token(), &LocalAudioTrack {})
 72            .await?;
 73
 74        Ok((
 75            LocalTrackPublication {
 76                room: self.room.downgrade(),
 77                sid,
 78            },
 79            AudioStream {},
 80            Arc::new(AtomicU64::new(0)),
 81        ))
 82    }
 83
 84    pub async fn publish_screenshare_track(
 85        &self,
 86        _source: &dyn ScreenCaptureSource,
 87        _cx: &mut AsyncApp,
 88    ) -> Result<(LocalTrackPublication, Box<dyn ScreenCaptureStream>)> {
 89        let this = self.clone();
 90        let server = this.room.test_server();
 91        let sid = server
 92            .publish_video_track(this.room.token(), LocalVideoTrack {})
 93            .await?;
 94        Ok((
 95            LocalTrackPublication {
 96                room: self.room.downgrade(),
 97                sid,
 98            },
 99            Box::new(TestScreenCaptureStream {}),
100        ))
101    }
102}
103
104impl RemoteParticipant {
105    pub fn connection_quality(&self) -> ConnectionQuality {
106        ConnectionQuality::Excellent
107    }
108
109    pub fn audio_level(&self) -> f32 {
110        0.0
111    }
112
113    pub fn track_publications(&self) -> HashMap<TrackSid, RemoteTrackPublication> {
114        if let Some(room) = self.room.upgrade() {
115            let server = room.test_server();
116            let audio = server
117                .audio_tracks(room.token())
118                .unwrap()
119                .into_iter()
120                .filter(|track| track.publisher_id() == self.identity)
121                .map(|track| {
122                    (
123                        track.sid(),
124                        RemoteTrackPublication {
125                            sid: track.sid(),
126                            room: self.room.clone(),
127                            track: RemoteTrack::Audio(track),
128                        },
129                    )
130                });
131            let video = server
132                .video_tracks(room.token())
133                .unwrap()
134                .into_iter()
135                .filter(|track| track.publisher_id() == self.identity)
136                .map(|track| {
137                    (
138                        track.sid(),
139                        RemoteTrackPublication {
140                            sid: track.sid(),
141                            room: self.room.clone(),
142                            track: RemoteTrack::Video(track),
143                        },
144                    )
145                });
146            audio.chain(video).collect()
147        } else {
148            HashMap::default()
149        }
150    }
151
152    pub fn identity(&self) -> ParticipantIdentity {
153        self.identity.clone()
154    }
155}
156
157struct TestScreenCaptureStream;
158
159impl ScreenCaptureStream for TestScreenCaptureStream {
160    fn metadata(&self) -> Result<SourceMetadata> {
161        Ok(SourceMetadata {
162            id: 0,
163            is_main: None,
164            label: None,
165            resolution: size(DevicePixels(1), DevicePixels(1)),
166        })
167    }
168}