Persistent vm_payload_service connection
Create a connection to Microdroid Manager when we first need it, then
hold it for use in any subsequent interaction.
Bug: 243512108
Test: atest MicrodroidTests
Change-Id: I191fabee64889ddf130f8c42da7c30074fdccd10
diff --git a/microdroid/vm_payload/include/vm_payload.h b/microdroid/vm_payload/include/vm_payload.h
index 82dbd6d..2eeaef8 100644
--- a/microdroid/vm_payload/include/vm_payload.h
+++ b/microdroid/vm_payload/include/vm_payload.h
@@ -56,8 +56,9 @@
void (*on_ready)(void *param), void *param);
/**
- * Get a secret that is uniquely bound to this VM instance. The secrets are 32-byte values and the
- * value associated with an identifier will not change over the lifetime of the VM instance.
+ * Get a secret that is uniquely bound to this VM instance. The secrets are
+ * values up to 32 bytes long and the value associated with an identifier will
+ * not change over the lifetime of the VM instance.
*
* \param identifier identifier of the secret to return.
* \param identifier_size size of the secret identifier.
diff --git a/microdroid/vm_payload/src/vm_payload_service.rs b/microdroid/vm_payload/src/vm_payload_service.rs
index dc1d100..eb4a38e 100644
--- a/microdroid/vm_payload/src/vm_payload_service.rs
+++ b/microdroid/vm_payload/src/vm_payload_service.rs
@@ -23,13 +23,31 @@
use rpcbinder::{get_unix_domain_rpc_interface, run_vsock_rpc_server};
use std::ffi::CString;
use std::os::raw::{c_char, c_void};
+use std::sync::Mutex;
lazy_static! {
static ref VM_APK_CONTENTS_PATH_C: CString =
CString::new(VM_APK_CONTENTS_PATH).expect("CString::new failed");
+ static ref PAYLOAD_CONNECTION: Mutex<Option<Strong<dyn IVmPayloadService>>> = Mutex::default();
}
-// Make sure our logging goes to logcat. It is harmless to call this more than once.
+/// Return a connection to the payload service in Microdroid Manager. Uses the existing connection
+/// if there is one, otherwise attempts to create a new one.
+fn get_vm_payload_service() -> Result<Strong<dyn IVmPayloadService>> {
+ let mut connection = PAYLOAD_CONNECTION.lock().unwrap();
+ if let Some(strong) = &*connection {
+ Ok(strong.clone())
+ } else {
+ let new_connection: Strong<dyn IVmPayloadService> = get_unix_domain_rpc_interface(
+ VM_PAYLOAD_SERVICE_SOCKET_NAME,
+ )
+ .context(format!("Failed to connect to service: {}", VM_PAYLOAD_SERVICE_SOCKET_NAME))?;
+ *connection = Some(new_connection.clone());
+ Ok(new_connection)
+ }
+}
+
+/// Make sure our logging goes to logcat. It is harmless to call this more than once.
fn initialize_logging() {
android_logger::init_once(
android_logger::Config::default().with_tag("vm_payload").with_min_level(Level::Debug),
@@ -215,8 +233,3 @@
fn try_get_dice_attestation_cdi() -> Result<Vec<u8>> {
get_vm_payload_service()?.getDiceAttestationCdi().context("Cannot get attestation CDI")
}
-
-fn get_vm_payload_service() -> Result<Strong<dyn IVmPayloadService>> {
- get_unix_domain_rpc_interface(VM_PAYLOAD_SERVICE_SOCKET_NAME)
- .context(format!("Failed to connect to service: {}", VM_PAYLOAD_SERVICE_SOCKET_NAME))
-}