diff --git a/Cargo.lock b/Cargo.lock index cc08e360c9..79b84d4af1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -171,6 +171,7 @@ dependencies = [ "alvr_common", "alvr_filesystem", "alvr_server_io", + "alvr_session", "anyhow", "ureq", "zip", diff --git a/alvr/adb/Cargo.toml b/alvr/adb/Cargo.toml index 4df2982789..842d6683e5 100644 --- a/alvr/adb/Cargo.toml +++ b/alvr/adb/Cargo.toml @@ -10,6 +10,7 @@ license.workspace = true alvr_common.workspace = true alvr_filesystem.workspace = true alvr_server_io.workspace = true +alvr_session.workspace = true anyhow = "1" ureq = "2.10" diff --git a/alvr/adb/src/lib.rs b/alvr/adb/src/lib.rs index d2aea4932d..a0ee62e009 100644 --- a/alvr/adb/src/lib.rs +++ b/alvr/adb/src/lib.rs @@ -3,8 +3,13 @@ mod parse; use alvr_common::anyhow::Result; use alvr_common::{dbg_connection, error}; +use alvr_session::{ClientFlavor, ConnectionConfig}; use std::collections::HashSet; +const PACKAGE_NAME_STORE: &str = "alvr.client"; +const PACKAGE_NAME_GITHUB_DEV: &str = "alvr.client.dev"; +const PACKAGE_NAME_GITHUB_STABLE: &str = "alvr.client.stable"; + pub enum WiredConnectionStatus { Ready, NotReady(String), @@ -24,7 +29,11 @@ impl WiredConnection { Ok(Self { adb_path }) } - pub fn setup(&self, control_port: u16, stream_port: u16) -> Result { + pub fn setup( + &self, + control_port: u16, + config: &ConnectionConfig, + ) -> Result { let Some(device_serial) = commands::list_devices(&self.adb_path)? .into_iter() .filter_map(|d| d.serial) @@ -35,7 +44,7 @@ impl WiredConnection { )); }; - let ports = HashSet::from([control_port, stream_port]); + let ports = HashSet::from([control_port, config.stream_port]); let forwarded_ports: HashSet = commands::list_forwarded_ports(&self.adb_path, &device_serial)? .into_iter() @@ -49,16 +58,26 @@ impl WiredConnection { ); } - #[cfg(debug_assertions)] - let process_name = "alvr.client.dev"; - #[cfg(not(debug_assertions))] - let process_name = "alvr.client.stable"; + let Some(process_name) = + get_process_name(&self.adb_path, &device_serial, &config.wired_client_type) + else { + return Ok(WiredConnectionStatus::NotReady( + "No suitable ALVR client is installed".to_owned(), + )); + }; - if commands::get_process_id(&self.adb_path, &device_serial, process_name)?.is_none() { - Ok(WiredConnectionStatus::NotReady( - "ALVR client is not running".to_owned(), - )) - } else if !commands::is_activity_resumed(&self.adb_path, &device_serial, process_name)? { + if commands::get_process_id(&self.adb_path, &device_serial, &process_name)?.is_none() { + if config.wired_client_autolaunch { + commands::start_application(&self.adb_path, &device_serial, &process_name)?; + Ok(WiredConnectionStatus::NotReady( + "Starting ALVR client".to_owned(), + )) + } else { + Ok(WiredConnectionStatus::NotReady( + "ALVR client is not running".to_owned(), + )) + } + } else if !commands::is_activity_resumed(&self.adb_path, &device_serial, &process_name)? { Ok(WiredConnectionStatus::NotReady( "ALVR client is paused".to_owned(), )) @@ -76,3 +95,41 @@ impl Drop for WiredConnection { } } } + +pub fn get_process_name( + adb_path: &str, + device_serial: &str, + flavor: &ClientFlavor, +) -> Option { + let fallbacks = match flavor { + ClientFlavor::Store => { + if alvr_common::is_stable() { + vec![PACKAGE_NAME_STORE, PACKAGE_NAME_GITHUB_STABLE] + } else { + vec![PACKAGE_NAME_GITHUB_DEV] + } + } + ClientFlavor::Github => { + if alvr_common::is_stable() { + vec![PACKAGE_NAME_GITHUB_STABLE, PACKAGE_NAME_STORE] + } else { + vec![PACKAGE_NAME_GITHUB_DEV] + } + } + ClientFlavor::Custom(name) => { + if alvr_common::is_stable() { + vec![name, PACKAGE_NAME_STORE, PACKAGE_NAME_GITHUB_STABLE] + } else { + vec![name, PACKAGE_NAME_GITHUB_DEV] + } + } + }; + + fallbacks + .iter() + .find(|name| { + commands::is_package_installed(adb_path, device_serial, name) + .is_ok_and(|installed| installed) + }) + .map(|name| name.to_string()) +} diff --git a/alvr/server_core/src/connection.rs b/alvr/server_core/src/connection.rs index d54d115c0f..1420b80b95 100644 --- a/alvr/server_core/src/connection.rs +++ b/alvr/server_core/src/connection.rs @@ -288,10 +288,9 @@ pub fn handshake_loop(ctx: Arc, lifecycle_state: Arc status, Err(e) => { error!("{e:?}"); diff --git a/alvr/session/src/settings.rs b/alvr/session/src/settings.rs index 1e64c6f874..d2ddc9f99f 100644 --- a/alvr/session/src/settings.rs +++ b/alvr/session/src/settings.rs @@ -1110,6 +1110,13 @@ pub enum SocketBufferSize { Custom(#[schema(suffix = "B")] u32), } +#[derive(SettingsSchema, Serialize, Deserialize, Clone)] +pub enum ClientFlavor { + Store, + Github, + Custom(String), +} + #[derive(SettingsSchema, Serialize, Deserialize, Clone)] pub struct ConnectionConfig { #[schema(strings( @@ -1120,6 +1127,16 @@ TCP: Slower than UDP, but more stable. Pick this if you experience video or audi pub client_discovery: Switch, + #[schema(strings( + help = r#"Which release type of client should ALVR look for when establishing a wired connection."# + ))] + pub wired_client_type: ClientFlavor, + + #[schema(strings( + help = r#"Wether ALVR should try to automatically launch the client when establishing a wired connection."# + ))] + pub wired_client_autolaunch: bool, + #[schema(strings( help = "This script will be ran when the headset connects. Env var ACTION will be set to `connect`." ))] @@ -1759,6 +1776,15 @@ pub fn session_settings_default() -> SettingsDefault { auto_trust_clients: cfg!(debug_assertions), }, }, + wired_client_type: ClientFlavorDefault { + Custom: "alvr.client".to_owned(), + variant: if alvr_common::is_stable() { + ClientFlavorDefaultVariant::Store + } else { + ClientFlavorDefaultVariant::Github + }, + }, + wired_client_autolaunch: true, web_server_port: 8082, stream_port: 9944, osc_local_port: 9942,