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

Commit 78c6534a authored by Andrew Walbran's avatar Andrew Walbran
Browse files

Wrap more methods to get and set properties of ANativeWindow.

Bug: 307535208
Test: atest libnativewindow_rs-internal_test
Change-Id: I18e4158321f71bd95bb6d3f4868bae4d8a7d417e
parent 8dd89273
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ rust_bindgen {
    source_stem: "bindings",
    bindgen_flags: [
        "--constified-enum-module=AHardwareBuffer_Format",
        "--bitfield-enum=ADataSpace",
        "--bitfield-enum=AHardwareBuffer_UsageFlags",

        "--allowlist-file=.*/nativewindow/include/.*\\.h",
@@ -110,6 +111,7 @@ rust_defaults {
    srcs: ["src/lib.rs"],
    rustlibs: [
        "libbinder_rs",
        "libbitflags",
        "libnativewindow_bindgen",
    ],
}
+112 −3
Original line number Diff line number Diff line
@@ -20,10 +20,14 @@ use binder::{
    unstable_api::{status_result, AsNative},
    StatusCode,
};
use bitflags::bitflags;
use nativewindow_bindgen::{
    AHardwareBuffer_Format, ANativeWindow, ANativeWindow_acquire, ANativeWindow_getFormat,
    ANativeWindow_getHeight, ANativeWindow_getWidth, ANativeWindow_readFromParcel,
    ANativeWindow_release, ANativeWindow_writeToParcel,
    ADataSpace, AHardwareBuffer_Format, ANativeWindow, ANativeWindow_acquire,
    ANativeWindow_getBuffersDataSpace, ANativeWindow_getBuffersDefaultDataSpace,
    ANativeWindow_getFormat, ANativeWindow_getHeight, ANativeWindow_getWidth,
    ANativeWindow_readFromParcel, ANativeWindow_release, ANativeWindow_setBuffersDataSpace,
    ANativeWindow_setBuffersGeometry, ANativeWindow_setBuffersTransform,
    ANativeWindow_writeToParcel,
};
use std::error::Error;
use std::fmt::{self, Debug, Display, Formatter};
@@ -60,6 +64,95 @@ impl Surface {
        let format = unsafe { ANativeWindow_getFormat(self.0.as_ptr()) };
        format.try_into().map_err(|_| ErrorCode(format))
    }

    /// Changes the format and size of the window buffers.
    ///
    /// The width and height control the number of pixels in the buffers, not the dimensions of the
    /// window on screen. If these are different than the window's physical size, then its buffer
    /// will be scaled to match that size when compositing it to the screen. The width and height
    /// must be either both zero or both non-zero. If both are 0 then the window's base value will
    /// come back in force.
    pub fn set_buffers_geometry(
        &mut self,
        width: i32,
        height: i32,
        format: AHardwareBuffer_Format::Type,
    ) -> Result<(), ErrorCode> {
        // SAFETY: The ANativeWindow pointer we pass is guaranteed to be non-null and valid because
        // it must have been allocated by `ANativeWindow_allocate` or `ANativeWindow_readFromParcel`
        // and we have not yet released it.
        let status = unsafe {
            ANativeWindow_setBuffersGeometry(
                self.0.as_ptr(),
                width,
                height,
                format.try_into().expect("Invalid format"),
            )
        };

        if status == 0 {
            Ok(())
        } else {
            Err(ErrorCode(status))
        }
    }

    /// Sets a transfom that will be applied to future buffers posted to the window.
    pub fn set_buffers_transform(&mut self, transform: Transform) -> Result<(), ErrorCode> {
        // SAFETY: The ANativeWindow pointer we pass is guaranteed to be non-null and valid because
        // it must have been allocated by `ANativeWindow_allocate` or `ANativeWindow_readFromParcel`
        // and we have not yet released it.
        let status =
            unsafe { ANativeWindow_setBuffersTransform(self.0.as_ptr(), transform.bits() as i32) };

        if status == 0 {
            Ok(())
        } else {
            Err(ErrorCode(status))
        }
    }

    /// Sets the data space that will be applied to future buffers posted to the window.
    pub fn set_buffers_data_space(&mut self, data_space: ADataSpace) -> Result<(), ErrorCode> {
        // SAFETY: The ANativeWindow pointer we pass is guaranteed to be non-null and valid because
        // it must have been allocated by `ANativeWindow_allocate` or `ANativeWindow_readFromParcel`
        // and we have not yet released it.
        let status = unsafe { ANativeWindow_setBuffersDataSpace(self.0.as_ptr(), data_space.0) };

        if status == 0 {
            Ok(())
        } else {
            Err(ErrorCode(status))
        }
    }

    /// Gets the data space of the buffers in the window.
    pub fn get_buffers_data_space(&mut self) -> Result<ADataSpace, ErrorCode> {
        // SAFETY: The ANativeWindow pointer we pass is guaranteed to be non-null and valid because
        // it must have been allocated by `ANativeWindow_allocate` or `ANativeWindow_readFromParcel`
        // and we have not yet released it.
        let data_space = unsafe { ANativeWindow_getBuffersDataSpace(self.0.as_ptr()) };

        if data_space < 0 {
            Err(ErrorCode(data_space))
        } else {
            Ok(ADataSpace(data_space))
        }
    }

    /// Gets the default data space of the buffers in the window as set by the consumer.
    pub fn get_buffers_default_data_space(&mut self) -> Result<ADataSpace, ErrorCode> {
        // SAFETY: The ANativeWindow pointer we pass is guaranteed to be non-null and valid because
        // it must have been allocated by `ANativeWindow_allocate` or `ANativeWindow_readFromParcel`
        // and we have not yet released it.
        let data_space = unsafe { ANativeWindow_getBuffersDefaultDataSpace(self.0.as_ptr()) };

        if data_space < 0 {
            Err(ErrorCode(data_space))
        } else {
            Ok(ADataSpace(data_space))
        }
    }
}

impl Drop for Surface {
@@ -141,3 +234,19 @@ impl Display for ErrorCode {
        write!(f, "Error {}", self.0)
    }
}

bitflags! {
    /// Transforms that can be applied to buffers as they are displayed to a window.
    #[derive(Copy, Clone, Debug, Eq, PartialEq)]
    pub struct Transform: u32 {
        const MIRROR_HORIZONTAL = 0x01;
        const MIRROR_VERTICAL = 0x02;
        const ROTATE_90 = 0x04;
    }
}

impl Transform {
    pub const IDENTITY: Self = Self::empty();
    pub const ROTATE_180: Self = Self::MIRROR_HORIZONTAL.union(Self::MIRROR_VERTICAL);
    pub const ROTATE_270: Self = Self::ROTATE_180.union(Self::ROTATE_90);
}