From d4327d4cfcc0aa2dfb3d0c59cc55bc03634b5977 Mon Sep 17 00:00:00 2001 From: Alex Black Date: Tue, 15 Dec 2020 21:15:42 +1100 Subject: [PATCH] EventEmitter: add VoIP event support (m.call.* event types) Signed-off-by: Alex Black --- matrix_sdk_base/src/client.rs | 12 +++ matrix_sdk_base/src/event_emitter/mod.rs | 57 +++++++++++ matrix_sdk_test/src/lib.rs | 2 + matrix_sdk_test/src/test_json/mod.rs | 4 +- matrix_sdk_test/src/test_json/sync.rs | 120 +++++++++++++++++++++++ 5 files changed, 194 insertions(+), 1 deletion(-) diff --git a/matrix_sdk_base/src/client.rs b/matrix_sdk_base/src/client.rs index 55142e98..3839419e 100644 --- a/matrix_sdk_base/src/client.rs +++ b/matrix_sdk_base/src/client.rs @@ -1498,6 +1498,18 @@ impl BaseClient { .on_custom_event(room, &CustomEvent::Message(e)) .await } + AnySyncMessageEvent::CallInvite(e) => { + event_emitter.on_room_call_invite(room, e).await + } + AnySyncMessageEvent::CallAnswer(e) => { + event_emitter.on_room_call_answer(room, e).await + } + AnySyncMessageEvent::CallCandidates(e) => { + event_emitter.on_room_call_candidates(room, e).await + } + AnySyncMessageEvent::CallHangup(e) => { + event_emitter.on_room_call_hangup(room, e).await + } _ => {} }, AnySyncRoomEvent::RedactedState(_event) => {} diff --git a/matrix_sdk_base/src/event_emitter/mod.rs b/matrix_sdk_base/src/event_emitter/mod.rs index 7a334f4d..8f5937a8 100644 --- a/matrix_sdk_base/src/event_emitter/mod.rs +++ b/matrix_sdk_base/src/event_emitter/mod.rs @@ -19,6 +19,10 @@ use serde_json::value::RawValue as RawJsonValue; use crate::{ events::{ + call::{ + answer::AnswerEventContent, candidates::CandidatesEventContent, + hangup::HangupEventContent, invite::InviteEventContent, + }, custom::CustomEventContent, fully_read::FullyReadEventContent, ignored_user_list::IgnoredUserListEventContent, @@ -135,6 +139,19 @@ pub trait EventEmitter: Send + Sync { _: &SyncMessageEvent, ) { } + /// Fires when `Client` receives a `RoomEvent::CallInvite` event + async fn on_room_call_invite(&self, _: SyncRoom, _: &SyncMessageEvent) {} + /// Fires when `Client` receives a `RoomEvent::CallAnswer` event + async fn on_room_call_answer(&self, _: SyncRoom, _: &SyncMessageEvent) {} + /// Fires when `Client` receives a `RoomEvent::CallCandidates` event + async fn on_room_call_candidates( + &self, + _: SyncRoom, + _: &SyncMessageEvent, + ) { + } + /// Fires when `Client` receives a `RoomEvent::CallHangup` event + async fn on_room_call_hangup(&self, _: SyncRoom, _: &SyncMessageEvent) {} /// Fires when `Client` receives a `RoomEvent::RoomRedaction` event. async fn on_room_redaction(&self, _: SyncRoom, _: &SyncRedactionEvent) {} /// Fires when `Client` receives a `RoomEvent::RoomPowerLevels` event. @@ -317,6 +334,22 @@ mod test { ) { self.0.lock().await.push("feedback".to_string()) } + async fn on_room_call_invite(&self, _: SyncRoom, _: &SyncMessageEvent) { + self.0.lock().await.push("call invite".to_string()) + } + async fn on_room_call_answer(&self, _: SyncRoom, _: &SyncMessageEvent) { + self.0.lock().await.push("call answer".to_string()) + } + async fn on_room_call_candidates( + &self, + _: SyncRoom, + _: &SyncMessageEvent, + ) { + self.0.lock().await.push("call candidates".to_string()) + } + async fn on_room_call_hangup(&self, _: SyncRoom, _: &SyncMessageEvent) { + self.0.lock().await.push("call hangup".to_string()) + } async fn on_room_redaction(&self, _: SyncRoom, _: &SyncRedactionEvent) { self.0.lock().await.push("redaction".to_string()) } @@ -601,4 +634,28 @@ mod test { ], ) } + + #[async_test] + async fn event_emitter_voip() { + let vec = Arc::new(Mutex::new(Vec::new())); + let test_vec = Arc::clone(&vec); + let emitter = Box::new(EvEmitterTest(vec)); + + let client = get_client().await; + client.add_event_emitter(emitter).await; + + let mut response = sync_response(SyncResponseFile::Voip); + client.receive_sync_response(&mut response).await.unwrap(); + + let v = test_vec.lock().await; + assert_eq!( + v.as_slice(), + [ + "call invite", + "call answer", + "call candidates", + "call hangup", + ], + ) + } } diff --git a/matrix_sdk_test/src/lib.rs b/matrix_sdk_test/src/lib.rs index c1659408..02bbd4db 100644 --- a/matrix_sdk_test/src/lib.rs +++ b/matrix_sdk_test/src/lib.rs @@ -355,6 +355,7 @@ pub enum SyncResponseFile { DefaultWithSummary, Invite, Leave, + Voip, } /// Get specific API responses for testing @@ -365,6 +366,7 @@ pub fn sync_response(kind: SyncResponseFile) -> SyncResponse { SyncResponseFile::DefaultWithSummary => &test_json::DEFAULT_SYNC_SUMMARY, SyncResponseFile::Invite => &test_json::INVITE_SYNC, SyncResponseFile::Leave => &test_json::LEAVE_SYNC, + SyncResponseFile::Voip => &test_json::VOIP_SYNC, }; let response = Response::builder() diff --git a/matrix_sdk_test/src/test_json/mod.rs b/matrix_sdk_test/src/test_json/mod.rs index d3e72df5..b03d55b7 100644 --- a/matrix_sdk_test/src/test_json/mod.rs +++ b/matrix_sdk_test/src/test_json/mod.rs @@ -16,7 +16,9 @@ pub use events::{ REACTION, REDACTED, REDACTED_INVALID, REDACTED_STATE, REDACTION, REGISTRATION_RESPONSE_ERR, ROOM_ID, ROOM_MESSAGES, TYPING, }; -pub use sync::{DEFAULT_SYNC_SUMMARY, INVITE_SYNC, LEAVE_SYNC, LEAVE_SYNC_EVENT, MORE_SYNC, SYNC}; +pub use sync::{ + DEFAULT_SYNC_SUMMARY, INVITE_SYNC, LEAVE_SYNC, LEAVE_SYNC_EVENT, MORE_SYNC, SYNC, VOIP_SYNC, +}; lazy_static! { pub static ref DEVICES: JsonValue = json!({ diff --git a/matrix_sdk_test/src/test_json/sync.rs b/matrix_sdk_test/src/test_json/sync.rs index 9bd262c1..868f94e0 100644 --- a/matrix_sdk_test/src/test_json/sync.rs +++ b/matrix_sdk_test/src/test_json/sync.rs @@ -1101,3 +1101,123 @@ lazy_static! { "next_batch": "s1380317562_757269739_1655566_503953763_334052043_1209862_55290918_65705002_101146" }); } + +lazy_static! { + pub static ref VOIP_SYNC: JsonValue = json!({ + "device_one_time_keys_count": {}, + "next_batch": "s526_47314_0_7_1_1_1_11444_1", + "device_lists": { + "changed": [ + "@example:example.org" + ], + "left": [] + }, + "rooms": { + "invite": {}, + "join": { + "!SVkFJHzfwvuaIEawgC:localhost": { + "summary": {}, + "account_data": { + "events": [] + }, + "ephemeral": { + "events": [ ] + }, + "state": { + "events": [] + }, + "timeline": { + "events": [ + { + "content": { + "call_id": "12345", + "lifetime": 60000, + "offer": { + "sdp": "v=0\r\no=- 6584580628695956864 2 IN IP4 127.0.0.1[...]", + "type": "offer" + }, + "version": 0 + }, + "event_id": "$143273582443PhrSn:example.org", + "origin_server_ts": 143273582, + "room_id": "!jEsUZKDJdhlrceRyVU:example.org", + "sender": "@example:example.org", + "type": "m.call.invite", + "unsigned": { + "age": 1234 + } + }, + { + "content": { + "answer": { + "sdp": "v=0\r\no=- 6584580628695956864 2 IN IP4 127.0.0.1[...]", + "type": "answer" + }, + "call_id": "12345", + "lifetime": 60000, + "version": 0 + }, + "event_id": "$143273582443PhrSn:example.org", + "origin_server_ts": 143273582, + "room_id": "!jEsUZKDJdhlrceRyVU:example.org", + "sender": "@example:example.org", + "type": "m.call.answer", + "unsigned": { + "age": 1234 + } + }, + { + "content": { + "call_id": "12345", + "candidates": [ + { + "candidate": "candidate:863018703 1 udp 2122260223 10.9.64.156 43670 typ host generation 0", + "sdpMLineIndex": 0, + "sdpMid": "audio" + } + ], + "version": 0 + }, + "event_id": "$143273582443PhrSn:example.org", + "origin_server_ts": 143273582, + "room_id": "!jEsUZKDJdhlrceRyVU:example.org", + "sender": "@example:example.org", + "type": "m.call.candidates", + "unsigned": { + "age": 1234 + } + }, + { + "content": { + "call_id": "12345", + "version": 0 + }, + "event_id": "$143273582443PhrSn:example.org", + "origin_server_ts": 143273582, + "room_id": "!jEsUZKDJdhlrceRyVU:example.org", + "sender": "@example:example.org", + "type": "m.call.hangup", + "unsigned": { + "age": 1234 + } + } + ], + "limited": true, + "prev_batch": "t392-516_47314_0_7_1_1_1_11444_1" + }, + "unread_notifications": { + "highlight_count": 0, + "notification_count": 11 + } + } + }, + "leave": {} + }, + "to_device": { + "events": [] + }, + "presence": { + "events": [] + } + }); +}