Skip to content

Commit 9487efd

Browse files
committed
Add Rust wrapper around native_handle_t.
Bug: 359100544 Test: atest libnativewindow_rs-internal_test Change-Id: Ia4082c7eb2682a58beb4757ac332a8af840f4455
1 parent cdca5ed commit 9487efd

4 files changed

Lines changed: 100 additions & 0 deletions

File tree

libs/nativewindow/rust/Android.bp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ rust_bindgen {
2929
"--bitfield-enum=AHardwareBuffer_UsageFlags",
3030

3131
"--allowlist-file=.*/nativewindow/include/.*\\.h",
32+
"--allowlist-file=.*/include/cutils/.*\\.h",
33+
"--allowlist-file=.*/include_outside_system/cutils/.*\\.h",
3234
"--blocklist-type",
3335
"AParcel",
3436
"--raw-line",
@@ -39,6 +41,7 @@ rust_bindgen {
3941
],
4042
shared_libs: [
4143
"libbinder_ndk",
44+
"libcutils",
4245
"libnativewindow",
4346
],
4447
rustlibs: [
@@ -66,6 +69,7 @@ rust_library {
6669
srcs: [":libnativewindow_bindgen_internal"],
6770
shared_libs: [
6871
"libbinder_ndk",
72+
"libcutils",
6973
"libnativewindow",
7074
],
7175
rustlibs: [
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Copyright (C) 2024 The Android Open Source Project
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
use std::{mem::forget, ptr::NonNull};
16+
17+
/// Rust wrapper around `native_handle_t`.
18+
///
19+
/// This owns the `native_handle_t` and its file descriptors, and will close them and free it when
20+
/// it is dropped.
21+
#[derive(Debug)]
22+
pub struct NativeHandle(NonNull<ffi::native_handle_t>);
23+
24+
impl NativeHandle {
25+
/// Wraps a raw `native_handle_t` pointer, taking ownership of it.
26+
///
27+
/// # Safety
28+
///
29+
/// `native_handle` must be a valid pointer to a `native_handle_t`, and must not be used
30+
/// anywhere else after calling this method.
31+
pub unsafe fn from_raw(native_handle: NonNull<ffi::native_handle_t>) -> Self {
32+
Self(native_handle)
33+
}
34+
35+
/// Creates a new `NativeHandle` wrapping a clone of the given `native_handle_t` pointer.
36+
///
37+
/// Unlike [`from_raw`](Self::from_raw) this doesn't take ownership of the pointer passed in, so
38+
/// the caller remains responsible for closing and freeing it.
39+
///
40+
/// # Safety
41+
///
42+
/// `native_handle` must be a valid pointer to a `native_handle_t`.
43+
pub unsafe fn clone_from_raw(native_handle: NonNull<ffi::native_handle_t>) -> Option<Self> {
44+
// SAFETY: The caller promised that `native_handle` was valid.
45+
let cloned = unsafe { ffi::native_handle_clone(native_handle.as_ptr()) };
46+
NonNull::new(cloned).map(Self)
47+
}
48+
49+
/// Returns a raw pointer to the wrapped `native_handle_t`.
50+
///
51+
/// This is only valid as long as this `NativeHandle` exists, so shouldn't be stored. It mustn't
52+
/// be closed or deleted.
53+
pub fn as_raw(&self) -> NonNull<ffi::native_handle_t> {
54+
self.0
55+
}
56+
57+
/// Turns the `NativeHandle` into a raw `native_handle_t`.
58+
///
59+
/// The caller takes ownership of the `native_handle_t` and its file descriptors, so is
60+
/// responsible for closing and freeing it.
61+
pub fn into_raw(self) -> NonNull<ffi::native_handle_t> {
62+
let raw = self.0;
63+
forget(self);
64+
raw
65+
}
66+
}
67+
68+
impl Clone for NativeHandle {
69+
fn clone(&self) -> Self {
70+
// SAFETY: Our wrapped `native_handle_t` pointer is always valid.
71+
unsafe { Self::clone_from_raw(self.0) }.expect("native_handle_clone returned null")
72+
}
73+
}
74+
75+
impl Drop for NativeHandle {
76+
fn drop(&mut self) {
77+
// SAFETY: Our wrapped `native_handle_t` pointer is always valid, and it won't be accessed
78+
// after this because we own it and are being dropped.
79+
unsafe {
80+
assert_eq!(ffi::native_handle_close(self.0.as_ptr()), 0);
81+
assert_eq!(ffi::native_handle_delete(self.0.as_ptr()), 0);
82+
}
83+
}
84+
}
85+
86+
// SAFETY: `NativeHandle` owns the `native_handle_t`, which just contains some integers and file
87+
// descriptors, which aren't tied to any particular thread.
88+
unsafe impl Send for NativeHandle {}
89+
90+
// SAFETY: A `NativeHandle` can be used from different threads simultaneously, as is is just
91+
// integers and file descriptors.
92+
unsafe impl Sync for NativeHandle {}

libs/nativewindow/rust/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@
1616
1717
extern crate nativewindow_bindgen as ffi;
1818

19+
mod handle;
1920
mod surface;
21+
22+
pub use handle::NativeHandle;
2023
pub use surface::Surface;
2124

2225
pub use ffi::{AHardwareBuffer_Format, AHardwareBuffer_UsageFlags};

libs/nativewindow/rust/sys/nativewindow_bindings.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@
2020
#include <android/hdr_metadata.h>
2121
#include <android/native_window.h>
2222
#include <android/native_window_aidl.h>
23+
#include <cutils/native_handle.h>

0 commit comments

Comments
 (0)