ReSet/src/components/base/utils.rs

450 lines
10 KiB
Rust

use std::{
sync::{
atomic::{AtomicBool, Ordering},
Arc,
},
thread,
time::Duration,
};
use dbus::{
arg::{self, Append},
blocking::Connection,
Error,
};
use gtk::gio;
use re_set_lib::{
audio::audio_structures::{InputStream, OutputStream, Sink, Source},
signals::GetVal,
};
use crate::components::{
input::source_box::{start_input_box_listener, SourceBox},
output::sink_box::{start_output_box_listener, SinkBox}, utils::{BASE, DBUS_PATH, AUDIO, WIRELESS},
};
#[derive(Default, PartialEq, Eq)]
pub enum Position {
Connectivity,
Wifi,
Bluetooth,
Audio,
AudioOutput,
AudioInput,
#[default]
Home,
}
#[derive(Default)]
pub struct Listeners {
pub wifi_disabled: AtomicBool,
pub wifi_listener: AtomicBool,
pub bluetooth_listener: AtomicBool,
pub bluetooth_scan_requested: AtomicBool,
pub pulse_listener: AtomicBool,
}
impl Listeners {
pub fn stop_network_listener(&self) {
if !self.wifi_listener.load(Ordering::SeqCst) {
return;
}
self.wifi_listener.store(false, Ordering::SeqCst);
thread::spawn(|| {
let conn = Connection::new_session().unwrap();
let proxy = conn.with_proxy(
BASE,
DBUS_PATH,
Duration::from_millis(1000),
);
let _: Result<(bool,), Error> =
proxy.method_call(WIRELESS, "StopNetworkListener", ());
});
}
pub fn stop_audio_listener(&self) {
self.pulse_listener.store(false, Ordering::SeqCst);
}
pub fn stop_bluetooth_listener(&self) {
self.bluetooth_listener.store(false, Ordering::SeqCst);
}
}
#[derive(Debug)]
pub struct SinkAdded {
pub sink: Sink,
}
impl arg::AppendAll for SinkAdded {
fn append(&self, i: &mut arg::IterAppend) {
self.sink.append_by_ref(i);
}
}
impl arg::ReadAll for SinkAdded {
fn read(i: &mut arg::Iter) -> Result<Self, arg::TypeMismatchError> {
Ok(SinkAdded { sink: i.read()? })
}
}
impl dbus::message::SignalArgs for SinkAdded {
const NAME: &'static str = "SinkAdded";
const INTERFACE: &'static str = AUDIO;
}
impl GetVal<(Sink,)> for SinkAdded {
fn get_value(&self) -> (Sink,) {
(self.sink.clone(),)
}
}
#[derive(Debug)]
pub struct SinkChanged {
pub sink: Sink,
}
impl arg::AppendAll for SinkChanged {
fn append(&self, i: &mut arg::IterAppend) {
self.sink.append_by_ref(i);
}
}
impl arg::ReadAll for SinkChanged {
fn read(i: &mut arg::Iter) -> Result<Self, arg::TypeMismatchError> {
Ok(SinkChanged { sink: i.read()? })
}
}
impl dbus::message::SignalArgs for SinkChanged {
const NAME: &'static str = "SinkChanged";
const INTERFACE: &'static str = AUDIO;
}
impl GetVal<(Sink,)> for SinkChanged {
fn get_value(&self) -> (Sink,) {
(self.sink.clone(),)
}
}
#[derive(Debug)]
pub struct SinkRemoved {
pub index: u32,
}
impl arg::AppendAll for SinkRemoved {
fn append(&self, i: &mut arg::IterAppend) {
self.index.append_by_ref(i);
}
}
impl arg::ReadAll for SinkRemoved {
fn read(i: &mut arg::Iter) -> Result<Self, arg::TypeMismatchError> {
Ok(SinkRemoved { index: i.read()? })
}
}
impl dbus::message::SignalArgs for SinkRemoved {
const NAME: &'static str = "SinkRemoved";
const INTERFACE: &'static str = AUDIO;
}
impl GetVal<(u32,)> for SinkRemoved {
fn get_value(&self) -> (u32,) {
(self.index,)
}
}
#[derive(Debug)]
pub struct InputStreamAdded {
pub stream: InputStream,
}
impl arg::AppendAll for InputStreamAdded {
fn append(&self, i: &mut arg::IterAppend) {
self.stream.append_by_ref(i);
}
}
impl arg::ReadAll for InputStreamAdded {
fn read(i: &mut arg::Iter) -> Result<Self, arg::TypeMismatchError> {
Ok(InputStreamAdded { stream: i.read()? })
}
}
impl dbus::message::SignalArgs for InputStreamAdded {
const NAME: &'static str = "InputStreamAdded";
const INTERFACE: &'static str = AUDIO;
}
impl GetVal<(InputStream,)> for InputStreamAdded {
fn get_value(&self) -> (InputStream,) {
(self.stream.clone(),)
}
}
#[derive(Debug)]
pub struct InputStreamChanged {
pub stream: InputStream,
}
impl arg::AppendAll for InputStreamChanged {
fn append(&self, i: &mut arg::IterAppend) {
self.stream.append_by_ref(i);
}
}
impl arg::ReadAll for InputStreamChanged {
fn read(i: &mut arg::Iter) -> Result<Self, arg::TypeMismatchError> {
Ok(InputStreamChanged { stream: i.read()? })
}
}
impl dbus::message::SignalArgs for InputStreamChanged {
const NAME: &'static str = "InputStreamChanged";
const INTERFACE: &'static str = AUDIO;
}
#[derive(Debug)]
pub struct InputStreamRemoved {
pub index: u32,
}
impl arg::AppendAll for InputStreamRemoved {
fn append(&self, i: &mut arg::IterAppend) {
self.index.append_by_ref(i);
}
}
impl arg::ReadAll for InputStreamRemoved {
fn read(i: &mut arg::Iter) -> Result<Self, arg::TypeMismatchError> {
Ok(InputStreamRemoved { index: i.read()? })
}
}
impl dbus::message::SignalArgs for InputStreamRemoved {
const NAME: &'static str = "InputStreamRemoved";
const INTERFACE: &'static str = AUDIO;
}
impl GetVal<(u32,)> for InputStreamRemoved {
fn get_value(&self) -> (u32,) {
(self.index,)
}
}
#[derive(Debug)]
pub struct SourceAdded {
pub source: Source,
}
impl arg::AppendAll for SourceAdded {
fn append(&self, i: &mut arg::IterAppend) {
self.source.append_by_ref(i);
}
}
impl arg::ReadAll for SourceAdded {
fn read(i: &mut arg::Iter) -> Result<Self, arg::TypeMismatchError> {
Ok(SourceAdded { source: i.read()? })
}
}
impl dbus::message::SignalArgs for SourceAdded {
const NAME: &'static str = "SourceAdded";
const INTERFACE: &'static str = AUDIO;
}
impl GetVal<(Source,)> for SourceAdded {
fn get_value(&self) -> (Source,) {
(self.source.clone(),)
}
}
#[derive(Debug)]
pub struct SourceChanged {
pub source: Source,
}
impl arg::AppendAll for SourceChanged {
fn append(&self, i: &mut arg::IterAppend) {
self.source.append_by_ref(i);
}
}
impl arg::ReadAll for SourceChanged {
fn read(i: &mut arg::Iter) -> Result<Self, arg::TypeMismatchError> {
Ok(SourceChanged { source: i.read()? })
}
}
impl dbus::message::SignalArgs for SourceChanged {
const NAME: &'static str = "SourceChanged";
const INTERFACE: &'static str = AUDIO;
}
impl GetVal<(Source,)> for SourceChanged {
fn get_value(&self) -> (Source,) {
(self.source.clone(),)
}
}
#[derive(Debug)]
pub struct SourceRemoved {
pub index: u32,
}
impl arg::AppendAll for SourceRemoved {
fn append(&self, i: &mut arg::IterAppend) {
self.index.append_by_ref(i);
}
}
impl arg::ReadAll for SourceRemoved {
fn read(i: &mut arg::Iter) -> Result<Self, arg::TypeMismatchError> {
Ok(SourceRemoved { index: i.read()? })
}
}
impl dbus::message::SignalArgs for SourceRemoved {
const NAME: &'static str = "SourceRemoved";
const INTERFACE: &'static str = AUDIO;
}
impl GetVal<(u32,)> for SourceRemoved {
fn get_value(&self) -> (u32,) {
(self.index,)
}
}
#[derive(Debug)]
pub struct OutputStreamAdded {
pub stream: OutputStream,
}
impl arg::AppendAll for OutputStreamAdded {
fn append(&self, i: &mut arg::IterAppend) {
self.stream.append_by_ref(i);
}
}
impl arg::ReadAll for OutputStreamAdded {
fn read(i: &mut arg::Iter) -> Result<Self, arg::TypeMismatchError> {
Ok(OutputStreamAdded { stream: i.read()? })
}
}
impl dbus::message::SignalArgs for OutputStreamAdded {
const NAME: &'static str = "OutputStreamAdded";
const INTERFACE: &'static str = AUDIO;
}
impl GetVal<(OutputStream,)> for OutputStreamAdded {
fn get_value(&self) -> (OutputStream,) {
(self.stream.clone(),)
}
}
#[derive(Debug)]
pub struct OutputStreamChanged {
pub stream: OutputStream,
}
impl arg::AppendAll for OutputStreamChanged {
fn append(&self, i: &mut arg::IterAppend) {
self.stream.append_by_ref(i);
}
}
impl arg::ReadAll for OutputStreamChanged {
fn read(i: &mut arg::Iter) -> Result<Self, arg::TypeMismatchError> {
Ok(OutputStreamChanged { stream: i.read()? })
}
}
impl dbus::message::SignalArgs for OutputStreamChanged {
const NAME: &'static str = "OutputStreamChanged";
const INTERFACE: &'static str = AUDIO;
}
#[derive(Debug)]
pub struct OutputStreamRemoved {
pub index: u32,
}
impl arg::AppendAll for OutputStreamRemoved {
fn append(&self, i: &mut arg::IterAppend) {
self.index.append_by_ref(i);
}
}
impl arg::ReadAll for OutputStreamRemoved {
fn read(i: &mut arg::Iter) -> Result<Self, arg::TypeMismatchError> {
Ok(OutputStreamRemoved { index: i.read()? })
}
}
impl dbus::message::SignalArgs for OutputStreamRemoved {
const NAME: &'static str = "OutputStreamRemoved";
const INTERFACE: &'static str = AUDIO;
}
impl GetVal<(u32,)> for OutputStreamRemoved {
fn get_value(&self) -> (u32,) {
(self.index,)
}
}
pub fn start_audio_listener(
listeners: Arc<Listeners>,
sink_box: Option<Arc<SinkBox>>,
source_box: Option<Arc<SourceBox>>,
) {
gio::spawn_blocking(move || {
let conn = Connection::new_session().unwrap();
if listeners.pulse_listener.load(Ordering::SeqCst) {
return;
}
let mut conn = start_dbus_audio_listener(conn);
if let Some(sink_box) = sink_box {
conn = start_output_box_listener(conn, sink_box);
}
if let Some(source_box) = source_box {
conn = start_input_box_listener(conn, source_box);
}
listeners.pulse_listener.store(true, Ordering::SeqCst);
loop {
let _ = conn.process(Duration::from_millis(1000));
if !listeners.pulse_listener.load(Ordering::SeqCst) {
stop_dbus_audio_listener(conn);
break;
}
// thread::sleep(Duration::from_millis(1000));
// TODO is this really how we should do this?
}
});
}
fn start_dbus_audio_listener(conn: Connection) -> Connection {
let proxy = conn.with_proxy(
BASE,
DBUS_PATH,
Duration::from_millis(1000),
);
let _: Result<(), Error> = proxy.method_call(AUDIO, "StartAudioListener", ());
conn
}
fn stop_dbus_audio_listener(conn: Connection) {
let proxy = conn.with_proxy(
BASE,
DBUS_PATH,
Duration::from_millis(1000),
);
let _: Result<(), Error> = proxy.method_call(AUDIO, "StopAudioListener", ());
}