Skip to content

Commit 9baa073

Browse files
committed
Pass arbitrary arguments in x run via -- suffix
I.e. if you want to pass string "extras" into an Android intent via `am start`, call `-e extraKey "extra string"` (and similar for other types like `--ez key bool` for booleans, or `-d URI` for data URIs). All arguments listed by `am help` under the `start` command (including the `INTENT` specification) is supported. On the host, this should pass the arguments as-is to the running executable, `cargo run .. -- <these args>` style. For IMD, it's unknown what should happen here.
1 parent 5662af2 commit 9baa073

File tree

7 files changed

+48
-15
lines changed

7 files changed

+48
-15
lines changed

xbuild/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ quick-xml = { version = "0.26.0", features = ["serialize"] }
3232
reqwest = { version = "0.11.13", default-features = false, features = ["blocking", "rustls-tls"] }
3333
serde = { version = "1.0.151", features = ["derive"] }
3434
serde_yaml = "0.9.16"
35+
shlex = "1"
3536
symlink = "0.1.0"
3637
tar = "0.4.38"
3738
toml = "0.5.10"

xbuild/src/command/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ pub fn devices() -> Result<()> {
2626
Ok(())
2727
}
2828

29-
pub fn run(env: &BuildEnv) -> Result<()> {
29+
pub fn run(env: &BuildEnv, launch_params: &[String]) -> Result<()> {
3030
let out = env.executable();
3131
if let Some(device) = env.target().device() {
32-
device.run(env, &out)?;
32+
device.run(env, &out, launch_params)?;
3333
} else {
3434
anyhow::bail!("no device specified");
3535
}

xbuild/src/devices/adb.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,16 @@ impl Adb {
9393
}
9494

9595
/// To run a native activity use "android.app.NativeActivity" as the activity name
96-
fn start(&self, device: &str, package: &str, activity: &str) -> Result<()> {
96+
fn start(
97+
&self,
98+
device: &str,
99+
package: &str,
100+
activity: &str,
101+
launch_params: &[String],
102+
) -> Result<()> {
103+
// Quote arguments for `am` so that they don't already get parsed by `adb`.
104+
let launch_params = shlex::try_join(launch_params.iter().map(String::as_str))
105+
.context("Failed to re-quote launch parameters")?;
97106
let status = self
98107
.shell(device, None)
99108
.arg("am")
@@ -102,6 +111,7 @@ impl Adb {
102111
.arg("android.intent.action.MAIN")
103112
.arg("-n")
104113
.arg(format!("{}/{}", package, activity))
114+
.arg(launch_params)
105115
.status()?;
106116
anyhow::ensure!(
107117
status.success(),
@@ -340,6 +350,7 @@ impl Adb {
340350
&self,
341351
device: &str,
342352
path: &Path,
353+
launch_params: &[String],
343354
debug_config: &AndroidDebugConfig,
344355
debug: bool,
345356
) -> Result<()> {
@@ -355,7 +366,7 @@ impl Adb {
355366
self.install(device, path)?;
356367
self.forward_reverse(device, debug_config)?;
357368
let last_timestamp = self.logcat_last_timestamp(device)?;
358-
self.start(device, package, activity)?;
369+
self.start(device, package, activity, launch_params)?;
359370
let uid = self.uidof(device, package)?;
360371
let logcat = self.logcat(device, uid, &last_timestamp)?;
361372
for line in logcat {

xbuild/src/devices/host.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ impl Host {
4646
}
4747
}
4848

49-
pub fn run(&self, path: &Path) -> Result<()> {
50-
Command::new(path).status()?;
49+
pub fn run(&self, path: &Path, launch_params: &[String]) -> Result<()> {
50+
Command::new(path).args(launch_params).status()?;
5151
Ok(())
5252
}
5353

xbuild/src/devices/imd.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,14 @@ impl IMobileDevice {
4848
Ok(())
4949
}
5050

51-
fn start(&self, device: &str, bundle_identifier: &str) -> Result<()> {
51+
fn start(&self, device: &str, bundle_identifier: &str, launch_params: &[String]) -> Result<()> {
5252
let status = Command::new(&self.idevicedebug)
5353
.arg("--udid")
5454
.arg(device)
5555
.arg("run")
5656
.arg(bundle_identifier)
57+
// TODO: Is this even supported?
58+
.args(launch_params)
5759
.status()?;
5860
anyhow::ensure!(status.success(), "failed to run idevicedebug");
5961
Ok(())
@@ -92,11 +94,17 @@ impl IMobileDevice {
9294
Ok(())
9395
}
9496

95-
pub fn run(&self, env: &BuildEnv, device: &str, path: &Path) -> Result<()> {
97+
pub fn run(
98+
&self,
99+
env: &BuildEnv,
100+
device: &str,
101+
path: &Path,
102+
launch_params: &[String],
103+
) -> Result<()> {
96104
let bundle_identifier = appbundle::app_bundle_identifier(path)?;
97105
self.mount_disk_image(env, device)?;
98106
self.install(device, path)?;
99-
self.start(device, &bundle_identifier)?;
107+
self.start(device, &bundle_identifier, launch_params)?;
100108
Ok(())
101109
}
102110

xbuild/src/devices/mod.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,17 @@ impl Device {
110110
}
111111
}
112112

113-
pub fn run(&self, env: &BuildEnv, path: &Path) -> Result<()> {
113+
pub fn run(&self, env: &BuildEnv, path: &Path, launch_params: &[String]) -> Result<()> {
114114
match &self.backend {
115-
Backend::Adb(adb) => adb.run(&self.id, path, &env.config.android().debug, false),
116-
Backend::Host(host) => host.run(path),
117-
Backend::Imd(imd) => imd.run(env, &self.id, path),
115+
Backend::Adb(adb) => adb.run(
116+
&self.id,
117+
path,
118+
launch_params,
119+
&env.config.android().debug,
120+
false,
121+
),
122+
Backend::Host(host) => host.run(path, launch_params),
123+
Backend::Imd(imd) => imd.run(env, &self.id, path, launch_params),
118124
}?;
119125
Ok(())
120126
}

xbuild/src/main.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ enum Commands {
4646
Run {
4747
#[clap(flatten)]
4848
args: BuildArgs,
49+
50+
/// Arbitrary platform-specific arguments to pass to the launch command (i.e. to `adb`'s `am start`).
51+
#[clap(last = true)]
52+
launch_params: Vec<String>,
4953
},
5054
/// Launch app in a debugger on an attached device
5155
Lldb {
@@ -104,10 +108,13 @@ impl Commands {
104108
let env = BuildEnv::new(args)?;
105109
command::build(&env)?;
106110
}
107-
Self::Run { args } => {
111+
Self::Run {
112+
args,
113+
launch_params,
114+
} => {
108115
let env = BuildEnv::new(args)?;
109116
command::build(&env)?;
110-
command::run(&env)?;
117+
command::run(&env, &launch_params)?;
111118
}
112119
Self::Lldb { args } => {
113120
let env = BuildEnv::new(args)?;

0 commit comments

Comments
 (0)