diff --git a/cargo-apk/src/apk.rs b/cargo-apk/src/apk.rs index f70f87c..a4be306 100644 --- a/cargo-apk/src/apk.rs +++ b/cargo-apk/src/apk.rs @@ -313,7 +313,8 @@ impl<'a> ApkBuilder<'a> { let apk = self.build(artifact)?; apk.reverse_port_forwarding(self.device_serial.as_deref())?; apk.install(self.device_serial.as_deref())?; - let pid = apk.start(self.device_serial.as_deref())?; + apk.start(self.device_serial.as_deref())?; + let uid = apk.uidof(self.device_serial.as_deref())?; if !no_logcat { self.ndk @@ -321,8 +322,8 @@ impl<'a> ApkBuilder<'a> { .arg("logcat") .arg("-v") .arg("color") - .arg("--pid") - .arg(pid.to_string()) + .arg("--uid") + .arg(uid.to_string()) .status()?; } diff --git a/ndk-build/CHANGELOG.md b/ndk-build/CHANGELOG.md index ade84da..16bd147 100644 --- a/ndk-build/CHANGELOG.md +++ b/ndk-build/CHANGELOG.md @@ -1,7 +1,8 @@ # Unreleased - Add `android:extractNativeLibs`, `android:usesCleartextTraffic` attributes to the manifest's `Application` element, and `android:alwaysRetainTaskState` to the `Activity` element. ([#15](https://github.com/rust-mobile/cargo-apk/pull/15)) -- Enable building from `android` host ([#29](https://github.com/rust-mobile/cargo-apk/pull/29)) +- Enable building from `android` host. ([#29](https://github.com/rust-mobile/cargo-apk/pull/29)) +- Use app `uid` instead of `pid` to limit `logcat` output to the current app. ([#33](https://github.com/rust-mobile/cargo-apk/pull/33)) # 0.9.0 (2022-11-23) diff --git a/ndk-build/src/apk.rs b/ndk-build/src/apk.rs index 0057661..66d2573 100644 --- a/ndk-build/src/apk.rs +++ b/ndk-build/src/apk.rs @@ -292,37 +292,52 @@ impl Apk { Ok(()) } - pub fn start(&self, device_serial: Option<&str>) -> Result { - let mut am_start = self.ndk.adb(device_serial)?; - am_start - .arg("shell") + pub fn start(&self, device_serial: Option<&str>) -> Result<(), NdkError> { + let mut adb = self.ndk.adb(device_serial)?; + adb.arg("shell") .arg("am") .arg("start") - .arg("-W") .arg("-a") .arg("android.intent.action.MAIN") .arg("-n") - .arg(format!("{}/android.app.NativeActivity", &self.package_name)); - if !am_start.status()?.success() { - return Err(NdkError::CmdFailed(am_start)); - } + .arg(format!("{}/android.app.NativeActivity", self.package_name)); - let pid_vec = self - .ndk - .adb(device_serial)? - .arg("shell") - .arg("pidof") - .arg(&self.package_name) - .output()? - .stdout; + if !adb.status()?.success() { + return Err(NdkError::CmdFailed(adb)); + } - let pid = std::str::from_utf8(&pid_vec).unwrap().trim(); - let pid: u32 = pid - .parse() - .map_err(|e| NdkError::NotAPid(e, pid.to_owned()))?; + Ok(()) + } - println!("Launched with PID {}", pid); + pub fn uidof(&self, device_serial: Option<&str>) -> Result { + let mut adb = self.ndk.adb(device_serial)?; + adb.arg("shell") + .arg("pm") + .arg("list") + .arg("package") + .arg("-U") + .arg(&self.package_name); + let output = adb.output()?; + + if !output.status.success() { + return Err(NdkError::CmdFailed(adb)); + } - Ok(pid) + let output = std::str::from_utf8(&output.stdout).unwrap(); + let (_package, uid) = output + .lines() + .filter_map(|line| line.split_once(' ')) + // `pm list package` uses the id as a substring filter; make sure + // we select the right package in case it returns multiple matches: + .find(|(package, _uid)| package.strip_prefix("package:") == Some(&self.package_name)) + .ok_or(NdkError::PackageNotInOutput { + package: self.package_name.clone(), + output: output.to_owned(), + })?; + let uid = uid + .strip_prefix("uid:") + .ok_or(NdkError::UidNotInOutput(output.to_owned()))?; + uid.parse() + .map_err(|e| NdkError::NotAUid(e, uid.to_owned())) } } diff --git a/ndk-build/src/error.rs b/ndk-build/src/error.rs index 9dee031..8c74050 100644 --- a/ndk-build/src/error.rs +++ b/ndk-build/src/error.rs @@ -48,6 +48,10 @@ pub enum NdkError { CmdFailed(Command), #[error(transparent)] Serialize(#[from] quick_xml::de::DeError), - #[error("String `{1}` is not a PID")] - NotAPid(#[source] ParseIntError, String), + #[error("String `{1}` is not a UID")] + NotAUid(#[source] ParseIntError, String), + #[error("Could not find `package:{package}` in output `{output}`")] + PackageNotInOutput { package: String, output: String }, + #[error("Could not find `uid:` in output `{0}`")] + UidNotInOutput(String), }