Add and use run_as::run_as_child_app helper

Test: keystore2_client_tests
Flag: None, pure refactor of test code
Change-Id: I7031a8fd23f9cee150135bca121b5be405f69dfc
diff --git a/keystore2/test_utils/run_as.rs b/keystore2/test_utils/run_as.rs
index d4fd06c..7a9acb7 100644
--- a/keystore2/test_utils/run_as.rs
+++ b/keystore2/test_utils/run_as.rs
@@ -352,6 +352,40 @@
     }
 }
 
+/// Run the given closure in a new process running as an untrusted app with the given `uid` and
+/// `gid`. Parent process will run without waiting for child status.
+///
+/// # Safety
+/// run_as_child runs the given closure in the client branch of fork. And it uses non
+/// async signal safe API. This means that calling this function in a multi threaded program
+/// yields undefined behavior in the child. As of this writing, it is safe to call this function
+/// from a Rust device test, because every test itself is spawned as a separate process.
+///
+/// # Safety Binder
+/// It is okay for the closure to use binder services, however, this does not work
+/// if the parent initialized libbinder already. So do not use binder outside of the closure
+/// in your test.
+pub unsafe fn run_as_child_app<F, R, M>(
+    uid: u32,
+    gid: u32,
+    f: F,
+) -> Result<ChildHandle<R, M>, nix::Error>
+where
+    R: Serialize + DeserializeOwned,
+    M: Serialize + DeserializeOwned,
+    F: 'static + Send + FnOnce(&mut ChannelReader<M>, &mut ChannelWriter<M>) -> R,
+{
+    // Safety: Caller guarantees that the process only has a single thread.
+    unsafe {
+        run_as_child(
+            "u:r:untrusted_app:s0:c91,c256,c10,c20",
+            Uid::from_raw(uid),
+            Gid::from_raw(gid),
+            f,
+        )
+    }
+}
+
 /// Run the given closure in a new process running with the new identity given as
 /// `uid`, `gid`, and `se_context`. Parent process will run without waiting for child status.
 ///
@@ -383,7 +417,7 @@
     let (response_reader, mut response_writer) =
         pipe_channel().expect("Failed to create cmd pipe.");
 
-    // SAFETY: Our caller guarantees that the process only has a single thread, so calling
+    // Safety: Our caller guarantees that the process only has a single thread, so calling
     // non-async-signal-safe functions in the child is in fact safe.
     match unsafe { fork() } {
         Ok(ForkResult::Parent { child, .. }) => {
diff --git a/keystore2/tests/user_auth.rs b/keystore2/tests/user_auth.rs
index 336af4f..187256b 100644
--- a/keystore2/tests/user_auth.rs
+++ b/keystore2/tests/user_auth.rs
@@ -43,12 +43,9 @@
     run_as::{ChannelReader, ChannelWriter}, expect_km_error,
 };
 use log::{warn, info};
-use nix::unistd::{Gid, Uid};
 use rustutils::users::AID_USER_OFFSET;
 use std::{time::Duration, thread::sleep};
 
-/// SELinux context.
-const CTX: &str = "u:r:untrusted_app:s0:c91,c256,c10,c20";
 /// Test user ID.
 const TEST_USER_ID: i32 = 100;
 /// Corresponding uid value.
@@ -263,7 +260,7 @@
     // `--test-threads=1`), and nothing yet done with binder.
     let mut child_handle = unsafe {
         // Perform keystore actions while running as the test user.
-        run_as::run_as_child(CTX, Uid::from_raw(UID), Gid::from_raw(UID), child_fn)
+        run_as::run_as_child_app(UID, UID, child_fn)
     }
     .unwrap();
 
@@ -385,7 +382,7 @@
     // `--test-threads=1`), and nothing yet done with binder.
     let mut child_handle = unsafe {
         // Perform keystore actions while running as the test user.
-        run_as::run_as_child(CTX, Uid::from_raw(UID), Gid::from_raw(UID), child_fn)
+        run_as::run_as_child_app(UID, UID, child_fn)
     }
     .unwrap();
 
@@ -514,7 +511,7 @@
     // `--test-threads=1`), and nothing yet done with binder.
     let mut child_handle = unsafe {
         // Perform keystore actions while running as the test user.
-        run_as::run_as_child(CTX, Uid::from_raw(UID), Gid::from_raw(UID), child_fn)
+        run_as::run_as_child_app(UID, UID, child_fn)
     }
     .unwrap();
 
@@ -659,7 +656,7 @@
     // `--test-threads=1`), and nothing yet done with binder.
     let mut child_handle = unsafe {
         // Perform keystore actions while running as the test user.
-        run_as::run_as_child(CTX, Uid::from_raw(UID), Gid::from_raw(UID), child_fn)
+        run_as::run_as_child_app(UID, UID, child_fn)
     }
     .unwrap();
 
@@ -788,7 +785,7 @@
     // `--test-threads=1`), and nothing yet done with binder.
     let mut child_handle = unsafe {
         // Perform keystore actions while running as the test user.
-        run_as::run_as_child(CTX, Uid::from_raw(UID), Gid::from_raw(UID), child_fn)
+        run_as::run_as_child_app(UID, UID, child_fn)
     }
     .unwrap();