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

fix: pass off env vars to android apps #3621

Merged
merged 3 commits into from
Jan 22, 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
5 changes: 3 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 11 additions & 4 deletions packages/cli-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,8 @@ 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> {
std::env::var(DEVSERVER_RAW_ADDR_ENV)
.unwrap_or_else(|_| "127.0.0.1:8080".to_string())
.parse()
.ok()
let addr = std::env::var(DEVSERVER_RAW_ADDR_ENV).ok()?;
addr.parse().ok()
}

/// Get the address of the devserver for use over a websocket
Expand Down Expand Up @@ -288,5 +286,14 @@ pub fn out_dir() -> Option<PathBuf> {
///
/// This is designed with desktop executables in mind.
pub fn session_cache_dir() -> Option<PathBuf> {
if cfg!(target_os = "android") {
return Some(android_session_cache_dir());
}

std::env::var(SESSION_CACHE_DIR).ok().map(PathBuf::from)
}

/// The session cache directory for android
pub fn android_session_cache_dir() -> PathBuf {
PathBuf::from("/data/local/tmp/dx/")
}
27 changes: 24 additions & 3 deletions packages/cli/src/serve/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,8 +292,8 @@ impl AppHandle {
// If the emulator is android, we need to copy the asset to the device with `adb push asset /data/local/tmp/dx/assets/filename.ext`
if self.app.build.build.platform() == Platform::Android {
if let Some(bundled_name) = bundled_name.as_ref() {
let target = format!("/data/local/tmp/dx/{}", bundled_name.display());
tracing::debug!("Pushing asset to device: {target}");
let target = dioxus_cli_config::android_session_cache_dir().join(bundled_name);
tracing::debug!("Pushing asset to device: {target:?}");
let res = tokio::process::Command::new(DioxusCrate::android_adb())
.arg("push")
.arg(&changed_file)
Expand Down Expand Up @@ -699,6 +699,7 @@ We checked the folder: {}

async fn open_android_sim(&self, 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
Expand All @@ -717,6 +718,27 @@ We checked the folder: {}
tracing::error!("Failed to install apk with `adb`: {e}");
};

// Write the env vars to a .env file in our session cache
let env_file = session_cache.join(".env");
let contents: String = envs
.iter()
.map(|(key, value)| format!("{key}={value}"))
.collect::<Vec<_>>()
.join("\n");
_ = std::fs::write(&env_file, contents);

// Push the env file to the device
if let Err(e) = tokio::process::Command::new(DioxusCrate::android_adb())
.arg("push")
.arg(env_file)
.arg(dioxus_cli_config::android_session_cache_dir().join(".env"))
.output()
.await
.context("Failed to push asset to device")
{
tracing::error!("Failed to push .env file to device: {e}");
}

// eventually, use the user's MainAcitivty, not our MainAcitivty
// adb shell am start -n dev.dioxus.main/dev.dioxus.main.MainActivity
let activity_name = format!("{}/dev.dioxus.main.MainActivity", full_mobile_app_name,);
Expand All @@ -727,7 +749,6 @@ We checked the folder: {}
.arg("start")
.arg("-n")
.arg(activity_name)
.envs(envs)
.stderr(Stdio::piped())
.stdout(Stdio::piped())
.output()
Expand Down
3 changes: 3 additions & 0 deletions packages/cli/src/serve/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,9 @@ impl WebServer {
pub fn displayed_address(&self) -> Option<SocketAddr> {
let mut address = self.server_address()?;

// Set the port to the devserver port since that's usually what people expect
address.set_port(self.devserver_port);

if self.devserver_bind_ip == IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)) {
address = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), address.port());
}
Expand Down
2 changes: 1 addition & 1 deletion packages/desktop/src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ pub(crate) fn to_java_load_asset(filepath: &str) -> Option<Vec<u8>> {
// in debug mode, the asset might be under `/data/local/tmp/dx/` - attempt to read it from there if it exists
#[cfg(debug_assertions)]
{
let path = std::path::PathBuf::from("/data/local/tmp/dx/").join(normalized);
let path = dioxus_cli_config::android_session_cache_dir().join(normalized);
if path.exists() {
return std::fs::read(path).ok();
}
Expand Down
1 change: 1 addition & 0 deletions packages/mobile/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ license = "MIT OR Apache-2.0"
[dependencies]
dioxus-desktop = { workspace = true }
dioxus-lib = { workspace = true }
dioxus-cli-config = { workspace = true }
libc = "0.2.159"
once_cell.workspace = true

Expand Down
22 changes: 22 additions & 0 deletions packages/mobile/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,31 @@ pub extern "C" fn JNI_OnLoad(
panic!("Failed to find main symbol");
}

// Set the env vars that rust code might expect, passed off to us by the android app
// Doing this before main emulates the behavior of a regular executable
if cfg!(target_os = "android") && cfg!(debug_assertions) {
load_env_file_from_session_cache();
}

let main_fn: extern "C" fn() = std::mem::transmute(main_fn_ptr);
main_fn();
};

jni::sys::JNI_VERSION_1_6
}

/// Load the env file from the session cache if we're in debug mode and on android
///
/// This is a slightly hacky way of being able to use std::env::var code in android apps without
/// going through their custom java-based system.
#[cfg(target_os = "android")]
fn load_env_file_from_session_cache() {
let env_file = dioxus_cli_config::android_session_cache_dir().join(".env");
if let Some(env_file) = std::fs::read_to_string(&env_file).ok() {
for line in env_file.lines() {
if let Some((key, value)) = line.trim().split_once('=') {
std::env::set_var(key, value);
}
}
}
}
Loading