[rkp] Return error code when requestAttestation fails

This cl converts the return value of
IVmPayloadService#requestAttestation from a binder status to
an error code defined in attestation_status_t.
In the event of an error, this value is now sent back to the
client VM payload.

Previously, the API would panic when encountering an error.

Bug: 309790130
Test: Run ServiceVmClientTestApp
Change-Id: I585e3553e2783ca019d2b8076671404398bde447
diff --git a/vm_payload/include/vm_payload.h b/vm_payload/include/vm_payload.h
index 2dfa2cb..951b57f 100644
--- a/vm_payload/include/vm_payload.h
+++ b/vm_payload/include/vm_payload.h
@@ -43,11 +43,14 @@
     /** The remote attestation completes successfully. */
     ATTESTATION_OK = 0,
 
-    /** The remote attestation has failed due to an unspecified cause. */
-    ATTESTATION_UNKNOWN_ERROR = -10000,
-
     /** The challenge size is not between 0 and 64. */
     ATTESTATION_ERROR_INVALID_CHALLENGE = -10001,
+
+    /** Failed to attest the VM. Please retry at a later time. */
+    ATTESTATION_ERROR_ATTESTATION_FAILED = -10002,
+
+    /** Remote attestation is not supported in the current environment. */
+    ATTESTATION_ERROR_UNSUPPORTED = -10003,
 } attestation_status_t;
 
 /**
diff --git a/vm_payload/src/api.rs b/vm_payload/src/api.rs
index 64f8d6a..c76f2d3 100644
--- a/vm_payload/src/api.rs
+++ b/vm_payload/src/api.rs
@@ -21,7 +21,7 @@
 use anyhow::{bail, ensure, Context, Result};
 use binder::{
     unstable_api::{new_spibinder, AIBinder},
-    Strong,
+    Strong, ExceptionCode,
 };
 use lazy_static::lazy_static;
 use log::{error, info, Level};
@@ -296,15 +296,24 @@
         // `challenge_size` bytes and `challenge_size` is not zero.
         unsafe { std::slice::from_raw_parts(challenge, challenge_size) }
     };
-    let attestation_res = unwrap_or_abort(try_request_attestation(challenge));
-    *res = Box::into_raw(Box::new(attestation_res));
-    attestation_status_t::ATTESTATION_OK
+    let service = unwrap_or_abort(get_vm_payload_service());
+    match service.requestAttestation(challenge) {
+        Ok(attestation_res) => {
+            *res = Box::into_raw(Box::new(attestation_res));
+            attestation_status_t::ATTESTATION_OK
+        }
+        Err(e) => {
+            error!("Remote attestation failed: {e:?}");
+            binder_status_to_attestation_status(e)
+        }
+    }
 }
 
-fn try_request_attestation(public_key: &[u8]) -> Result<AttestationResult> {
-    get_vm_payload_service()?
-        .requestAttestation(public_key)
-        .context("Failed to request attestation")
+fn binder_status_to_attestation_status(status: binder::Status) -> attestation_status_t {
+    match status.exception_code() {
+        ExceptionCode::UNSUPPORTED_OPERATION => attestation_status_t::ATTESTATION_ERROR_UNSUPPORTED,
+        _ => attestation_status_t::ATTESTATION_ERROR_ATTESTATION_FAILED,
+    }
 }
 
 /// Converts the return value from `AVmPayload_requestAttestation` to a text string
@@ -320,8 +329,12 @@
         attestation_status_t::ATTESTATION_ERROR_INVALID_CHALLENGE => {
             CStr::from_bytes_with_nul(b"The challenge size is not between 0 and 64.\0").unwrap()
         }
-        _ => CStr::from_bytes_with_nul(
-            b"The remote attestation has failed due to an unspecified cause.\0",
+        attestation_status_t::ATTESTATION_ERROR_ATTESTATION_FAILED => {
+            CStr::from_bytes_with_nul(b"Failed to attest the VM. Please retry at a later time.\0")
+                .unwrap()
+        }
+        attestation_status_t::ATTESTATION_ERROR_UNSUPPORTED => CStr::from_bytes_with_nul(
+            b"Remote attestation is not supported in the current environment.\0",
         )
         .unwrap(),
     };