Merge "Convert the pose buffer into a more generic named buffer" into oc-dev
diff --git a/libs/ui/Gralloc1On0Adapter.cpp b/libs/ui/Gralloc1On0Adapter.cpp
index bd7c6a1..9ee9838 100644
--- a/libs/ui/Gralloc1On0Adapter.cpp
+++ b/libs/ui/Gralloc1On0Adapter.cpp
@@ -20,6 +20,9 @@
 
 #include <ui/Gralloc1On0Adapter.h>
 
+#include <algorithm>
+#include <array>
+
 #include <grallocusage/GrallocUsageConversion.h>
 
 #include <hardware/gralloc.h>
@@ -67,13 +70,18 @@
 void Gralloc1On0Adapter::doGetCapabilities(uint32_t* outCount,
         int32_t* outCapabilities)
 {
+    constexpr std::array<int32_t, 2> supportedCapabilities = {{
+        GRALLOC1_CAPABILITY_ON_ADAPTER,
+        GRALLOC1_CAPABILITY_RELEASE_IMPLY_DELETE,
+    }};
+
     if (outCapabilities == nullptr) {
-        *outCount = 1;
-        return;
-    }
-    if (*outCount >= 1) {
-        *outCapabilities = GRALLOC1_CAPABILITY_ON_ADAPTER;
-        *outCount = 1;
+        *outCount = supportedCapabilities.size();
+    } else {
+        *outCount = std::min(*outCount, static_cast<uint32_t>(
+                    supportedCapabilities.size()));
+        std::copy_n(supportedCapabilities.begin(),
+                *outCount, outCapabilities);
     }
 }
 
@@ -325,6 +333,9 @@
         if (result != 0) {
             ALOGE("gralloc0 unregister failed: %d", result);
         }
+
+        native_handle_close(handle);
+        native_handle_delete(const_cast<native_handle_t*>(handle));
     }
 
     mBuffers.erase(handle);
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
index 2f4d5fb..87519bf 100644
--- a/libs/ui/GraphicBufferMapper.cpp
+++ b/libs/ui/GraphicBufferMapper.cpp
@@ -122,8 +122,10 @@
         error = GRALLOC1_ERROR_NONE;
     } else {
         error = mDevice->release(handle);
-        native_handle_close(handle);
-        native_handle_delete(const_cast<native_handle_t*>(handle));
+        if (!mDevice->hasCapability(GRALLOC1_CAPABILITY_RELEASE_IMPLY_DELETE)) {
+            native_handle_close(handle);
+            native_handle_delete(const_cast<native_handle_t*>(handle));
+        }
     }
 
     ALOGW_IF(error != GRALLOC1_ERROR_NONE, "freeBuffer(%p): failed %d",
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/schedulerservice/SchedulingPolicyService.cpp b/services/schedulerservice/SchedulingPolicyService.cpp
index 522a8c0..a1106cf 100644
--- a/services/schedulerservice/SchedulingPolicyService.cpp
+++ b/services/schedulerservice/SchedulingPolicyService.cpp
@@ -29,23 +29,37 @@
 namespace V1_0 {
 namespace implementation {
 
-Return<bool> SchedulingPolicyService::requestPriority(int32_t pid, int32_t tid, int32_t priority) {
+bool SchedulingPolicyService::isAllowed() {
     using ::android::hardware::IPCThreadState;
 
+    return IPCThreadState::self()->getCallingUid() == AID_CAMERASERVER;
+}
+
+Return<bool> SchedulingPolicyService::requestPriority(int32_t pid, int32_t tid, int32_t priority) {
     if (priority < static_cast<int32_t>(Priority::MIN) ||
             priority > static_cast<int32_t>(Priority::MAX)) {
         return false;
     }
 
-    if (IPCThreadState::self()->getCallingUid() != AID_CAMERASERVER) {
+    if (!isAllowed()) {
         return false;
     }
 
+    // TODO(b/37226359): decouple from and remove AIDL service
     // this should always be allowed since we are in system_server.
     int value = ::android::requestPriority(pid, tid, priority, false /* isForApp */);
     return value == 0 /* success */;
 }
 
+Return<int32_t> SchedulingPolicyService::getMaxAllowedPriority() {
+    if (!isAllowed()) {
+        return 0;
+    }
+
+    // TODO(b/37226359): decouple from and remove AIDL service
+    return 3;
+}
+
 }  // namespace implementation
 }  // namespace V1_0
 }  // namespace schedulerservice
diff --git a/services/schedulerservice/include/schedulerservice/SchedulingPolicyService.h b/services/schedulerservice/include/schedulerservice/SchedulingPolicyService.h
index eb5a4ae..7d1c478 100644
--- a/services/schedulerservice/include/schedulerservice/SchedulingPolicyService.h
+++ b/services/schedulerservice/include/schedulerservice/SchedulingPolicyService.h
@@ -38,6 +38,9 @@
 
 struct SchedulingPolicyService : public ISchedulingPolicyService {
     Return<bool> requestPriority(int32_t pid, int32_t tid, int32_t priority) override;
+    Return<int32_t> getMaxAllowedPriority() override;
+private:
+    bool isAllowed();
 };
 
 }  // namespace implementation
diff --git a/services/sensorservice/hidl/DirectReportChannel.cpp b/services/sensorservice/hidl/DirectReportChannel.cpp
index 773ce8c..adc4675 100644
--- a/services/sensorservice/hidl/DirectReportChannel.cpp
+++ b/services/sensorservice/hidl/DirectReportChannel.cpp
@@ -31,10 +31,13 @@
 }
 
 // Methods from ::android::frameworks::sensorservice::V1_0::IDirectReportChannel follow.
-Return<Result> DirectReportChannel::configure(int32_t sensorHandle, RateLevel rate) {
+Return<void> DirectReportChannel::configure(int32_t sensorHandle, RateLevel rate,
+        configure_cb _hidl_cb) {
     int token = mManager.configureDirectChannel(mId,
             static_cast<int>(sensorHandle), static_cast<int>(rate));
-    return token <= 0 ? convertResult(token) : Result::OK;
+    _hidl_cb(token <= 0 ? 0 : token,
+             token <= 0 ? convertResult(token) : Result::OK);
+    return Void();
 }
 
 
diff --git a/services/sensorservice/hidl/DirectReportChannel.h b/services/sensorservice/hidl/DirectReportChannel.h
index 9134944..dd67827 100644
--- a/services/sensorservice/hidl/DirectReportChannel.h
+++ b/services/sensorservice/hidl/DirectReportChannel.h
@@ -47,7 +47,8 @@
     ~DirectReportChannel();
 
     // Methods from ::android::frameworks::sensorservice::V1_0::IDirectReportChannel follow.
-    Return<Result> configure(int32_t sensorHandle, RateLevel rate) override;
+    Return<void> configure(int32_t sensorHandle, RateLevel rate,
+            configure_cb _hidl_cb) override;
 
 private:
     ::android::SensorManager& mManager;
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..40979c9 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -206,7 +206,7 @@
         }
         disp = DisplayDevice::DISPLAY_EXTERNAL;
     }
-    mEventHandler->onHotplugReceived(disp,
+    mEventHandler->onHotplugReceived(this, disp,
             connected == HWC2::Connection::Connected);
 }
 
@@ -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/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 81f1619..78d0307 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -70,7 +70,7 @@
         friend class HWComposer;
         virtual void onVSyncReceived(
             HWComposer* composer, int32_t disp, nsecs_t timestamp) = 0;
-        virtual void onHotplugReceived(int32_t disp, bool connected) = 0;
+        virtual void onHotplugReceived(HWComposer* composer, int32_t disp, bool connected) = 0;
         virtual void onInvalidateReceived(HWComposer* composer) = 0;
     protected:
         virtual ~EventHandler() {}
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp
index 5b5f1cf..dcb2913 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp
@@ -315,7 +315,7 @@
     queryDisplayProperties(disp);
     // Do not teardown or recreate the primary display
     if (disp != HWC_DISPLAY_PRIMARY) {
-        mEventHandler.onHotplugReceived(disp, bool(connected));
+        mEventHandler.onHotplugReceived(this, disp, bool(connected));
     }
 }
 
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h
index f64d69a..4bc63bb 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h
@@ -62,7 +62,7 @@
         friend class HWComposer;
         virtual void onVSyncReceived(
             HWComposer* composer, int32_t disp, nsecs_t timestamp) = 0;
-        virtual void onHotplugReceived(int disp, bool connected) = 0;
+        virtual void onHotplugReceived(HWComposer* composer, int disp, bool connected) = 0;
         virtual void onInvalidateReceived(HWComposer* composer) = 0;
     protected:
         virtual ~EventHandler() {}
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/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 26baaae..76a5d06 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -598,7 +598,7 @@
 
     // make the GLContext current so that we can create textures when creating
     // Layers (which may happens before we render something)
-    getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
+    getDefaultDisplayDeviceLocked()->makeCurrent(mEGLDisplay, mEGLContext);
 
     mEventControlThread = new EventControlThread(this);
     mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
@@ -714,8 +714,11 @@
             info.density = density;
 
             // TODO: this needs to go away (currently needed only by webkit)
-            sp<const DisplayDevice> hw(getDefaultDisplayDevice());
-            info.orientation = hw->getOrientation();
+            {
+                Mutex::Autolock _l(mStateLock);
+                sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked());
+                info.orientation = hw->getOrientation();
+            }
         } else {
             // TODO: where should this value come from?
             static const int TV_DENSITY = 213;
@@ -772,10 +775,13 @@
         ALOGE("%s : display is NULL", __func__);
         return BAD_VALUE;
     }
+
+    Mutex::Autolock _l(mStateLock);
     sp<DisplayDevice> device(getDisplayDevice(display));
     if (device != NULL) {
         return device->getActiveConfig();
     }
+
     return BAD_VALUE;
 }
 
@@ -863,6 +869,7 @@
 }
 
 android_color_mode_t SurfaceFlinger::getActiveColorMode(const sp<IBinder>& display) {
+    Mutex::Autolock _l(mStateLock);
     sp<DisplayDevice> device(getDisplayDevice(display));
     if (device != nullptr) {
         return device->getActiveColorMode();
@@ -1124,55 +1131,60 @@
     *compositorTiming = mCompositorTiming;
 }
 
-void SurfaceFlinger::onHotplugReceived(int32_t disp, bool connected) {
+void SurfaceFlinger::createDefaultDisplayDevice() {
+    const int32_t type = DisplayDevice::DISPLAY_PRIMARY;
+    wp<IBinder> token = mBuiltinDisplays[type];
+
+    // All non-virtual displays are currently considered secure.
+    const bool isSecure = true;
+
+    sp<IGraphicBufferProducer> producer;
+    sp<IGraphicBufferConsumer> consumer;
+    BufferQueue::createBufferQueue(&producer, &consumer, new GraphicBufferAlloc());
+
+    sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, type, consumer);
+
+    bool hasWideColorModes = false;
+    std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(
+        type);
+    for (android_color_mode_t colorMode : modes) {
+        switch (colorMode) {
+            case HAL_COLOR_MODE_DISPLAY_P3:
+            case HAL_COLOR_MODE_ADOBE_RGB:
+            case HAL_COLOR_MODE_DCI_P3:
+                hasWideColorModes = true;
+                break;
+            default:
+                break;
+        }
+    }
+    sp<DisplayDevice> hw = new DisplayDevice(this, DisplayDevice::DISPLAY_PRIMARY, type, isSecure,
+                                             token, fbs, producer, mRenderEngine->getEGLConfig(),
+                                             hasWideColorModes && hasWideColorDisplay);
+    mDisplays.add(token, hw);
+    android_color_mode defaultColorMode = HAL_COLOR_MODE_NATIVE;
+    if (hasWideColorModes && hasWideColorDisplay) {
+        defaultColorMode = HAL_COLOR_MODE_SRGB;
+    }
+    setActiveColorModeInternal(hw, defaultColorMode);
+}
+
+void SurfaceFlinger::onHotplugReceived(HWComposer* composer, int32_t disp, bool connected) {
     ALOGV("onHotplugReceived(%d, %s)", disp, connected ? "true" : "false");
+
+    if (composer->isUsingVrComposer()) {
+        // We handle initializing the primary display device for the VR
+        // window manager hwc explicitly at the time of transition.
+        if (disp != DisplayDevice::DISPLAY_PRIMARY) {
+            ALOGE("External displays are not supported by the vr hardware composer.");
+        }
+        return;
+    }
+
     if (disp == DisplayDevice::DISPLAY_PRIMARY) {
         Mutex::Autolock lock(mStateLock);
-
-        // All non-virtual displays are currently considered secure.
-        bool isSecure = true;
-
-        int32_t type = DisplayDevice::DISPLAY_PRIMARY;
-
-        // When we're using the vr composer, the assumption is that we've
-        // already created the IBinder object for the primary display.
-        if (!mHwc->isUsingVrComposer()) {
-            createBuiltinDisplayLocked(DisplayDevice::DISPLAY_PRIMARY);
-        }
-
-        wp<IBinder> token = mBuiltinDisplays[type];
-
-        sp<IGraphicBufferProducer> producer;
-        sp<IGraphicBufferConsumer> consumer;
-        BufferQueue::createBufferQueue(&producer, &consumer,
-                new GraphicBufferAlloc());
-
-        sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc,
-                DisplayDevice::DISPLAY_PRIMARY, consumer);
-
-        bool hasWideColorModes = false;
-        std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(type);
-        for (android_color_mode_t colorMode : modes) {
-            switch (colorMode) {
-                case HAL_COLOR_MODE_DISPLAY_P3:
-                case HAL_COLOR_MODE_ADOBE_RGB:
-                case HAL_COLOR_MODE_DCI_P3:
-                    hasWideColorModes = true;
-                    break;
-                default:
-                    break;
-            }
-        }
-        sp<DisplayDevice> hw =
-                new DisplayDevice(this, DisplayDevice::DISPLAY_PRIMARY, disp, isSecure, token, fbs,
-                                  producer, mRenderEngine->getEGLConfig(),
-                                  hasWideColorModes && hasWideColorDisplay);
-        mDisplays.add(token, hw);
-        android_color_mode defaultColorMode = HAL_COLOR_MODE_NATIVE;
-        if (hasWideColorModes && hasWideColorDisplay) {
-            defaultColorMode = HAL_COLOR_MODE_SRGB;
-        }
-        setActiveColorModeInternal(hw, defaultColorMode);
+        createBuiltinDisplayLocked(DisplayDevice::DISPLAY_PRIMARY);
+        createDefaultDisplayDevice();
     } else {
         auto type = DisplayDevice::DISPLAY_EXTERNAL;
         Mutex::Autolock _l(mStateLock);
@@ -1214,6 +1226,7 @@
     }
 }
 
+// Note: it is assumed the caller holds |mStateLock| when this is called
 void SurfaceFlinger::resetHwc() {
     disableHardwareVsync(true);
     clearHwcLayers(mDrawingState.layersSortedByZ);
@@ -1234,36 +1247,46 @@
     if (vrFlingerRequestsDisplay == mHwc->isUsingVrComposer()) {
         return;
     }
+
+    bool vrHwcNewlyInitialized = false;
+
     if (vrFlingerRequestsDisplay && !mVrHwc) {
         // Construct new HWComposer without holding any locks.
         mVrHwc = new HWComposer(true);
+        vrHwcNewlyInitialized = true;
         ALOGV("Vr HWC created");
     }
-    {
-        Mutex::Autolock _l(mStateLock);
 
-        if (vrFlingerRequestsDisplay) {
-            resetHwc();
+    Mutex::Autolock _l(mStateLock);
 
-            mHwc = mVrHwc;
-            mVrFlinger->GrantDisplayOwnership();
-        } else {
-            mVrFlinger->SeizeDisplayOwnership();
+    if (vrFlingerRequestsDisplay) {
+        resetHwc();
 
-            resetHwc();
+        mHwc = mVrHwc;
+        mVrFlinger->GrantDisplayOwnership();
 
-            mHwc = mRealHwc;
-            enableHardwareVsync();
+        if (vrHwcNewlyInitialized) {
+            mVrHwc->setEventHandler(
+                static_cast<HWComposer::EventHandler*>(this));
         }
+    } else {
+        mVrFlinger->SeizeDisplayOwnership();
 
-        mVisibleRegionsDirty = true;
-        invalidateHwcGeometry();
-        android_atomic_or(1, &mRepaintEverything);
-        setTransactionFlags(eDisplayTransactionNeeded);
+        resetHwc();
+
+        mHwc = mRealHwc;
+        enableHardwareVsync();
     }
-    if (mVrHwc) {
-        mVrHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this));
-    }
+
+    mVisibleRegionsDirty = true;
+    invalidateHwcGeometry();
+
+    // Explicitly re-initialize the primary display. This is because some other
+    // parts of this class rely on the primary display always being available.
+    createDefaultDisplayDevice();
+
+    android_atomic_or(1, &mRepaintEverything);
+    setTransactionFlags(eDisplayTransactionNeeded);
 }
 
 void SurfaceFlinger::onMessageReceived(int32_t what) {
@@ -1473,7 +1496,8 @@
         layer->releasePendingBuffer(dequeueReadyTime);
     }
 
-    const sp<const DisplayDevice> hw(getDefaultDisplayDevice());
+    // |mStateLock| not needed as we are on the main thread
+    const sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked());
 
     std::shared_ptr<FenceTime> glCompositionDoneFenceTime;
     if (mHwc->hasClientComposition(HWC_DISPLAY_PRIMARY)) {
@@ -1821,7 +1845,8 @@
     mLastSwapBufferTime = systemTime() - now;
     mDebugInSwapBuffers = 0;
 
-    uint32_t flipCount = getDefaultDisplayDevice()->getPageFlipCount();
+    // |mStateLock| not needed as we are on the main thread
+    uint32_t flipCount = getDefaultDisplayDeviceLocked()->getPageFlipCount();
     if (flipCount % LOG_FRAME_STATS_PERIOD == 0) {
         logFrameStats();
     }
@@ -1906,7 +1931,7 @@
                         // Call makeCurrent() on the primary display so we can
                         // be sure that nothing associated with this display
                         // is current.
-                        const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDevice());
+                        const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDeviceLocked());
                         defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext);
                         sp<DisplayDevice> hw(getDisplayDevice(draw.keyAt(i)));
                         if (hw != NULL)
@@ -2096,7 +2121,7 @@
                 // could be null when this layer is using a layerStack
                 // that is not visible on any display. Also can occur at
                 // screen off/on times.
-                disp = getDefaultDisplayDevice();
+                disp = getDefaultDisplayDeviceLocked();
             }
             layer->updateTransformHint(disp);
 
@@ -2452,7 +2477,9 @@
             ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
                   displayDevice->getDisplayName().string());
             eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-            if(!getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext)) {
+
+            // |mStateLock| not needed as we are on the main thread
+            if(!getDefaultDisplayDeviceLocked()->makeCurrent(mEGLDisplay, mEGLContext)) {
               ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting.");
             }
             return false;
@@ -3539,7 +3566,7 @@
     colorizer.reset(result);
 
     HWComposer& hwc(getHwComposer());
-    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
+    sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked());
 
     colorizer.bold(result);
     result.appendFormat("EGL implementation : %s\n",
@@ -3769,7 +3796,7 @@
                 return NO_ERROR;
             case 1013: {
                 Mutex::Autolock _l(mStateLock);
-                sp<const DisplayDevice> hw(getDefaultDisplayDevice());
+                sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked());
                 reply->writeInt32(hw->getPageFlipCount());
                 return NO_ERROR;
             }
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 46121cf..219d662 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -184,8 +184,9 @@
     void repaintEverything();
 
     // returns the default Display
-    sp<const DisplayDevice> getDefaultDisplayDevice() const {
-        return getDisplayDevice(mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY]);
+    sp<const DisplayDevice> getDefaultDisplayDevice() {
+        Mutex::Autolock _l(mStateLock);
+        return getDefaultDisplayDeviceLocked();
     }
 
     // utility function to delete a texture on the main thread
@@ -304,7 +305,7 @@
      * HWComposer::EventHandler interface
      */
     virtual void onVSyncReceived(HWComposer* composer, int type, nsecs_t timestamp);
-    virtual void onHotplugReceived(int disp, bool connected);
+    virtual void onHotplugReceived(HWComposer* composer, int disp, bool connected);
     virtual void onInvalidateReceived(HWComposer* composer);
 
     /* ------------------------------------------------------------------------
@@ -439,6 +440,12 @@
         return mDisplays.valueFor(dpy);
     }
 
+    sp<const DisplayDevice> getDefaultDisplayDeviceLocked() const {
+        return getDisplayDevice(mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY]);
+    }
+
+    void createDefaultDisplayDevice();
+
     int32_t getDisplayType(const sp<IBinder>& display) {
         if (!display.get()) return NAME_NOT_FOUND;
         for (int i = 0; i < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES; ++i) {
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index e640ef7..cd2acef 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -584,7 +584,7 @@
 
     // make the GLContext current so that we can create textures when creating Layers
     // (which may happens before we render something)
-    getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
+    getDefaultDisplayDeviceLocked()->makeCurrent(mEGLDisplay, mEGLContext);
 
     mEventControlThread = new EventControlThread(this);
     mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
@@ -1040,7 +1040,7 @@
     *compositorTiming = mCompositorTiming;
 }
 
-void SurfaceFlinger::onHotplugReceived(int type, bool connected) {
+void SurfaceFlinger::onHotplugReceived(HWComposer* /*composer*/, int type, bool connected) {
     if (mEventThread == NULL) {
         // This is a temporary workaround for b/7145521.  A non-null pointer
         // does not mean EventThread has finished initializing, so this
@@ -3222,7 +3222,7 @@
     colorizer.reset(result);
 
     HWComposer& hwc(getHwComposer());
-    sp<const DisplayDevice> hw(getDefaultDisplayDevice());
+    sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked());
 
     colorizer.bold(result);
     result.appendFormat("EGL implementation : %s\n",
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;