AHB: add AHardwareBuffer_getId API in ndk

Add this api to ndk so that there's a reliable system-wide unique id for
caching.

libui is not linkable from sphal so vendors cannot convert an AHB into
GraphicBuffer to call getId(). This change solves the problem.

This change has been forced to refactor the existing docs and
annotations due to -Wnullability-completeness.

Bug: 162425097
Bug: 163615119
Test: atest libnativewindow_test:AHardwareBufferTest#GetIdTest
Change-Id: I91043b96b83bc9a896c361385581e9620fe373c3
diff --git a/libs/nativewindow/AHardwareBuffer.cpp b/libs/nativewindow/AHardwareBuffer.cpp
index 1ec73ce..a375d43 100644
--- a/libs/nativewindow/AHardwareBuffer.cpp
+++ b/libs/nativewindow/AHardwareBuffer.cpp
@@ -397,6 +397,16 @@
     return 0;
 }
 
+int AHardwareBuffer_getId(const AHardwareBuffer* buffer, uint64_t* outId) {
+    if (!buffer || !outId) return BAD_VALUE;
+
+    const GraphicBuffer* gb = AHardwareBuffer_to_GraphicBuffer(buffer);
+    if (!gb) return BAD_VALUE;
+
+    *outId = gb->getId();
+
+    return OK;
+}
 
 // ----------------------------------------------------------------------------
 // VNDK functions
diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h
index ae5e47b..4fcca9e 100644
--- a/libs/nativewindow/include/android/hardware_buffer.h
+++ b/libs/nativewindow/include/android/hardware_buffer.h
@@ -45,14 +45,14 @@
 #ifndef ANDROID_HARDWARE_BUFFER_H
 #define ANDROID_HARDWARE_BUFFER_H
 
+#include <android/rect.h>
 #include <inttypes.h>
-
 #include <sys/cdefs.h>
 
-#include <android/rect.h>
-
 __BEGIN_DECLS
 
+// clang-format off
+
 /**
  * Buffer pixel formats.
  */
@@ -201,9 +201,9 @@
     AHARDWAREBUFFER_USAGE_CPU_WRITE_MASK        = 0xFUL << 4,
 
     /// The buffer will be read from by the GPU as a texture.
-    AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE      = 1UL << 8,
+    AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE     = 1UL << 8,
     /// The buffer will be written to by the GPU as a framebuffer attachment.
-    AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER        = 1UL << 9,
+    AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER       = 1UL << 9,
     /**
      * The buffer will be written to by the GPU as a framebuffer
      * attachment.
@@ -214,7 +214,7 @@
      * attachment should also have this flag. Use the equivalent flag
      * AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER to avoid this confusion.
      */
-    AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT       = AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER,
+    AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT      = AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER,
     /**
      * The buffer will be used as a composer HAL overlay layer.
      *
@@ -225,7 +225,7 @@
      * directly through AHardwareBuffer_allocate instead of buffers allocated
      * by the framework.
      */
-    AHARDWAREBUFFER_USAGE_COMPOSER_OVERLAY       = 1ULL << 11,
+    AHARDWAREBUFFER_USAGE_COMPOSER_OVERLAY      = 1ULL << 11,
     /**
      * The buffer is protected from direct CPU access or being read by
      * non-secure hardware, such as video encoders.
@@ -236,19 +236,19 @@
      * GL_EXT_protected_textures for more information on how these
      * buffers are expected to behave.
      */
-    AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT      = 1UL << 14,
+    AHARDWAREBUFFER_USAGE_PROTECTED_CONTENT     = 1UL << 14,
     /// The buffer will be read by a hardware video encoder.
-    AHARDWAREBUFFER_USAGE_VIDEO_ENCODE           = 1UL << 16,
+    AHARDWAREBUFFER_USAGE_VIDEO_ENCODE          = 1UL << 16,
     /**
      * The buffer will be used for direct writes from sensors.
      * When this flag is present, the format must be AHARDWAREBUFFER_FORMAT_BLOB.
      */
-    AHARDWAREBUFFER_USAGE_SENSOR_DIRECT_DATA     = 1UL << 23,
+    AHARDWAREBUFFER_USAGE_SENSOR_DIRECT_DATA    = 1UL << 23,
     /**
      * The buffer will be used as a shader storage or uniform buffer object.
      * When this flag is present, the format must be AHARDWAREBUFFER_FORMAT_BLOB.
      */
-    AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER        = 1UL << 24,
+    AHARDWAREBUFFER_USAGE_GPU_DATA_BUFFER       = 1UL << 24,
     /**
      * The buffer will be used as a cube map texture.
      * When this flag is present, the buffer must have a layer count
@@ -256,13 +256,13 @@
      * bound to OpenGL textures using the extension
      * GL_EXT_EGL_image_storage instead of GL_KHR_EGL_image.
      */
-    AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP               = 1UL << 25,
+    AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP          = 1UL << 25,
     /**
      * The buffer contains a complete mipmap hierarchy.
      * Note that buffers with this flag must be bound to OpenGL textures using
      * the extension GL_EXT_EGL_image_storage instead of GL_KHR_EGL_image.
      */
-    AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE        = 1UL << 26,
+    AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE   = 1UL << 26,
 
     AHARDWAREBUFFER_USAGE_VENDOR_0  = 1ULL << 28,
     AHARDWAREBUFFER_USAGE_VENDOR_1  = 1ULL << 29,
@@ -291,8 +291,8 @@
  * parameters of existing ones.
  */
 typedef struct AHardwareBuffer_Desc {
-    uint32_t    width;      ///< Width in pixels.
-    uint32_t    height;     ///< Height in pixels.
+    uint32_t width;  ///< Width in pixels.
+    uint32_t height; ///< Height in pixels.
     /**
      * Number of images in an image array. AHardwareBuffers with one
      * layer correspond to regular 2D textures. AHardwareBuffers with
@@ -301,21 +301,21 @@
      * AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP is present, the buffer is
      * a cube map or a cube map array.
      */
-    uint32_t    layers;
-    uint32_t    format;     ///< One of AHardwareBuffer_Format.
-    uint64_t    usage;      ///< Combination of AHardwareBuffer_UsageFlags.
-    uint32_t    stride;     ///< Row stride in pixels, ignored for AHardwareBuffer_allocate()
-    uint32_t    rfu0;       ///< Initialize to zero, reserved for future use.
-    uint64_t    rfu1;       ///< Initialize to zero, reserved for future use.
+    uint32_t layers;
+    uint32_t format; ///< One of AHardwareBuffer_Format.
+    uint64_t usage;  ///< Combination of AHardwareBuffer_UsageFlags.
+    uint32_t stride; ///< Row stride in pixels, ignored for AHardwareBuffer_allocate()
+    uint32_t rfu0;   ///< Initialize to zero, reserved for future use.
+    uint64_t rfu1;   ///< Initialize to zero, reserved for future use.
 } AHardwareBuffer_Desc;
 
 /**
  * Holds data for a single image plane.
  */
 typedef struct AHardwareBuffer_Plane {
-    void*       data;        ///< Points to first byte in plane
-    uint32_t    pixelStride; ///< Distance in bytes from the color channel of one pixel to the next
-    uint32_t    rowStride;   ///< Distance in bytes from the first value of one row of the image to
+    void*    _Nullable data; ///< Points to first byte in plane
+    uint32_t pixelStride;    ///< Distance in bytes from the color channel of one pixel to the next
+    uint32_t rowStride;      ///< Distance in bytes from the first value of one row of the image to
                              ///  the first value of the next row.
 } AHardwareBuffer_Plane;
 
@@ -323,8 +323,8 @@
  * Holds all image planes that contain the pixel data.
  */
 typedef struct AHardwareBuffer_Planes {
-    uint32_t               planeCount; ///< Number of distinct planes
-    AHardwareBuffer_Plane  planes[4];     ///< Array of image planes
+    uint32_t              planeCount; ///< Number of distinct planes
+    AHardwareBuffer_Plane planes[4];  ///< Array of image planes
 } AHardwareBuffer_Planes;
 
 /**
@@ -332,6 +332,8 @@
  */
 typedef struct AHardwareBuffer AHardwareBuffer;
 
+// clang-format on
+
 #if __ANDROID_API__ >= 26
 
 /**
@@ -347,8 +349,8 @@
  * \return 0 on success, or an error number of the allocation fails for
  * any reason. The returned buffer has a reference count of 1.
  */
-int AHardwareBuffer_allocate(const AHardwareBuffer_Desc* desc,
-        AHardwareBuffer** outBuffer) __INTRODUCED_IN(26);
+int AHardwareBuffer_allocate(const AHardwareBuffer_Desc* _Nonnull desc,
+                             AHardwareBuffer* _Nullable* _Nonnull outBuffer) __INTRODUCED_IN(26);
 /**
  * Acquire a reference on the given AHardwareBuffer object.
  *
@@ -357,7 +359,7 @@
  *
  * Available since API level 26.
  */
-void AHardwareBuffer_acquire(AHardwareBuffer* buffer) __INTRODUCED_IN(26);
+void AHardwareBuffer_acquire(AHardwareBuffer* _Nonnull buffer) __INTRODUCED_IN(26);
 
 /**
  * Remove a reference that was previously acquired with
@@ -365,7 +367,7 @@
  *
  * Available since API level 26.
  */
-void AHardwareBuffer_release(AHardwareBuffer* buffer) __INTRODUCED_IN(26);
+void AHardwareBuffer_release(AHardwareBuffer* _Nonnull buffer) __INTRODUCED_IN(26);
 
 /**
  * Return a description of the AHardwareBuffer in the passed
@@ -373,8 +375,8 @@
  *
  * Available since API level 26.
  */
-void AHardwareBuffer_describe(const AHardwareBuffer* buffer,
-        AHardwareBuffer_Desc* outDesc) __INTRODUCED_IN(26);
+void AHardwareBuffer_describe(const AHardwareBuffer* _Nonnull buffer,
+                              AHardwareBuffer_Desc* _Nonnull outDesc) __INTRODUCED_IN(26);
 
 /**
  * Lock the AHardwareBuffer for direct CPU access.
@@ -428,8 +430,57 @@
  * has more than one layer. Error number if the lock fails for any other
  * reason.
  */
-int AHardwareBuffer_lock(AHardwareBuffer* buffer, uint64_t usage,
-        int32_t fence, const ARect* rect, void** outVirtualAddress) __INTRODUCED_IN(26);
+int AHardwareBuffer_lock(AHardwareBuffer* _Nonnull buffer, uint64_t usage, int32_t fence,
+                         const ARect* _Nullable rect, void* _Nullable* _Nonnull outVirtualAddress)
+        __INTRODUCED_IN(26);
+
+/**
+ * Unlock the AHardwareBuffer from direct CPU access.
+ *
+ * Must be called after all changes to the buffer are completed by the
+ * caller.  If \a fence is NULL, the function will block until all work
+ * is completed.  Otherwise, \a fence will be set either to a valid file
+ * descriptor or to -1.  The file descriptor will become signaled once
+ * the unlocking is complete and buffer contents are updated.
+ * The caller is responsible for closing the file descriptor once it's
+ * no longer needed.  The value -1 indicates that unlocking has already
+ * completed before the function returned and no further operations are
+ * necessary.
+ *
+ * Available since API level 26.
+ *
+ * \return 0 on success. -EINVAL if \a buffer is NULL. Error number if
+ * the unlock fails for any reason.
+ */
+int AHardwareBuffer_unlock(AHardwareBuffer* _Nonnull buffer, int32_t* _Nullable fence)
+        __INTRODUCED_IN(26);
+
+/**
+ * Send the AHardwareBuffer to an AF_UNIX socket.
+ *
+ * Available since API level 26.
+ *
+ * \return 0 on success, -EINVAL if \a buffer is NULL, or an error
+ * number if the operation fails for any reason.
+ */
+int AHardwareBuffer_sendHandleToUnixSocket(const AHardwareBuffer* _Nonnull buffer, int socketFd)
+        __INTRODUCED_IN(26);
+
+/**
+ * Receive an AHardwareBuffer from an AF_UNIX socket.
+ *
+ * Available since API level 26.
+ *
+ * \return 0 on success, -EINVAL if \a outBuffer is NULL, or an error
+ * number if the operation fails for any reason.
+ */
+int AHardwareBuffer_recvHandleFromUnixSocket(int socketFd,
+                                             AHardwareBuffer* _Nullable* _Nonnull outBuffer)
+        __INTRODUCED_IN(26);
+
+#endif // __ANDROID_API__ >= 26
+
+#if __ANDROID_API__ >= 29
 
 /**
  * Lock a potentially multi-planar AHardwareBuffer for direct CPU access.
@@ -458,52 +509,9 @@
  * has more than one layer. Error number if the lock fails for any other
  * reason.
  */
-int AHardwareBuffer_lockPlanes(AHardwareBuffer* buffer, uint64_t usage,
-        int32_t fence, const ARect* rect, AHardwareBuffer_Planes* outPlanes) __INTRODUCED_IN(29);
-
-/**
- * Unlock the AHardwareBuffer from direct CPU access.
- *
- * Must be called after all changes to the buffer are completed by the
- * caller.  If \a fence is NULL, the function will block until all work
- * is completed.  Otherwise, \a fence will be set either to a valid file
- * descriptor or to -1.  The file descriptor will become signaled once
- * the unlocking is complete and buffer contents are updated.
- * The caller is responsible for closing the file descriptor once it's
- * no longer needed.  The value -1 indicates that unlocking has already
- * completed before the function returned and no further operations are
- * necessary.
- *
- * Available since API level 26.
- *
- * \return 0 on success. -EINVAL if \a buffer is NULL. Error number if
- * the unlock fails for any reason.
- */
-int AHardwareBuffer_unlock(AHardwareBuffer* buffer, int32_t* fence) __INTRODUCED_IN(26);
-
-/**
- * Send the AHardwareBuffer to an AF_UNIX socket.
- *
- * Available since API level 26.
- *
- * \return 0 on success, -EINVAL if \a buffer is NULL, or an error
- * number if the operation fails for any reason.
- */
-int AHardwareBuffer_sendHandleToUnixSocket(const AHardwareBuffer* buffer, int socketFd) __INTRODUCED_IN(26);
-
-/**
- * Receive an AHardwareBuffer from an AF_UNIX socket.
- *
- * Available since API level 26.
- *
- * \return 0 on success, -EINVAL if \a outBuffer is NULL, or an error
- * number if the operation fails for any reason.
- */
-int AHardwareBuffer_recvHandleFromUnixSocket(int socketFd, AHardwareBuffer** outBuffer) __INTRODUCED_IN(26);
-
-#endif // __ANDROID_API__ >= 26
-
-#if __ANDROID_API__ >= 29
+int AHardwareBuffer_lockPlanes(AHardwareBuffer* _Nonnull buffer, uint64_t usage, int32_t fence,
+                               const ARect* _Nullable rect,
+                               AHardwareBuffer_Planes* _Nonnull outPlanes) __INTRODUCED_IN(29);
 
 /**
  * Test whether the given format and usage flag combination is
@@ -524,7 +532,7 @@
  * \return 1 if the format and usage flag combination is allocatable,
  *     0 otherwise.
  */
-int AHardwareBuffer_isSupported(const AHardwareBuffer_Desc* desc) __INTRODUCED_IN(29);
+int AHardwareBuffer_isSupported(const AHardwareBuffer_Desc* _Nonnull desc) __INTRODUCED_IN(29);
 
 /**
  * Lock an AHardwareBuffer for direct CPU access.
@@ -537,11 +545,29 @@
  *
  * Available since API level 29.
  */
-int AHardwareBuffer_lockAndGetInfo(AHardwareBuffer* buffer, uint64_t usage,
-        int32_t fence, const ARect* rect, void** outVirtualAddress,
-        int32_t* outBytesPerPixel, int32_t* outBytesPerStride) __INTRODUCED_IN(29);
+int AHardwareBuffer_lockAndGetInfo(AHardwareBuffer* _Nonnull buffer, uint64_t usage, int32_t fence,
+                                   const ARect* _Nullable rect,
+                                   void* _Nullable* _Nonnull outVirtualAddress,
+                                   int32_t* _Nonnull outBytesPerPixel,
+                                   int32_t* _Nonnull outBytesPerStride) __INTRODUCED_IN(29);
+
 #endif // __ANDROID_API__ >= 29
 
+#if __ANDROID_API__ >= 31
+
+/**
+ * Get the system wide unique id for an AHardwareBuffer.
+ *
+ * Available since API level 31.
+ *
+ * \return 0 on success, -EINVAL if \a buffer or \a outId is NULL, or an error number if the
+ * operation fails for any reason.
+ */
+int AHardwareBuffer_getId(const AHardwareBuffer* _Nonnull buffer, uint64_t* _Nonnull outId)
+        __INTRODUCED_IN(31);
+
+#endif // __ANDROID_API__ >= 31
+
 __END_DECLS
 
 #endif // ANDROID_HARDWARE_BUFFER_H
diff --git a/libs/nativewindow/include/vndk/hardware_buffer.h b/libs/nativewindow/include/vndk/hardware_buffer.h
index 3392d7f..50fe0b7 100644
--- a/libs/nativewindow/include/vndk/hardware_buffer.h
+++ b/libs/nativewindow/include/vndk/hardware_buffer.h
@@ -24,7 +24,14 @@
 
 __BEGIN_DECLS
 
-const native_handle_t* AHardwareBuffer_getNativeHandle(const AHardwareBuffer* buffer);
+/**
+ * Get the native handle from an AHardwareBuffer.
+ *
+ * \return a non-NULL native handle on success, NULL if \a buffer is nullptr or the operation fails
+ * for any reason.
+ */
+const native_handle_t* _Nullable AHardwareBuffer_getNativeHandle(
+        const AHardwareBuffer* _Nonnull buffer);
 
 enum CreateFromHandleMethod {
     // enum values chosen to match internal GraphicBuffer::HandleWrapMethod
@@ -33,9 +40,9 @@
 };
 
 /**
- * Create a AHardwareBuffer from a native handle.
+ * Create an AHardwareBuffer from a native handle.
  *
- * This function wraps a native handle in a AHardwareBuffer suitable for use by applications or
+ * This function wraps a native handle in an AHardwareBuffer suitable for use by applications or
  * other parts of the system. The contents of desc will be returned by AHardwareBuffer_describe().
  *
  * If method is AHARDWAREBUFFER_CREATE_FROM_HANDLE_METHOD_REGISTER, the handle is assumed to be
@@ -44,10 +51,13 @@
  *
  * If method is AHARDWAREBUFFER_CREATE_FROM_HANDLE_METHOD_CLONE, the handle will be cloned and the
  * clone registered. The AHardwareBuffer will own the cloned handle but not the original.
+ *
+ * \return 0 on success, -EINVAL if \a desc or \a handle or outBuffer is NULL, or an error number if
+ * the operation fails for any reason.
  */
-int AHardwareBuffer_createFromHandle(const AHardwareBuffer_Desc* desc,
-                                     const native_handle_t* handle, int32_t method,
-                                     AHardwareBuffer** outBuffer);
+int AHardwareBuffer_createFromHandle(const AHardwareBuffer_Desc* _Nonnull desc,
+                                     const native_handle_t* _Nonnull handle, int32_t method,
+                                     AHardwareBuffer* _Nullable* _Nonnull outBuffer);
 
 /**
  * Buffer pixel formats.
diff --git a/libs/nativewindow/libnativewindow.map.txt b/libs/nativewindow/libnativewindow.map.txt
index 1b5d20d..8f2a074 100644
--- a/libs/nativewindow/libnativewindow.map.txt
+++ b/libs/nativewindow/libnativewindow.map.txt
@@ -4,6 +4,7 @@
     AHardwareBuffer_allocate;
     AHardwareBuffer_createFromHandle; # llndk # apex
     AHardwareBuffer_describe;
+    AHardwareBuffer_getId; # introduced=31
     AHardwareBuffer_getNativeHandle; # llndk # apex
     AHardwareBuffer_isSupported; # introduced=29
     AHardwareBuffer_lock;
diff --git a/libs/nativewindow/tests/AHardwareBufferTest.cpp b/libs/nativewindow/tests/AHardwareBufferTest.cpp
index 71b1f9f..ef863b6 100644
--- a/libs/nativewindow/tests/AHardwareBufferTest.cpp
+++ b/libs/nativewindow/tests/AHardwareBufferTest.cpp
@@ -17,12 +17,11 @@
 #define LOG_TAG "AHardwareBuffer_test"
 //#define LOG_NDEBUG 0
 
-#include <android/hardware_buffer.h>
-#include <private/android/AHardwareBufferHelpers.h>
 #include <android/hardware/graphics/common/1.0/types.h>
-#include <vndk/hardware_buffer.h>
-
 #include <gtest/gtest.h>
+#include <private/android/AHardwareBufferHelpers.h>
+#include <ui/GraphicBuffer.h>
+#include <vndk/hardware_buffer.h>
 
 using namespace android;
 using android::hardware::graphics::common::V1_0::BufferUsage;
@@ -131,3 +130,43 @@
     AHardwareBuffer_release(buffer);
     AHardwareBuffer_release(otherBuffer);
 }
+
+TEST(AHardwareBufferTest, GetIdTest) {
+    const uint32_t testWidth = 4;
+    const uint32_t testHeight = 4;
+    const uint32_t testLayers = 1;
+
+    AHardwareBuffer* ahb1 = nullptr;
+    uint64_t id1 = 0;
+    const AHardwareBuffer_Desc desc = {
+            .width = testWidth,
+            .height = testHeight,
+            .layers = testLayers,
+            .format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
+            .usage = AHARDWAREBUFFER_USAGE_CPU_READ_RARELY,
+    };
+    int res = AHardwareBuffer_allocate(&desc, &ahb1);
+    EXPECT_EQ(NO_ERROR, res);
+    EXPECT_NE(nullptr, ahb1);
+    EXPECT_EQ(0, AHardwareBuffer_getId(ahb1, &id1));
+    const GraphicBuffer* gb1 = AHardwareBuffer_to_GraphicBuffer(ahb1);
+    EXPECT_NE(nullptr, gb1);
+    EXPECT_EQ(id1, gb1->getId());
+    EXPECT_NE(id1, 0);
+
+    sp<GraphicBuffer> gb2(new GraphicBuffer(testWidth,
+                                            testHeight,
+                                            PIXEL_FORMAT_RGBA_8888,
+                                            testLayers,
+                                            GraphicBuffer::USAGE_SW_READ_RARELY,
+                                            std::string("test")));
+    EXPECT_NE(nullptr, gb2.get());
+    const AHardwareBuffer* ahb2 = AHardwareBuffer_from_GraphicBuffer(gb2.get());
+    EXPECT_NE(nullptr, ahb2);
+    uint64_t id2 = 0;
+    EXPECT_EQ(0, AHardwareBuffer_getId(ahb2, &id2));
+    EXPECT_EQ(id2, gb2->getId());
+    EXPECT_NE(id2, 0);
+
+    EXPECT_NE(id1, id2);
+}
diff --git a/libs/nativewindow/tests/Android.bp b/libs/nativewindow/tests/Android.bp
index cdb3d20..2e4bd99 100644
--- a/libs/nativewindow/tests/Android.bp
+++ b/libs/nativewindow/tests/Android.bp
@@ -24,6 +24,7 @@
         "liblog",
         "libnativewindow",
         "libsync",
+        "libui",
         "libutils",
         "android.hardware.graphics.common@1.0",
     ],