Merge "libui: clean up GraphicBuffer interface" into oc-dev
diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h
index 040d1e7..33ec4bb 100644
--- a/include/ui/GraphicBuffer.h
+++ b/include/ui/GraphicBuffer.h
@@ -72,27 +72,66 @@
         USAGE_CURSOR            = GRALLOC_USAGE_CURSOR,
     };
 
+    // Create a GraphicBuffer to be unflatten'ed into or be reallocated.
     GraphicBuffer();
 
-    // creates w * h buffer
-    GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
-            uint32_t inUsage, std::string requestorName = "<Unknown>");
-
-    // creates w * h buffer with a layer count using gralloc1
+    // Create a GraphicBuffer by allocating and managing a buffer internally.
+    // This function is privileged.  See reallocate for details.
     GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
             uint32_t inLayerCount, uint64_t inProducerUsage,
             uint64_t inConsumerUsage, std::string requestorName = "<Unknown>");
 
-    // create a buffer from an existing handle
+    // Create a GraphicBuffer from an existing handle.
+    enum HandleWrapMethod : uint8_t {
+        // Wrap and use the handle directly.  It assumes the handle has been
+        // registered and never fails.  The handle must have a longer lifetime
+        // than this wrapping GraphicBuffer.
+        //
+        // This can be used when, for example, you want to wrap a handle that
+        // is already managed by another GraphicBuffer.
+        WRAP_HANDLE,
+
+        // Take ownership of the handle and use it directly.  It assumes the
+        // handle has been registered and never fails.
+        //
+        // This can be used to manage an already registered handle with
+        // GraphicBuffer.
+        TAKE_HANDLE,
+
+        // Take onwership of an unregistered handle and use it directly.  It
+        // can fail when the buffer does not register.  There is no ownership
+        // transfer on failures.
+        //
+        // This can be used to, for example, create a GraphicBuffer from a
+        // handle returned by Parcel::readNativeHandle.
+        TAKE_UNREGISTERED_HANDLE,
+
+        // Make a clone of the handle and use the cloned handle.  It can fail
+        // when cloning fails or when the buffer does not register.  There is
+        // never ownership transfer.
+        //
+        // This can be used to create a GraphicBuffer from a handle that
+        // cannot be used directly, such as one from hidl_handle.
+        CLONE_HANDLE,
+    };
+    GraphicBuffer(const native_handle_t* handle, HandleWrapMethod method,
+            uint32_t width, uint32_t height,
+            PixelFormat format, uint32_t layerCount,
+            uint64_t producerUsage, uint64_t consumerUsage, uint32_t stride);
+
+    // These functions are deprecated because they do not distinguish producer
+    // and consumer usages.
+    GraphicBuffer(const native_handle_t* handle, HandleWrapMethod method,
+            uint32_t width, uint32_t height,
+            PixelFormat format, uint32_t layerCount,
+            uint32_t usage, uint32_t stride)
+        : GraphicBuffer(handle, method, width, height, format, layerCount,
+                usage, usage, stride) {}
     GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
             uint32_t inLayerCount, uint32_t inUsage, uint32_t inStride,
             native_handle_t* inHandle, bool keepOwnership);
-
-    // create a buffer from an existing handle using gralloc1
     GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
-            uint32_t inLayerCount, uint32_t inProducerUsage,
-            uint32_t inConsumerUsage, uint32_t inStride,
-            native_handle_t* inHandle, bool keepOwnership);
+            uint32_t inUsage, std::string requestorName = "<Unknown>");
 
     // create a buffer from an existing ANativeWindowBuffer
     GraphicBuffer(ANativeWindowBuffer* buffer, bool keepOwnership);
@@ -114,6 +153,9 @@
         mGenerationNumber = generation;
     }
 
+    // This function is privileged.  It requires access to the allocator
+    // device or service, which usually involves adding suitable selinux
+    // rules.
     status_t reallocate(uint32_t inWidth, uint32_t inHeight,
             PixelFormat inFormat, uint32_t inLayerCount, uint32_t inUsage);
 
@@ -175,9 +217,15 @@
     GraphicBuffer& operator = (const GraphicBuffer& rhs);
     const GraphicBuffer& operator = (const GraphicBuffer& rhs) const;
 
-    status_t initSize(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
-            uint32_t inLayerCount, uint64_t inProducerUsage,
-            uint64_t inConsumerUsage, std::string requestorName);
+    status_t initWithSize(uint32_t inWidth, uint32_t inHeight,
+            PixelFormat inFormat, uint32_t inLayerCount,
+            uint64_t inProducerUsage, uint64_t inConsumerUsage,
+            std::string requestorName);
+
+    status_t initWithHandle(const native_handle_t* handle,
+            HandleWrapMethod method, uint32_t width, uint32_t height,
+            PixelFormat format, uint32_t layerCount,
+            uint64_t producerUsage, uint64_t consumerUsage, uint32_t stride);
 
     void free_handle();
 
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index 6e84730..4fae233 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -52,73 +52,33 @@
     handle = NULL;
 }
 
+// deprecated
 GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight,
         PixelFormat inFormat, uint32_t inUsage, std::string requestorName)
-    : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
-      mInitCheck(NO_ERROR), mId(getUniqueId()), mGenerationNumber(0)
+    : GraphicBuffer(inWidth, inHeight, inFormat, 1, inUsage, inUsage,
+            requestorName)
 {
-    width  =
-    height =
-    stride =
-    format =
-    usage  = 0;
-    layerCount = 0;
-    handle = NULL;
-    mInitCheck = initSize(inWidth, inHeight, inFormat, 1, inUsage, inUsage,
-            std::move(requestorName));
 }
 
 GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight,
         PixelFormat inFormat, uint32_t inLayerCount, uint64_t producerUsage,
         uint64_t consumerUsage, std::string requestorName)
-    : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
-      mInitCheck(NO_ERROR), mId(getUniqueId()), mGenerationNumber(0)
+    : GraphicBuffer()
 {
-    width  =
-    height =
-    stride =
-    format =
-    usage  = 0;
-    layerCount = 0;
-    handle = NULL;
-    mInitCheck = initSize(inWidth, inHeight, inFormat, inLayerCount,
+    mInitCheck = initWithSize(inWidth, inHeight, inFormat, inLayerCount,
             producerUsage, consumerUsage, std::move(requestorName));
 }
 
+// deprecated
 GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight,
         PixelFormat inFormat, uint32_t inLayerCount, uint32_t inUsage,
         uint32_t inStride, native_handle_t* inHandle, bool keepOwnership)
-    : BASE(), mOwner(keepOwnership ? ownHandle : ownNone),
-      mBufferMapper(GraphicBufferMapper::get()),
-      mInitCheck(NO_ERROR), mId(getUniqueId()), mGenerationNumber(0)
+    : GraphicBuffer(inHandle, keepOwnership ? TAKE_HANDLE : WRAP_HANDLE,
+            inWidth, inHeight, inFormat, inLayerCount, inUsage, inUsage,
+            inStride)
 {
-    width  = static_cast<int>(inWidth);
-    height = static_cast<int>(inHeight);
-    stride = static_cast<int>(inStride);
-    format = inFormat;
-    layerCount = inLayerCount;
-    usage  = static_cast<int>(inUsage);
-    handle = inHandle;
 }
 
-GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight,
-        PixelFormat inFormat, uint32_t inLayerCount, uint32_t inProducerUsage,
-        uint32_t inConsumerUsage, uint32_t inStride,
-        native_handle_t* inHandle, bool keepOwnership)
-    : BASE(), mOwner(keepOwnership ? ownHandle : ownNone),
-      mBufferMapper(GraphicBufferMapper::get()),
-      mInitCheck(NO_ERROR), mId(getUniqueId()), mGenerationNumber(0)
-{
-    width  = static_cast<int>(inWidth);
-    height = static_cast<int>(inHeight);
-    stride = static_cast<int>(inStride);
-    format = inFormat;
-    layerCount = inLayerCount;
-    usage = android_convertGralloc1To0Usage(inProducerUsage, inConsumerUsage);
-    handle = inHandle;
-}
-
-
 GraphicBuffer::GraphicBuffer(ANativeWindowBuffer* buffer, bool keepOwnership)
     : BASE(), mOwner(keepOwnership ? ownHandle : ownNone),
       mBufferMapper(GraphicBufferMapper::get()),
@@ -134,6 +94,17 @@
     handle = buffer->handle;
 }
 
+GraphicBuffer::GraphicBuffer(const native_handle_t* handle,
+        HandleWrapMethod method, uint32_t width, uint32_t height,
+        PixelFormat format, uint32_t layerCount,
+        uint64_t producerUsage, uint64_t consumerUsage,
+        uint32_t stride)
+    : GraphicBuffer()
+{
+    mInitCheck = initWithHandle(handle, method, width, height, format,
+            layerCount, producerUsage, consumerUsage, stride);
+}
+
 GraphicBuffer::~GraphicBuffer()
 {
     if (handle) {
@@ -192,8 +163,8 @@
         allocator.free(handle);
         handle = 0;
     }
-    return initSize(inWidth, inHeight, inFormat, inLayerCount, inUsage, inUsage,
-            "[Reallocation]");
+    return initWithSize(inWidth, inHeight, inFormat, inLayerCount,
+            inUsage, inUsage, "[Reallocation]");
 }
 
 bool GraphicBuffer::needsReallocation(uint32_t inWidth, uint32_t inHeight,
@@ -207,7 +178,7 @@
     return false;
 }
 
-status_t GraphicBuffer::initSize(uint32_t inWidth, uint32_t inHeight,
+status_t GraphicBuffer::initWithSize(uint32_t inWidth, uint32_t inHeight,
         PixelFormat inFormat, uint32_t inLayerCount, uint64_t inProducerUsage,
         uint64_t inConsumerUsage, std::string requestorName)
 {
@@ -227,6 +198,54 @@
     return err;
 }
 
+status_t GraphicBuffer::initWithHandle(const native_handle_t* handle,
+        HandleWrapMethod method, uint32_t width, uint32_t height,
+        PixelFormat format, uint32_t layerCount,
+        uint64_t producerUsage, uint64_t consumerUsage,
+        uint32_t stride)
+{
+    native_handle_t* clone = nullptr;
+
+    if (method == CLONE_HANDLE) {
+        clone = native_handle_clone(handle);
+        if (!clone) {
+            return NO_MEMORY;
+        }
+
+        handle = clone;
+        method = TAKE_UNREGISTERED_HANDLE;
+    }
+
+    ANativeWindowBuffer::width  = static_cast<int>(width);
+    ANativeWindowBuffer::height = static_cast<int>(height);
+    ANativeWindowBuffer::stride = static_cast<int>(stride);
+    ANativeWindowBuffer::format = format;
+    ANativeWindowBuffer::usage  =
+        android_convertGralloc1To0Usage(producerUsage, consumerUsage);
+
+    ANativeWindowBuffer::layerCount = layerCount;
+    ANativeWindowBuffer::handle = handle;
+
+    mOwner = (method == WRAP_HANDLE) ? ownNone : ownHandle;
+
+    if (method == TAKE_UNREGISTERED_HANDLE) {
+        status_t err = mBufferMapper.registerBuffer(this);
+        if (err != NO_ERROR) {
+            // clean up cloned handle
+            if (clone) {
+                native_handle_close(clone);
+                native_handle_delete(clone);
+            }
+
+            initWithHandle(nullptr, WRAP_HANDLE, 0, 0, 0, 0, 0, 0, 0);
+
+            return err;
+        }
+    }
+
+    return NO_ERROR;
+}
+
 status_t GraphicBuffer::lock(uint32_t inUsage, void** vaddr)
 {
     const Rect lockBounds(width, height);
diff --git a/libs/vr/libbufferhub/ion_buffer.cpp b/libs/vr/libbufferhub/ion_buffer.cpp
index 3fb3f3c..e5a56c1 100644
--- a/libs/vr/libbufferhub/ion_buffer.cpp
+++ b/libs/vr/libbufferhub/ion_buffer.cpp
@@ -1,5 +1,4 @@
 #include <private/dvr/ion_buffer.h>
-#include <ui/GraphicBufferMapper.h>
 
 #include <log/log.h>
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
@@ -70,10 +69,9 @@
   ALOGD_IF(TRACE, "IonBuffer::Alloc: width=%d height=%d format=%d usage=%d",
            width, height, format, usage);
 
-  GraphicBufferMapper& mapper = GraphicBufferMapper::get();
   buffer_ = new GraphicBuffer(width, height, format, usage);
-  if (mapper.registerBuffer(buffer_.get()) != OK) {
-    ALOGE("IonBuffer::Aloc: Failed to register buffer");
+  if (buffer_->initCheck() != OK) {
+    ALOGE("IonBuffer::Aloc: Failed to allocate buffer");
   }
   return 0;
 }
@@ -96,11 +94,10 @@
       "usage=%d",
       handle, width, height, stride, format, usage);
   FreeHandle();
-  GraphicBufferMapper& mapper = GraphicBufferMapper::get();
-  buffer_ = new GraphicBuffer(width, height, format, 1, usage,
-                              stride, (native_handle_t*)handle, true);
-  if (mapper.registerBuffer(buffer_.get()) != OK) {
-    ALOGE("IonBuffer::Import: Failed to register cloned buffer");
+  buffer_ = new GraphicBuffer(handle, GraphicBuffer::TAKE_UNREGISTERED_HANDLE,
+          width, height, format, 1, usage, stride);
+  if (buffer_->initCheck() != OK) {
+    ALOGE("IonBuffer::Import: Failed to import buffer");
     return -EINVAL;
   }
   return 0;
diff --git a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.cpp b/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.cpp
index 34e2b7e..999d71e 100644
--- a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.cpp
+++ b/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.cpp
@@ -34,9 +34,9 @@
   // capability. Otherwise assume a count of 1.
   mapper.getLayerCount(handle, &layer_count);
 
-  sp<GraphicBuffer> buffer = new GraphicBuffer(
-      width, height, format, layer_count, producer_usage, consumer_usage,
-      stride, handle, true);
+  sp<GraphicBuffer> buffer = new GraphicBuffer(handle,
+      GraphicBuffer::TAKE_HANDLE, width, height, format, layer_count,
+      producer_usage, consumer_usage, stride);
 
   return buffer;
 }
diff --git a/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp b/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp
index 3393ade..d142729 100644
--- a/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp
+++ b/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp
@@ -69,11 +69,10 @@
   mapper.getLayerCount(handle, &layer_count);
 
   // NOTE: Can't re-use |handle| since we don't own it.
-  sp<GraphicBuffer> buffer = new GraphicBuffer(
-      width, height, format, layer_count, producer_usage, consumer_usage,
-      stride, native_handle_clone(handle), true);
-  // Need to register the cloned buffer otherwise it can't be used later on.
-  if (mapper.registerBuffer(buffer.get()) != OK) {
+  sp<GraphicBuffer> buffer = new GraphicBuffer(handle,
+      GraphicBuffer::CLONE_HANDLE, width, height, format, layer_count,
+      producer_usage, consumer_usage, stride);
+  if (buffer->initCheck() != OK) {
     ALOGE("Failed to register cloned buffer");
     return nullptr;
   }