Merge "Error fix from enabling Clang thread-safety checks" into main
diff --git a/Android.bp b/Android.bp
index 119c7ea..ba55082 100644
--- a/Android.bp
+++ b/Android.bp
@@ -42,6 +42,7 @@
     export_include_dirs: [
         "include/",
     ],
+    product_available: true,
 }
 
 ndk_headers {
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index c407f48..add9f92 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -4631,7 +4631,7 @@
 void Dumpstate::TakeScreenshot(const std::string& path) {
     const std::string& real_path = path.empty() ? screenshot_path_ : path;
     int status =
-        RunCommand("", {"/system/bin/screencap", "-p", real_path},
+        RunCommand("", {"screencap", "-p", real_path},
                    CommandOptions::WithTimeout(10).Always().DropRoot().RedirectStderr().Build());
     if (status == 0) {
         MYLOGD("Screenshot saved on %s\n", real_path.c_str());
diff --git a/include/android/OWNERS b/include/android/OWNERS
index fad8c1b..64d7e54 100644
--- a/include/android/OWNERS
+++ b/include/android/OWNERS
@@ -3,3 +3,6 @@
 # Window manager
 per-file surface_control_input_receiver.h = file:platform/frameworks/base:/services/core/java/com/android/server/wm/OWNERS
 per-file input_transfer_token.h = file:platform/frameworks/base:/services/core/java/com/android/server/wm/OWNERS
+
+# CoGS
+per-file *luts* = file:platform/frameworks/base:/graphics/java/android/graphics/OWNERS
\ No newline at end of file
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 2ef642a..0a61178 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -829,6 +829,7 @@
     backend: {
         rust: {
             apex_available: [
+                "//apex_available:platform",
                 "com.android.virt",
             ],
             enabled: true,
@@ -881,7 +882,6 @@
         ":__subpackages__",
         "//packages/modules/Virtualization:__subpackages__",
         "//device/google/cuttlefish/shared/minidroid:__subpackages__",
-        "//system/software_defined_vehicle:__subpackages__",
         "//visibility:any_system_partition",
     ],
 }
diff --git a/libs/binder/rust/rpcbinder/Android.bp b/libs/binder/rust/rpcbinder/Android.bp
index 174fe8a..4036551 100644
--- a/libs/binder/rust/rpcbinder/Android.bp
+++ b/libs/binder/rust/rpcbinder/Android.bp
@@ -27,7 +27,6 @@
     visibility: [
         "//device/google/cuttlefish/shared/minidroid/sample",
         "//packages/modules/Virtualization:__subpackages__",
-        "//system/software_defined_vehicle:__subpackages__",
     ],
     apex_available: [
         "//apex_available:platform",
diff --git a/libs/gui/include/gui/IGraphicBufferProducer.h b/libs/gui/include/gui/IGraphicBufferProducer.h
index 8fca946..84a1730 100644
--- a/libs/gui/include/gui/IGraphicBufferProducer.h
+++ b/libs/gui/include/gui/IGraphicBufferProducer.h
@@ -403,7 +403,7 @@
         uint64_t nextFrameNumber{0};
         FrameEventHistoryDelta frameTimestamps;
         bool bufferReplaced{false};
-        int maxBufferCount{0};
+        int maxBufferCount{BufferQueueDefs::NUM_BUFFER_SLOTS};
         status_t result{NO_ERROR};
     };
 
diff --git a/libs/nativewindow/rust/src/lib.rs b/libs/nativewindow/rust/src/lib.rs
index 014c912..9876362 100644
--- a/libs/nativewindow/rust/src/lib.rs
+++ b/libs/nativewindow/rust/src/lib.rs
@@ -31,11 +31,13 @@
 };
 use ffi::{
     AHardwareBuffer, AHardwareBuffer_Desc, AHardwareBuffer_readFromParcel,
-    AHardwareBuffer_writeToParcel,
+    AHardwareBuffer_writeToParcel, ARect,
 };
+use std::ffi::c_void;
 use std::fmt::{self, Debug, Formatter};
-use std::mem::ManuallyDrop;
-use std::ptr::{self, null_mut, NonNull};
+use std::mem::{forget, ManuallyDrop};
+use std::os::fd::{AsRawFd, BorrowedFd, FromRawFd, OwnedFd};
+use std::ptr::{self, null, null_mut, NonNull};
 
 /// Wrapper around a C `AHardwareBuffer_Desc`.
 #[derive(Clone, Debug, PartialEq, Eq)]
@@ -267,10 +269,141 @@
             rfu0: 0,
             rfu1: 0,
         };
-        // SAFETY: neither the buffer nor AHardwareBuffer_Desc pointers will be null.
+        // SAFETY: The `AHardwareBuffer` pointer we wrap is always valid, and the
+        // AHardwareBuffer_Desc pointer is valid because it comes from a reference.
         unsafe { ffi::AHardwareBuffer_describe(self.0.as_ref(), &mut buffer_desc) };
         HardwareBufferDescription(buffer_desc)
     }
+
+    /// Locks the hardware buffer for direct CPU access.
+    ///
+    /// # Safety
+    ///
+    /// - If `fence` is `None`, the caller must ensure that all writes to the buffer have completed
+    ///   before calling this function.
+    /// - If the buffer has `AHARDWAREBUFFER_FORMAT_BLOB`, multiple threads or process may lock the
+    ///   buffer simultaneously, but the caller must ensure that they don't access it simultaneously
+    ///   and break Rust's aliasing rules, like any other shared memory.
+    /// - Otherwise if `usage` includes `AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY` or
+    ///   `AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN`, the caller must ensure that no other threads or
+    ///   processes lock the buffer simultaneously for any usage.
+    /// - Otherwise, the caller must ensure that no other threads lock the buffer for writing
+    ///   simultaneously.
+    /// - If `rect` is not `None`, the caller must not modify the buffer outside of that rectangle.
+    pub unsafe fn lock<'a>(
+        &'a self,
+        usage: AHardwareBuffer_UsageFlags,
+        fence: Option<BorrowedFd>,
+        rect: Option<&ARect>,
+    ) -> Result<HardwareBufferGuard<'a>, StatusCode> {
+        let fence = if let Some(fence) = fence { fence.as_raw_fd() } else { -1 };
+        let rect = rect.map(ptr::from_ref).unwrap_or(null());
+        let mut address = null_mut();
+        // SAFETY: The `AHardwareBuffer` pointer we wrap is always valid, and the buffer address out
+        // pointer is valid because it comes from a reference. Our caller promises that writes have
+        // completed and there will be no simultaneous read/write locks.
+        let status = unsafe {
+            ffi::AHardwareBuffer_lock(self.0.as_ptr(), usage.0, fence, rect, &mut address)
+        };
+        status_result(status)?;
+        Ok(HardwareBufferGuard {
+            buffer: self,
+            address: NonNull::new(address)
+                .expect("AHardwareBuffer_lock set a null outVirtualAddress"),
+        })
+    }
+
+    /// Locks the hardware buffer for direct CPU access, returning information about the bytes per
+    /// pixel and stride as well.
+    ///
+    /// # Safety
+    ///
+    /// - If `fence` is `None`, the caller must ensure that all writes to the buffer have completed
+    ///   before calling this function.
+    /// - If the buffer has `AHARDWAREBUFFER_FORMAT_BLOB`, multiple threads or process may lock the
+    ///   buffer simultaneously, but the caller must ensure that they don't access it simultaneously
+    ///   and break Rust's aliasing rules, like any other shared memory.
+    /// - Otherwise if `usage` includes `AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY` or
+    ///   `AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN`, the caller must ensure that no other threads or
+    ///   processes lock the buffer simultaneously for any usage.
+    /// - Otherwise, the caller must ensure that no other threads lock the buffer for writing
+    ///   simultaneously.
+    pub unsafe fn lock_and_get_info<'a>(
+        &'a self,
+        usage: AHardwareBuffer_UsageFlags,
+        fence: Option<BorrowedFd>,
+        rect: Option<&ARect>,
+    ) -> Result<LockedBufferInfo<'a>, StatusCode> {
+        let fence = if let Some(fence) = fence { fence.as_raw_fd() } else { -1 };
+        let rect = rect.map(ptr::from_ref).unwrap_or(null());
+        let mut address = null_mut();
+        let mut bytes_per_pixel = 0;
+        let mut stride = 0;
+        // SAFETY: The `AHardwareBuffer` pointer we wrap is always valid, and the various out
+        // pointers are valid because they come from references. Our caller promises that writes have
+        // completed and there will be no simultaneous read/write locks.
+        let status = unsafe {
+            ffi::AHardwareBuffer_lockAndGetInfo(
+                self.0.as_ptr(),
+                usage.0,
+                fence,
+                rect,
+                &mut address,
+                &mut bytes_per_pixel,
+                &mut stride,
+            )
+        };
+        status_result(status)?;
+        Ok(LockedBufferInfo {
+            guard: HardwareBufferGuard {
+                buffer: self,
+                address: NonNull::new(address)
+                    .expect("AHardwareBuffer_lockAndGetInfo set a null outVirtualAddress"),
+            },
+            bytes_per_pixel: bytes_per_pixel as u32,
+            stride: stride as u32,
+        })
+    }
+
+    /// Unlocks the hardware buffer from direct CPU access.
+    ///
+    /// Must be called after all changes to the buffer are completed by the caller. This will block
+    /// until the unlocking is complete and the buffer contents are updated.
+    fn unlock(&self) -> Result<(), StatusCode> {
+        // SAFETY: The `AHardwareBuffer` pointer we wrap is always valid.
+        let status = unsafe { ffi::AHardwareBuffer_unlock(self.0.as_ptr(), null_mut()) };
+        status_result(status)?;
+        Ok(())
+    }
+
+    /// Unlocks the hardware buffer from direct CPU access.
+    ///
+    /// Must be called after all changes to the buffer are completed by the caller.
+    ///
+    /// This may not block until all work is completed, but rather will return a file descriptor
+    /// which will be signalled once the unlocking is complete and the buffer contents is updated.
+    /// If `Ok(None)` is returned then unlocking has already completed and no further waiting is
+    /// necessary. The file descriptor may be passed to a subsequent call to [`Self::lock`].
+    pub fn unlock_with_fence(
+        &self,
+        guard: HardwareBufferGuard,
+    ) -> Result<Option<OwnedFd>, StatusCode> {
+        // Forget the guard so that its `Drop` implementation doesn't try to unlock the
+        // HardwareBuffer again.
+        forget(guard);
+
+        let mut fence = -2;
+        // SAFETY: The `AHardwareBuffer` pointer we wrap is always valid.
+        let status = unsafe { ffi::AHardwareBuffer_unlock(self.0.as_ptr(), &mut fence) };
+        let fence = if fence < 0 {
+            None
+        } else {
+            // SAFETY: `AHardwareBuffer_unlock` gives us ownership of the fence file descriptor.
+            Some(unsafe { OwnedFd::from_raw_fd(fence) })
+        };
+        status_result(status)?;
+        Ok(fence)
+    }
 }
 
 impl Drop for HardwareBuffer {
@@ -346,6 +479,37 @@
 //     according to the docs on the underlying gralloc calls)
 unsafe impl Sync for HardwareBuffer {}
 
+/// A guard for when a `HardwareBuffer` is locked.
+///
+/// The `HardwareBuffer` will be unlocked when this is dropped, or may be unlocked via
+/// [`HardwareBuffer::unlock_with_fence`].
+#[derive(Debug)]
+pub struct HardwareBufferGuard<'a> {
+    buffer: &'a HardwareBuffer,
+    /// The address of the buffer in memory.
+    pub address: NonNull<c_void>,
+}
+
+impl<'a> Drop for HardwareBufferGuard<'a> {
+    fn drop(&mut self) {
+        self.buffer
+            .unlock()
+            .expect("Failed to unlock HardwareBuffer when dropping HardwareBufferGuard");
+    }
+}
+
+/// A guard for when a `HardwareBuffer` is locked, with additional information about the number of
+/// bytes per pixel and stride.
+#[derive(Debug)]
+pub struct LockedBufferInfo<'a> {
+    /// The locked buffer guard.
+    pub guard: HardwareBufferGuard<'a>,
+    /// The number of bytes used for each pixel in the buffer.
+    pub bytes_per_pixel: u32,
+    /// The stride in bytes between rows in the buffer.
+    pub stride: u32,
+}
+
 #[cfg(test)]
 mod test {
     use super::*;
@@ -499,4 +663,108 @@
         assert_eq!(buffer.description(), buffer_description);
         assert_eq!(buffer2.description(), buffer_description);
     }
+
+    #[test]
+    fn lock() {
+        let buffer = HardwareBuffer::new(&HardwareBufferDescription::new(
+            1024,
+            512,
+            1,
+            AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
+            AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
+            0,
+        ))
+        .expect("Failed to create buffer");
+
+        // SAFETY: No other threads or processes have access to the buffer.
+        let guard = unsafe {
+            buffer.lock(
+                AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
+                None,
+                None,
+            )
+        }
+        .unwrap();
+
+        drop(guard);
+    }
+
+    #[test]
+    fn lock_with_rect() {
+        let buffer = HardwareBuffer::new(&HardwareBufferDescription::new(
+            1024,
+            512,
+            1,
+            AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
+            AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
+            0,
+        ))
+        .expect("Failed to create buffer");
+        let rect = ARect { left: 10, right: 20, top: 35, bottom: 45 };
+
+        // SAFETY: No other threads or processes have access to the buffer.
+        let guard = unsafe {
+            buffer.lock(
+                AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
+                None,
+                Some(&rect),
+            )
+        }
+        .unwrap();
+
+        drop(guard);
+    }
+
+    #[test]
+    fn unlock_with_fence() {
+        let buffer = HardwareBuffer::new(&HardwareBufferDescription::new(
+            1024,
+            512,
+            1,
+            AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
+            AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
+            0,
+        ))
+        .expect("Failed to create buffer");
+
+        // SAFETY: No other threads or processes have access to the buffer.
+        let guard = unsafe {
+            buffer.lock(
+                AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
+                None,
+                None,
+            )
+        }
+        .unwrap();
+
+        buffer.unlock_with_fence(guard).unwrap();
+    }
+
+    #[test]
+    fn lock_with_info() {
+        const WIDTH: u32 = 1024;
+        let buffer = HardwareBuffer::new(&HardwareBufferDescription::new(
+            WIDTH,
+            512,
+            1,
+            AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
+            AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
+            0,
+        ))
+        .expect("Failed to create buffer");
+
+        // SAFETY: No other threads or processes have access to the buffer.
+        let info = unsafe {
+            buffer.lock_and_get_info(
+                AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
+                None,
+                None,
+            )
+        }
+        .unwrap();
+
+        assert_eq!(info.bytes_per_pixel, 4);
+        assert_eq!(info.stride, WIDTH * 4);
+        drop(info);
+    }
 }