Skip to content

Commit

Permalink
fix(dashboard): 🐛 Allow dashboard logging to bypass notification level
Browse files Browse the repository at this point in the history
  • Loading branch information
zmerp committed Nov 22, 2023
1 parent 41be267 commit 0b0d044
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 91 deletions.
14 changes: 12 additions & 2 deletions alvr/dashboard/src/dashboard/components/notifications.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,19 @@ impl NotificationBar {
}
}

pub fn push_notification(&mut self, event: LogEntry) {
pub fn push_notification(&mut self, event: LogEntry, from_dashboard: bool) {
let now = Instant::now();
if event.severity >= self.min_notification_level
let min_severity = if from_dashboard {
if cfg!(debug_assertions) {
LogSeverity::Debug
} else {
LogSeverity::Info
}
} else {
self.min_notification_level
};

if event.severity >= min_severity
&& (now > self.receive_instant + TIMEOUT || event.severity >= self.current_level)
{
self.message = event.content;
Expand Down
122 changes: 55 additions & 67 deletions alvr/dashboard/src/dashboard/components/setup_wizard.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
use crate::dashboard::basic_components;
use alvr_common::{error, warn};
use alvr_packets::{FirewallRulesAction, PathValuePair, ServerRequest};
use eframe::{
egui::{Button, Label, Layout, RichText, Ui},
emath::Align,
};
use std::error::Error;
use std::{
fs::{self, File},
io,
};

pub enum SetupWizardRequest {
ServerRequest(ServerRequest),
Expand Down Expand Up @@ -120,58 +114,58 @@ impl SetupWizard {
Make sure you have at least one output audio device.",
|_| (),
),
Page::SoftwareRequirements => {
page_content(
ui,
"Software requirements",
if cfg!(windows) {
r"To stream the headset microphone on Windows you need to install VB-Cable or Voicemeeter."
} else if cfg!(target_os = "linux") {
r"To stream the headset microphone on Linux, you might be required to use pipewire and On connect/On disconnect script.
Page::SoftwareRequirements => page_content(
ui,
"Software requirements",
if cfg!(windows) {
r"To stream the headset microphone on Windows you need to install VB-Cable or Voicemeeter."
} else if cfg!(target_os = "linux") {
r"To stream the headset microphone on Linux, you might be required to use pipewire and On connect/On disconnect script.
Script is not 100% stable and might cause some instability issues with pipewire, but it should work."
} else {
r"N/A"
},
|ui| {
#[cfg(windows)]
if ui.button("Download VB-Cable").clicked() {
ui.ctx().open_url(crate::dashboard::egui::OpenUrl::same_tab(
"https://vb-audio.com/Cable/",
));
}
} else {
r"Unsupported OS"
},
|ui| {
#[cfg(windows)]
if ui.button("Download VB-Cable").clicked() {
ui.ctx().open_url(crate::dashboard::egui::OpenUrl::same_tab(
"https://vb-audio.com/Cable/",
));
}

#[cfg(target_os = "linux")]
if ui
.button("Download and set 'On connect/On disconnect' script")
.clicked()
{
match download_and_prepare_audio_script() {
Ok(audio_script_path) => {
request =
Some(SetupWizardRequest::ServerRequest(
ServerRequest::SetValues(vec![
PathValuePair {
path: alvr_packets::parse_path(
"session_settings.connection.on_connect_script",
),
value: serde_json::Value::String(audio_script_path.clone()),
},
PathValuePair {
path: alvr_packets::parse_path(
"session_settings.connection.on_disconnect_script",
),
value: serde_json::Value::String(audio_script_path.clone()),
},
]),
));
warn!("Successfully downloaded and set On connect / On disconnect script")
}
Err(e) => error!("{e}"),
#[cfg(target_os = "linux")]
if ui
.button("Download and set 'On connect/On disconnect' script")
.clicked()
{
match download_and_prepare_audio_script() {
Ok(audio_script_path) => {
let path_json = serde_json::Value::String(
audio_script_path.to_string_lossy().to_string(),
);
request = Some(SetupWizardRequest::ServerRequest(
ServerRequest::SetValues(vec![
PathValuePair {
path: alvr_packets::parse_path(
"session_settings.connection.on_connect_script",
),
value: path_json.clone(),
},
PathValuePair {
path: alvr_packets::parse_path(
"session_settings.connection.on_disconnect_script",
),
value: path_json,
},
]),
));
alvr_common::info!("Successfully downloaded and set On connect / On disconnect script")
}
Err(e) => alvr_common::error!("{e}"),
}
},
)
}
}
},
),
Page::HandGestures => page_content(
ui,
"Hand Gestures",
Expand Down Expand Up @@ -244,25 +238,19 @@ This requires administrator rights!",
}

#[cfg(target_os = "linux")]
fn download_and_prepare_audio_script() -> Result<String, Box<dyn Error>> {
use std::os::unix::fs::PermissionsExt;
fn download_and_prepare_audio_script() -> alvr_common::anyhow::Result<std::path::PathBuf> {
use std::{fs, os::unix::fs::PermissionsExt};

let audio_script_path = alvr_filesystem::filesystem_layout_invalid()
.config_dir
.join("audio-setup.sh");
let response = ureq::get(
"https://raw.githubusercontent.com/alvr-org/ALVR-Distrobox-Linux-Guide/main/audio-setup.sh",
)
.call()?;

let layout = alvr_filesystem::filesystem_layout_invalid();
let config_path = layout
.config_dir
.to_str()
.ok_or("Couldn't get config dir")?;
let audio_script_path = format!("{}/audio-setup.sh", config_path);
let mut out = File::create(audio_script_path.clone())?;

let script_body = response.into_string()?;
io::copy(&mut script_body.as_bytes(), &mut out)?;
fs::set_permissions(audio_script_path.clone(), fs::Permissions::from_mode(0o755))?;
fs::write(&audio_script_path, response.into_string()?);
fs::set_permissions(&audio_script_path, fs::Permissions::from_mode(0o755))?;

Ok(audio_script_path)
}
9 changes: 5 additions & 4 deletions alvr/dashboard/src/dashboard/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,12 @@ impl eframe::App for Dashboard {
let connected_to_server = self.data_sources.server_connected();

while let Some(event) = self.data_sources.poll_event() {
self.logs_tab.push_event(event.clone());
self.logs_tab.push_event(event.inner.clone());

match event.event_type {
EventType::Log(event) => {
self.notification_bar.push_notification(event);
match event.inner.event_type {
EventType::Log(log_event) => {
self.notification_bar
.push_notification(log_event, event.from_dashboard);
}
EventType::GraphStatistics(graph_statistics) => self
.statistics_tab
Expand Down
35 changes: 24 additions & 11 deletions alvr/dashboard/src/data_sources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,24 @@ pub fn get_local_data_source() -> ServerDataManager {

fn report_event_local(
context: &egui::Context,
sender: &mpsc::Sender<Event>,
sender: &mpsc::Sender<PolledEvent>,
event_type: EventType,
) {
sender
.send(Event {
timestamp: "".into(),
event_type,
.send(PolledEvent {
inner: Event {
timestamp: "".into(),
event_type,
},
from_dashboard: false,
})
.ok();
context.request_repaint();
}

fn report_session_local(
context: &egui::Context,
sender: &mpsc::Sender<Event>,
sender: &mpsc::Sender<PolledEvent>,
data_manager: &mut ServerDataManager,
) {
report_event_local(
Expand All @@ -55,10 +58,15 @@ fn report_session_local(
)
}

pub struct PolledEvent {
pub inner: Event,
pub from_dashboard: bool,
}

pub struct DataSources {
running: Arc<RelaxedAtomic>,
requests_sender: mpsc::Sender<ServerRequest>,
events_receiver: mpsc::Receiver<Event>,
events_receiver: mpsc::Receiver<PolledEvent>,
server_connected: Arc<RelaxedAtomic>,
requests_thread: Option<JoinHandle<()>>,
events_thread: Option<JoinHandle<()>>,
Expand All @@ -68,8 +76,8 @@ pub struct DataSources {
impl DataSources {
pub fn new(
context: egui::Context,
events_sender: mpsc::Sender<Event>,
events_receiver: mpsc::Receiver<Event>,
events_sender: mpsc::Sender<PolledEvent>,
events_receiver: mpsc::Receiver<PolledEvent>,
) -> Self {
let running = Arc::new(RelaxedAtomic::new(true));
let (requests_sender, requests_receiver) = mpsc::channel();
Expand Down Expand Up @@ -223,8 +231,13 @@ impl DataSources {
match ws.read() {
Ok(tungstenite::Message::Text(json_string)) => {
if let Ok(event) = serde_json::from_str(&json_string) {
debug!("Server event received: {event:?}");
events_sender.send(event).ok();
debug!("Server event received: {:?}", event);
events_sender
.send(PolledEvent {
inner: event,
from_dashboard: false,
})
.ok();
context.request_repaint();
}
}
Expand Down Expand Up @@ -303,7 +316,7 @@ impl DataSources {
self.requests_sender.send(request).ok();
}

pub fn poll_event(&self) -> Option<Event> {
pub fn poll_event(&self) -> Option<PolledEvent> {
self.events_receiver.try_recv().ok()
}

Expand Down
18 changes: 11 additions & 7 deletions alvr/dashboard/src/logging_backend.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
use crate::data_sources::PolledEvent;
use alvr_common::{log::LevelFilter, parking_lot::Mutex, LogEntry, LogSeverity};
use alvr_events::{Event, EventType};
use std::{
io::Write,
sync::{mpsc, Arc},
};

pub fn init_logging(event_sender: mpsc::Sender<Event>) {
pub fn init_logging(event_sender: mpsc::Sender<PolledEvent>) {
let event_sender = Arc::new(Mutex::new(event_sender));

env_logger::Builder::new()
Expand All @@ -24,12 +25,15 @@ pub fn init_logging(event_sender: mpsc::Sender<Event>) {

event_sender
.lock()
.send(Event {
timestamp: timestamp.clone(),
event_type: EventType::Log(LogEntry {
severity: LogSeverity::from_log_level(record.level()),
content: format!("{}", record.args()),
}),
.send(PolledEvent {
inner: Event {
timestamp: timestamp.clone(),
event_type: EventType::Log(LogEntry {
severity: LogSeverity::from_log_level(record.level()),
content: format!("{}", record.args()),
}),
},
from_dashboard: true,
})
.ok();

Expand Down

0 comments on commit 0b0d044

Please sign in to comment.