Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2637db75 authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Add Rust wrapper around native_handle_t." into main am: b169c759 am: 3a3e2849

parents ee1e8ea6 3a3e2849
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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: [
+92 −0
Original line number Diff line number Diff line
// 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 {}
+3 −0
Original line number Diff line number Diff line
@@ -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};
+1 −0
Original line number Diff line number Diff line
@@ -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>