Merge "Revert "SF: enable high refresh rate virtual mode""
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index cd0fbd4..16abc1e 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -4,6 +4,7 @@
 [Builtin Hooks Options]
 # Only turn on clang-format check for the following subfolders.
 clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
+               libs/graphicsenv/
                libs/gui/
                libs/ui/
                libs/vr/
diff --git a/libs/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp
index e53f7fd..024d72b 100644
--- a/libs/graphicsenv/GraphicsEnv.cpp
+++ b/libs/graphicsenv/GraphicsEnv.cpp
@@ -167,7 +167,7 @@
         auto sphalNamespace = android_get_exported_namespace("sphal");
         if (!sphalNamespace) return;
         mDriverNamespace = android_create_namespace("gfx driver",
-                                                    nullptr,             // ld_library_path
+                                                    mDriverPath.c_str(), // ld_library_path
                                                     mDriverPath.c_str(), // default_library_path
                                                     ANDROID_NAMESPACE_TYPE_SHARED |
                                                             ANDROID_NAMESPACE_TYPE_ISOLATED,
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index f99bc53..cf9d4c5 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -103,11 +103,15 @@
     }
 
     virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer,
-                                   Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
-                                   bool useIdentityTransform, ISurfaceComposer::Rotation rotation) {
+                                   const ui::Dataspace reqDataspace,
+                                   const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
+                                   uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform,
+                                   ISurfaceComposer::Rotation rotation) {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         data.writeStrongBinder(display);
+        data.writeInt32(static_cast<int32_t>(reqDataspace));
+        data.writeInt32(static_cast<int32_t>(reqPixelFormat));
         data.write(sourceCrop);
         data.writeUint32(reqWidth);
         data.writeUint32(reqHeight);
@@ -126,15 +130,19 @@
 
         *outBuffer = new GraphicBuffer();
         reply.read(**outBuffer);
+
         return result;
     }
 
     virtual status_t captureLayers(const sp<IBinder>& layerHandleBinder,
-                                   sp<GraphicBuffer>* outBuffer, const Rect& sourceCrop,
+                                   sp<GraphicBuffer>* outBuffer, const ui::Dataspace reqDataspace,
+                                   const ui::PixelFormat reqPixelFormat, const Rect& sourceCrop,
                                    float frameScale, bool childrenOnly) {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         data.writeStrongBinder(layerHandleBinder);
+        data.writeInt32(static_cast<int32_t>(reqDataspace));
+        data.writeInt32(static_cast<int32_t>(reqPixelFormat));
         data.write(sourceCrop);
         data.writeFloat(frameScale);
         data.writeBool(childrenOnly);
@@ -148,6 +156,7 @@
             ALOGE("captureLayers failed to readInt32: %d", result);
             return result;
         }
+
         *outBuffer = new GraphicBuffer();
         reply.read(**outBuffer);
 
@@ -645,6 +654,8 @@
         case CAPTURE_SCREEN: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
             sp<IBinder> display = data.readStrongBinder();
+            ui::Dataspace reqDataspace = static_cast<ui::Dataspace>(data.readInt32());
+            ui::PixelFormat reqPixelFormat = static_cast<ui::PixelFormat>(data.readInt32());
             sp<GraphicBuffer> outBuffer;
             Rect sourceCrop(Rect::EMPTY_RECT);
             data.read(sourceCrop);
@@ -653,8 +664,8 @@
             bool useIdentityTransform = static_cast<bool>(data.readInt32());
             int32_t rotation = data.readInt32();
 
-            status_t res = captureScreen(display, &outBuffer, sourceCrop, reqWidth, reqHeight,
-                                         useIdentityTransform,
+            status_t res = captureScreen(display, &outBuffer, reqDataspace, reqPixelFormat,
+                                         sourceCrop, reqWidth, reqHeight, useIdentityTransform,
                                          static_cast<ISurfaceComposer::Rotation>(rotation));
             reply->writeInt32(res);
             if (res == NO_ERROR) {
@@ -665,14 +676,16 @@
         case CAPTURE_LAYERS: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
             sp<IBinder> layerHandleBinder = data.readStrongBinder();
+            ui::Dataspace reqDataspace = static_cast<ui::Dataspace>(data.readInt32());
+            ui::PixelFormat reqPixelFormat = static_cast<ui::PixelFormat>(data.readInt32());
             sp<GraphicBuffer> outBuffer;
             Rect sourceCrop(Rect::EMPTY_RECT);
             data.read(sourceCrop);
             float frameScale = data.readFloat();
             bool childrenOnly = data.readBool();
 
-            status_t res = captureLayers(layerHandleBinder, &outBuffer, sourceCrop, frameScale,
-                                         childrenOnly);
+            status_t res = captureLayers(layerHandleBinder, &outBuffer, reqDataspace,
+                                         reqPixelFormat, sourceCrop, frameScale, childrenOnly);
             reply->writeInt32(res);
             if (res == NO_ERROR) {
                 reply->write(*outBuffer);
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 1ac9609..7498f36 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -887,13 +887,14 @@
 
 // ----------------------------------------------------------------------------
 
-status_t ScreenshotClient::capture(const sp<IBinder>& display, Rect sourceCrop, uint32_t reqWidth,
-                                   uint32_t reqHeight, bool useIdentityTransform, uint32_t rotation,
-                                   sp<GraphicBuffer>* outBuffer) {
+status_t ScreenshotClient::capture(const sp<IBinder>& display, const ui::Dataspace reqDataSpace,
+                                   const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
+                                   uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform,
+                                   uint32_t rotation, sp<GraphicBuffer>* outBuffer) {
     sp<ISurfaceComposer> s(ComposerService::getComposerService());
     if (s == nullptr) return NO_INIT;
-    status_t ret = s->captureScreen(display, outBuffer, sourceCrop, reqWidth, reqHeight,
-                                    useIdentityTransform,
+    status_t ret = s->captureScreen(display, outBuffer, reqDataSpace, reqPixelFormat, sourceCrop,
+                                    reqWidth, reqHeight, useIdentityTransform,
                                     static_cast<ISurfaceComposer::Rotation>(rotation));
     if (ret != NO_ERROR) {
         return ret;
@@ -901,21 +902,25 @@
     return ret;
 }
 
-status_t ScreenshotClient::captureLayers(const sp<IBinder>& layerHandle, Rect sourceCrop,
+status_t ScreenshotClient::captureLayers(const sp<IBinder>& layerHandle,
+                                         const ui::Dataspace reqDataSpace,
+                                         const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
                                          float frameScale, sp<GraphicBuffer>* outBuffer) {
     sp<ISurfaceComposer> s(ComposerService::getComposerService());
     if (s == nullptr) return NO_INIT;
-    status_t ret = s->captureLayers(layerHandle, outBuffer, sourceCrop, frameScale,
-                                    false /* childrenOnly */);
+    status_t ret = s->captureLayers(layerHandle, outBuffer, reqDataSpace, reqPixelFormat,
+                                    sourceCrop, frameScale, false /* childrenOnly */);
     return ret;
 }
 
-status_t ScreenshotClient::captureChildLayers(const sp<IBinder>& layerHandle, Rect sourceCrop,
+status_t ScreenshotClient::captureChildLayers(const sp<IBinder>& layerHandle,
+                                              const ui::Dataspace reqDataSpace,
+                                              const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
                                               float frameScale, sp<GraphicBuffer>* outBuffer) {
     sp<ISurfaceComposer> s(ComposerService::getComposerService());
     if (s == nullptr) return NO_INIT;
-    status_t ret = s->captureLayers(layerHandle, outBuffer, sourceCrop, frameScale,
-                                    true /* childrenOnly */);
+    status_t ret = s->captureLayers(layerHandle, outBuffer, reqDataSpace, reqPixelFormat,
+                                    sourceCrop, frameScale, true /* childrenOnly */);
     return ret;
 }
 // ----------------------------------------------------------------------------
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index a55cfe0..781e062 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -180,6 +180,36 @@
      * The subregion can be optionally rotated.  It will also be scaled to
      * match the size of the output buffer.
      *
+     * reqDataspace and reqPixelFormat specify the data space and pixel format
+     * of the buffer. The caller should pick the data space and pixel format
+     * that it can consume.
+     *
+     * At the moment, sourceCrop is ignored and is always set to the visible
+     * region (projected display viewport) of the screen.
+     *
+     * reqWidth and reqHeight specifies the size of the buffer.  When either
+     * of them is 0, they are set to the size of the logical display viewport.
+     *
+     * When useIdentityTransform is true, layer transformations are disabled.
+     *
+     * rotation specifies the rotation of the source crop (and the pixels in
+     * it) around its center.
+     */
+    virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer,
+                                   const ui::Dataspace reqDataspace,
+                                   const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
+                                   uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform,
+                                   Rotation rotation = eRotateNone) = 0;
+    /**
+     * Capture the specified screen. This requires READ_FRAME_BUFFER
+     * permission.  This function will fail if there is a secure window on
+     * screen.
+     *
+     * This function can capture a subregion (the source crop) of the screen
+     * into an sRGB buffer with RGBA_8888 pixel format.
+     * The subregion can be optionally rotated.  It will also be scaled to
+     * match the size of the output buffer.
+     *
      * At the moment, sourceCrop is ignored and is always set to the visible
      * region (projected display viewport) of the screen.
      *
@@ -193,15 +223,34 @@
      */
     virtual status_t captureScreen(const sp<IBinder>& display, sp<GraphicBuffer>* outBuffer,
                                    Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
-                                   bool useIdentityTransform, Rotation rotation = eRotateNone) = 0;
+                                   bool useIdentityTransform, Rotation rotation = eRotateNone) {
+        return captureScreen(display, outBuffer, ui::Dataspace::V0_SRGB, ui::PixelFormat::RGBA_8888,
+                             sourceCrop, reqWidth, reqHeight, useIdentityTransform, rotation);
+    }
 
     /**
      * Capture a subtree of the layer hierarchy, potentially ignoring the root node.
+     *
+     * reqDataspace and reqPixelFormat specify the data space and pixel format
+     * of the buffer. The caller should pick the data space and pixel format
+     * that it can consume.
      */
     virtual status_t captureLayers(const sp<IBinder>& layerHandleBinder,
-                                   sp<GraphicBuffer>* outBuffer, const Rect& sourceCrop,
+                                   sp<GraphicBuffer>* outBuffer, const ui::Dataspace reqDataspace,
+                                   const ui::PixelFormat reqPixelFormat, const Rect& sourceCrop,
                                    float frameScale = 1.0, bool childrenOnly = false) = 0;
 
+    /**
+     * Capture a subtree of the layer hierarchy into an sRGB buffer with RGBA_8888 pixel format,
+     * potentially ignoring the root node.
+     */
+    status_t captureLayers(const sp<IBinder>& layerHandleBinder, sp<GraphicBuffer>* outBuffer,
+                           const Rect& sourceCrop, float frameScale = 1.0,
+                           bool childrenOnly = false) {
+        return captureLayers(layerHandleBinder, outBuffer, ui::Dataspace::V0_SRGB,
+                             ui::PixelFormat::RGBA_8888, sourceCrop, frameScale, childrenOnly);
+    }
+
     /* Clears the frame statistics for animations.
      *
      * Requires the ACCESS_SURFACE_FLINGER permission.
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 69a759f..1b4eda7 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -329,12 +329,16 @@
 public:
     // if cropping isn't required, callers may pass in a default Rect, e.g.:
     //   capture(display, producer, Rect(), reqWidth, ...);
-    static status_t capture(const sp<IBinder>& display, Rect sourceCrop, uint32_t reqWidth,
-                            uint32_t reqHeight, bool useIdentityTransform, uint32_t rotation,
-                            sp<GraphicBuffer>* outBuffer);
-    static status_t captureLayers(const sp<IBinder>& layerHandle, Rect sourceCrop, float frameScale,
-                                  sp<GraphicBuffer>* outBuffer);
-    static status_t captureChildLayers(const sp<IBinder>& layerHandle, Rect sourceCrop,
+    static status_t capture(const sp<IBinder>& display, const ui::Dataspace reqDataSpace,
+                            const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
+                            uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform,
+                            uint32_t rotation, sp<GraphicBuffer>* outBuffer);
+    static status_t captureLayers(const sp<IBinder>& layerHandle, const ui::Dataspace reqDataSpace,
+                                  const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
+                                  float frameScale, sp<GraphicBuffer>* outBuffer);
+    static status_t captureChildLayers(const sp<IBinder>& layerHandle,
+                                       const ui::Dataspace reqDataSpace,
+                                       const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
                                        float frameScale, sp<GraphicBuffer>* outBuffer);
 };
 
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index bc80899..500df05 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -134,8 +134,9 @@
     sp<IBinder> display(sf->getBuiltInDisplay(
             ISurfaceComposer::eDisplayIdMain));
     sp<GraphicBuffer> outBuffer;
-    ASSERT_EQ(NO_ERROR, sf->captureScreen(display, &outBuffer, Rect(),
-            64, 64, false));
+    ASSERT_EQ(NO_ERROR,
+              sf->captureScreen(display, &outBuffer, ui::Dataspace::V0_SRGB,
+                                ui::PixelFormat::RGBA_8888, Rect(), 64, 64, false));
 
     ASSERT_EQ(NO_ERROR, native_window_api_connect(anw.get(),
             NATIVE_WINDOW_API_CPU));
@@ -165,8 +166,9 @@
                 &buf));
         ASSERT_EQ(NO_ERROR, anw->queueBuffer(anw.get(), buf, -1));
     }
-    ASSERT_EQ(NO_ERROR, sf->captureScreen(display, &outBuffer, Rect(),
-            64, 64, false));
+    ASSERT_EQ(NO_ERROR,
+              sf->captureScreen(display, &outBuffer, ui::Dataspace::V0_SRGB,
+                                ui::PixelFormat::RGBA_8888, Rect(), 64, 64, false));
 }
 
 TEST_F(SurfaceTest, ConcreteTypeIsSurface) {
@@ -596,14 +598,19 @@
     }
     status_t setActiveColorMode(const sp<IBinder>& /*display*/,
         ColorMode /*colorMode*/) override { return NO_ERROR; }
-    status_t captureScreen(const sp<IBinder>& /*display*/,
-            sp<GraphicBuffer>* /*outBuffer*/,
-            Rect /*sourceCrop*/, uint32_t /*reqWidth*/, uint32_t /*reqHeight*/,
-            bool /*useIdentityTransform*/,
-            Rotation /*rotation*/) override { return NO_ERROR; }
+    status_t captureScreen(const sp<IBinder>& /*display*/, sp<GraphicBuffer>* /*outBuffer*/,
+                           const ui::Dataspace /*reqDataspace*/,
+                           const ui::PixelFormat /*reqPixelFormat*/, Rect /*sourceCrop*/,
+                           uint32_t /*reqWidth*/, uint32_t /*reqHeight*/,
+                           bool /*useIdentityTransform*/, Rotation /*rotation*/) override {
+        return NO_ERROR;
+    }
     virtual status_t captureLayers(const sp<IBinder>& /*parentHandle*/,
-                                   sp<GraphicBuffer>* /*outBuffer*/, const Rect& /*sourceCrop*/,
-                                   float /*frameScale*/, bool /*childrenOnly*/) override {
+                                   sp<GraphicBuffer>* /*outBuffer*/,
+                                   const ui::Dataspace /*reqDataspace*/,
+                                   const ui::PixelFormat /*reqPixelFormat*/,
+                                   const Rect& /*sourceCrop*/, float /*frameScale*/,
+                                   bool /*childrenOnly*/) override {
         return NO_ERROR;
     }
     status_t clearAnimationFrameStats() override { return NO_ERROR; }
diff --git a/libs/vr/libbufferhub/Android.bp b/libs/vr/libbufferhub/Android.bp
index ba5cfcd..43ac79e 100644
--- a/libs/vr/libbufferhub/Android.bp
+++ b/libs/vr/libbufferhub/Android.bp
@@ -22,6 +22,7 @@
     "buffer_hub_base.cpp",
     "buffer_hub_rpc.cpp",
     "consumer_buffer.cpp",
+    "buffer_client_impl.cpp",
     "ion_buffer.cpp",
     "producer_buffer.cpp",
 ]
diff --git a/libs/vr/libbufferhub/buffer_client_impl.cpp b/libs/vr/libbufferhub/buffer_client_impl.cpp
new file mode 100644
index 0000000..6bef98a
--- /dev/null
+++ b/libs/vr/libbufferhub/buffer_client_impl.cpp
@@ -0,0 +1,55 @@
+#include <log/log.h>
+#include <private/dvr/IBufferClient.h>
+
+namespace android {
+namespace dvr {
+
+class BpBufferClient : public BpInterface<IBufferClient> {
+ public:
+  explicit BpBufferClient(const sp<IBinder>& impl)
+      : BpInterface<IBufferClient>(impl) {}
+
+  bool isValid() override;
+};
+
+IMPLEMENT_META_INTERFACE(BufferClient, "android.dvr.IBufferClient");
+
+// Transaction code
+enum {
+  IS_VALID = IBinder::FIRST_CALL_TRANSACTION,
+};
+
+bool BpBufferClient::isValid() {
+  Parcel data, reply;
+  status_t ret =
+      data.writeInterfaceToken(IBufferClient::getInterfaceDescriptor());
+  if (ret != NO_ERROR) {
+    ALOGE("BpBufferClient::isValid: failed to write into parcel; errno=%d",
+          ret);
+    return false;
+  }
+
+  ret = remote()->transact(IS_VALID, data, &reply);
+  if (ret == NO_ERROR) {
+    return reply.readBool();
+  } else {
+    ALOGE("BpBufferClient::isValid: failed to transact; errno=%d", ret);
+    return false;
+  }
+}
+
+status_t BnBufferClient::onTransact(uint32_t code, const Parcel& data,
+                                    Parcel* reply, uint32_t flags) {
+  switch (code) {
+    case IS_VALID: {
+      CHECK_INTERFACE(IBufferClient, data, reply);
+      return reply->writeBool(isValid());
+    } break;
+    default:
+      // Should not reach except binder defined transactions such as dumpsys
+      return BBinder::onTransact(code, data, reply, flags);
+  }
+}
+
+}  // namespace dvr
+}  // namespace android
\ No newline at end of file
diff --git a/libs/vr/libbufferhub/buffer_hub-test.cpp b/libs/vr/libbufferhub/buffer_hub-test.cpp
index 8c6e7e2..4d98dfc 100644
--- a/libs/vr/libbufferhub/buffer_hub-test.cpp
+++ b/libs/vr/libbufferhub/buffer_hub-test.cpp
@@ -214,13 +214,12 @@
       ConsumerBuffer::Import(p->CreateConsumer());
   ASSERT_TRUE(c.get() != nullptr);
 
-  uint64_t context;
   LocalHandle fence;
 
   // The producer buffer starts in gained state.
 
   // Acquire, release, and gain in gained state should fail.
-  EXPECT_EQ(-EBUSY, c->Acquire(&fence, &context));
+  EXPECT_EQ(-EBUSY, c->Acquire(&fence));
   EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
   EXPECT_EQ(-EALREADY, p->Gain(&fence));
 
@@ -233,10 +232,10 @@
   EXPECT_EQ(-EBUSY, p->Gain(&fence));
 
   // Acquire in posted state should succeed.
-  EXPECT_LE(0, c->Acquire(&fence, &context));
+  EXPECT_LE(0, c->Acquire(&fence));
 
   // Acquire, post, and gain in acquired state should fail.
-  EXPECT_EQ(-EBUSY, c->Acquire(&fence, &context));
+  EXPECT_EQ(-EBUSY, c->Acquire(&fence));
   EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
   EXPECT_EQ(-EBUSY, p->Gain(&fence));
 
@@ -246,14 +245,14 @@
 
   // Release, acquire, and post in released state should fail.
   EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
-  EXPECT_EQ(-EBUSY, c->Acquire(&fence, &context));
+  EXPECT_EQ(-EBUSY, c->Acquire(&fence));
   EXPECT_EQ(-EBUSY, p->Post(LocalHandle()));
 
   // Gain in released state should succeed.
   EXPECT_EQ(0, p->Gain(&fence));
 
   // Acquire, release, and gain in gained state should fail.
-  EXPECT_EQ(-EBUSY, c->Acquire(&fence, &context));
+  EXPECT_EQ(-EBUSY, c->Acquire(&fence));
   EXPECT_EQ(-EBUSY, c->Release(LocalHandle()));
   EXPECT_EQ(-EALREADY, p->Gain(&fence));
 }
@@ -491,7 +490,7 @@
   EXPECT_LE(0, RETRY_EINTR(c->Poll(kPollTimeoutMs)));
   LocalHandle fence;
   Metadata m2 = {};
-  EXPECT_EQ(0, c->Acquire(&fence, &m2));
+  EXPECT_EQ(0, c->Acquire(&fence, &m2, sizeof(m2)));
   EXPECT_EQ(m.field1, m2.field1);
   EXPECT_EQ(m.field2, m2.field2);
   EXPECT_EQ(0, c->Release(LocalHandle()));
@@ -552,11 +551,11 @@
 
   // It is illegal to acquire metadata larger than originally requested during
   // buffer allocation.
-  EXPECT_NE(0, c->Acquire(&fence, &e));
+  EXPECT_NE(0, c->Acquire(&fence, &e, sizeof(e)));
 
   // It is ok to acquire metadata smaller than originally requested during
   // buffer allocation.
-  EXPECT_EQ(0, c->Acquire(&fence, &sequence));
+  EXPECT_EQ(0, c->Acquire(&fence, &sequence, sizeof(sequence)));
   EXPECT_EQ(m.field1, sequence);
 }
 
diff --git a/libs/vr/libbufferhub/include/private/dvr/IBufferClient.h b/libs/vr/libbufferhub/include/private/dvr/IBufferClient.h
new file mode 100644
index 0000000..03f2d95
--- /dev/null
+++ b/libs/vr/libbufferhub/include/private/dvr/IBufferClient.h
@@ -0,0 +1,29 @@
+#ifndef ANDROID_DVR_IBUFFERCLIENT_H
+#define ANDROID_DVR_IBUFFERCLIENT_H
+
+#include <binder/IInterface.h>
+#include <binder/Parcel.h>
+
+namespace android {
+namespace dvr {
+
+// Interface for acessing BufferHubBuffer remotely.
+class IBufferClient : public IInterface {
+ public:
+  DECLARE_META_INTERFACE(BufferClient);
+
+  // Checks if the buffer node is valid.
+  virtual bool isValid() = 0;
+};
+
+// BnInterface for IBufferClient. Should only be created in bufferhub service.
+class BnBufferClient : public BnInterface<IBufferClient> {
+ public:
+  virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply,
+                              uint32_t flags = 0);
+};
+
+}  // namespace dvr
+}  // namespace android
+
+#endif  // ANDROID_DVR_IBUFFERCLIENT_H
\ No newline at end of file
diff --git a/libs/vr/libbufferhub/include/private/dvr/consumer_buffer.h b/libs/vr/libbufferhub/include/private/dvr/consumer_buffer.h
index 2044c53..7349779 100644
--- a/libs/vr/libbufferhub/include/private/dvr/consumer_buffer.h
+++ b/libs/vr/libbufferhub/include/private/dvr/consumer_buffer.h
@@ -45,15 +45,6 @@
   // Returns zero on success, or a negative errno code otherwise.
   int Acquire(LocalHandle* ready_fence, void* meta, size_t user_metadata_size);
 
-  // Attempt to retrieve a post event from buffer hub. If successful,
-  // |ready_fence| is set to a fence to wait on until the buffer is ready. This
-  // call will only succeed after the fd is signaled. This returns zero or a
-  // negative unix error code.
-  template <typename Meta>
-  int Acquire(LocalHandle* ready_fence, Meta* meta) {
-    return Acquire(ready_fence, meta, sizeof(*meta));
-  }
-
   // Asynchronously acquires a bufer.
   int AcquireAsync(DvrNativeBufferMetadata* out_meta, LocalHandle* out_fence);
 
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 6f792ec..a7fea33 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -549,7 +549,14 @@
         char model[PROPERTY_VALUE_MAX];
         property_get("ro.product.manufacturer", manufacturer, "UNSET");
         property_get("ro.product.model", model, "UNSET");
-        so = load_angle_from_namespace("feature_support", ns);
+
+        // Check if ANGLE is enabled. Workaround for b/118375731
+        // We suspect that loading & unloading a library somehow corrupts
+        // the process.
+        property_get("debug.angle.enable", prop, "0");
+        if (atoi(prop)) {
+            so = load_angle_from_namespace("feature_support", ns);
+        }
         if (so) {
             ALOGV("Temporarily loaded ANGLE's opt-in/out logic from namespace");
             bool use_version0_API = false;
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 38482c9..918f7de 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -349,10 +349,11 @@
     DisplayRenderArea(const sp<const DisplayDevice> device,
                       ui::Transform::orientation_flags rotation = ui::Transform::ROT_0)
           : DisplayRenderArea(device, device->getBounds(), device->getWidth(), device->getHeight(),
-                              rotation) {}
+                              device->getCompositionDataSpace(), rotation) {}
     DisplayRenderArea(const sp<const DisplayDevice> device, Rect sourceCrop, uint32_t reqWidth,
-                      uint32_t reqHeight, ui::Transform::orientation_flags rotation)
-          : RenderArea(reqWidth, reqHeight, CaptureFill::OPAQUE,
+                      uint32_t reqHeight, ui::Dataspace reqDataSpace,
+                      ui::Transform::orientation_flags rotation)
+          : RenderArea(reqWidth, reqHeight, CaptureFill::OPAQUE, reqDataSpace,
                        getDisplayRotation(rotation, device->getInstallOrientation())),
             mDevice(device),
             mSourceCrop(sourceCrop) {}
diff --git a/services/surfaceflinger/RenderArea.h b/services/surfaceflinger/RenderArea.h
index 3c11e73..9bad6de 100644
--- a/services/surfaceflinger/RenderArea.h
+++ b/services/surfaceflinger/RenderArea.h
@@ -1,5 +1,6 @@
 #pragma once
 
+#include <ui/GraphicTypes.h>
 #include <ui/Transform.h>
 
 #include <functional>
@@ -19,9 +20,11 @@
     static float getCaptureFillValue(CaptureFill captureFill);
 
     RenderArea(uint32_t reqWidth, uint32_t reqHeight, CaptureFill captureFill,
+               ui::Dataspace reqDataSpace,
                ui::Transform::orientation_flags rotation = ui::Transform::ROT_0)
           : mReqWidth(reqWidth),
             mReqHeight(reqHeight),
+            mReqDataSpace(reqDataSpace),
             mCaptureFill(captureFill),
             mRotationFlags(rotation) {}
 
@@ -66,6 +69,9 @@
     int getReqWidth() const { return mReqWidth; };
     int getReqHeight() const { return mReqHeight; };
 
+    // Returns the composition data space of the render area.
+    ui::Dataspace getReqDataSpace() const { return mReqDataSpace; }
+
     // Returns the fill color of the physical render area.  Regions not
     // covered by any rendered layer should be filled with this color.
     CaptureFill getCaptureFill() const { return mCaptureFill; };
@@ -73,6 +79,7 @@
 private:
     const uint32_t mReqWidth;
     const uint32_t mReqHeight;
+    const ui::Dataspace mReqDataSpace;
     const CaptureFill mCaptureFill;
     const ui::Transform::orientation_flags mRotationFlags;
 };
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index a81e6c0..e5bef82 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -4778,9 +4778,9 @@
         code == IBinder::SYSPROPS_TRANSACTION) {
         return OK;
     }
-    // Numbers from 1000 to 1029 are currently use for backdoors. The code
+    // Numbers from 1000 to 1030 are currently use for backdoors. The code
     // in onTransact verifies that the user is root, and has access to use SF.
-    if (code >= 1000 && code <= 1029) {
+    if (code >= 1000 && code <= 1030) {
         ALOGV("Accessing SurfaceFlinger through backdoor code: %u", code);
         return OK;
     }
@@ -5060,7 +5060,8 @@
 };
 
 status_t SurfaceFlinger::captureScreen(const sp<IBinder>& displayToken,
-                                       sp<GraphicBuffer>* outBuffer, Rect sourceCrop,
+                                       sp<GraphicBuffer>* outBuffer, const Dataspace reqDataspace,
+                                       const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
                                        uint32_t reqWidth, uint32_t reqHeight,
                                        bool useIdentityTransform,
                                        ISurfaceComposer::Rotation rotation) {
@@ -5089,23 +5090,27 @@
         }
     }
 
-    DisplayRenderArea renderArea(display, sourceCrop, reqWidth, reqHeight, renderAreaRotation);
+    DisplayRenderArea renderArea(display, sourceCrop, reqWidth, reqHeight, reqDataspace,
+                                 renderAreaRotation);
 
     auto traverseLayers = std::bind(std::mem_fn(&SurfaceFlinger::traverseLayersInDisplay), this,
                                     display, std::placeholders::_1);
-    return captureScreenCommon(renderArea, traverseLayers, outBuffer, useIdentityTransform);
+    return captureScreenCommon(renderArea, traverseLayers, outBuffer, reqPixelFormat,
+                               useIdentityTransform);
 }
 
 status_t SurfaceFlinger::captureLayers(const sp<IBinder>& layerHandleBinder,
-                                       sp<GraphicBuffer>* outBuffer, const Rect& sourceCrop,
+                                       sp<GraphicBuffer>* outBuffer, const Dataspace reqDataspace,
+                                       const ui::PixelFormat reqPixelFormat, const Rect& sourceCrop,
                                        float frameScale, bool childrenOnly) {
     ATRACE_CALL();
 
     class LayerRenderArea : public RenderArea {
     public:
         LayerRenderArea(SurfaceFlinger* flinger, const sp<Layer>& layer, const Rect crop,
-                        int32_t reqWidth, int32_t reqHeight, bool childrenOnly)
-              : RenderArea(reqWidth, reqHeight, CaptureFill::CLEAR),
+                        int32_t reqWidth, int32_t reqHeight, Dataspace reqDataSpace,
+                        bool childrenOnly)
+              : RenderArea(reqWidth, reqHeight, CaptureFill::CLEAR, reqDataSpace),
                 mLayer(layer),
                 mCrop(crop),
                 mNeedsFiltering(false),
@@ -5212,7 +5217,7 @@
         reqHeight = 1;
     }
 
-    LayerRenderArea renderArea(this, parent, crop, reqWidth, reqHeight, childrenOnly);
+    LayerRenderArea renderArea(this, parent, crop, reqWidth, reqHeight, reqDataspace, childrenOnly);
 
     auto traverseLayers = [parent, childrenOnly](const LayerVector::Visitor& visitor) {
         parent->traverseChildrenInZOrder(LayerVector::StateSet::Drawing, [&](Layer* layer) {
@@ -5224,19 +5229,22 @@
             visitor(layer);
         });
     };
-    return captureScreenCommon(renderArea, traverseLayers, outBuffer, false);
+    return captureScreenCommon(renderArea, traverseLayers, outBuffer, reqPixelFormat, false);
 }
 
 status_t SurfaceFlinger::captureScreenCommon(RenderArea& renderArea,
                                              TraverseLayersFunction traverseLayers,
                                              sp<GraphicBuffer>* outBuffer,
+                                             const ui::PixelFormat reqPixelFormat,
                                              bool useIdentityTransform) {
     ATRACE_CALL();
 
+    // TODO(b/116112787) Make buffer usage a parameter.
     const uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
             GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
     *outBuffer = new GraphicBuffer(renderArea.getReqWidth(), renderArea.getReqHeight(),
-                                   HAL_PIXEL_FORMAT_RGBA_8888, 1, usage, "screenshot");
+                                   static_cast<android_pixel_format>(reqPixelFormat), 1, usage,
+                                   "screenshot");
 
     // This mutex protects syncFd and captureResult for communication of the return values from the
     // main thread back to this Binder thread
@@ -5312,8 +5320,7 @@
     const auto sourceCrop = renderArea.getSourceCrop();
     const auto rotation = renderArea.getRotationFlags();
 
-    // assume ColorMode::SRGB / RenderIntent::COLORIMETRIC
-    engine.setOutputDataSpace(Dataspace::SRGB);
+    engine.setOutputDataSpace(renderArea.getReqDataSpace());
     engine.setDisplayMaxLuminance(DisplayDevice::sDefaultMaxLumiance);
 
     // make sure to clear all GL error flags
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 658f04e..8045246 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -433,10 +433,14 @@
     virtual sp<IDisplayEventConnection> createDisplayEventConnection(
             ISurfaceComposer::VsyncSource vsyncSource = eVsyncSourceApp);
     virtual status_t captureScreen(const sp<IBinder>& displayToken, sp<GraphicBuffer>* outBuffer,
-                                   Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
-                                   bool useIdentityTransform, ISurfaceComposer::Rotation rotation);
+                                   const ui::Dataspace reqDataspace,
+                                   const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
+                                   uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform,
+                                   ISurfaceComposer::Rotation rotation);
     virtual status_t captureLayers(const sp<IBinder>& parentHandle, sp<GraphicBuffer>* outBuffer,
-                                   const Rect& sourceCrop, float frameScale, bool childrenOnly);
+                                   const ui::Dataspace reqDataspace,
+                                   const ui::PixelFormat reqPixelFormat, const Rect& sourceCrop,
+                                   float frameScale, bool childrenOnly);
     virtual status_t getDisplayStats(const sp<IBinder>& displayToken, DisplayStatInfo* stats);
     virtual status_t getDisplayConfigs(const sp<IBinder>& displayToken,
                                        Vector<DisplayInfo>* configs);
@@ -586,7 +590,7 @@
     void renderScreenImplLocked(const RenderArea& renderArea, TraverseLayersFunction traverseLayers,
                                 bool useIdentityTransform);
     status_t captureScreenCommon(RenderArea& renderArea, TraverseLayersFunction traverseLayers,
-                                 sp<GraphicBuffer>* outBuffer,
+                                 sp<GraphicBuffer>* outBuffer, const ui::PixelFormat reqPixelFormat,
                                  bool useIdentityTransform);
     status_t captureScreenImplLocked(const RenderArea& renderArea,
                                      TraverseLayersFunction traverseLayers,
diff --git a/services/surfaceflinger/tests/Credentials_test.cpp b/services/surfaceflinger/tests/Credentials_test.cpp
index 9e762f0..a73ec6c 100644
--- a/services/surfaceflinger/tests/Credentials_test.cpp
+++ b/services/surfaceflinger/tests/Credentials_test.cpp
@@ -267,8 +267,9 @@
     sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain));
     std::function<status_t()> condition = [=]() {
         sp<GraphicBuffer> outBuffer;
-        return ScreenshotClient::capture(display, Rect(), 0 /*reqWidth*/, 0 /*reqHeight*/, false,
-                                         ROTATION, &outBuffer);
+        return ScreenshotClient::capture(display, ui::Dataspace::V0_SRGB,
+                                         ui::PixelFormat::RGBA_8888, Rect(), 0 /*reqWidth*/,
+                                         0 /*reqHeight*/, false, ROTATION, &outBuffer);
     };
     ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
 }
@@ -278,8 +279,9 @@
     sp<GraphicBuffer> outBuffer;
     std::function<status_t()> condition = [=]() {
         sp<GraphicBuffer> outBuffer;
-        return ScreenshotClient::captureLayers(mBGSurfaceControl->getHandle(), Rect(), FRAME_SCALE,
-                                               &outBuffer);
+        return ScreenshotClient::captureLayers(mBGSurfaceControl->getHandle(),
+                                               ui::Dataspace::V0_SRGB, ui::PixelFormat::RGBA_8888,
+                                               Rect(), FRAME_SCALE, &outBuffer);
     };
     ASSERT_NO_FATAL_FAILURE(checkWithPrivileges<status_t>(condition, NO_ERROR, PERMISSION_DENIED));
 }
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 3719a3d..1352df5 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -190,7 +190,8 @@
     constexpr bool forSystem = true;
 
     DisplayRenderArea renderArea(mDisplay, sourceCrop, DEFAULT_DISPLAY_WIDTH,
-                                 DEFAULT_DISPLAY_HEIGHT, ui::Transform::ROT_0);
+                                 DEFAULT_DISPLAY_HEIGHT, ui::Dataspace::V0_SRGB,
+                                 ui::Transform::ROT_0);
 
     auto traverseLayers = [this](const LayerVector::Visitor& visitor) {
         return mFlinger.traverseLayersInDisplay(mDisplay, visitor);
@@ -288,7 +289,7 @@
         EXPECT_CALL(*test->mRenderEngine, flush()).WillOnce(Return(ByMove(base::unique_fd())));
         EXPECT_CALL(*test->mRenderEngine, finish()).WillOnce(Return(true));
 
-        EXPECT_CALL(*test->mRenderEngine, setOutputDataSpace(ui::Dataspace::SRGB)).Times(1);
+        EXPECT_CALL(*test->mRenderEngine, setOutputDataSpace(_)).Times(1);
         EXPECT_CALL(*test->mRenderEngine, setDisplayMaxLuminance(DEFAULT_DISPLAY_MAX_LUMINANCE))
                 .Times(1);
         // This expectation retires on saturation as setViewportAndProjection is
diff --git a/services/vr/bufferhubd/IBufferHub.cpp b/services/vr/bufferhubd/IBufferHub.cpp
index 9d5b91a..2f39e41 100644
--- a/services/vr/bufferhubd/IBufferHub.cpp
+++ b/services/vr/bufferhubd/IBufferHub.cpp
@@ -4,14 +4,69 @@
 namespace android {
 namespace dvr {
 
+class BpBufferHub : public BpInterface<IBufferHub> {
+ public:
+  explicit BpBufferHub(const sp<IBinder>& impl)
+      : BpInterface<IBufferHub>(impl) {}
+
+  sp<IBufferClient> createBuffer(uint32_t width, uint32_t height,
+                                 uint32_t layer_count, uint32_t format,
+                                 uint64_t usage,
+                                 uint64_t user_metadata_size) override;
+};
+
 IMPLEMENT_META_INTERFACE(BufferHub, "android.dvr.IBufferHub");
 
+// Transaction code
+enum {
+  CREATE_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
+};
+
+sp<IBufferClient> BpBufferHub::createBuffer(uint32_t width, uint32_t height,
+                                            uint32_t layer_count,
+                                            uint32_t format, uint64_t usage,
+                                            uint64_t user_metadata_size) {
+  Parcel data, reply;
+  status_t ret = NO_ERROR;
+  ret |= data.writeInterfaceToken(IBufferHub::getInterfaceDescriptor());
+  ret |= data.writeUint32(width);
+  ret |= data.writeUint32(height);
+  ret |= data.writeUint32(layer_count);
+  ret |= data.writeUint32(format);
+  ret |= data.writeUint64(usage);
+  ret |= data.writeUint64(user_metadata_size);
+
+  if (ret != NO_ERROR) {
+    ALOGE("BpBufferHub::createBuffer: failed to write into parcel");
+    return nullptr;
+  }
+
+  ret = remote()->transact(CREATE_BUFFER, data, &reply);
+  if (ret == NO_ERROR) {
+    return interface_cast<IBufferClient>(reply.readStrongBinder());
+  } else {
+    ALOGE("BpBufferHub::createBuffer: failed to transact; errno=%d", ret);
+    return nullptr;
+  }
+}
+
 status_t BnBufferHub::onTransact(uint32_t code, const Parcel& data,
                                  Parcel* reply, uint32_t flags) {
   switch (code) {
+    case CREATE_BUFFER: {
+      CHECK_INTERFACE(IBufferHub, data, reply);
+      uint32_t width = data.readUint32();
+      uint32_t height = data.readUint32();
+      uint32_t layer_count = data.readUint32();
+      uint32_t format = data.readUint32();
+      uint64_t usage = data.readUint64();
+      uint64_t user_metadata_size = data.readUint64();
+      sp<IBufferClient> ret = createBuffer(width, height, layer_count, format,
+                                           usage, user_metadata_size);
+      return reply->writeStrongBinder(IInterface::asBinder(ret));
+    } break;
     default:
-      // Should not reach
-      ALOGE("onTransact(): unknown code %u received!", code);
+      // Should not reach except binder defined transactions such as dumpsys
       return BBinder::onTransact(code, data, reply, flags);
   }
 }
diff --git a/services/vr/bufferhubd/buffer_hub_binder.cpp b/services/vr/bufferhubd/buffer_hub_binder.cpp
index de82c09..f8a9758 100644
--- a/services/vr/bufferhubd/buffer_hub_binder.cpp
+++ b/services/vr/bufferhubd/buffer_hub_binder.cpp
@@ -5,6 +5,7 @@
 #include <binder/ProcessState.h>
 #include <log/log.h>
 #include <private/dvr/buffer_hub_binder.h>
+#include <private/dvr/buffer_node.h>
 
 namespace android {
 namespace dvr {
@@ -45,8 +46,14 @@
             "Input arguments are ignored.\n");
   }
 
-  // TODO(b/116526156): output real data in this class once we have it
+  fprintf(out, "Binder service:\n");
+  // Active buffers
+  fprintf(out, "Active BufferClients: %zu\n", client_list_.size());
+  // TODO(b/117790952): print buffer information after BufferNode has it
+  // TODO(b/116526156): print more information once we have them
+
   if (pdx_service_) {
+    fprintf(out, "\nPDX service:\n");
     // BufferHubService::Dumpstate(size_t) is not actually using the param
     // So just using 0 as the length
     fprintf(out, "%s", pdx_service_->DumpState(0).c_str());
@@ -58,23 +65,17 @@
   return NO_ERROR;
 }
 
-sp<IBufferHub> BufferHubBinderService::getServiceProxy() {
-  sp<IServiceManager> sm = defaultServiceManager();
-  sp<IBinder> service = sm->checkService(String16(getServiceName()));
+sp<IBufferClient> BufferHubBinderService::createBuffer(
+    uint32_t width, uint32_t height, uint32_t layer_count, uint32_t format,
+    uint64_t usage, uint64_t user_metadata_size) {
+  std::shared_ptr<BufferNode> node = std::make_shared<BufferNode>(
+      width, height, layer_count, format, usage, user_metadata_size);
 
-  if (service == nullptr) {
-    ALOGE("getServiceProxy(): %s binder service not found!", getServiceName());
-    return nullptr;
-  }
+  sp<BufferClient> client = new BufferClient(node);
+  // Add it to list for bookkeeping and dumpsys.
+  client_list_.push_back(client);
 
-  sp<IBufferHub> ret = interface_cast<IBufferHub>(service);
-  if (ret == nullptr) {
-    ALOGE("getServiceProxy(): %s binder service type casting error!",
-          getServiceName());
-    return nullptr;
-  }
-
-  return ret;
+  return client;
 }
 
 }  // namespace dvr
diff --git a/services/vr/bufferhubd/include/private/dvr/IBufferHub.h b/services/vr/bufferhubd/include/private/dvr/IBufferHub.h
index 266ae88..bd5f9cf 100644
--- a/services/vr/bufferhubd/include/private/dvr/IBufferHub.h
+++ b/services/vr/bufferhubd/include/private/dvr/IBufferHub.h
@@ -3,6 +3,7 @@
 
 #include <binder/IInterface.h>
 #include <binder/Parcel.h>
+#include <private/dvr/IBufferClient.h>
 
 namespace android {
 namespace dvr {
@@ -10,6 +11,12 @@
 class IBufferHub : public IInterface {
  public:
   DECLARE_META_INTERFACE(BufferHub);
+
+  static const char* getServiceName() { return "bufferhubd"; }
+  virtual sp<IBufferClient> createBuffer(uint32_t width, uint32_t height,
+                                         uint32_t layer_count, uint32_t format,
+                                         uint64_t usage,
+                                         uint64_t user_metadata_size) = 0;
 };
 
 class BnBufferHub : public BnInterface<IBufferHub> {
@@ -18,13 +25,7 @@
                               uint32_t flags = 0);
 };
 
-class BpBufferHub : public BpInterface<IBufferHub> {
- public:
-  explicit BpBufferHub(const sp<IBinder>& impl)
-      : BpInterface<IBufferHub>(impl) {}
-};
-
 }  // namespace dvr
 }  // namespace android
 
-#endif
\ No newline at end of file
+#endif  // ANDROID_DVR_IBUFFERHUB_H
\ No newline at end of file
diff --git a/services/vr/bufferhubd/include/private/dvr/buffer_client.h b/services/vr/bufferhubd/include/private/dvr/buffer_client.h
new file mode 100644
index 0000000..20d51ee
--- /dev/null
+++ b/services/vr/bufferhubd/include/private/dvr/buffer_client.h
@@ -0,0 +1,29 @@
+#ifndef ANDROID_DVR_BUFFERCLIENT_H
+#define ANDROID_DVR_BUFFERCLIENT_H
+
+#include <private/dvr/IBufferClient.h>
+#include <private/dvr/buffer_node.h>
+
+namespace android {
+namespace dvr {
+
+class BufferClient : public BnBufferClient {
+ public:
+  // Creates a server-side buffer client from an existing BufferNode. Note that
+  // this funciton takes ownership of the shared_ptr.
+  explicit BufferClient(std::shared_ptr<BufferNode> node)
+      : buffer_node_(std::move(node)){};
+
+  // Binder IPC functions
+  bool isValid() override {
+    return buffer_node_ ? buffer_node_->IsValid() : false;
+  };
+
+ private:
+  std::shared_ptr<BufferNode> buffer_node_;
+};
+
+}  // namespace dvr
+}  // namespace android
+
+#endif  // ANDROID_DVR_IBUFFERCLIENT_H
\ No newline at end of file
diff --git a/services/vr/bufferhubd/include/private/dvr/buffer_hub_binder.h b/services/vr/bufferhubd/include/private/dvr/buffer_hub_binder.h
index e266ff8..9064d87 100644
--- a/services/vr/bufferhubd/include/private/dvr/buffer_hub_binder.h
+++ b/services/vr/bufferhubd/include/private/dvr/buffer_hub_binder.h
@@ -1,8 +1,11 @@
 #ifndef ANDROID_DVR_BUFFER_HUB_BINDER_H
 #define ANDROID_DVR_BUFFER_HUB_BINDER_H
 
+#include <vector>
+
 #include <binder/BinderService.h>
 #include <private/dvr/IBufferHub.h>
+#include <private/dvr/buffer_client.h>
 #include <private/dvr/buffer_hub.h>
 
 namespace android {
@@ -12,16 +15,20 @@
                                public BnBufferHub {
  public:
   static status_t start(const std::shared_ptr<BufferHubService>& pdx_service);
-  static const char* getServiceName() { return "bufferhubd"; }
   // Dump bufferhub related information to given fd (usually stdout)
   // usage: adb shell dumpsys bufferhubd
   virtual status_t dump(int fd, const Vector<String16>& args) override;
 
-  // Helper function to get the BpReference to this service
-  static sp<IBufferHub> getServiceProxy();
+  // Binder IPC functions
+  sp<IBufferClient> createBuffer(uint32_t width, uint32_t height,
+                                 uint32_t layer_count, uint32_t format,
+                                 uint64_t usage,
+                                 uint64_t user_metadata_size) override;
 
  private:
   std::shared_ptr<BufferHubService> pdx_service_;
+
+  std::vector<sp<BufferClient>> client_list_;
 };
 
 }  // namespace dvr
diff --git a/services/vr/bufferhubd/tests/buffer_hub_binder_service-test.cpp b/services/vr/bufferhubd/tests/buffer_hub_binder_service-test.cpp
index 587e6db..7fa2226 100644
--- a/services/vr/bufferhubd/tests/buffer_hub_binder_service-test.cpp
+++ b/services/vr/bufferhubd/tests/buffer_hub_binder_service-test.cpp
@@ -1,23 +1,41 @@
+#include <binder/IServiceManager.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
-#include <private/dvr/buffer_hub_binder.h>
+#include <private/dvr/IBufferClient.h>
+#include <private/dvr/IBufferHub.h>
+#include <ui/PixelFormat.h>
 
 namespace android {
 namespace dvr {
 
 namespace {
 
-using testing::Ne;
+using testing::NotNull;
+
+const int kWidth = 640;
+const int kHeight = 480;
+const int kLayerCount = 1;
+const int kFormat = HAL_PIXEL_FORMAT_RGBA_8888;
+const int kUsage = 0;
+const size_t kUserMetadataSize = 0;
 
 class BufferHubBinderServiceTest : public ::testing::Test {
-  // Add setup and teardown if necessary
+ protected:
+  void SetUp() override {
+    status_t ret = getService<IBufferHub>(
+        String16(IBufferHub::getServiceName()), &service);
+    ASSERT_EQ(ret, OK);
+    ASSERT_THAT(service, NotNull());
+  }
+
+  sp<IBufferHub> service;
 };
 
-TEST_F(BufferHubBinderServiceTest, TestInitialize) {
-  // Create a new service will kill the current one.
-  // So just check if Binder service is running
-  sp<IBufferHub> service = BufferHubBinderService::getServiceProxy();
-  EXPECT_THAT(service, Ne(nullptr));
+TEST_F(BufferHubBinderServiceTest, TestCreateBuffer) {
+  sp<IBufferClient> bufferClient = service->createBuffer(
+      kWidth, kHeight, kLayerCount, kFormat, kUsage, kUserMetadataSize);
+  ASSERT_THAT(bufferClient, NotNull());
+  EXPECT_TRUE(bufferClient->isValid());
 }
 
 }  // namespace