[API] Add vm_payload API to get APK contents path

Bug: 243515282
Test: atest MicrodroidTests
Change-Id: Ic78d0744ef6ae5cd39a86a9cfcc08a3c85519621
diff --git a/microdroid/vm_payload/Android.bp b/microdroid/vm_payload/Android.bp
index dc314ce..eeca1c1 100644
--- a/microdroid/vm_payload/Android.bp
+++ b/microdroid/vm_payload/Android.bp
@@ -13,6 +13,7 @@
         "libandroid_logger",
         "libanyhow",
         "libbinder_rs",
+        "liblazy_static",
         "liblog_rust",
         "librpcbinder_rs",
     ],
diff --git a/microdroid/vm_payload/include/vm_payload.h b/microdroid/vm_payload/include/vm_payload.h
index dc01662..2aeb44e 100644
--- a/microdroid/vm_payload/include/vm_payload.h
+++ b/microdroid/vm_payload/include/vm_payload.h
@@ -96,6 +96,17 @@
  */
 bool AVmPayload_getDiceAttestationCdi(void *data, size_t size, size_t *total);
 
+/**
+ * Gets the path to the APK contents. It is a directory, under which are
+ * the unzipped contents of the APK containing the payload, all read-only
+ * but accessible to the payload.
+ *
+ * \return the path to the APK contents. The returned string should not be
+ * deleted or freed by the application. The string remains valid for the
+ * lifetime of the VM.
+ */
+const char *AVmPayload_getApkContentsPath(void);
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
diff --git a/microdroid/vm_payload/src/vm_payload_service.rs b/microdroid/vm_payload/src/vm_payload_service.rs
index bec4fde..b0dd891 100644
--- a/microdroid/vm_payload/src/vm_payload_service.rs
+++ b/microdroid/vm_payload/src/vm_payload_service.rs
@@ -15,12 +15,19 @@
 //! This module handles the interaction with virtual machine payload service.
 
 use android_system_virtualization_payload::aidl::android::system::virtualization::payload::IVmPayloadService::{
-    IVmPayloadService, VM_PAYLOAD_SERVICE_NAME};
+    IVmPayloadService, VM_PAYLOAD_SERVICE_NAME, VM_APK_CONTENTS_PATH};
 use anyhow::{Context, Result};
 use binder::{wait_for_interface, Strong, unstable_api::{AIBinder, new_spibinder}};
+use lazy_static::lazy_static;
 use log::{error, info, Level};
 use rpcbinder::run_vsock_rpc_server;
-use std::os::raw::c_void;
+use std::ffi::CString;
+use std::os::raw::{c_char, c_void};
+
+lazy_static! {
+    static ref VM_APK_CONTENTS_PATH_C: CString =
+        CString::new(VM_APK_CONTENTS_PATH).expect("CString::new failed");
+}
 
 /// Notifies the host that the payload is ready.
 /// Returns true if the notification succeeds else false.
@@ -185,6 +192,12 @@
     }
 }
 
+/// Gets the path to the APK contents.
+#[no_mangle]
+pub extern "C" fn AVmPayload_getApkContentsPath() -> *const c_char {
+    (*VM_APK_CONTENTS_PATH_C).as_ptr()
+}
+
 fn try_get_dice_attestation_cdi() -> Result<Vec<u8>> {
     get_vm_payload_service()?.getDiceAttestationCdi().context("Cannot get attestation CDI")
 }