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/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);