Retry connecting to /default KeyMint

Make the cfg-controlled retry behaviour universal.  This allows for
slower-starting /default KeyMint instances, at a cost of slower boot
time.  It will also still eventually fail, making incorrect
configurations visible.

Bug: 406623055
Test: boot, logcat
Change-Id: Id973ca678b57753456d4260628f31c27f02d52ae
diff --git a/keystore2/Android.bp b/keystore2/Android.bp
index 92a4bed..abd0f63 100644
--- a/keystore2/Android.bp
+++ b/keystore2/Android.bp
@@ -31,10 +31,6 @@
         "keystore2_use_latest_aidl_rust",
         "structured_log_rust_defaults",
     ],
-    cfgs: select(release_flag("RELEASE_AVF_ENABLE_EARLY_VM"), {
-        true: ["early_vm"],
-        default: [],
-    }),
     rustlibs: [
         "android.hardware.security.rkp-V3-rust",
         "android.hardware.security.secureclock-V1-rust",
diff --git a/keystore2/src/globals.rs b/keystore2/src/globals.rs
index a9d4fbc..28e3b7f 100644
--- a/keystore2/src/globals.rs
+++ b/keystore2/src/globals.rs
@@ -235,13 +235,13 @@
         .context(ks_err!("Get service name from binder service"))?;
 
     let (keymint, hal_version) = if let Some(service_name) = service_name {
+        // Allow a few retries for retrieving the /default KeyMint instance, as it is needed at
+        // startup and may also be starting up.  (However, note that a slow-starting /default
+        // KeyMint will result in extended boot times.)
+        let retry_count = if *security_level == SecurityLevel::TRUSTED_ENVIRONMENT { 6 } else { 1 };
         let km: Strong<dyn IKeyMintDevice> =
-            if SecurityLevel::TRUSTED_ENVIRONMENT == *security_level {
-                map_binder_status_code(retry_get_interface(&service_name))
-            } else {
-                map_binder_status_code(binder::get_interface(&service_name))
-            }
-            .context(ks_err!("Trying to connect to genuine KeyMint service."))?;
+            map_binder_status_code(retry_get_interface(&service_name, retry_count))
+                .context(ks_err!("Trying to connect to genuine KeyMint service."))?;
         // Map the HAL version code for KeyMint to be <AIDL version> * 100, so
         // - V1 is 100
         // - V2 is 200
diff --git a/keystore2/src/utils.rs b/keystore2/src/utils.rs
index 183bc0b..deb3e18 100644
--- a/keystore2/src/utils.rs
+++ b/keystore2/src/utils.rs
@@ -48,7 +48,7 @@
     APC_COMPAT_ERROR_SYSTEM_ERROR,
 };
 use keystore2_crypto::{aes_gcm_decrypt, aes_gcm_encrypt, ZVec};
-use log::{debug, info, warn};
+use log::{debug, error, info, warn};
 use std::iter::IntoIterator;
 use std::thread::sleep;
 use std::time::Duration;
@@ -665,24 +665,32 @@
     }
 }
 
+/// Get the Binder interface identified by `name`, retrying any failures up to the given
+/// `retry_count`.
 pub(crate) fn retry_get_interface<T: FromIBinder + ?Sized>(
     name: &str,
+    retry_count: usize,
 ) -> 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;
+    let mut attempts = 0;
+    let mut wait_time = Duration::from_secs(1);
+    loop {
+        let err = match binder::get_interface(name) {
+            Ok(res) => {
+                if attempts > 1 {
+                    info!("Success on get_interface({name}) after {attempts} failures!");
+                }
+                return Ok(res);
             }
+            Err(e) => e,
+        };
+        attempts += 1;
+        error!("Failed (attempt {attempts} of {retry_count}) to get_interface {name}: {err:?}");
+        if attempts >= retry_count {
+            error!("Give up retrying after {attempts} failures, return final error: {err:?}");
+            return Err(err);
         }
+        info!("Blocking wait {wait_time:?} before retry of get_interface({name})");
+        sleep(wait_time);
+        wait_time *= 2;
     }
-    if retry_count > 1 {
-        info!("{retry_count}-th (last) retry to get interface: {name}");
-    }
-    binder::get_interface(name)
 }