test_app_macos.rs

  1use std::time::Duration;
  2
  3use futures::StreamExt;
  4use gpui::{actions, KeyBinding, Menu, MenuItem};
  5use livekit_api::token::{self, VideoGrant};
  6use livekit_client_macos::{LocalAudioTrack, LocalVideoTrack, Room, RoomUpdate};
  7use log::LevelFilter;
  8use simplelog::SimpleLogger;
  9
 10actions!(livekit_client_macos, [Quit]);
 11
 12fn main() {
 13    SimpleLogger::init(LevelFilter::Info, Default::default()).expect("could not initialize logger");
 14
 15    gpui::Application::new().run(|cx| {
 16        #[cfg(any(test, feature = "test-support"))]
 17        println!("USING TEST LIVEKIT");
 18
 19        #[cfg(not(any(test, feature = "test-support")))]
 20        println!("USING REAL LIVEKIT");
 21
 22        cx.activate(true);
 23
 24        cx.on_action(quit);
 25        cx.bind_keys([KeyBinding::new("cmd-q", Quit, None)]);
 26
 27        cx.set_menus(vec![Menu {
 28            name: "Zed".into(),
 29            items: vec![MenuItem::Action {
 30                name: "Quit".into(),
 31                action: Box::new(Quit),
 32                os_action: None,
 33            }],
 34        }]);
 35
 36        let live_kit_url = std::env::var("LIVE_KIT_URL").unwrap_or("http://localhost:7880".into());
 37        let live_kit_key = std::env::var("LIVE_KIT_KEY").unwrap_or("devkey".into());
 38        let live_kit_secret = std::env::var("LIVE_KIT_SECRET").unwrap_or("secret".into());
 39
 40        cx.spawn(async move |cx| {
 41            let user_a_token = token::create(
 42                &live_kit_key,
 43                &live_kit_secret,
 44                Some("test-participant-1"),
 45                VideoGrant::to_join("test-room"),
 46            )
 47            .unwrap();
 48            let room_a = Room::new();
 49            room_a.connect(&live_kit_url, &user_a_token).await.unwrap();
 50
 51            let user2_token = token::create(
 52                &live_kit_key,
 53                &live_kit_secret,
 54                Some("test-participant-2"),
 55                VideoGrant::to_join("test-room"),
 56            )
 57            .unwrap();
 58            let room_b = Room::new();
 59            room_b.connect(&live_kit_url, &user2_token).await.unwrap();
 60
 61            let mut room_updates = room_b.updates();
 62            let audio_track = LocalAudioTrack::create();
 63            let audio_track_publication = room_a.publish_audio_track(audio_track).await.unwrap();
 64
 65            if let RoomUpdate::SubscribedToRemoteAudioTrack(track, _) =
 66                room_updates.next().await.unwrap()
 67            {
 68                let remote_tracks = room_b.remote_audio_tracks("test-participant-1");
 69                assert_eq!(remote_tracks.len(), 1);
 70                assert_eq!(remote_tracks[0].publisher_id(), "test-participant-1");
 71                assert_eq!(track.publisher_id(), "test-participant-1");
 72            } else {
 73                panic!("unexpected message");
 74            }
 75
 76            audio_track_publication.set_mute(true).await.unwrap();
 77
 78            println!("waiting for mute changed!");
 79            if let RoomUpdate::RemoteAudioTrackMuteChanged { track_id, muted } =
 80                room_updates.next().await.unwrap()
 81            {
 82                let remote_tracks = room_b.remote_audio_tracks("test-participant-1");
 83                assert_eq!(remote_tracks[0].sid(), track_id);
 84                assert!(muted);
 85            } else {
 86                panic!("unexpected message");
 87            }
 88
 89            audio_track_publication.set_mute(false).await.unwrap();
 90
 91            if let RoomUpdate::RemoteAudioTrackMuteChanged { track_id, muted } =
 92                room_updates.next().await.unwrap()
 93            {
 94                let remote_tracks = room_b.remote_audio_tracks("test-participant-1");
 95                assert_eq!(remote_tracks[0].sid(), track_id);
 96                assert!(!muted);
 97            } else {
 98                panic!("unexpected message");
 99            }
100
101            println!("Pausing for 5 seconds to test audio, make some noise!");
102            let timer = cx.background_executor().timer(Duration::from_secs(5));
103            timer.await;
104            let remote_audio_track = room_b
105                .remote_audio_tracks("test-participant-1")
106                .pop()
107                .unwrap();
108            room_a.unpublish_track(audio_track_publication);
109
110            // Clear out any active speakers changed messages
111            let mut next = room_updates.next().await.unwrap();
112            while let RoomUpdate::ActiveSpeakersChanged { speakers } = next {
113                println!("Speakers changed: {:?}", speakers);
114                next = room_updates.next().await.unwrap();
115            }
116
117            if let RoomUpdate::UnsubscribedFromRemoteAudioTrack {
118                publisher_id,
119                track_id,
120            } = next
121            {
122                assert_eq!(publisher_id, "test-participant-1");
123                assert_eq!(remote_audio_track.sid(), track_id);
124                assert_eq!(room_b.remote_audio_tracks("test-participant-1").len(), 0);
125            } else {
126                panic!("unexpected message");
127            }
128
129            let displays = room_a.display_sources().await.unwrap();
130            let display = displays.into_iter().next().unwrap();
131
132            let local_video_track = LocalVideoTrack::screen_share_for_display(&display);
133            let local_video_track_publication =
134                room_a.publish_video_track(local_video_track).await.unwrap();
135
136            if let RoomUpdate::SubscribedToRemoteVideoTrack(track) =
137                room_updates.next().await.unwrap()
138            {
139                let remote_video_tracks = room_b.remote_video_tracks("test-participant-1");
140                assert_eq!(remote_video_tracks.len(), 1);
141                assert_eq!(remote_video_tracks[0].publisher_id(), "test-participant-1");
142                assert_eq!(track.publisher_id(), "test-participant-1");
143            } else {
144                panic!("unexpected message");
145            }
146
147            let remote_video_track = room_b
148                .remote_video_tracks("test-participant-1")
149                .pop()
150                .unwrap();
151            room_a.unpublish_track(local_video_track_publication);
152            if let RoomUpdate::UnsubscribedFromRemoteVideoTrack {
153                publisher_id,
154                track_id,
155            } = room_updates.next().await.unwrap()
156            {
157                assert_eq!(publisher_id, "test-participant-1");
158                assert_eq!(remote_video_track.sid(), track_id);
159                assert_eq!(room_b.remote_video_tracks("test-participant-1").len(), 0);
160            } else {
161                panic!("unexpected message");
162            }
163
164            cx.update(|cx| cx.shutdown()).ok();
165        })
166        .detach();
167    });
168}
169
170fn quit(_: &Quit, cx: &mut gpui::App) {
171    cx.quit();
172}