From 45b93100d6d0837d53d12dca30605cc0b10b1ea4 Mon Sep 17 00:00:00 2001 From: Kingtous Date: Sun, 5 Feb 2023 23:47:06 +0800 Subject: [PATCH] feat: add voice call proto --- libs/hbb_common/protos/message.proto | 14 ++++++ src/client.rs | 49 +++++++++++---------- src/client/io_loop.rs | 64 ++++++++++++++++++---------- src/flutter_ffi.rs | 18 ++++++-- src/server/connection.rs | 6 +++ src/ui/remote.rs | 8 ++-- src/ui_session_interface.rs | 48 +++++++++++++-------- 7 files changed, 138 insertions(+), 69 deletions(-) diff --git a/libs/hbb_common/protos/message.proto b/libs/hbb_common/protos/message.proto index 48b999438..323b464fa 100644 --- a/libs/hbb_common/protos/message.proto +++ b/libs/hbb_common/protos/message.proto @@ -604,6 +604,18 @@ message Misc { } } +message VoiceCallRequest { + int64 req_timestamp = 1; + // Indicates whether the request is a connect action or a disconnect action. + bool is_connect = 2; +} + +message VoiceCallResponse { + bool accepted = 1; + int64 req_timestamp = 2; // Should copy from [VoiceCallRequest::req_timestamp]. + int64 ack_timestamp = 3; +} + message Message { oneof union { SignedId signed_id = 3; @@ -626,5 +638,7 @@ message Message { Cliprdr cliprdr = 20; MessageBox message_box = 21; SwitchSidesResponse switch_sides_response = 22; + VoiceCallRequest voice_call_request = 23; + VoiceCallResponse voice_call_response = 24; } } diff --git a/src/client.rs b/src/client.rs index 649b180bb..5911c40ed 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,58 +1,61 @@ -pub use async_trait::async_trait; -use bytes::Bytes; -#[cfg(not(any(target_os = "android", target_os = "linux")))] -use cpal::{ - traits::{DeviceTrait, HostTrait, StreamTrait}, - Device, Host, StreamConfig, -}; -use magnum_opus::{Channels::*, Decoder as AudioDecoder}; -use sha2::{Digest, Sha256}; use std::{ collections::HashMap, net::SocketAddr, ops::{Deref, Not}, str::FromStr, - sync::{atomic::AtomicBool, mpsc, Arc, Mutex, RwLock}, + sync::{Arc, atomic::AtomicBool, mpsc, Mutex, RwLock}, }; + +pub use async_trait::async_trait; +use bytes::Bytes; +#[cfg(not(any(target_os = "android", target_os = "linux")))] +use cpal::{ + Device, + Host, StreamConfig, traits::{DeviceTrait, HostTrait, StreamTrait}, +}; +use magnum_opus::{Channels::*, Decoder as AudioDecoder}; +use sha2::{Digest, Sha256}; use uuid::Uuid; pub use file_trait::FileManager; use hbb_common::{ + AddrMangle, allow_err, anyhow::{anyhow, Context}, bail, config::{ - Config, PeerConfig, PeerInfoSerde, CONNECT_TIMEOUT, READ_TIMEOUT, RELAY_PORT, + Config, CONNECT_TIMEOUT, PeerConfig, PeerInfoSerde, READ_TIMEOUT, RELAY_PORT, RENDEZVOUS_TIMEOUT, - }, - get_version_number, log, - message_proto::{option_message::BoolOption, *}, + }, get_version_number, + log, + message_proto::{*, option_message::BoolOption}, protobuf::Message as _, rand, rendezvous_proto::*, + ResultType, socket_client, sodiumoxide::crypto::{box_, secretbox, sign}, - timeout, - tokio::time::Duration, - AddrMangle, ResultType, Stream, + Stream, timeout, tokio::time::Duration, }; -pub use helper::LatencyController; pub use helper::*; +pub use helper::LatencyController; use scrap::{ codec::{Decoder, DecoderCfg}, record::{Recorder, RecorderContext}, VpxDecoderConfig, VpxVideoCodecId, }; +use crate::{ + common::{self, is_keyboard_mode_supported}, + server::video_service::{SCRAP_X11_REF_URL, SCRAP_X11_REQUIRED}, +}; + pub use super::lang::*; pub mod file_trait; pub mod helper; pub mod io_loop; -use crate::{ - common::{self, is_keyboard_mode_supported}, - server::video_service::{SCRAP_X11_REF_URL, SCRAP_X11_REQUIRED}, -}; + pub static SERVER_KEYBOARD_ENABLED: AtomicBool = AtomicBool::new(true); pub static SERVER_FILE_TRANSFER_ENABLED: AtomicBool = AtomicBool::new(true); pub static SERVER_CLIPBOARD_ENABLED: AtomicBool = AtomicBool::new(true); @@ -1989,6 +1992,8 @@ pub enum Data { RecordScreen(bool, i32, i32, String), ElevateDirect, ElevateWithLogon(String, String), + NewVoiceCall, + CloseVoiceCall, } /// Keycode for key events. diff --git a/src/client/io_loop.rs b/src/client/io_loop.rs index dcfa7b74e..67946f546 100644 --- a/src/client/io_loop.rs +++ b/src/client/io_loop.rs @@ -1,42 +1,38 @@ -use crate::client::{ - Client, CodecFormat, LoginConfigHandler, MediaData, MediaSender, QualityStatus, MILLI1, SEC30, - SERVER_CLIPBOARD_ENABLED, SERVER_FILE_TRANSFER_ENABLED, SERVER_KEYBOARD_ENABLED, -}; -use crate::common::{get_default_sound_input, set_sound_input}; -#[cfg(not(any(target_os = "android", target_os = "ios")))] -use crate::common::{check_clipboard, update_clipboard, ClipboardContext, CLIPBOARD_INTERVAL}; -use crate::{audio_service, common, ConnInner, CLIENT_SERVER}; +use std::collections::HashMap; +use std::sync::{Arc, Mutex}; +use std::sync::atomic::{AtomicUsize, Ordering}; #[cfg(windows)] use clipboard::{cliprdr::CliprdrClientContext, ContextSend}; - -use hbb_common::tokio::sync::mpsc::error::TryRecvError; - -use crate::ui_session_interface::{InvokeUiSession, Session}; -use crate::{client::Data, client::Interface}; - +use hbb_common::{allow_err, message_proto::*, sleep, get_time}; +use hbb_common::{fs, log, Stream}; use hbb_common::config::{PeerConfig, TransferSerde}; use hbb_common::fs::{ - can_enable_overwrite_detection, get_job, get_string, new_send_confirm, DigestCheckResult, + can_enable_overwrite_detection, DigestCheckResult, get_job, get_string, new_send_confirm, RemoveJobMeta, }; use hbb_common::message_proto::permission_info::Permission; use hbb_common::protobuf::Message as _; use hbb_common::rendezvous_proto::ConnType; -#[cfg(windows)] -use hbb_common::tokio::sync::Mutex as TokioMutex; use hbb_common::tokio::{ self, sync::mpsc, time::{self, Duration, Instant, Interval}, }; -use hbb_common::{allow_err, message_proto::*, sleep}; -use hbb_common::{fs, log, Stream}; +use hbb_common::tokio::sync::mpsc::error::TryRecvError; +#[cfg(windows)] +use hbb_common::tokio::sync::Mutex as TokioMutex; -use std::collections::HashMap; - -use std::sync::atomic::{AtomicUsize, Ordering}; -use std::sync::{Arc, Mutex}; +use crate::{audio_service, CLIENT_SERVER, common, ConnInner}; +use crate::{client::Data, client::Interface}; +use crate::client::{ + Client, CodecFormat, LoginConfigHandler, MediaData, MediaSender, MILLI1, QualityStatus, SEC30, + SERVER_CLIPBOARD_ENABLED, SERVER_FILE_TRANSFER_ENABLED, SERVER_KEYBOARD_ENABLED, +}; +use crate::common::{get_default_sound_input, set_sound_input}; +#[cfg(not(any(target_os = "android", target_os = "ios")))] +use crate::common::{check_clipboard, CLIPBOARD_INTERVAL, ClipboardContext, update_clipboard}; +use crate::ui_session_interface::{InvokeUiSession, Session}; pub struct Remote { handler: Session, @@ -752,6 +748,22 @@ impl Remote { msg.set_misc(misc); allow_err!(peer.send(&msg).await); } + Data::NewVoiceCall => { + let mut request = VoiceCallRequest::new(); + request.is_connect = true; + request.req_timestamp = get_time(); + let mut msg = Message::new(); + msg.set_voice_call_request(request); + allow_err!(peer.send(&msg).await); + } + Data::CloseVoiceCall => { + let mut request = VoiceCallRequest::new(); + request.is_connect = false; + request.req_timestamp = get_time(); + let mut msg = Message::new(); + msg.set_voice_call_request(request); + allow_err!(peer.send(&msg).await); + } _ => {} } true @@ -1262,6 +1274,12 @@ impl Remote { self.handler .msgbox(&msgbox.msgtype, &msgbox.title, &msgbox.text, &link); } + Some(message::Union::VoiceCallRequest(request)) => { + // TODO + } + Some(message::Union::VoiceCallResponse(response)) => { + // TODO + } _ => {} } } diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index 1ecbb0646..15bfe90d4 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -4,19 +4,19 @@ use std::str::FromStr; use flutter_rust_bridge::{StreamSink, SyncReturn, ZeroCopyBuffer}; use serde_json::json; -use crate::common::{is_keyboard_mode_supported, get_default_sound_input}; -use hbb_common::message_proto::KeyboardMode; -use hbb_common::ResultType; use hbb_common::{ config::{self, LocalConfig, ONLINE, PeerConfig}, fs, log, }; +use hbb_common::message_proto::KeyboardMode; +use hbb_common::ResultType; use crate::{ client::file_trait::FileManager, common::make_fd_to_json, flutter::{session_add, session_start_}, }; +use crate::common::{get_default_sound_input, is_keyboard_mode_supported}; use crate::flutter::{self, SESSIONS}; use crate::ui_interface::{self, *}; @@ -840,6 +840,18 @@ pub fn session_new_rdp(id: String) { } } +pub fn session_request_voice_call(id: String) { + if let Some(session) = SESSIONS.write().unwrap().get_mut(&id) { + session.request_voice_call(); + } +} + +pub fn session_close_voice_call(id: String) { + if let Some(session) = SESSIONS.write().unwrap().get_mut(&id) { + session.close_voice_call(); + } +} + pub fn main_get_last_remote_id() -> String { LocalConfig::get_remote_id() } diff --git a/src/server/connection.rs b/src/server/connection.rs index 20cbe0f86..c3acae9cc 100644 --- a/src/server/connection.rs +++ b/src/server/connection.rs @@ -1572,6 +1572,12 @@ impl Connection { allow_err!(self.audio_sender.send(MediaData::AudioFrame(frame))); } } + Some(message::Union::VoiceCallRequest(request)) => { + // TODO + } + Some(message::Union::VoiceCallResponse(response)) => { + // TODO + } _ => {} } } diff --git a/src/ui/remote.rs b/src/ui/remote.rs index 541d3a141..1b0d172b9 100644 --- a/src/ui/remote.rs +++ b/src/ui/remote.rs @@ -6,12 +6,12 @@ use std::{ use sciter::{ dom::{ - event::{EventReason, BEHAVIOR_EVENTS, EVENT_GROUPS, PHASE_MASK}, - Element, HELEMENT, + Element, + event::{BEHAVIOR_EVENTS, EVENT_GROUPS, EventReason, PHASE_MASK}, HELEMENT, }, make_args, - video::{video_destination, AssetPtr, COLOR_SPACE}, Value, + video::{AssetPtr, COLOR_SPACE, video_destination}, }; use hbb_common::{ @@ -422,6 +422,8 @@ impl sciter::EventHandler for SciterSession { fn restart_remote_device(); fn save_audio_mode(String); fn get_audio_mode(); + fn request_voice_call(); + fn close_voice_call(); } } diff --git a/src/ui_session_interface.rs b/src/ui_session_interface.rs index 1e7848505..147cd9149 100644 --- a/src/ui_session_interface.rs +++ b/src/ui_session_interface.rs @@ -1,26 +1,30 @@ -use crate::client::io_loop::Remote; -use crate::client::{ - check_if_retry, handle_hash, handle_login_error, handle_login_from_ui, handle_test_delay, - input_os_password, load_config, send_mouse, start_video_audio_threads, FileManager, Key, - LoginConfigHandler, QualityStatus, KEY_MAP, -}; -use crate::common::{self, GrabState}; -use crate::keyboard; -use crate::{client::Data, client::Interface}; -use async_trait::async_trait; -use bytes::Bytes; -use hbb_common::config::{Config, LocalConfig, PeerConfig, RS_PUB_KEY}; -use hbb_common::rendezvous_proto::ConnType; -use hbb_common::tokio::{self, sync::mpsc}; -use hbb_common::{allow_err, message_proto::*}; -use hbb_common::{fs, get_version_number, log, Stream}; -use rdev::{Event, EventType::*}; use std::collections::HashMap; use std::ops::{Deref, DerefMut}; use std::str::FromStr; -use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; use std::sync::{Arc, Mutex, RwLock}; +use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering}; + +use async_trait::async_trait; +use bytes::Bytes; +use rdev::{Event, EventType::*}; use uuid::Uuid; + +use hbb_common::{allow_err, message_proto::*}; +use hbb_common::{fs, get_version_number, log, Stream}; +use hbb_common::config::{Config, LocalConfig, PeerConfig, RS_PUB_KEY}; +use hbb_common::rendezvous_proto::ConnType; +use hbb_common::tokio::{self, sync::mpsc}; + +use crate::{client::Data, client::Interface}; +use crate::client::{ + check_if_retry, FileManager, handle_hash, handle_login_error, handle_login_from_ui, + handle_test_delay, input_os_password, Key, KEY_MAP, load_config, LoginConfigHandler, + QualityStatus, send_mouse, start_video_audio_threads, +}; +use crate::client::io_loop::Remote; +use crate::common::{self, GrabState}; +use crate::keyboard; + pub static IS_IN: AtomicBool = AtomicBool::new(false); #[derive(Clone, Default)] @@ -669,6 +673,14 @@ impl Session { } } } + + pub fn request_voice_call(&self) { + self.send(Data::NewVoiceCall); + } + + pub fn close_voice_call(&self) { + self.send(Data::CloseVoiceCall); + } } pub trait InvokeUiSession: Send + Sync + Clone + 'static + Sized + Default {