Merge changes I4c3a967c,I3fd5732f into pi-dev
am: 17368c3f62

Change-Id: I3ef9e9b534e13d6822d3271b40ab0573371b38f0
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index f71f814..e477a83 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -83,6 +83,7 @@
         "libhidlbase",
         "libhidltransport",
         "libhwbinder",
+        "libpdx_default_transport",
         "libsync",
         "libutils",
         "libutilscallstack",
@@ -99,10 +100,9 @@
         "libbase_headers",
         "libnativebase_headers",
         "libhardware_headers",
+        "libui_headers",
     ],
 
-    export_include_dirs: ["include"],
-
     export_static_lib_headers: [
         "libarect",
         "libmath",
@@ -112,6 +112,7 @@
         "libbase_headers",
         "libnativebase_headers",
         "libhardware_headers",
+        "libui_headers",
     ],
 }
 
@@ -119,6 +120,11 @@
     name: "libui_headers",
     export_include_dirs: ["include"],
     vendor_available: true,
+    target: {
+        vendor: {
+            override_export_include_dirs: ["include_vndk"],
+        },
+    },
 }
 
 subdirs = [
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index 4ed2aa4..254038b 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -22,6 +22,7 @@
 
 #include <grallocusage/GrallocUsageConversion.h>
 
+#include <ui/DetachedBufferHandle.h>
 #include <ui/Gralloc2.h>
 #include <ui/GraphicBufferAllocator.h>
 #include <ui/GraphicBufferMapper.h>
@@ -486,6 +487,24 @@
     return NO_ERROR;
 }
 
+bool GraphicBuffer::isDetachedBuffer() const {
+    return mDetachedBufferHandle && mDetachedBufferHandle->isValid();
+}
+
+status_t GraphicBuffer::setDetachedBufferHandle(std::unique_ptr<DetachedBufferHandle> channel) {
+    if (isDetachedBuffer()) {
+        ALOGW("setDetachedBuffer: there is already a BufferHub channel associated with this "
+              "GraphicBuffer. Replacing the old one.");
+    }
+
+    mDetachedBufferHandle = std::move(channel);
+    return NO_ERROR;
+}
+
+std::unique_ptr<DetachedBufferHandle> GraphicBuffer::takeDetachedBufferHandle() {
+    return std::move(mDetachedBufferHandle);
+}
+
 // ---------------------------------------------------------------------------
 
 }; // namespace android
diff --git a/libs/ui/include/ui/DetachedBufferHandle.h b/libs/ui/include/ui/DetachedBufferHandle.h
new file mode 100644
index 0000000..f3c328d
--- /dev/null
+++ b/libs/ui/include/ui/DetachedBufferHandle.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_DETACHED_BUFFER_HUB_HANDLE_H
+#define ANDROID_DETACHED_BUFFER_HUB_HANDLE_H
+
+#include <pdx/channel_handle.h>
+
+#include <memory>
+
+namespace android {
+
+// A wrapper that holds a pdx::LocalChannelHandle object. From the handle, a BufferHub buffer can be
+// created. Current implementation assumes that the underlying transport is using libpdx (thus
+// holding a pdx::LocalChannelHandle object), but future implementation can change it to a Binder
+// backend if ever needed.
+class DetachedBufferHandle {
+public:
+    static std::unique_ptr<DetachedBufferHandle> Create(pdx::LocalChannelHandle handle) {
+        return std::unique_ptr<DetachedBufferHandle>(new DetachedBufferHandle(std::move(handle)));
+    }
+
+    // Accessors to get or take the internal pdx::LocalChannelHandle.
+    pdx::LocalChannelHandle& handle() { return mHandle; }
+    const pdx::LocalChannelHandle& handle() const { return mHandle; }
+
+    // Returns whether the DetachedBufferHandle holds a BufferHub channel.
+    bool isValid() const { return mHandle.valid(); }
+
+private:
+    // Constructs a DetachedBufferHandle from a pdx::LocalChannelHandle.
+    explicit DetachedBufferHandle(pdx::LocalChannelHandle handle) : mHandle(std::move(handle)) {}
+
+    pdx::LocalChannelHandle mHandle;
+};
+
+} // namespace android
+
+#endif // ANDROID_DETACHED_BUFFER_HUB_HANDLE_H
diff --git a/libs/ui/include/ui/GraphicBuffer.h b/libs/ui/include/ui/GraphicBuffer.h
index e794462..cc38982 100644
--- a/libs/ui/include/ui/GraphicBuffer.h
+++ b/libs/ui/include/ui/GraphicBuffer.h
@@ -34,6 +34,7 @@
 
 namespace android {
 
+class DetachedBufferHandle;
 class GraphicBufferMapper;
 
 // ===========================================================================
@@ -190,6 +191,11 @@
     status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const;
     status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count);
 
+    // Sets and takes DetachedBuffer. Should only be called from BufferHub.
+    bool isDetachedBuffer() const;
+    status_t setDetachedBufferHandle(std::unique_ptr<DetachedBufferHandle> detachedBuffer);
+    std::unique_ptr<DetachedBufferHandle> takeDetachedBufferHandle();
+
 private:
     ~GraphicBuffer();
 
@@ -240,6 +246,17 @@
     // match the BufferQueue's internal generation number (set through
     // IGBP::setGenerationNumber), attempts to attach the buffer will fail.
     uint32_t mGenerationNumber;
+
+    // Stores a BufferHub handle that can be used to re-attach this GraphicBuffer back into a
+    // BufferHub producer/consumer set. In terms of GraphicBuffer's relationship with BufferHub,
+    // there are three different modes:
+    // 1. Legacy mode: GraphicBuffer is not backed by BufferHub and mDetachedBufferHandle must be
+    //    invalid.
+    // 2. Detached mode: GraphicBuffer is backed by BufferHub, but not part of a producer/consumer
+    //    set. In this mode, mDetachedBufferHandle must be valid.
+    // 3. Attached mode: GraphicBuffer is backed by BufferHub and it's part of a producer/consumer
+    //    set. In this mode, mDetachedBufferHandle must be invalid.
+    std::unique_ptr<DetachedBufferHandle> mDetachedBufferHandle;
 };
 
 }; // namespace android
diff --git a/libs/ui/include_vndk/ui/ANativeObjectBase.h b/libs/ui/include_vndk/ui/ANativeObjectBase.h
new file mode 120000
index 0000000..4dab8d8
--- /dev/null
+++ b/libs/ui/include_vndk/ui/ANativeObjectBase.h
@@ -0,0 +1 @@
+../../include/ui/ANativeObjectBase.h
\ No newline at end of file
diff --git a/libs/ui/include_vndk/ui/BufferQueueDefs.h b/libs/ui/include_vndk/ui/BufferQueueDefs.h
new file mode 120000
index 0000000..c886ed8
--- /dev/null
+++ b/libs/ui/include_vndk/ui/BufferQueueDefs.h
@@ -0,0 +1 @@
+../../include/ui/BufferQueueDefs.h
\ No newline at end of file
diff --git a/libs/ui/include_vndk/ui/ColorSpace.h b/libs/ui/include_vndk/ui/ColorSpace.h
new file mode 120000
index 0000000..ddf70d5
--- /dev/null
+++ b/libs/ui/include_vndk/ui/ColorSpace.h
@@ -0,0 +1 @@
+../../include/ui/ColorSpace.h
\ No newline at end of file
diff --git a/libs/ui/include_vndk/ui/DebugUtils.h b/libs/ui/include_vndk/ui/DebugUtils.h
new file mode 120000
index 0000000..8461bb3
--- /dev/null
+++ b/libs/ui/include_vndk/ui/DebugUtils.h
@@ -0,0 +1 @@
+../../include/ui/DebugUtils.h
\ No newline at end of file
diff --git a/libs/ui/include_vndk/ui/DisplayInfo.h b/libs/ui/include_vndk/ui/DisplayInfo.h
new file mode 120000
index 0000000..75f14cf
--- /dev/null
+++ b/libs/ui/include_vndk/ui/DisplayInfo.h
@@ -0,0 +1 @@
+../../include/ui/DisplayInfo.h
\ No newline at end of file
diff --git a/libs/ui/include_vndk/ui/DisplayStatInfo.h b/libs/ui/include_vndk/ui/DisplayStatInfo.h
new file mode 120000
index 0000000..6689ad3
--- /dev/null
+++ b/libs/ui/include_vndk/ui/DisplayStatInfo.h
@@ -0,0 +1 @@
+../../include/ui/DisplayStatInfo.h
\ No newline at end of file
diff --git a/libs/ui/include_vndk/ui/Fence.h b/libs/ui/include_vndk/ui/Fence.h
new file mode 120000
index 0000000..b110201
--- /dev/null
+++ b/libs/ui/include_vndk/ui/Fence.h
@@ -0,0 +1 @@
+../../include/ui/Fence.h
\ No newline at end of file
diff --git a/libs/ui/include_vndk/ui/FenceTime.h b/libs/ui/include_vndk/ui/FenceTime.h
new file mode 120000
index 0000000..01a6ff2
--- /dev/null
+++ b/libs/ui/include_vndk/ui/FenceTime.h
@@ -0,0 +1 @@
+../../include/ui/FenceTime.h
\ No newline at end of file
diff --git a/libs/ui/include_vndk/ui/FloatRect.h b/libs/ui/include_vndk/ui/FloatRect.h
new file mode 120000
index 0000000..a526211
--- /dev/null
+++ b/libs/ui/include_vndk/ui/FloatRect.h
@@ -0,0 +1 @@
+../../include/ui/FloatRect.h
\ No newline at end of file
diff --git a/libs/ui/include_vndk/ui/FrameStats.h b/libs/ui/include_vndk/ui/FrameStats.h
new file mode 120000
index 0000000..e68e5c8
--- /dev/null
+++ b/libs/ui/include_vndk/ui/FrameStats.h
@@ -0,0 +1 @@
+../../include/ui/FrameStats.h
\ No newline at end of file
diff --git a/libs/ui/include_vndk/ui/Gralloc2.h b/libs/ui/include_vndk/ui/Gralloc2.h
new file mode 120000
index 0000000..66098c4
--- /dev/null
+++ b/libs/ui/include_vndk/ui/Gralloc2.h
@@ -0,0 +1 @@
+../../include/ui/Gralloc2.h
\ No newline at end of file
diff --git a/libs/ui/include_vndk/ui/GraphicBuffer.h b/libs/ui/include_vndk/ui/GraphicBuffer.h
new file mode 120000
index 0000000..445eae5
--- /dev/null
+++ b/libs/ui/include_vndk/ui/GraphicBuffer.h
@@ -0,0 +1 @@
+../../include/ui/GraphicBuffer.h
\ No newline at end of file
diff --git a/libs/ui/include_vndk/ui/GraphicBufferAllocator.h b/libs/ui/include_vndk/ui/GraphicBufferAllocator.h
new file mode 120000
index 0000000..9634533
--- /dev/null
+++ b/libs/ui/include_vndk/ui/GraphicBufferAllocator.h
@@ -0,0 +1 @@
+../../include/ui/GraphicBufferAllocator.h
\ No newline at end of file
diff --git a/libs/ui/include_vndk/ui/GraphicBufferMapper.h b/libs/ui/include_vndk/ui/GraphicBufferMapper.h
new file mode 120000
index 0000000..c3b3a7c
--- /dev/null
+++ b/libs/ui/include_vndk/ui/GraphicBufferMapper.h
@@ -0,0 +1 @@
+../../include/ui/GraphicBufferMapper.h
\ No newline at end of file
diff --git a/libs/ui/include_vndk/ui/GraphicTypes.h b/libs/ui/include_vndk/ui/GraphicTypes.h
new file mode 120000
index 0000000..b1859e0
--- /dev/null
+++ b/libs/ui/include_vndk/ui/GraphicTypes.h
@@ -0,0 +1 @@
+../../include/ui/GraphicTypes.h
\ No newline at end of file
diff --git a/libs/ui/include_vndk/ui/HdrCapabilities.h b/libs/ui/include_vndk/ui/HdrCapabilities.h
new file mode 120000
index 0000000..a240828
--- /dev/null
+++ b/libs/ui/include_vndk/ui/HdrCapabilities.h
@@ -0,0 +1 @@
+../../include/ui/HdrCapabilities.h
\ No newline at end of file
diff --git a/libs/ui/include_vndk/ui/PixelFormat.h b/libs/ui/include_vndk/ui/PixelFormat.h
new file mode 120000
index 0000000..0aba056
--- /dev/null
+++ b/libs/ui/include_vndk/ui/PixelFormat.h
@@ -0,0 +1 @@
+../../include/ui/PixelFormat.h
\ No newline at end of file
diff --git a/libs/ui/include_vndk/ui/Point.h b/libs/ui/include_vndk/ui/Point.h
new file mode 120000
index 0000000..0aeda3e
--- /dev/null
+++ b/libs/ui/include_vndk/ui/Point.h
@@ -0,0 +1 @@
+../../include/ui/Point.h
\ No newline at end of file
diff --git a/libs/ui/include_vndk/ui/Rect.h b/libs/ui/include_vndk/ui/Rect.h
new file mode 120000
index 0000000..01ed689
--- /dev/null
+++ b/libs/ui/include_vndk/ui/Rect.h
@@ -0,0 +1 @@
+../../include/ui/Rect.h
\ No newline at end of file
diff --git a/libs/ui/include_vndk/ui/Region.h b/libs/ui/include_vndk/ui/Region.h
new file mode 120000
index 0000000..3f829bf
--- /dev/null
+++ b/libs/ui/include_vndk/ui/Region.h
@@ -0,0 +1 @@
+../../include/ui/Region.h
\ No newline at end of file
diff --git a/libs/ui/include_vndk/ui/UiConfig.h b/libs/ui/include_vndk/ui/UiConfig.h
new file mode 120000
index 0000000..f580ce1
--- /dev/null
+++ b/libs/ui/include_vndk/ui/UiConfig.h
@@ -0,0 +1 @@
+../../include/ui/UiConfig.h
\ No newline at end of file
diff --git a/libs/ui/tests/Android.bp b/libs/ui/tests/Android.bp
index 08067fc..aef6428 100644
--- a/libs/ui/tests/Android.bp
+++ b/libs/ui/tests/Android.bp
@@ -27,3 +27,10 @@
     srcs: ["colorspace_test.cpp"],
     cflags: ["-Wall", "-Werror"],
 }
+
+cc_test {
+    name: "GraphicBuffer_test",
+    shared_libs: ["libpdx_default_transport", "libui", "libutils"],
+    srcs: ["GraphicBuffer_test.cpp"],
+    cflags: ["-Wall", "-Werror"],
+}
diff --git a/libs/ui/tests/GraphicBuffer_test.cpp b/libs/ui/tests/GraphicBuffer_test.cpp
new file mode 100644
index 0000000..eb679ac
--- /dev/null
+++ b/libs/ui/tests/GraphicBuffer_test.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GraphicBufferTest"
+
+#include <ui/DetachedBufferHandle.h>
+#include <ui/GraphicBuffer.h>
+
+#include <gtest/gtest.h>
+
+namespace android {
+
+namespace {
+
+constexpr uint32_t kTestWidth = 1024;
+constexpr uint32_t kTestHeight = 1;
+constexpr uint32_t kTestFormat = HAL_PIXEL_FORMAT_BLOB;
+constexpr uint32_t kTestLayerCount = 1;
+constexpr uint64_t kTestUsage = GraphicBuffer::USAGE_SW_WRITE_OFTEN;
+
+} // namespace
+
+class GraphicBufferTest : public testing::Test {};
+
+TEST_F(GraphicBufferTest, DetachedBuffer) {
+    sp<GraphicBuffer> buffer(
+            new GraphicBuffer(kTestWidth, kTestHeight, kTestFormat, kTestLayerCount, kTestUsage));
+
+    // Currently a newly allocated GraphicBuffer is in legacy mode, i.e. not associated with
+    // BufferHub. But this may change in the future.
+    EXPECT_FALSE(buffer->isDetachedBuffer());
+
+    pdx::LocalChannelHandle channel{nullptr, 1234};
+    EXPECT_TRUE(channel.valid());
+
+    std::unique_ptr<DetachedBufferHandle> handle = DetachedBufferHandle::Create(std::move(channel));
+    EXPECT_FALSE(channel.valid());
+    EXPECT_TRUE(handle->isValid());
+    EXPECT_TRUE(handle->handle().valid());
+
+    buffer->setDetachedBufferHandle(std::move(handle));
+    EXPECT_TRUE(handle == nullptr);
+    EXPECT_TRUE(buffer->isDetachedBuffer());
+
+    handle = buffer->takeDetachedBufferHandle();
+    EXPECT_TRUE(handle != nullptr);
+    EXPECT_TRUE(handle->isValid());
+    EXPECT_FALSE(buffer->isDetachedBuffer());
+}
+
+} // namespace android