Replace keystore2_vintf's bindgen with cxx

This simplifies things by removing code and unsafe blocks.

Test: Boot
Test: keystore2_vintf_test
Change-Id: I5858a2a25e0ee27e42ee9846d44762da2454f706
diff --git a/keystore2/Android.bp b/keystore2/Android.bp
index 18d082b..b591d8c 100644
--- a/keystore2/Android.bp
+++ b/keystore2/Android.bp
@@ -133,7 +133,6 @@
         "libkeystore2_aaid",
         "libkeystore2_apc_compat",
         "libkeystore2_crypto",
-        "libkeystore2_vintf_cpp",
         "libkm_compat_service",
         "libkm_compat",
         "libm",
diff --git a/keystore2/src/globals.rs b/keystore2/src/globals.rs
index a03a61c..eae5ad0 100644
--- a/keystore2/src/globals.rs
+++ b/keystore2/src/globals.rs
@@ -208,14 +208,14 @@
 
     let service_name = match *security_level {
         SecurityLevel::TRUSTED_ENVIRONMENT => {
-            if keymint_instances.as_vec()?.iter().any(|instance| *instance == "default") {
+            if keymint_instances.iter().any(|instance| *instance == "default") {
                 Some(format!("{}/default", KEYMINT_SERVICE_NAME))
             } else {
                 None
             }
         }
         SecurityLevel::STRONGBOX => {
-            if keymint_instances.as_vec()?.iter().any(|instance| *instance == "strongbox") {
+            if keymint_instances.iter().any(|instance| *instance == "strongbox") {
                 Some(format!("{}/strongbox", KEYMINT_SERVICE_NAME))
             } else {
                 None
@@ -319,7 +319,7 @@
         get_aidl_instances("android.hardware.security.secureclock", 1, "ISecureClock");
 
     let secure_clock_available =
-        secureclock_instances.as_vec()?.iter().any(|instance| *instance == "default");
+        secureclock_instances.iter().any(|instance| *instance == "default");
 
     let default_time_stamp_service_name = format!("{}/default", TIME_STAMP_SERVICE_NAME);
 
@@ -372,14 +372,14 @@
 
     let service_name = match *security_level {
         SecurityLevel::TRUSTED_ENVIRONMENT => {
-            if remotely_prov_instances.as_vec()?.iter().any(|instance| *instance == "default") {
+            if remotely_prov_instances.iter().any(|instance| *instance == "default") {
                 Some(format!("{}/default", REMOTE_PROVISIONING_HAL_SERVICE_NAME))
             } else {
                 None
             }
         }
         SecurityLevel::STRONGBOX => {
-            if remotely_prov_instances.as_vec()?.iter().any(|instance| *instance == "strongbox") {
+            if remotely_prov_instances.iter().any(|instance| *instance == "strongbox") {
                 Some(format!("{}/strongbox", REMOTE_PROVISIONING_HAL_SERVICE_NAME))
             } else {
                 None
diff --git a/keystore2/src/shared_secret_negotiation.rs b/keystore2/src/shared_secret_negotiation.rs
index e32b675..1862f73 100644
--- a/keystore2/src/shared_secret_negotiation.rs
+++ b/keystore2/src/shared_secret_negotiation.rs
@@ -21,7 +21,7 @@
     ISharedSecret::ISharedSecret, SharedSecretParameters::SharedSecretParameters,
 };
 use android_security_compat::aidl::android::security::compat::IKeystoreCompatService::IKeystoreCompatService;
-use anyhow::{Context, Result};
+use anyhow::Result;
 use keystore2_vintf::{get_aidl_instances, get_hidl_instances};
 use std::fmt::{self, Display, Formatter};
 use std::time::Duration;
@@ -118,48 +118,32 @@
         .iter()
         .map(|(ma, mi)| {
             get_hidl_instances(KEYMASTER_PACKAGE_NAME, *ma, *mi, KEYMASTER_INTERFACE_NAME)
-                .as_vec()
-                .with_context(|| format!("Trying to convert KM{}.{} names to vector.", *ma, *mi))
-                .map(|instances| {
-                    instances
-                        .into_iter()
-                        .filter_map(|name| {
-                            filter_map_legacy_km_instances(name.to_string(), (*ma, *mi)).and_then(
-                                |sp| {
-                                    if let SharedSecretParticipant::Hidl {
-                                        is_strongbox: true,
-                                        ..
-                                    } = &sp
-                                    {
-                                        if !legacy_strongbox_found {
-                                            legacy_strongbox_found = true;
-                                            return Some(sp);
-                                        }
-                                    } else if !legacy_default_found {
-                                        legacy_default_found = true;
-                                        return Some(sp);
-                                    }
-                                    None
-                                },
-                            )
-                        })
-                        .collect::<Vec<SharedSecretParticipant>>()
+                .into_iter()
+                .filter_map(|name| {
+                    filter_map_legacy_km_instances(name, (*ma, *mi)).and_then(|sp| {
+                        if let SharedSecretParticipant::Hidl { is_strongbox: true, .. } = &sp {
+                            if !legacy_strongbox_found {
+                                legacy_strongbox_found = true;
+                                return Some(sp);
+                            }
+                        } else if !legacy_default_found {
+                            legacy_default_found = true;
+                            return Some(sp);
+                        }
+                        None
+                    })
                 })
+                .collect::<Vec<SharedSecretParticipant>>()
         })
-        .collect::<Result<Vec<_>>>()
-        .map(|v| v.into_iter().flatten())
-        .and_then(|i| {
-            Ok(i.chain(
-                get_aidl_instances(SHARED_SECRET_PACKAGE_NAME, 1, SHARED_SECRET_INTERFACE_NAME)
-                    .as_vec()
-                    .context("In list_participants: Trying to convert KM1.0 names to vector.")?
-                    .into_iter()
-                    .map(|name| SharedSecretParticipant::Aidl(name.to_string()))
-                    .collect::<Vec<_>>()
-                    .into_iter(),
-            ))
+        .into_iter()
+        .flatten()
+        .chain({
+            get_aidl_instances(SHARED_SECRET_PACKAGE_NAME, 1, SHARED_SECRET_INTERFACE_NAME)
+                .into_iter()
+                .map(SharedSecretParticipant::Aidl)
+                .collect::<Vec<_>>()
+                .into_iter()
         })
-        .context("In list_participants.")?
         .collect())
 }
 
diff --git a/keystore2/src/vintf/Android.bp b/keystore2/src/vintf/Android.bp
index 352f2be..34719aa 100644
--- a/keystore2/src/vintf/Android.bp
+++ b/keystore2/src/vintf/Android.bp
@@ -26,39 +26,32 @@
     crate_name: "keystore2_vintf",
     srcs: ["lib.rs"],
     rustlibs: [
-        "libkeystore2_vintf_bindgen",
+        "libcxx",
     ],
     shared_libs: [
+        "libvintf",
+    ],
+    static_libs: [
         "libkeystore2_vintf_cpp",
-        "libvintf",
     ],
 }
 
-cc_library {
+cc_library_static {
     name: "libkeystore2_vintf_cpp",
-    srcs: [
-        "vintf.cpp",
-    ],
+    srcs: ["vintf.cpp"],
+    generated_headers: ["cxx-bridge-header"],
+    generated_sources: ["vintf_bridge_code"],
     shared_libs: [
         "libvintf",
     ],
 }
 
-rust_bindgen {
-    name: "libkeystore2_vintf_bindgen",
-    wrapper_src: "vintf.hpp",
-    crate_name: "keystore2_vintf_bindgen",
-    source_stem: "bindings",
-    host_supported: true,
-    shared_libs: ["libvintf"],
-    bindgen_flags: [
-        "--size_t-is-usize",
-        "--allowlist-function", "getHalNames",
-        "--allowlist-function", "getHalNamesAndVersions",
-        "--allowlist-function", "getHidlInstances",
-        "--allowlist-function", "getAidlInstances",
-        "--allowlist-function", "freeNames",
-    ],
+genrule {
+    name: "vintf_bridge_code",
+    tools: ["cxxbridge"],
+    cmd: "$(location cxxbridge) $(in) >> $(out)",
+    srcs: ["lib.rs"],
+    out: ["vintf_cxx_generated.cc"],
 }
 
 rust_test {
@@ -68,7 +61,7 @@
     test_suites: ["general-tests"],
     auto_gen_config: true,
     rustlibs: [
-        "libkeystore2_vintf_bindgen",
+        "libcxx",
     ],
     static_libs: [
         "libkeystore2_vintf_cpp",
@@ -78,13 +71,3 @@
         "libvintf",
     ],
 }
-
-rust_test {
-    name: "libkeystore2_vintf_bindgen_test",
-    srcs: [":libkeystore2_vintf_bindgen"],
-    crate_name: "keystore2_vintf_bindgen_test",
-    test_suites: ["general-tests"],
-    auto_gen_config: true,
-    clippy_lints: "none",
-    lints: "none",
-}
diff --git a/keystore2/src/vintf/lib.rs b/keystore2/src/vintf/lib.rs
index 8730a3e..89e18eb 100644
--- a/keystore2/src/vintf/lib.rs
+++ b/keystore2/src/vintf/lib.rs
@@ -14,96 +14,35 @@
 
 //! Bindings for getting the list of HALs.
 
-use keystore2_vintf_bindgen::{
-    freeNames, getAidlInstances, getHalNames, getHalNamesAndVersions, getHidlInstances,
-};
-use std::ffi::{CStr, CString};
-use std::os::raw::c_char;
-use std::str::Utf8Error;
+#[cxx::bridge]
+mod ffi {
+    unsafe extern "C++" {
+        include!("vintf.hpp");
 
-/// A struct that contains a list of HALs (optionally with version numbers).
-/// To use it, call as_vec to get a Vec view of the data it contains.
-pub struct HalNames {
-    data: *mut *mut c_char,
-    len: usize,
-}
+        /// Gets all HAL names.
+        /// Note that this is not a zero-cost shim: it will make copies of the strings.
+        fn get_hal_names() -> Vec<String>;
 
-impl Drop for HalNames {
-    fn drop(&mut self) {
-        // Safety: The memory is allocated by our C shim so it must free it as well.
-        unsafe { freeNames(self.data, self.len) }
+        /// Gets all HAL names and versions.
+        /// Note that this is not a zero-cost shim: it will make copies of the strings.
+        fn get_hal_names_and_versions() -> Vec<String>;
+
+        /// Gets the instances of the given package, version, and interface tuple.
+        /// Note that this is not a zero-cost shim: it will make copies of the strings.
+        fn get_hidl_instances(
+            package: &str,
+            major_version: usize,
+            minor_version: usize,
+            interface_name: &str,
+        ) -> Vec<String>;
+
+        /// Gets the instances of the given package, version, and interface tuple.
+        /// Note that this is not a zero-cost shim: it will make copies of the strings.
+        fn get_aidl_instances(package: &str, version: usize, interface_name: &str) -> Vec<String>;
     }
 }
 
-impl<'a> HalNames {
-    /// Get a Vec view of the list of HALs.
-    pub fn as_vec(&'a self) -> Result<Vec<&'a str>, Utf8Error> {
-        // Safety: self.data contains self.len C strings.
-        // The lifetimes ensure that the HalNames (and hence the strings) live
-        // at least as long as the returned vector.
-        unsafe { (0..self.len).map(|i| CStr::from_ptr(*self.data.add(i)).to_str()) }.collect()
-    }
-}
-
-/// Gets all HAL names.
-/// Note that this is not a zero-cost shim: it will make copies of the strings.
-pub fn get_hal_names() -> HalNames {
-    let mut len: usize = 0;
-    // Safety: We'll wrap this in HalNames to free the memory it allocates.
-    // It stores the size of the array it returns in len.
-    let raw_strs = unsafe { getHalNames(&mut len) };
-    HalNames { data: raw_strs, len }
-}
-
-/// Gets all HAL names and versions.
-/// Note that this is not a zero-cost shim: it will make copies of the strings.
-pub fn get_hal_names_and_versions() -> HalNames {
-    let mut len: usize = 0;
-    // Safety: We'll wrap this in HalNames to free the memory it allocates.
-    // It stores the size of the array it returns in len.
-    let raw_strs = unsafe { getHalNamesAndVersions(&mut len) };
-    HalNames { data: raw_strs, len }
-}
-
-/// Gets the instances of the given package, version, and interface tuple.
-/// Note that this is not a zero-cost shim: it will make copies of the strings.
-pub fn get_hidl_instances(
-    package: &str,
-    major_version: usize,
-    minor_version: usize,
-    interface_name: &str,
-) -> HalNames {
-    let mut len: usize = 0;
-    let packages = CString::new(package).expect("Failed to make CString from package.");
-    let interface_name =
-        CString::new(interface_name).expect("Failed to make CString from interface_name.");
-    // Safety: We'll wrap this in HalNames to free the memory it allocates.
-    // It stores the size of the array it returns in len.
-    let raw_strs = unsafe {
-        getHidlInstances(
-            &mut len,
-            packages.as_ptr(),
-            major_version,
-            minor_version,
-            interface_name.as_ptr(),
-        )
-    };
-    HalNames { data: raw_strs, len }
-}
-
-/// Gets the instances of the given package, version, and interface tuple.
-/// Note that this is not a zero-cost shim: it will make copies of the strings.
-pub fn get_aidl_instances(package: &str, version: usize, interface_name: &str) -> HalNames {
-    let mut len: usize = 0;
-    let packages = CString::new(package).expect("Failed to make CString from package.");
-    let interface_name =
-        CString::new(interface_name).expect("Failed to make CString from interface_name.");
-    // Safety: We'll wrap this in HalNames to free the memory it allocates.
-    // It stores the size of the array it returns in len.
-    let raw_strs =
-        unsafe { getAidlInstances(&mut len, packages.as_ptr(), version, interface_name.as_ptr()) };
-    HalNames { data: raw_strs, len }
-}
+pub use ffi::*;
 
 #[cfg(test)]
 mod tests {
@@ -111,17 +50,13 @@
     use super::*;
 
     #[test]
-    fn test() -> Result<(), Utf8Error> {
-        let result = get_hal_names();
-        let names = result.as_vec()?;
+    fn test() {
+        let names = get_hal_names();
         assert_ne!(names.len(), 0);
 
-        let result = get_hal_names_and_versions();
-        let names_and_versions = result.as_vec()?;
+        let names_and_versions = get_hal_names_and_versions();
         assert_ne!(names_and_versions.len(), 0);
 
         assert!(names_and_versions.len() >= names.len());
-
-        Ok(())
     }
 }
diff --git a/keystore2/src/vintf/vintf.cpp b/keystore2/src/vintf/vintf.cpp
index e407efa..00625bf 100644
--- a/keystore2/src/vintf/vintf.cpp
+++ b/keystore2/src/vintf/vintf.cpp
@@ -14,55 +14,43 @@
  * limitations under the License.
  */
 
-#include "vintf.hpp"
-
+#include <algorithm>
 #include <vintf/HalManifest.h>
 #include <vintf/VintfObject.h>
 
-// Converts a set<string> into a C-style array of C strings.
-static char** convert(const std::set<std::string>& names) {
-    char** ret = new char*[names.size()];
-    char** ptr = ret;
-    for (const auto& name : names) {
-        *(ptr++) = strdup(name.c_str());
-    }
-    return ret;
+#include "rust/cxx.h"
+
+rust::Vec<rust::String> convert(const std::set<std::string>& names) {
+    rust::Vec<rust::String> result;
+    std::copy(names.begin(), names.end(), std::back_inserter(result));
+    return result;
 }
 
-char** getHalNames(size_t* len) {
-    auto manifest = android::vintf::VintfObject::GetDeviceHalManifest();
+rust::Vec<rust::String> get_hal_names() {
+    const auto manifest = android::vintf::VintfObject::GetDeviceHalManifest();
     const auto names = manifest->getHalNames();
-    *len = names.size();
     return convert(names);
 }
 
-char** getHalNamesAndVersions(size_t* len) {
-    auto manifest = android::vintf::VintfObject::GetDeviceHalManifest();
+rust::Vec<rust::String> get_hal_names_and_versions() {
+    const auto manifest = android::vintf::VintfObject::GetDeviceHalManifest();
     const auto names = manifest->getHalNamesAndVersions();
-    *len = names.size();
     return convert(names);
 }
 
-char** getHidlInstances(size_t* len, const char* package, size_t major_version,
-                        size_t minor_version, const char* interfaceName) {
+rust::Vec<rust::String> get_hidl_instances(rust::Str package, size_t major_version,
+                                           size_t minor_version, rust::Str interfaceName) {
     android::vintf::Version version(major_version, minor_version);
-    auto manifest = android::vintf::VintfObject::GetDeviceHalManifest();
-    const auto names = manifest->getHidlInstances(package, version, interfaceName);
-    *len = names.size();
+    const auto manifest = android::vintf::VintfObject::GetDeviceHalManifest();
+    const auto names = manifest->getHidlInstances(static_cast<std::string>(package), version,
+                                                  static_cast<std::string>(interfaceName));
     return convert(names);
 }
 
-char** getAidlInstances(size_t* len, const char* package, size_t version,
-                        const char* interfaceName) {
-    auto manifest = android::vintf::VintfObject::GetDeviceHalManifest();
-    const auto names = manifest->getAidlInstances(package, version, interfaceName);
-    *len = names.size();
+rust::Vec<rust::String> get_aidl_instances(rust::Str package, size_t version,
+                                           rust::Str interfaceName) {
+    const auto manifest = android::vintf::VintfObject::GetDeviceHalManifest();
+    const auto names = manifest->getAidlInstances(static_cast<std::string>(package), version,
+                                                  static_cast<std::string>(interfaceName));
     return convert(names);
 }
-
-void freeNames(char** names, size_t len) {
-    for (int i = 0; i < len; i++) {
-        free(names[i]);
-    }
-    delete[] names;
-}
diff --git a/keystore2/src/vintf/vintf.hpp b/keystore2/src/vintf/vintf.hpp
index 091e8e8..dbc88f0 100644
--- a/keystore2/src/vintf/vintf.hpp
+++ b/keystore2/src/vintf/vintf.hpp
@@ -14,20 +14,13 @@
  * limitations under the License.
  */
 
-#ifndef __VINTF_H__
-#define __VINTF_H__
+#pragma once
 
-#include <stddef.h>
+#include "rust/cxx.h"
 
-extern "C" {
-
-char** getHalNames(size_t* len);
-char** getHalNamesAndVersions(size_t* len);
-char** getHidlInstances(size_t* len, const char* package, size_t major_version,
-                        size_t minor_version, const char* interfaceName);
-char** getAidlInstances(size_t* len, const char* package, size_t version,
-                        const char* interfaceName);
-void freeNames(char** names, size_t len);
-}
-
-#endif  //  __VINTF_H__
+rust::Vec<rust::String> get_hal_names();
+rust::Vec<rust::String> get_hal_names_and_versions();
+rust::Vec<rust::String> get_hidl_instances(rust::Str package, size_t major_version,
+                                           size_t minor_version, rust::Str interfaceName);
+rust::Vec<rust::String> get_aidl_instances(rust::Str package, size_t version,
+                                           rust::Str interfaceName);