Merge "Don't call fdopendir on unique_fd::get."
diff --git a/libs/nativewindow/AHardwareBuffer.cpp b/libs/nativewindow/AHardwareBuffer.cpp
index ed292e7..2038162 100644
--- a/libs/nativewindow/AHardwareBuffer.cpp
+++ b/libs/nativewindow/AHardwareBuffer.cpp
@@ -279,6 +279,35 @@
     return gbuffer->handle;
 }
 
+int AHardwareBuffer_createFromHandle(const AHardwareBuffer_Desc* desc,
+                                     const native_handle_t* handle, int32_t method,
+                                     AHardwareBuffer** outBuffer) {
+    static_assert(static_cast<int32_t>(AHARDWAREBUFFER_CREATE_FROM_HANDLE_METHOD_REGISTER) ==
+                  static_cast<int32_t>(GraphicBuffer::TAKE_UNREGISTERED_HANDLE));
+    static_assert(static_cast<int32_t>(AHARDWAREBUFFER_CREATE_FROM_HANDLE_METHOD_CLONE) ==
+                  static_cast<int32_t>(GraphicBuffer::CLONE_HANDLE));
+
+    if (!desc || !handle || !outBuffer) return BAD_VALUE;
+    if (!(method == AHARDWAREBUFFER_CREATE_FROM_HANDLE_METHOD_REGISTER ||
+          method == AHARDWAREBUFFER_CREATE_FROM_HANDLE_METHOD_CLONE))
+        return BAD_VALUE;
+    if (desc->rfu0 != 0 || desc->rfu1 != 0) return BAD_VALUE;
+    if (desc->format == AHARDWAREBUFFER_FORMAT_BLOB && desc->height != 1) return BAD_VALUE;
+
+    const int format = AHardwareBuffer_convertToPixelFormat(desc->format);
+    const uint64_t usage = AHardwareBuffer_convertToGrallocUsageBits(desc->usage);
+    const auto wrapMethod = static_cast<GraphicBuffer::HandleWrapMethod>(method);
+    sp<GraphicBuffer> gbuffer(new GraphicBuffer(handle, wrapMethod, desc->width, desc->height,
+                                                format, desc->layers, usage, desc->stride));
+    status_t err = gbuffer->initCheck();
+    if (err != 0 || gbuffer->handle == 0) return err;
+
+    *outBuffer = AHardwareBuffer_from_GraphicBuffer(gbuffer.get());
+    // Ensure the buffer doesn't get destroyed when the sp<> goes away.
+    AHardwareBuffer_acquire(*outBuffer);
+
+    return NO_ERROR;
+}
 
 // ----------------------------------------------------------------------------
 // Helpers implementation
diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h
index ef4875a..277560b 100644
--- a/libs/nativewindow/include/android/hardware_buffer.h
+++ b/libs/nativewindow/include/android/hardware_buffer.h
@@ -162,25 +162,25 @@
  * any reason.
  */
 int AHardwareBuffer_allocate(const AHardwareBuffer_Desc* desc,
-        AHardwareBuffer** outBuffer);
+        AHardwareBuffer** outBuffer) __INTRODUCED_IN(26);
 /**
  * Acquire a reference on the given AHardwareBuffer object.  This prevents the
  * object from being deleted until the last reference is removed.
  */
-void AHardwareBuffer_acquire(AHardwareBuffer* buffer);
+void AHardwareBuffer_acquire(AHardwareBuffer* buffer) __INTRODUCED_IN(26);
 
 /**
  * Remove a reference that was previously acquired with
  * AHardwareBuffer_acquire().
  */
-void AHardwareBuffer_release(AHardwareBuffer* buffer);
+void AHardwareBuffer_release(AHardwareBuffer* buffer) __INTRODUCED_IN(26);
 
 /**
  * Return a description of the AHardwareBuffer in the passed
  * AHardwareBuffer_Desc struct.
  */
 void AHardwareBuffer_describe(const AHardwareBuffer* buffer,
-        AHardwareBuffer_Desc* outDesc);
+        AHardwareBuffer_Desc* outDesc) __INTRODUCED_IN(26);
 
 /*
  * Lock the AHardwareBuffer for reading or writing, depending on the usage flags
@@ -216,7 +216,7 @@
  * number of the lock fails for any reason.
  */
 int AHardwareBuffer_lock(AHardwareBuffer* buffer, uint64_t usage,
-        int32_t fence, const ARect* rect, void** outVirtualAddress);
+        int32_t fence, const ARect* rect, void** outVirtualAddress) __INTRODUCED_IN(26);
 
 /*
  * Unlock the AHardwareBuffer; must be called after all changes to the buffer
@@ -228,7 +228,7 @@
  * Returns NO_ERROR on success, BAD_VALUE if the buffer is NULL, or an error
  * number of the lock fails for any reason.
  */
-int AHardwareBuffer_unlock(AHardwareBuffer* buffer, int32_t* fence);
+int AHardwareBuffer_unlock(AHardwareBuffer* buffer, int32_t* fence) __INTRODUCED_IN(26);
 
 /*
  * Send the AHardwareBuffer to an AF_UNIX socket.
@@ -236,7 +236,7 @@
  * Returns NO_ERROR on success, BAD_VALUE if the buffer is NULL, or an error
  * number of the lock fails for any reason.
  */
-int AHardwareBuffer_sendHandleToUnixSocket(const AHardwareBuffer* buffer, int socketFd);
+int AHardwareBuffer_sendHandleToUnixSocket(const AHardwareBuffer* buffer, int socketFd) __INTRODUCED_IN(26);
 
 /*
  * Receive the AHardwareBuffer from an AF_UNIX socket.
@@ -244,7 +244,7 @@
  * Returns NO_ERROR on success, BAD_VALUE if the buffer is NULL, or an error
  * number of the lock fails for any reason.
  */
-int AHardwareBuffer_recvHandleFromUnixSocket(int socketFd, AHardwareBuffer** outBuffer);
+int AHardwareBuffer_recvHandleFromUnixSocket(int socketFd, AHardwareBuffer** outBuffer) __INTRODUCED_IN(26);
 
 __END_DECLS
 
diff --git a/libs/nativewindow/include/android/native_window.h b/libs/nativewindow/include/android/native_window.h
index 5290dd5..fd5d8b5 100644
--- a/libs/nativewindow/include/android/native_window.h
+++ b/libs/nativewindow/include/android/native_window.h
@@ -108,33 +108,33 @@
  * Acquire a reference on the given {@link ANativeWindow} object. This prevents the object
  * from being deleted until the reference is removed.
  */
-void ANativeWindow_acquire(ANativeWindow* window);
+void ANativeWindow_acquire(ANativeWindow* window) __INTRODUCED_IN(26);
 
 /**
  * Remove a reference that was previously acquired with {@link ANativeWindow_acquire()}.
  */
-void ANativeWindow_release(ANativeWindow* window);
+void ANativeWindow_release(ANativeWindow* window) __INTRODUCED_IN(26);
 
 /**
  * Return the current width in pixels of the window surface.
  *
  * \return negative value on error.
  */
-int32_t ANativeWindow_getWidth(ANativeWindow* window);
+int32_t ANativeWindow_getWidth(ANativeWindow* window) __INTRODUCED_IN(26);
 
 /**
  * Return the current height in pixels of the window surface.
  *
  * \return a negative value on error.
  */
-int32_t ANativeWindow_getHeight(ANativeWindow* window);
+int32_t ANativeWindow_getHeight(ANativeWindow* window) __INTRODUCED_IN(26);
 
 /**
  * Return the current pixel format (AHARDWAREBUFFER_FORMAT_*) of the window surface.
  *
  * \return a negative value on error.
  */
-int32_t ANativeWindow_getFormat(ANativeWindow* window);
+int32_t ANativeWindow_getFormat(ANativeWindow* window) __INTRODUCED_IN(26);
 
 /**
  * Change the format and size of the window buffers.
@@ -154,7 +154,7 @@
  * \return 0 for success, or a negative value on error.
  */
 int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window,
-        int32_t width, int32_t height, int32_t format);
+        int32_t width, int32_t height, int32_t format) __INTRODUCED_IN(26);
 
 /**
  * Lock the window's next drawing surface for writing.
@@ -167,7 +167,7 @@
  * \return 0 for success, or a negative value on error.
  */
 int32_t ANativeWindow_lock(ANativeWindow* window, ANativeWindow_Buffer* outBuffer,
-        ARect* inOutDirtyBounds);
+        ARect* inOutDirtyBounds) __INTRODUCED_IN(26);
 
 /**
  * Unlock the window's drawing surface after previously locking it,
@@ -175,9 +175,7 @@
  *
  * \return 0 for success, or a negative value on error.
  */
-int32_t ANativeWindow_unlockAndPost(ANativeWindow* window);
-
-#if __ANDROID_API__ >= __ANDROID_API_O__
+int32_t ANativeWindow_unlockAndPost(ANativeWindow* window) __INTRODUCED_IN(26);
 
 /**
  * Set a transform that will be applied to future buffers posted to the window.
@@ -185,9 +183,7 @@
  * \param transform combination of {@link ANativeWindowTransform} flags
  * \return 0 for success, or -EINVAL if \p transform is invalid
  */
-int32_t ANativeWindow_setBuffersTransform(ANativeWindow* window, int32_t transform);
-
-#endif // __ANDROID_API__ >= __ANDROID_API_O__
+int32_t ANativeWindow_setBuffersTransform(ANativeWindow* window, int32_t transform) __INTRODUCED_IN(26);
 
 #ifdef __cplusplus
 };
diff --git a/libs/nativewindow/include/vndk/hardware_buffer.h b/libs/nativewindow/include/vndk/hardware_buffer.h
index 802edcc..9b06475 100644
--- a/libs/nativewindow/include/vndk/hardware_buffer.h
+++ b/libs/nativewindow/include/vndk/hardware_buffer.h
@@ -26,6 +26,28 @@
 
 const native_handle_t* AHardwareBuffer_getNativeHandle(const AHardwareBuffer* buffer);
 
+enum CreateFromHandleMethod {
+    // enum values chosen to match internal GraphicBuffer::HandleWrapMethod
+    AHARDWAREBUFFER_CREATE_FROM_HANDLE_METHOD_REGISTER = 2,
+    AHARDWAREBUFFER_CREATE_FROM_HANDLE_METHOD_CLONE = 3,
+};
+
+/**
+ * Create a AHardwareBuffer from a native handle.
+ *
+ * This function wraps a native handle in a 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
+ * unregistered, and it will be registered/imported before being wrapped in the AHardwareBuffer.
+ * If successful, the AHardwareBuffer will own the handle.
+ *
+ * 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.
+ */
+int AHardwareBuffer_createFromHandle(const AHardwareBuffer_Desc* desc,
+                                     const native_handle_t* handle, int32_t method,
+                                     AHardwareBuffer** outBuffer);
 
 /**
  * Buffer pixel formats.
diff --git a/libs/nativewindow/libnativewindow.map.txt b/libs/nativewindow/libnativewindow.map.txt
index 105d01b..fd06ec4 100644
--- a/libs/nativewindow/libnativewindow.map.txt
+++ b/libs/nativewindow/libnativewindow.map.txt
@@ -2,6 +2,7 @@
   global:
     AHardwareBuffer_acquire;
     AHardwareBuffer_allocate;
+    AHardwareBuffer_createFromHandle; # vndk
     AHardwareBuffer_describe;
     AHardwareBuffer_getNativeHandle; # vndk
     AHardwareBuffer_lock;