From f58cf19db896df113684c546aee5e053f7f39e5d Mon Sep 17 00:00:00 2001 From: Marijn Suijten Date: Tue, 10 Oct 2023 14:48:44 +0200 Subject: [PATCH] adb: Explicitly match package name in `pm list package` output (#135) The positional `FILTER` argument to `pm list package` works as a substring match: if you have a package named `foo.bar.baz` and `foo.bar.baz_debug` for example, and try to run `foo.bar.baz`, both packages will be returned, the `_debug`-suffixed one likely first, and the wrong UID ends up being used as `logcat` filter. To counter that we could use the very slow and extremely verbose (thousands of lines) `pm dump PACKAGE`, _or_ look for the right explicit text match in the line-based `package:foo.bar.baz uid:1234` output from `pm list package`: the latter approach is chosen here. --- xbuild/src/devices/adb.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/xbuild/src/devices/adb.rs b/xbuild/src/devices/adb.rs index 756d54eb..561942cc 100644 --- a/xbuild/src/devices/adb.rs +++ b/xbuild/src/devices/adb.rs @@ -220,10 +220,16 @@ impl Adb { std::str::from_utf8(&output.stderr)?.trim() ); let output = std::str::from_utf8(&output.stdout)?; - let uid = output - .split_whitespace() - .find_map(|kv| kv.strip_prefix("uid:")) - .with_context(|| format!("Could not find `uid:`` in output `{output}`"))?; + 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(id)) + .with_context(|| format!("Could not find `package:{id}` in output `{output}`"))?; + let uid = uid + .strip_prefix("uid:") + .with_context(|| format!("Could not find `uid:` in output `{output}`"))?; Ok(uid.parse()?) }