[rkpd_client] Add Error type to rkpd_client

This makes rkpd_client independent of keystore2 and facilitates
the extraction of rkpd_client as a standalone library later.

Test: atest keystore2_test
Bug: 241428146
Change-Id: I3bcf0afdb587b2e95bd9a970631c29696f57ed4f
diff --git a/keystore2/src/rkpd_client.rs b/keystore2/src/rkpd_client.rs
index fe64150..9868838 100644
--- a/keystore2/src/rkpd_client.rs
+++ b/keystore2/src/rkpd_client.rs
@@ -14,7 +14,6 @@
 
 //! Helper wrapper around RKPD interface.
 
-use crate::error::{map_binder_status_code, Error, ResponseCode};
 use android_security_rkp_aidl::aidl::android::security::rkp::{
     IGetKeyCallback::BnGetKeyCallback, IGetKeyCallback::ErrorCode::ErrorCode as GetKeyErrorCode,
     IGetKeyCallback::IGetKeyCallback, IGetRegistrationCallback::BnGetRegistrationCallback,
@@ -24,8 +23,8 @@
     IStoreUpgradedKeyCallback::IStoreUpgradedKeyCallback,
     RemotelyProvisionedKey::RemotelyProvisionedKey,
 };
-use android_security_rkp_aidl::binder::{BinderFeatures, Interface, Strong};
 use anyhow::{Context, Result};
+use binder::{BinderFeatures, Interface, StatusCode, Strong};
 use message_macro::source_location_msg;
 use std::sync::Mutex;
 use std::time::Duration;
@@ -41,6 +40,40 @@
     tokio::runtime::Builder::new_current_thread().enable_all().build().unwrap()
 }
 
+/// Errors occurred during the interaction with RKPD.
+#[derive(Debug, Clone, Copy, thiserror::Error, PartialEq, Eq)]
+pub enum Error {
+    /// An RKPD request gets cancelled.
+    #[error("An RKPD request gets cancelled")]
+    RequestCancelled,
+
+    /// Failed to get registration.
+    #[error("Failed to get registration")]
+    GetRegistrationFailed,
+
+    /// Failed to get key.
+    #[error("Failed to get key: {0:?}")]
+    GetKeyFailed(GetKeyErrorCode),
+
+    /// Failed to store upgraded key.
+    #[error("Failed to store upgraded key")]
+    StoreUpgradedKeyFailed,
+
+    /// Timeout when waiting for a callback.
+    #[error("Timeout when waiting for a callback")]
+    Timeout,
+
+    /// Wraps a Binder status code.
+    #[error("Binder transaction error {0:?}")]
+    BinderTransaction(StatusCode),
+}
+
+impl From<StatusCode> for Error {
+    fn from(s: StatusCode) -> Self {
+        Self::BinderTransaction(s)
+    }
+}
+
 /// Thread-safe channel for sending a value once and only once. If a value has
 /// already been send, subsequent calls to send will noop.
 struct SafeSender<T> {
@@ -87,17 +120,17 @@
     fn onCancel(&self) -> binder::Result<()> {
         log::warn!("IGetRegistrationCallback cancelled");
         self.registration_tx.send(
-            Err(Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR))
+            Err(Error::RequestCancelled)
                 .context(source_location_msg!("GetRegistrationCallback cancelled.")),
         );
         Ok(())
     }
     fn onError(&self, description: &str) -> binder::Result<()> {
         log::error!("IGetRegistrationCallback failed: '{description}'");
-        self.registration_tx
-            .send(Err(Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)).context(
-                source_location_msg!("GetRegistrationCallback failed: {:?}", description),
-            ));
+        self.registration_tx.send(
+            Err(Error::GetRegistrationFailed)
+                .context(source_location_msg!("GetRegistrationCallback failed: {:?}", description)),
+        );
         Ok(())
     }
 }
@@ -105,7 +138,8 @@
 /// Make a new connection to a IRegistration service.
 async fn get_rkpd_registration(rpc_name: &str) -> Result<binder::Strong<dyn IRegistration>> {
     let remote_provisioning: Strong<dyn IRemoteProvisioning> =
-        map_binder_status_code(binder::get_interface("remote_provisioning"))
+        binder::get_interface("remote_provisioning")
+            .map_err(Error::from)
             .context(source_location_msg!("Trying to connect to IRemoteProvisioning service."))?;
 
     let (tx, rx) = oneshot::channel();
@@ -116,8 +150,7 @@
         .context(source_location_msg!("Trying to get registration."))?;
 
     match timeout(RKPD_TIMEOUT, rx).await {
-        Err(e) => Err(Error::Rc(ResponseCode::SYSTEM_ERROR))
-            .context(source_location_msg!("Waiting for RKPD: {:?}", e)),
+        Err(e) => Err(Error::Timeout).context(source_location_msg!("Waiting for RKPD: {:?}", e)),
         Ok(v) => v.unwrap(),
     }
 }
@@ -148,28 +181,13 @@
     fn onCancel(&self) -> binder::Result<()> {
         log::warn!("IGetKeyCallback cancelled");
         self.key_tx.send(
-            Err(Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR))
-                .context(source_location_msg!("GetKeyCallback cancelled.")),
+            Err(Error::RequestCancelled).context(source_location_msg!("GetKeyCallback cancelled.")),
         );
         Ok(())
     }
     fn onError(&self, error: GetKeyErrorCode, description: &str) -> binder::Result<()> {
         log::error!("IGetKeyCallback failed: {description}");
-        let rc = match error {
-            GetKeyErrorCode::ERROR_UNKNOWN => ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR,
-            GetKeyErrorCode::ERROR_PERMANENT => ResponseCode::OUT_OF_KEYS_PERMANENT_ERROR,
-            GetKeyErrorCode::ERROR_PENDING_INTERNET_CONNECTIVITY => {
-                ResponseCode::OUT_OF_KEYS_PENDING_INTERNET_CONNECTIVITY
-            }
-            GetKeyErrorCode::ERROR_REQUIRES_SECURITY_PATCH => {
-                ResponseCode::OUT_OF_KEYS_REQUIRES_SYSTEM_UPGRADE
-            }
-            _ => {
-                log::error!("Unexpected error from rkpd: {error:?}");
-                ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR
-            }
-        };
-        self.key_tx.send(Err(Error::Rc(rc)).context(source_location_msg!(
+        self.key_tx.send(Err(Error::GetKeyFailed(error)).context(source_location_msg!(
             "GetKeyCallback failed: {:?} {:?}",
             error,
             description
@@ -195,7 +213,7 @@
             if let Err(e) = registration.cancelGetKey(&cb) {
                 log::error!("IRegistration::cancelGetKey failed: {:?}", e);
             }
-            Err(Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR))
+            Err(Error::Timeout)
                 .context(source_location_msg!("Waiting for RKPD key timed out: {:?}", e))
         }
         Ok(v) => v.unwrap(),
@@ -234,9 +252,9 @@
     }
 
     fn onError(&self, error: &str) -> binder::Result<()> {
-        log::error!("IGetRegistrationCallback failed: {error}");
+        log::error!("IStoreUpgradedKeyCallback failed: {error}");
         self.completer.send(
-            Err(Error::Rc(ResponseCode::SYSTEM_ERROR))
+            Err(Error::StoreUpgradedKeyFailed)
                 .context(source_location_msg!("Failed to store upgraded key: {:?}", error)),
         );
         Ok(())
@@ -256,7 +274,7 @@
         .context(source_location_msg!("Failed to store upgraded blob with RKPD."))?;
 
     match timeout(RKPD_TIMEOUT, rx).await {
-        Err(e) => Err(Error::Rc(ResponseCode::SYSTEM_ERROR))
+        Err(e) => Err(Error::Timeout)
             .context(source_location_msg!("Waiting for RKPD to complete storing key: {:?}", e)),
         Ok(v) => v.unwrap(),
     }
@@ -291,7 +309,6 @@
 mod tests {
     use super::*;
     use android_security_rkp_aidl::aidl::android::security::rkp::IRegistration::BnRegistration;
-    use std::collections::HashMap;
     use std::sync::atomic::{AtomicU32, Ordering};
     use std::sync::{Arc, Mutex};
 
@@ -415,10 +432,7 @@
         assert!(cb.onCancel().is_ok());
 
         let result = tokio_rt().block_on(rx).unwrap();
-        assert_eq!(
-            result.unwrap_err().downcast::<Error>().unwrap(),
-            Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
-        );
+        assert_eq!(result.unwrap_err().downcast::<Error>().unwrap(), Error::RequestCancelled);
     }
 
     #[test]
@@ -428,10 +442,7 @@
         assert!(cb.onError("error").is_ok());
 
         let result = tokio_rt().block_on(rx).unwrap();
-        assert_eq!(
-            result.unwrap_err().downcast::<Error>().unwrap(),
-            Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
-        );
+        assert_eq!(result.unwrap_err().downcast::<Error>().unwrap(), Error::GetRegistrationFailed);
     }
 
     #[test]
@@ -453,29 +464,11 @@
         assert!(cb.onCancel().is_ok());
 
         let result = tokio_rt().block_on(rx).unwrap();
-        assert_eq!(
-            result.unwrap_err().downcast::<Error>().unwrap(),
-            Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
-        );
+        assert_eq!(result.unwrap_err().downcast::<Error>().unwrap(), Error::RequestCancelled);
     }
 
     #[test]
     fn test_get_key_cb_error() {
-        let error_mapping = HashMap::from([
-            (GetKeyErrorCode::ERROR_UNKNOWN, ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR),
-            (GetKeyErrorCode::ERROR_PERMANENT, ResponseCode::OUT_OF_KEYS_PERMANENT_ERROR),
-            (
-                GetKeyErrorCode::ERROR_PENDING_INTERNET_CONNECTIVITY,
-                ResponseCode::OUT_OF_KEYS_PENDING_INTERNET_CONNECTIVITY,
-            ),
-            (
-                GetKeyErrorCode::ERROR_REQUIRES_SECURITY_PATCH,
-                ResponseCode::OUT_OF_KEYS_REQUIRES_SYSTEM_UPGRADE,
-            ),
-        ]);
-
-        // Loop over the generated list of enum values to better ensure this test stays in
-        // sync with the AIDL.
         for get_key_error in GetKeyErrorCode::enum_values() {
             let (tx, rx) = oneshot::channel();
             let cb = GetKeyCallback::new_native_binder(tx);
@@ -484,7 +477,7 @@
             let result = tokio_rt().block_on(rx).unwrap();
             assert_eq!(
                 result.unwrap_err().downcast::<Error>().unwrap(),
-                Error::Rc(error_mapping[&get_key_error]),
+                Error::GetKeyFailed(get_key_error),
             );
         }
     }
@@ -505,10 +498,7 @@
         assert!(cb.onError("oh no! it failed").is_ok());
 
         let result = tokio_rt().block_on(rx).unwrap();
-        assert_eq!(
-            result.unwrap_err().downcast::<Error>().unwrap(),
-            Error::Rc(ResponseCode::SYSTEM_ERROR)
-        );
+        assert_eq!(result.unwrap_err().downcast::<Error>().unwrap(), Error::StoreUpgradedKeyFailed);
     }
 
     #[test]
@@ -532,10 +522,7 @@
 
         let result =
             tokio_rt().block_on(get_rkpd_attestation_key_from_registration_async(&registration, 0));
-        assert_eq!(
-            result.unwrap_err().downcast::<Error>().unwrap(),
-            Error::Rc(ResponseCode::OUT_OF_KEYS_TRANSIENT_ERROR)
-        );
+        assert_eq!(result.unwrap_err().downcast::<Error>().unwrap(), Error::Timeout);
     }
 
     #[test]
@@ -560,10 +547,7 @@
             &[],
             &[],
         ));
-        assert_eq!(
-            result.unwrap_err().downcast::<Error>().unwrap(),
-            Error::Rc(ResponseCode::SYSTEM_ERROR)
-        );
+        assert_eq!(result.unwrap_err().downcast::<Error>().unwrap(), Error::Timeout);
     }
 
     #[test]