[getService] Retry get_interface in keystore2

This cl retries to the get_interface function in keystore2 when
it connects to the KeyMint TA.

This is needed because when KeyMint TA runs in VM, it can take
several retries for the host to connect to the Trusty VM.
A timeout longer than the 5-second timeout in getService is
needed to handle this.

Bug: 355194622
Test: CF is gets booted with KeyMint TA in VM
Change-Id: I3b8a2aee77ad2e6111239898f165bc5bfd3ad479
diff --git a/keystore2/src/utils.rs b/keystore2/src/utils.rs
index 0a545f7..03c0626 100644
--- a/keystore2/src/utils.rs
+++ b/keystore2/src/utils.rs
@@ -40,14 +40,17 @@
     Authorization::Authorization, Domain::Domain, KeyDescriptor::KeyDescriptor,
 };
 use anyhow::{Context, Result};
-use binder::{Strong, ThreadState};
+use binder::{FromIBinder, StatusCode, Strong, ThreadState};
 use keystore2_apc_compat::{
     ApcCompatUiOptions, APC_COMPAT_ERROR_ABORTED, APC_COMPAT_ERROR_CANCELLED,
     APC_COMPAT_ERROR_IGNORED, APC_COMPAT_ERROR_OK, APC_COMPAT_ERROR_OPERATION_PENDING,
     APC_COMPAT_ERROR_SYSTEM_ERROR,
 };
 use keystore2_crypto::{aes_gcm_decrypt, aes_gcm_encrypt, ZVec};
+use log::{info, warn};
 use std::iter::IntoIterator;
+use std::thread::sleep;
+use std::time::Duration;
 
 #[cfg(test)]
 mod tests;
@@ -634,3 +637,25 @@
         aes_gcm_encrypt(plaintext, self.key()).context(ks_err!("Encryption failed."))
     }
 }
+
+pub(crate) fn retry_get_interface<T: FromIBinder + ?Sized>(
+    name: &str,
+) -> Result<Strong<T>, StatusCode> {
+    let retry_count = if cfg!(early_vm) { 5 } else { 1 };
+
+    let mut wait_time = Duration::from_secs(5);
+    for i in 1..retry_count {
+        match binder::get_interface(name) {
+            Ok(res) => return Ok(res),
+            Err(e) => {
+                warn!("failed to get interface {name}. Retry {i}/{retry_count}: {e:?}");
+                sleep(wait_time);
+                wait_time *= 2;
+            }
+        }
+    }
+    if retry_count > 1 {
+        info!("{retry_count}-th (last) retry to get interface: {name}");
+    }
+    binder::get_interface(name)
+}