Add isNewInstanceStatus to vm_payload api

This can be used by payload to determine if this the first boot of the
VM. This becomes useful since `AVmPayload_getVmInstanceSecret` is
essentially equivalent to get_or_create secrets. Payload should be able
to check if the secrets were newly created or are the old ones & this
could be used to meaningfully use the secret.

For ex, encryptedstore or other data encrypted using the VM secrets
restored via backup and restore cannot be meaningfully decrypted using
newly created secrets on the new device.

Test: MicrodroidTests#isNewInstanceTest
Bug: 327576724
Bug: 378911776
Change-Id: I05983c7b1239d29f86f2b3fb9be7e3a1f2f91039
diff --git a/libs/libvm_payload/include/vm_payload.h b/libs/libvm_payload/include/vm_payload.h
index 43fba82..e4609fa 100644
--- a/libs/libvm_payload/include/vm_payload.h
+++ b/libs/libvm_payload/include/vm_payload.h
@@ -118,6 +118,11 @@
  * byte sequences and do not need to be kept secret; typically they are
  * hardcoded in the calling code.
  *
+ * The secret is linked to the instance & will be created for a new instance.
+ * Callers should check `AVmPayload_isNewInstance()` to meaningfully use the secret.
+ * For ex, decryption of any old data is meaningless with the returned secret of a new
+ * VM instance with fresh keys.
+ *
  * \param identifier identifier of the secret to return.
  * \param identifier_size size of the secret identifier.
  * \param secret pointer to size bytes where the secret is written.
@@ -304,4 +309,13 @@
 int32_t AVmPayload_readRollbackProtectedSecret(void* _Nullable buf, size_t n) __INTRODUCED_IN(36);
 ;
 
+/**
+ * Checks whether the VM instance is new - i.e., if this is the first run of an instance.
+ * This is an indication of fresh new VM secrets. Payload can use this to setup the fresh
+ * instance if needed.
+ *
+ *  \return true if this is the first run of an instance, false otherwise.
+ */
+bool AVmPayload_isNewInstance() __INTRODUCED_IN(36);
+
 __END_DECLS
diff --git a/libs/libvm_payload/libvm_payload.map.txt b/libs/libvm_payload/libvm_payload.map.txt
index 0c6b56d..ca949d9 100644
--- a/libs/libvm_payload/libvm_payload.map.txt
+++ b/libs/libvm_payload/libvm_payload.map.txt
@@ -17,6 +17,7 @@
     AVmAttestationResult_getCertificateAt; # systemapi introduced=VanillaIceCream
     AVmPayload_writeRollbackProtectedSecret; # systemapi introduced=36
     AVmPayload_readRollbackProtectedSecret; # systemapi introduced=36
+    AVmPayload_isNewInstance;                # systemapi introduced=36
   local:
     *;
 };
diff --git a/libs/libvm_payload/src/lib.rs b/libs/libvm_payload/src/lib.rs
index 29b0cbd..cbadec2 100644
--- a/libs/libvm_payload/src/lib.rs
+++ b/libs/libvm_payload/src/lib.rs
@@ -652,3 +652,15 @@
         .context("Failed to read rollback protected data")?;
     Ok(rp)
 }
+
+/// Checks whether the VM instance is new - i.e., if this is the first run of an instance.
+///
+/// Panics on error (including unexpected server exit).
+#[no_mangle]
+pub extern "C" fn AVmPayload_isNewInstance() -> bool {
+    unwrap_or_abort(try_is_new_instance())
+}
+
+fn try_is_new_instance() -> Result<bool> {
+    get_vm_payload_service()?.isNewInstance().context("Cannot determine if the instance is new")
+}
diff --git a/libs/libvm_payload/wrapper/lib.rs b/libs/libvm_payload/wrapper/lib.rs
index 133b14e..bf274b0 100644
--- a/libs/libvm_payload/wrapper/lib.rs
+++ b/libs/libvm_payload/wrapper/lib.rs
@@ -31,7 +31,7 @@
 use std::ptr;
 use vm_payload_bindgen::{
     AIBinder, AVmPayload_getApkContentsPath, AVmPayload_getEncryptedStoragePath,
-    AVmPayload_getVmInstanceSecret, AVmPayload_notifyPayloadReady,
+    AVmPayload_getVmInstanceSecret, AVmPayload_isNewInstance, AVmPayload_notifyPayloadReady,
     AVmPayload_readRollbackProtectedSecret, AVmPayload_runVsockRpcServer,
     AVmPayload_writeRollbackProtectedSecret,
 };
@@ -208,3 +208,11 @@
     // SAFETY: The function only writes to `[data]` within its bounds.
     unsafe { AVmPayload_writeRollbackProtectedSecret(data.as_ptr() as *const c_void, data.len()) }
 }
+
+/// Checks whether the VM instance is new - i.e., if this is the first run of an instance.
+/// This is an indication of fresh new VM secrets. Payload can use this to setup the fresh
+/// instance if needed.
+pub fn is_new_instance_status() -> bool {
+    // SAFETY: The function returns bool, no arguments are needed.
+    unsafe { AVmPayload_isNewInstance() }
+}