Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to connect to the dev server from a physical Android device #3634

Merged
merged 3 commits into from
Jan 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions packages/cli-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ use std::{
pub const CLI_ENABLED_ENV: &str = "DIOXUS_CLI_ENABLED";
pub const SERVER_IP_ENV: &str = "IP";
pub const SERVER_PORT_ENV: &str = "PORT";
pub const DEVSERVER_RAW_ADDR_ENV: &str = "DIOXUS_DEVSERVER_ADDR";
pub const DEVSERVER_IP_ENV: &str = "DIOXUS_DEVSERVER_IP";
pub const DEVSERVER_PORT_ENV: &str = "DIOXUS_DEVSERVER_PORT";
pub const ALWAYS_ON_TOP_ENV: &str = "DIOXUS_ALWAYS_ON_TOP";
pub const ASSET_ROOT_ENV: &str = "DIOXUS_ASSET_ROOT";
pub const APP_TITLE_ENV: &str = "DIOXUS_APP_TITLE";
Expand Down Expand Up @@ -100,8 +101,16 @@ macro_rules! read_env_config {
/// For reference, the devserver typically lives on `127.0.0.1:8080` and serves the devserver websocket
/// on `127.0.0.1:8080/_dioxus`.
pub fn devserver_raw_addr() -> Option<SocketAddr> {
let addr = std::env::var(DEVSERVER_RAW_ADDR_ENV).ok()?;
addr.parse().ok()
let ip = std::env::var(DEVSERVER_IP_ENV).ok()?;
let port = std::env::var(DEVSERVER_PORT_ENV).ok()?;

if cfg!(target_os = "android") {
// Since `adb reverse` is used for Android, the 127.0.0.1 will always be
// the correct IP address.
return Some(format!("127.0.0.1:{}", port).parse().unwrap());
}

format!("{}:{}", ip, port).parse().ok()
}

/// Get the address of the devserver for use over a websocket
Expand Down
29 changes: 25 additions & 4 deletions packages/cli/src/serve/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,12 @@ impl AppHandle {
),
("RUST_BACKTRACE", "1".to_string()),
(
dioxus_cli_config::DEVSERVER_RAW_ADDR_ENV,
devserver_ip.to_string(),
dioxus_cli_config::DEVSERVER_IP_ENV,
devserver_ip.ip().to_string(),
),
(
dioxus_cli_config::DEVSERVER_PORT_ENV,
devserver_ip.port().to_string(),
),
// unset the cargo dirs in the event we're running `dx` locally
// since the child process will inherit the env vars, we don't want to confuse the downstream process
Expand Down Expand Up @@ -145,7 +149,7 @@ impl AppHandle {

// https://developer.android.com/studio/run/emulator-commandline
Platform::Android => {
self.open_android_sim(envs).await;
self.open_android_sim(devserver_ip, envs).await;
None
}

Expand Down Expand Up @@ -697,13 +701,30 @@ We checked the folder: {}
Ok(())
}

async fn open_android_sim(&self, envs: Vec<(&'static str, String)>) {
async fn open_android_sim(
&self,
devserver_socket: SocketAddr,
envs: Vec<(&'static str, String)>,
) {
let apk_path = self.app.apk_path();
let session_cache = self.app.build.krate.session_cache_dir();
let full_mobile_app_name = self.app.build.krate.full_mobile_app_name();

// Start backgrounded since .open() is called while in the arm of the top-level match
tokio::task::spawn(async move {
let port = devserver_socket.port();
if let Err(e) = Command::new("adb")
.arg("reverse")
.arg(format!("tcp:{}", port))
.arg(format!("tcp:{}", port))
.stderr(Stdio::piped())
.stdout(Stdio::piped())
.output()
.await
{
tracing::error!("failed to forward port {port}: {e}");
}

// Install
// adb install -r app-debug.apk
if let Err(e) = Command::new(DioxusCrate::android_adb())
Expand Down
17 changes: 17 additions & 0 deletions packages/cli/src/serve/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,23 @@ impl WebServer {
}

pub(crate) async fn shutdown(&mut self) {
if matches!(self.platform, Platform::Android) {
use std::process::{Command, Stdio};
if let Err(err) = Command::new("adb")
.arg("reverse")
.arg("--remove")
.arg(format!("tcp:{}", self.devserver_port))
.stderr(Stdio::piped())
.stdout(Stdio::piped())
.output()
{
tracing::error!(
"failed to remove forwarded port {}: {err}",
self.devserver_port
);
}
}

self.send_shutdown().await;
for socket in self.hot_reload_sockets.drain(..) {
_ = socket.close().await;
Expand Down
8 changes: 1 addition & 7 deletions packages/dioxus/src/launch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -162,14 +162,8 @@ impl LaunchBuilder {
{
use dioxus_fullstack::prelude::server_fn::client::{get_server_url, set_server_url};
if get_server_url().is_empty() {
let ip = if cfg!(target_os = "android") {
"10.0.2.2"
} else {
"127.0.0.1"
};

let serverurl = format!(
"http://{ip}:{}",
"http://127.0.0.1:{}",
std::env::var("PORT").unwrap_or_else(|_| "8080".to_string())
)
.leak();
Expand Down
Loading