diff --git a/.github/workflows/android_test.sh b/.github/workflows/android_test.sh index 186b122..b5bc47d 100755 --- a/.github/workflows/android_test.sh +++ b/.github/workflows/android_test.sh @@ -12,7 +12,13 @@ if [ -z "$1" ]; then cargo apk run -p ndk-examples --target x86_64-linux-android --example hello_world --no-logcat else - adb install -r "$1/hello_world.apk" + user_id=$(adb shell am get-current-user) + if [ -z "$user_id" ]; + then + adb install -r "$1/hello_world.apk" + else + adb install --user $user_id -r "$1/hello_world.apk" + fi adb shell am start -a android.intent.action.MAIN -n "rust.example.hello_world/android.app.NativeActivity" fi diff --git a/cargo-apk/src/apk.rs b/cargo-apk/src/apk.rs index a4be306..ee9894c 100644 --- a/cargo-apk/src/apk.rs +++ b/cargo-apk/src/apk.rs @@ -15,6 +15,7 @@ pub struct ApkBuilder<'a> { ndk: Ndk, manifest: Manifest, build_dir: PathBuf, + current_user: Option, build_targets: Vec, device_serial: Option, } @@ -44,6 +45,7 @@ impl<'a> ApkBuilder<'a> { .detect_abi(device_serial.as_deref()) .unwrap_or(Target::Arm64V8a)] }; + let current_user = ndk.get_current_user(device_serial.as_deref()); let build_dir = dunce::simplified(cmd.target_dir()) .join(cmd.profile()) .join("apk"); @@ -132,6 +134,7 @@ impl<'a> ApkBuilder<'a> { manifest, build_dir, build_targets, + current_user, device_serial, }) } @@ -310,15 +313,18 @@ impl<'a> ApkBuilder<'a> { } pub fn run(&self, artifact: &Artifact, no_logcat: bool) -> Result<(), Error> { + let device_serial = self.device_serial.as_deref(); + let user_id = self.current_user.as_deref(); + let apk = self.build(artifact)?; - apk.reverse_port_forwarding(self.device_serial.as_deref())?; - apk.install(self.device_serial.as_deref())?; - apk.start(self.device_serial.as_deref())?; - let uid = apk.uidof(self.device_serial.as_deref())?; + apk.reverse_port_forwarding(device_serial)?; + apk.install(device_serial, user_id)?; + apk.start(device_serial)?; + let uid = apk.uidof(device_serial, user_id)?; if !no_logcat { self.ndk - .adb(self.device_serial.as_deref())? + .adb(device_serial)? .arg("logcat") .arg("-v") .arg("color") @@ -332,7 +338,7 @@ impl<'a> ApkBuilder<'a> { pub fn gdb(&self, artifact: &Artifact) -> Result<(), Error> { let apk = self.build(artifact)?; - apk.install(self.device_serial.as_deref())?; + apk.install(self.device_serial.as_deref(), self.current_user.as_deref())?; let target_dir = self.build_dir.join(artifact.build_dir()); self.ndk.ndk_gdb( diff --git a/ndk-build/src/apk.rs b/ndk-build/src/apk.rs index 66d2573..c64eb37 100644 --- a/ndk-build/src/apk.rs +++ b/ndk-build/src/apk.rs @@ -282,10 +282,19 @@ impl Apk { Ok(()) } - pub fn install(&self, device_serial: Option<&str>) -> Result<(), NdkError> { + pub fn install( + &self, + device_serial: Option<&str>, + user_id: Option<&str>, + ) -> Result<(), NdkError> { let mut adb = self.ndk.adb(device_serial)?; adb.arg("install").arg("-r").arg(&self.path); + + if let Some(uid) = user_id { + adb.arg("--user").arg(uid); + } + if !adb.status()?.success() { return Err(NdkError::CmdFailed(adb)); } @@ -309,7 +318,11 @@ impl Apk { Ok(()) } - pub fn uidof(&self, device_serial: Option<&str>) -> Result { + pub fn uidof( + &self, + device_serial: Option<&str>, + user_id: Option<&str>, + ) -> Result { let mut adb = self.ndk.adb(device_serial)?; adb.arg("shell") .arg("pm") @@ -317,6 +330,11 @@ impl Apk { .arg("package") .arg("-U") .arg(&self.package_name); + + if let Some(uid) = user_id { + adb.arg("--user").arg(uid); + } + let output = adb.output()?; if !output.status.success() { diff --git a/ndk-build/src/ndk.rs b/ndk-build/src/ndk.rs index 744dac3..968970b 100644 --- a/ndk-build/src/ndk.rs +++ b/ndk-build/src/ndk.rs @@ -478,6 +478,21 @@ impl Ndk { Target::from_android_abi(abi.trim()) } + pub fn get_current_user(&self, device_serial: Option<&str>) -> Option { + let mut adb = self.adb(device_serial).ok()?; + + adb.arg("shell").arg("am").arg("get-current-user"); + let output = adb.output().ok()?; + + if !output.status.success() { + return None; + } + + let stdout = String::from_utf8(output.stdout).ok()?; + + stdout.lines().next().map(|s| s.to_owned()) + } + pub fn adb(&self, device_serial: Option<&str>) -> Result { let mut adb = Command::new(self.adb_path()?);