diff options
author | 2024-08-20 18:37:59 +0100 | |
---|---|---|
committer | 2024-09-02 15:50:18 +0100 | |
commit | 9487efdccdc730953b3fead3bccfcd2f84e3229c (patch) | |
tree | cc3a534872fbd4efcd6688d9df2b672b71169d1e | |
parent | cdca5ed76e491039f1ac9500731d1dc795c0d783 (diff) |
Add Rust wrapper around native_handle_t.
Bug: 359100544
Test: atest libnativewindow_rs-internal_test
Change-Id: Ia4082c7eb2682a58beb4757ac332a8af840f4455
-rw-r--r-- | libs/nativewindow/rust/Android.bp | 4 | ||||
-rw-r--r-- | libs/nativewindow/rust/src/handle.rs | 92 | ||||
-rw-r--r-- | libs/nativewindow/rust/src/lib.rs | 3 | ||||
-rw-r--r-- | libs/nativewindow/rust/sys/nativewindow_bindings.h | 1 |
4 files changed, 100 insertions, 0 deletions
diff --git a/libs/nativewindow/rust/Android.bp b/libs/nativewindow/rust/Android.bp index 97740dbcd8..d68d6ba1af 100644 --- a/libs/nativewindow/rust/Android.bp +++ b/libs/nativewindow/rust/Android.bp @@ -29,6 +29,8 @@ rust_bindgen { "--bitfield-enum=AHardwareBuffer_UsageFlags", "--allowlist-file=.*/nativewindow/include/.*\\.h", + "--allowlist-file=.*/include/cutils/.*\\.h", + "--allowlist-file=.*/include_outside_system/cutils/.*\\.h", "--blocklist-type", "AParcel", "--raw-line", @@ -39,6 +41,7 @@ rust_bindgen { ], shared_libs: [ "libbinder_ndk", + "libcutils", "libnativewindow", ], rustlibs: [ @@ -66,6 +69,7 @@ rust_library { srcs: [":libnativewindow_bindgen_internal"], shared_libs: [ "libbinder_ndk", + "libcutils", "libnativewindow", ], rustlibs: [ diff --git a/libs/nativewindow/rust/src/handle.rs b/libs/nativewindow/rust/src/handle.rs new file mode 100644 index 0000000000..a3a9dc6258 --- /dev/null +++ b/libs/nativewindow/rust/src/handle.rs @@ -0,0 +1,92 @@ +// Copyright (C) 2024 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use std::{mem::forget, ptr::NonNull}; + +/// Rust wrapper around `native_handle_t`. +/// +/// This owns the `native_handle_t` and its file descriptors, and will close them and free it when +/// it is dropped. +#[derive(Debug)] +pub struct NativeHandle(NonNull<ffi::native_handle_t>); + +impl NativeHandle { + /// Wraps a raw `native_handle_t` pointer, taking ownership of it. + /// + /// # Safety + /// + /// `native_handle` must be a valid pointer to a `native_handle_t`, and must not be used + /// anywhere else after calling this method. + pub unsafe fn from_raw(native_handle: NonNull<ffi::native_handle_t>) -> Self { + Self(native_handle) + } + + /// Creates a new `NativeHandle` wrapping a clone of the given `native_handle_t` pointer. + /// + /// Unlike [`from_raw`](Self::from_raw) this doesn't take ownership of the pointer passed in, so + /// the caller remains responsible for closing and freeing it. + /// + /// # Safety + /// + /// `native_handle` must be a valid pointer to a `native_handle_t`. + pub unsafe fn clone_from_raw(native_handle: NonNull<ffi::native_handle_t>) -> Option<Self> { + // SAFETY: The caller promised that `native_handle` was valid. + let cloned = unsafe { ffi::native_handle_clone(native_handle.as_ptr()) }; + NonNull::new(cloned).map(Self) + } + + /// Returns a raw pointer to the wrapped `native_handle_t`. + /// + /// This is only valid as long as this `NativeHandle` exists, so shouldn't be stored. It mustn't + /// be closed or deleted. + pub fn as_raw(&self) -> NonNull<ffi::native_handle_t> { + self.0 + } + + /// Turns the `NativeHandle` into a raw `native_handle_t`. + /// + /// The caller takes ownership of the `native_handle_t` and its file descriptors, so is + /// responsible for closing and freeing it. + pub fn into_raw(self) -> NonNull<ffi::native_handle_t> { + let raw = self.0; + forget(self); + raw + } +} + +impl Clone for NativeHandle { + fn clone(&self) -> Self { + // SAFETY: Our wrapped `native_handle_t` pointer is always valid. + unsafe { Self::clone_from_raw(self.0) }.expect("native_handle_clone returned null") + } +} + +impl Drop for NativeHandle { + fn drop(&mut self) { + // SAFETY: Our wrapped `native_handle_t` pointer is always valid, and it won't be accessed + // after this because we own it and are being dropped. + unsafe { + assert_eq!(ffi::native_handle_close(self.0.as_ptr()), 0); + assert_eq!(ffi::native_handle_delete(self.0.as_ptr()), 0); + } + } +} + +// SAFETY: `NativeHandle` owns the `native_handle_t`, which just contains some integers and file +// descriptors, which aren't tied to any particular thread. +unsafe impl Send for NativeHandle {} + +// SAFETY: A `NativeHandle` can be used from different threads simultaneously, as is is just +// integers and file descriptors. +unsafe impl Sync for NativeHandle {} diff --git a/libs/nativewindow/rust/src/lib.rs b/libs/nativewindow/rust/src/lib.rs index dc3f51f7fd..ffde137ccb 100644 --- a/libs/nativewindow/rust/src/lib.rs +++ b/libs/nativewindow/rust/src/lib.rs @@ -16,7 +16,10 @@ extern crate nativewindow_bindgen as ffi; +mod handle; mod surface; + +pub use handle::NativeHandle; pub use surface::Surface; pub use ffi::{AHardwareBuffer_Format, AHardwareBuffer_UsageFlags}; diff --git a/libs/nativewindow/rust/sys/nativewindow_bindings.h b/libs/nativewindow/rust/sys/nativewindow_bindings.h index 5689f7df94..7c93c5aa1b 100644 --- a/libs/nativewindow/rust/sys/nativewindow_bindings.h +++ b/libs/nativewindow/rust/sys/nativewindow_bindings.h @@ -20,3 +20,4 @@ #include <android/hdr_metadata.h> #include <android/native_window.h> #include <android/native_window_aidl.h> +#include <cutils/native_handle.h> |