Cope better with errors in child processes

If a test needs to run in a child process, make it easier to cope if
that child process encounters a failure along the way.

- Add a stringly-typed `Error` to the `run_as` module, which can:
  - be serialized and so emitted from child processes
  - be constructed from an `anyhow::Error`.
- Add helper macros that construct and `return` an `Error` rather than
  directly panicking.
- Add a `recv_or_die()` method that attempts to read a response message
  from the child process, but copes with the channel being gone. This
  happens if the child has already exited; in this case a final result
  message is hopefully available on the `result_reader`.
- Migrate the auth-bound tests to use `Result<(), run_as::Error>`.

Test: keystore2_client_tests auth_bound
Change-Id: Ic306bb272f740a44c0e1d06c948f11435ac3b211
diff --git a/keystore2/test_utils/key_generations.rs b/keystore2/test_utils/key_generations.rs
index c40e944..5e823c2 100644
--- a/keystore2/test_utils/key_generations.rs
+++ b/keystore2/test_utils/key_generations.rs
@@ -393,22 +393,27 @@
 }
 
 /// Check for a specific KeyMint error.
-pub fn assert_km_error<T: std::fmt::Debug>(result: &BinderResult<T>, want: ErrorCode) {
-    match result {
-        Ok(_) => panic!("Expected KeyMint error {want:?}, found success"),
-        Err(s) => {
-            assert_eq!(
-                s.exception_code(),
-                ExceptionCode::SERVICE_SPECIFIC,
-                "Expected KeyMint service-specific error {want:?}, got {result:?}"
-            );
-            assert_eq!(
-                s.service_specific_error(),
-                want.0,
-                "Expected KeyMint service-specific error {want:?}, got {result:?}"
-            );
+#[macro_export]
+macro_rules! expect_km_error {
+    { $result:expr, $want:expr } => {
+        match $result {
+            Ok(_) => return Err(format!(
+                "{}:{}: Expected KeyMint error {:?}, found success",
+                file!(),
+                line!(),
+                $want
+            ).into()),
+            Err(s) if s.exception_code() == ExceptionCode::SERVICE_SPECIFIC
+                    && s.service_specific_error() == $want.0 => {}
+            Err(e) => return Err(format!(
+                "{}:{}: Expected KeyMint service-specific error {:?}, got {e:?}",
+                file!(),
+                line!(),
+                $want
+            ).into()),
         }
-    }
+
+    };
 }
 
 /// Get the value of the given system property, if the given system property doesn't exist