VR: Update VR HWC to use buffer metadata passed by SurfaceFlinger

Without gralloc1 support, need to pass buffer metadata in order to
import native buffers and used them as graphic buffers.

Bug: 36481301
Test: Compiled and ran on device; Verified VR Window Manager properly
displays SurfaceFlinger buffers.

Change-Id: I8426be1d79dcc2fbd631c399427ae03cb2afc21d
diff --git a/libs/vr/libvrflinger/Android.bp b/libs/vr/libvrflinger/Android.bp
index 0daab64..632978b 100644
--- a/libs/vr/libvrflinger/Android.bp
+++ b/libs/vr/libvrflinger/Android.bp
@@ -47,6 +47,7 @@
 ]
 
 sharedLibraries = [
+    "android.frameworks.vr.composer@1.0",
     "android.hardware.graphics.allocator@2.0",
     "android.hardware.graphics.composer@2.1",
     "libbinder",
@@ -75,7 +76,7 @@
     cflags: [
         "-DLOG_TAG=\"vr_flinger\"",
         "-DTRACE=0",
-	"-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
+        "-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
         "-DGL_GLEXT_PROTOTYPES",
         "-DEGL_EGLEXT_PROTOTYPES",
     ],
diff --git a/libs/vr/libvrflinger/hardware_composer.cpp b/libs/vr/libvrflinger/hardware_composer.cpp
index 542bbd9..6602d78 100644
--- a/libs/vr/libvrflinger/hardware_composer.cpp
+++ b/libs/vr/libvrflinger/hardware_composer.cpp
@@ -1416,7 +1416,7 @@
 
 void Layer::Prepare() {
   int right, bottom;
-  buffer_handle_t handle;
+  sp<GraphicBuffer> handle;
 
   if (surface_) {
     // Only update the acquired buffer when one is either available or this is
@@ -1465,14 +1465,14 @@
     }
     right = acquired_buffer_.buffer()->width();
     bottom = acquired_buffer_.buffer()->height();
-    handle = acquired_buffer_.buffer()->native_handle();
+    handle = acquired_buffer_.buffer()->buffer()->buffer();
     acquire_fence_fd_.Reset(acquired_buffer_.ClaimAcquireFence().Release());
   } else {
     // TODO(jwcai) Note: this is the GPU compositor's layer, and we need the
     // mechanism to accept distorted layers from VrCore.
     right = direct_buffer_->width();
     bottom = direct_buffer_->height();
-    handle = direct_buffer_->handle();
+    handle = direct_buffer_->buffer();
     acquire_fence_fd_.Close();
   }
 
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
index 33aa759..262ab62 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
@@ -17,7 +17,6 @@
 #undef LOG_TAG
 #define LOG_TAG "HwcComposer"
 
-#include <android/frameworks/vr/composer/1.0/IVrComposerClient.h>
 #include <inttypes.h>
 #include <log/log.h>
 #include <gui/BufferQueue.h>
@@ -26,7 +25,6 @@
 
 namespace android {
 
-using frameworks::vr::composer::V1_0::IVrComposerClient;
 using hardware::Return;
 using hardware::hidl_vec;
 using hardware::hidl_handle;
@@ -124,6 +122,41 @@
     endCommand();
 }
 
+void Composer::CommandWriter::setClientTargetMetadata(
+        const IVrComposerClient::BufferMetadata& metadata)
+{
+    constexpr uint16_t kSetClientTargetMetadataLength = 7;
+    beginCommand(
+        static_cast<IComposerClient::Command>(
+            IVrComposerClient::VrCommand::SET_CLIENT_TARGET_METADATA),
+        kSetClientTargetMetadataLength);
+    writeBufferMetadata(metadata);
+    endCommand();
+}
+
+void Composer::CommandWriter::setLayerBufferMetadata(
+        const IVrComposerClient::BufferMetadata& metadata)
+{
+    constexpr uint16_t kSetLayerBufferMetadataLength = 7;
+    beginCommand(
+        static_cast<IComposerClient::Command>(
+            IVrComposerClient::VrCommand::SET_LAYER_BUFFER_METADATA),
+        kSetLayerBufferMetadataLength);
+    writeBufferMetadata(metadata);
+    endCommand();
+}
+
+void Composer::CommandWriter::writeBufferMetadata(
+        const IVrComposerClient::BufferMetadata& metadata)
+{
+    write(metadata.width);
+    write(metadata.height);
+    write(metadata.stride);
+    write(metadata.layerCount);
+    writeSigned(static_cast<int32_t>(metadata.format));
+    write64(metadata.usage);
+}
+
 Composer::Composer(bool useVrComposer)
     : mWriter(kWriterInitialSize),
       mIsUsingVrComposer(useVrComposer)
@@ -426,12 +459,29 @@
 }
 
 Error Composer::setClientTarget(Display display, uint32_t slot,
-        const native_handle_t* target,
+        const sp<GraphicBuffer>& target,
         int acquireFence, Dataspace dataspace,
         const std::vector<IComposerClient::Rect>& damage)
 {
     mWriter.selectDisplay(display);
-    mWriter.setClientTarget(slot, target, acquireFence, dataspace, damage);
+    if (mIsUsingVrComposer && target.get()) {
+        IVrComposerClient::BufferMetadata metadata = {
+            .width = target->getWidth(),
+            .height = target->getHeight(),
+            .stride = target->getStride(),
+            .layerCount = target->getLayerCount(),
+            .format = static_cast<PixelFormat>(target->getPixelFormat()),
+            .usage = target->getUsage(),
+        };
+        mWriter.setClientTargetMetadata(metadata);
+    }
+
+    const native_handle_t* handle = nullptr;
+    if (target.get()) {
+        handle = target->getNativeBuffer()->handle;
+    }
+
+    mWriter.setClientTarget(slot, handle, acquireFence, dataspace, damage);
     return Error::NONE;
 }
 
@@ -502,11 +552,28 @@
 }
 
 Error Composer::setLayerBuffer(Display display, Layer layer,
-        uint32_t slot, const native_handle_t* buffer, int acquireFence)
+        uint32_t slot, const sp<GraphicBuffer>& buffer, int acquireFence)
 {
     mWriter.selectDisplay(display);
     mWriter.selectLayer(layer);
-    mWriter.setLayerBuffer(slot, buffer, acquireFence);
+    if (mIsUsingVrComposer && buffer.get()) {
+        IVrComposerClient::BufferMetadata metadata = {
+            .width = buffer->getWidth(),
+            .height = buffer->getHeight(),
+            .stride = buffer->getStride(),
+            .layerCount = buffer->getLayerCount(),
+            .format = static_cast<PixelFormat>(buffer->getPixelFormat()),
+            .usage = buffer->getUsage(),
+        };
+        mWriter.setLayerBufferMetadata(metadata);
+    }
+
+    const native_handle_t* handle = nullptr;
+    if (buffer.get()) {
+        handle = buffer->getNativeBuffer()->handle;
+    }
+
+    mWriter.setLayerBuffer(slot, handle, acquireFence);
     return Error::NONE;
 }
 
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h
index 18af9dd..37b7766 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h
@@ -23,6 +23,7 @@
 #include <utility>
 #include <vector>
 
+#include <android/frameworks/vr/composer/1.0/IVrComposerClient.h>
 #include <android/hardware/graphics/composer/2.1/IComposer.h>
 #include <utils/StrongPointer.h>
 #include <IComposerCommandBuffer.h>
@@ -31,6 +32,8 @@
 
 namespace Hwc2 {
 
+using android::frameworks::vr::composer::V1_0::IVrComposerClient;
+
 using android::hardware::graphics::common::V1_0::ColorMode;
 using android::hardware::graphics::common::V1_0::ColorTransform;
 using android::hardware::graphics::common::V1_0::Dataspace;
@@ -179,7 +182,7 @@
      * When target is not nullptr, the cache is updated with the new target.
      */
     Error setClientTarget(Display display, uint32_t slot,
-            const native_handle_t* target,
+            const sp<GraphicBuffer>& target,
             int acquireFence, Dataspace dataspace,
             const std::vector<IComposerClient::Rect>& damage);
     Error setColorMode(Display display, ColorMode mode);
@@ -199,7 +202,7 @@
             int32_t x, int32_t y);
     /* see setClientTarget for the purpose of slot */
     Error setLayerBuffer(Display display, Layer layer, uint32_t slot,
-            const native_handle_t* buffer, int acquireFence);
+            const sp<GraphicBuffer>& buffer, int acquireFence);
     Error setLayerSurfaceDamage(Display display, Layer layer,
             const std::vector<IComposerClient::Rect>& damage);
     Error setLayerBlendMode(Display display, Layer layer,
@@ -232,6 +235,14 @@
         ~CommandWriter() override;
 
         void setLayerInfo(uint32_t type, uint32_t appId);
+        void setClientTargetMetadata(
+                const IVrComposerClient::BufferMetadata& metadata);
+        void setLayerBufferMetadata(
+                const IVrComposerClient::BufferMetadata& metadata);
+
+    private:
+        void writeBufferMetadata(
+                const IVrComposerClient::BufferMetadata& metadata);
     };
 
     // Many public functions above simply write a command into the command
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index e49e734..250631f 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -961,14 +961,19 @@
     return static_cast<Error>(intError);
 }
 
-Error Display::setClientTarget(uint32_t slot, buffer_handle_t target,
+Error Display::setClientTarget(uint32_t slot, const sp<GraphicBuffer>& target,
         const sp<Fence>& acquireFence, android_dataspace_t dataspace)
 {
     // TODO: Properly encode client target surface damage
     int32_t fenceFd = acquireFence->dup();
 #ifdef BYPASS_IHWC
     (void) slot;
-    int32_t intError = mDevice.mSetClientTarget(mDevice.mHwcDevice, mId, target,
+    buffer_handle_t handle = nullptr;
+    if (target.get() && target->getNativeBuffer()) {
+        handle = target->getNativeBuffer()->handle;
+    }
+
+    int32_t intError = mDevice.mSetClientTarget(mDevice.mHwcDevice, mId, handle,
             fenceFd, static_cast<int32_t>(dataspace), {0, nullptr});
 #else
     auto intError = mDevice.mComposer->setClientTarget(mId, slot, target,
@@ -1195,14 +1200,19 @@
     return static_cast<Error>(intError);
 }
 
-Error Layer::setBuffer(uint32_t slot, buffer_handle_t buffer,
+Error Layer::setBuffer(uint32_t slot, const sp<GraphicBuffer>& buffer,
         const sp<Fence>& acquireFence)
 {
     int32_t fenceFd = acquireFence->dup();
 #ifdef BYPASS_IHWC
     (void) slot;
+    buffer_handle_t handle = nullptr;
+    if (buffer.get() && buffer->getNativeBuffer()) {
+        handle = buffer->getNativeBuffer()->handle;
+    }
+
     int32_t intError = mDevice.mSetLayerBuffer(mDevice.mHwcDevice, mDisplayId,
-            mId, buffer, fenceFd);
+            mId, handle, fenceFd);
 #else
     auto intError = mDevice.mComposer->setLayerBuffer(mDisplayId,
             mId, slot, buffer, fenceFd);
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index 4419dc1..da6c06f 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -329,7 +329,7 @@
     [[clang::warn_unused_result]] Error setActiveConfig(
             const std::shared_ptr<const Config>& config);
     [[clang::warn_unused_result]] Error setClientTarget(
-            uint32_t slot, buffer_handle_t target,
+            uint32_t slot, const android::sp<android::GraphicBuffer>& target,
             const android::sp<android::Fence>& acquireFence,
             android_dataspace_t dataspace);
     [[clang::warn_unused_result]] Error setColorMode(android_color_mode_t mode);
@@ -392,7 +392,7 @@
 
     [[clang::warn_unused_result]] Error setCursorPosition(int32_t x, int32_t y);
     [[clang::warn_unused_result]] Error setBuffer(uint32_t slot,
-            buffer_handle_t buffer,
+            const android::sp<android::GraphicBuffer>& buffer,
             const android::sp<android::Fence>& acquireFence);
     [[clang::warn_unused_result]] Error setSurfaceDamage(
             const android::Region& damage);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 09434f6..7314127 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -465,12 +465,7 @@
 
     ALOGV("setClientTarget for display %d", displayId);
     auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
-    buffer_handle_t handle = nullptr;
-    if ((target != nullptr) && target->getNativeBuffer()) {
-        handle = target->getNativeBuffer()->handle;
-    }
-    auto error = hwcDisplay->setClientTarget(slot, handle,
-            acquireFence, dataspace);
+    auto error = hwcDisplay->setClientTarget(slot, target, acquireFence, dataspace);
     if (error != HWC2::Error::None) {
         ALOGE("Failed to set client target for display %d: %s (%d)", displayId,
                 to_string(error).c_str(), static_cast<int32_t>(error));
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index c211c7b..598a65a 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -852,18 +852,12 @@
     }
 
     uint32_t hwcSlot = 0;
-    buffer_handle_t hwcHandle = nullptr;
-    {
-        sp<GraphicBuffer> hwcBuffer;
-        hwcInfo.bufferCache.getHwcBuffer(mActiveBufferSlot, mActiveBuffer,
-                &hwcSlot, &hwcBuffer);
-        if (hwcBuffer != nullptr) {
-            hwcHandle = hwcBuffer->handle;
-        }
-    }
+    sp<GraphicBuffer> hwcBuffer;
+    hwcInfo.bufferCache.getHwcBuffer(mActiveBufferSlot, mActiveBuffer,
+            &hwcSlot, &hwcBuffer);
 
     auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence();
-    error = hwcLayer->setBuffer(hwcSlot, hwcHandle, acquireFence);
+    error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence);
     if (error != HWC2::Error::None) {
         ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
                 mActiveBuffer->handle, to_string(error).c_str(),
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 6e4daa0..15f63fa 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
@@ -7,15 +7,6 @@
 
 namespace android {
 namespace dvr {
-namespace {
-
-sp<GraphicBuffer> GetBufferFromHandle(native_handle_t* handle) {
-  // Querying properties from |handle| is never properly supported.
-  ALOGE("Failed to read handle %p properties", handle);
-  return nullptr;
-}
-
-}  // namespace
 
 ParcelableComposerLayer::ParcelableComposerLayer() {}
 
@@ -28,7 +19,7 @@
   status_t ret = parcel->writeUint64(layer_.id);
   if (ret != OK) return ret;
 
-  ret = parcel->writeNativeHandle(layer_.buffer->getNativeBuffer()->handle);
+  ret = parcel->write(*layer_.buffer);
   if (ret != OK) return ret;
 
   ret = parcel->writeBool(layer_.fence->isValid());
@@ -82,11 +73,12 @@
   status_t ret = parcel->readUint64(&layer_.id);
   if (ret != OK) return ret;
 
-  native_handle* handle = parcel->readNativeHandle();
-  if (!handle) return BAD_VALUE;
-
-  layer_.buffer = GetBufferFromHandle(handle);
-  if (!layer_.buffer.get()) return BAD_VALUE;
+  layer_.buffer = new GraphicBuffer();
+  ret = parcel->read(*layer_.buffer);
+  if (ret != OK) {
+    layer_.buffer.clear();
+    return ret;
+  }
 
   bool has_fence = 0;
   ret = parcel->readBool(&has_fence);
diff --git a/services/vr/vr_window_manager/composer/Android.bp b/services/vr/vr_window_manager/composer/Android.bp
index 007251f..f01bb28 100644
--- a/services/vr/vr_window_manager/composer/Android.bp
+++ b/services/vr/vr_window_manager/composer/Android.bp
@@ -35,6 +35,7 @@
   ],
 
   export_shared_lib_headers: [
+    "android.frameworks.vr.composer@1.0",
     "android.hardware.graphics.composer@2.1",
   ],
 
diff --git a/services/vr/vr_window_manager/composer/impl/vr_composer_client.cpp b/services/vr/vr_window_manager/composer/impl/vr_composer_client.cpp
index acf0dac..e0bdf1c 100644
--- a/services/vr/vr_window_manager/composer/impl/vr_composer_client.cpp
+++ b/services/vr/vr_window_manager/composer/impl/vr_composer_client.cpp
@@ -50,6 +50,10 @@
   switch (vrCommand) {
     case IVrComposerClient::VrCommand::SET_LAYER_INFO:
       return parseSetLayerInfo(length);
+    case IVrComposerClient::VrCommand::SET_CLIENT_TARGET_METADATA:
+      return parseSetClientTargetMetadata(length);
+    case IVrComposerClient::VrCommand::SET_LAYER_BUFFER_METADATA:
+      return parseSetLayerBufferMetadata(length);
     default:
       return CommandReader::parseCommand(command, length);
   }
@@ -68,5 +72,43 @@
   return true;
 }
 
+bool VrComposerClient::VrCommandReader::parseSetClientTargetMetadata(
+    uint16_t length) {
+  if (length != 7)
+    return false;
+
+  auto err = mVrHal.setClientTargetMetadata(mDisplay, readBufferMetadata());
+  if (err != Error::NONE)
+    mWriter.setError(getCommandLoc(), err);
+
+  return true;
+}
+
+bool VrComposerClient::VrCommandReader::parseSetLayerBufferMetadata(
+    uint16_t length) {
+  if (length != 7)
+    return false;
+
+  auto err = mVrHal.setLayerBufferMetadata(mDisplay, mLayer,
+                                           readBufferMetadata());
+  if (err != Error::NONE)
+    mWriter.setError(getCommandLoc(), err);
+
+  return true;
+}
+
+IVrComposerClient::BufferMetadata
+VrComposerClient::VrCommandReader::readBufferMetadata() {
+  IVrComposerClient::BufferMetadata metadata = {
+    .width = read(),
+    .height = read(),
+    .stride = read(),
+    .layerCount = read(),
+    .format = static_cast<PixelFormat>(readSigned()),
+    .usage = read64(),
+  };
+  return metadata;
+}
+
 }  // namespace dvr
 }  // namespace android
diff --git a/services/vr/vr_window_manager/composer/impl/vr_composer_client.h b/services/vr/vr_window_manager/composer/impl/vr_composer_client.h
index 8f0c562..8d601ab 100644
--- a/services/vr/vr_window_manager/composer/impl/vr_composer_client.h
+++ b/services/vr/vr_window_manager/composer/impl/vr_composer_client.h
@@ -17,6 +17,7 @@
 #ifndef VR_WINDOW_MANAGER_COMPOSER_IMPL_VR_COMPOSER_CLIENT_H_
 #define VR_WINDOW_MANAGER_COMPOSER_IMPL_VR_COMPOSER_CLIENT_H_
 
+#include <android/frameworks/vr/composer/1.0/IVrComposerClient.h>
 #include <ComposerClient.h>
 #include <IComposerCommandBuffer.h>
 
@@ -44,6 +45,10 @@
 
    private:
     bool parseSetLayerInfo(uint16_t length);
+    bool parseSetClientTargetMetadata(uint16_t length);
+    bool parseSetLayerBufferMetadata(uint16_t length);
+
+    IVrComposerClient::BufferMetadata readBufferMetadata();
 
     VrComposerClient& mVrClient;
     android::dvr::VrHwc& mVrHal;
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 c60a4f5..5efc482 100644
--- a/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp
+++ b/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp
@@ -16,8 +16,6 @@
 #include "vr_hwc.h"
 
 #include <ui/Fence.h>
-#include <ui/GraphicBuffer.h>
-#include <ui/GraphicBufferMapper.h>
 
 #include <mutex>
 
@@ -43,10 +41,19 @@
 const Display kDefaultDisplayId = 1;
 const Config kDefaultConfigId = 1;
 
-sp<GraphicBuffer> GetBufferFromHandle(const native_handle_t* handle) {
-  // Querying properties from |handle| is never properly supported.
-  ALOGE("Failed to read handle %p properties", handle);
-  return nullptr;
+sp<GraphicBuffer> CreateGraphicBuffer(
+    const native_handle_t* handle,
+    const IVrComposerClient::BufferMetadata& metadata) {
+   sp<GraphicBuffer> buffer = new GraphicBuffer(
+      handle, GraphicBuffer::CLONE_HANDLE, metadata.width, metadata.height,
+      static_cast<int32_t>(metadata.format), metadata.layerCount,
+      metadata.usage, metadata.usage, metadata.stride);
+   if (buffer->initCheck() != OK) {
+     ALOGE("Failed to create graphic buffer");
+     return nullptr;
+   }
+
+   return buffer;
 }
 
 void GetPrimaryDisplaySize(int32_t* width, int32_t* height) {
@@ -84,12 +91,17 @@
 bool HwcDisplay::SetClientTarget(const native_handle_t* handle,
                                  base::unique_fd fence) {
   if (handle)
-    buffer_ = GetBufferFromHandle(handle);
+    buffer_ = CreateGraphicBuffer(handle, buffer_metadata_);
 
   fence_ = new Fence(fence.release());
   return true;
 }
 
+void HwcDisplay::SetClientTargetMetadata(
+    const IVrComposerClient::BufferMetadata& metadata) {
+  buffer_metadata_ = metadata;
+}
+
 HwcLayer* HwcDisplay::CreateLayer() {
   uint64_t layer_id = layer_ids_++;
   layers_.push_back(HwcLayer(layer_id));
@@ -528,7 +540,8 @@
   if (!hwc_layer)
     return Error::BAD_LAYER;
 
-  hwc_layer->info.buffer = GetBufferFromHandle(buffer);
+  hwc_layer->info.buffer = CreateGraphicBuffer(
+      buffer, hwc_layer->buffer_metadata);
   hwc_layer->info.fence = new Fence(fence.release());
 
   return Error::NONE;
@@ -694,6 +707,35 @@
   return Error::NONE;
 }
 
+Error VrHwc::setClientTargetMetadata(
+    Display display, const IVrComposerClient::BufferMetadata& metadata) {
+  std::lock_guard<std::mutex> guard(mutex_);
+  auto display_ptr = FindDisplay(display);
+  if (!display_ptr)
+    return Error::BAD_DISPLAY;
+
+  display_ptr->SetClientTargetMetadata(metadata);
+
+  return Error::NONE;
+}
+
+Error VrHwc::setLayerBufferMetadata(
+    Display display, Layer layer,
+    const IVrComposerClient::BufferMetadata& metadata) {
+  std::lock_guard<std::mutex> guard(mutex_);
+  auto display_ptr = FindDisplay(display);
+  if (!display_ptr)
+    return Error::BAD_DISPLAY;
+
+  HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
+  if (!hwc_layer)
+    return Error::BAD_LAYER;
+
+  hwc_layer->buffer_metadata = metadata;
+
+  return Error::NONE;
+}
+
 Return<void> VrHwc::getCapabilities(getCapabilities_cb hidl_cb) {
   hidl_cb(hidl_vec<Capability>());
   return Void();
diff --git a/services/vr/vr_window_manager/composer/impl/vr_hwc.h b/services/vr/vr_window_manager/composer/impl/vr_hwc.h
index bfca9a6..3da2fb8 100644
--- a/services/vr/vr_window_manager/composer/impl/vr_hwc.h
+++ b/services/vr/vr_window_manager/composer/impl/vr_hwc.h
@@ -17,6 +17,7 @@
 #define VR_WINDOW_MANAGER_COMPOSER_IMPL_VR_HWC_H_
 
 #include <android-base/unique_fd.h>
+#include <android/frameworks/vr/composer/1.0/IVrComposerClient.h>
 #include <android/hardware/graphics/composer/2.1/IComposer.h>
 #include <ComposerBase.h>
 #include <ui/Fence.h>
@@ -26,6 +27,7 @@
 #include <mutex>
 #include <unordered_map>
 
+using namespace android::frameworks::vr::composer::V1_0;
 using namespace android::hardware::graphics::common::V1_0;
 using namespace android::hardware::graphics::composer::V2_1;
 
@@ -38,7 +40,6 @@
 namespace android {
 
 class Fence;
-class GraphicBuffer;
 
 namespace dvr {
 
@@ -105,6 +106,7 @@
   Composition composition_type;
   uint32_t z_order;
   ComposerView::ComposerLayer info;
+  IVrComposerClient::BufferMetadata buffer_metadata;
 };
 
 class HwcDisplay {
@@ -120,6 +122,8 @@
   HwcLayer* GetLayer(Layer id);
 
   bool SetClientTarget(const native_handle_t* handle, base::unique_fd fence);
+  void SetClientTargetMetadata(
+      const IVrComposerClient::BufferMetadata& metadata);
 
   void GetChangedCompositionTypes(
       std::vector<Layer>* layer_ids,
@@ -131,8 +135,8 @@
 
  private:
   // The client target buffer and the associated fence.
-  // TODO(dnicoara): Replace this with a list of ComposerView::ComposerLayer.
   sp<GraphicBuffer> buffer_;
+  IVrComposerClient::BufferMetadata buffer_metadata_;
   sp<Fence> fence_;
 
   // List of currently active layers.
@@ -159,6 +163,11 @@
 
   Error setLayerInfo(Display display, Layer layer, uint32_t type,
                      uint32_t appId);
+  Error setClientTargetMetadata(
+      Display display, const IVrComposerClient::BufferMetadata& metadata);
+  Error setLayerBufferMetadata(
+      Display display, Layer layer,
+      const IVrComposerClient::BufferMetadata& metadata);
 
   // ComposerBase
   void removeClient() override;