VR: Create VR implementation for HWC HIDL interface

* Implement the IComposerClient interface for a VR HWC.
* Introduce new command to send layer information to the VR HWC.
* Add observer interface in the VR HWC service allowing VR Window
  Manager to consume SurfaceFlinger output.

Bug: 32541196, 33297385
Test: Compiled and ran with modified surfaceflinger that connects to the
VR hwcomposer and made sure there are no crashes.

Change-Id: Ic2c882ba5e4c570cbd0b7a180845a5e61a768cad
diff --git a/services/vr/Android.bp b/services/vr/Android.bp
new file mode 100644
index 0000000..80df479
--- /dev/null
+++ b/services/vr/Android.bp
@@ -0,0 +1,3 @@
+subdirs = [
+  "*",
+]
diff --git a/services/vr/vr_window_manager/Android.bp b/services/vr/vr_window_manager/Android.bp
new file mode 100644
index 0000000..c30219f
--- /dev/null
+++ b/services/vr/vr_window_manager/Android.bp
@@ -0,0 +1,39 @@
+subdirs = [
+  "composer/1.0",
+]
+
+cc_library_shared {
+  name: "libvrhwc",
+
+  srcs: [
+    "composer/impl/sync_timeline.cpp",
+    "composer/impl/vr_hwc.cpp",
+    "composer/impl/vr_composer_client.cpp",
+  ],
+
+  static_libs: [
+    "libhwcomposer-client",
+  ],
+
+  shared_libs: [
+    "android.dvr.composer@1.0",
+    "android.hardware.graphics.composer@2.1",
+    "libbase",
+    "libcutils",
+    "libfmq",
+    "libhardware",
+    "libhidlbase",
+    "libhidltransport",
+    "liblog",
+    "libsync",
+    "libui",
+    "libutils",
+  ],
+
+  // Access to software sync timeline.
+  include_dirs: [ "system/core/libsync" ],
+
+  cflags: [
+    "-DLOG_TAG=\"vrhwc\"",
+  ],
+}
diff --git a/services/vr/vr_window_manager/composer/1.0/Android.bp b/services/vr/vr_window_manager/composer/1.0/Android.bp
new file mode 100644
index 0000000..f69481f
--- /dev/null
+++ b/services/vr/vr_window_manager/composer/1.0/Android.bp
@@ -0,0 +1,54 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+
+genrule {
+    name: "android.dvr.composer@1.0_genc++",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hidl:system/libhidl/transport -randroid.hardware:hardware/interfaces/ -randroid.dvr:frameworks/native/services/vr/vr_window_manager android.dvr.composer@1.0",
+    srcs: [
+        "IVrComposerClient.hal",
+    ],
+    out: [
+        "android/dvr/composer/1.0/VrComposerClientAll.cpp",
+    ],
+}
+
+genrule {
+    name: "android.dvr.composer@1.0_genc++_headers",
+    tools: ["hidl-gen"],
+    cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hidl:system/libhidl/transport -randroid.hardware:hardware/interfaces/ -randroid.dvr:frameworks/native/services/vr/vr_window_manager android.dvr.composer@1.0",
+    srcs: [
+        "IVrComposerClient.hal",
+    ],
+    out: [
+        "android/dvr/composer/1.0/IVrComposerClient.h",
+        "android/dvr/composer/1.0/IHwVrComposerClient.h",
+        "android/dvr/composer/1.0/BnVrComposerClient.h",
+        "android/dvr/composer/1.0/BpVrComposerClient.h",
+        "android/dvr/composer/1.0/BsVrComposerClient.h",
+    ],
+}
+
+cc_library_shared {
+    name: "android.dvr.composer@1.0",
+    generated_sources: ["android.dvr.composer@1.0_genc++"],
+    generated_headers: ["android.dvr.composer@1.0_genc++_headers"],
+    export_generated_headers: ["android.dvr.composer@1.0_genc++_headers"],
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+        "libcutils",
+        "android.hardware.graphics.composer@2.1",
+        "android.hidl.base@1.0",
+    ],
+    export_shared_lib_headers: [
+        "libhidlbase",
+        "libhidltransport",
+        "libhwbinder",
+        "libutils",
+        "android.hardware.graphics.composer@2.1",
+        "android.hidl.base@1.0",
+    ],
+}
diff --git a/services/vr/vr_window_manager/composer/1.0/IVrComposerClient.hal b/services/vr/vr_window_manager/composer/1.0/IVrComposerClient.hal
new file mode 100644
index 0000000..230a68a
--- /dev/null
+++ b/services/vr/vr_window_manager/composer/1.0/IVrComposerClient.hal
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.dvr.composer@1.0;
+
+import android.hardware.graphics.composer@2.1::IComposerClient;
+
+interface IVrComposerClient
+    extends android.hardware.graphics.composer@2.1::IComposerClient {
+    /*
+     * Used to annotate the layer with additional information, which will be
+     * used to describe the content of the layer (ie: notification, permission,
+     * etc) which allows VR window manager to treat certain layer types
+     * specially.
+     *
+     * @param display is the display on which the layer was created.
+     * @param layer is the layer affected by the change.
+     * @param layer_type the type of the layer as described by the window
+     * manager.
+     * @param application_id the application id the layer belongs to.
+     * @return error is NONE upon success. Otherwise,
+     *         BAD_DISPLAY when an invalid display handle was passed in.
+     *         BAD_LAYER when an invalid layer handle was passed in.
+     *
+     * setLayerInfo(Display display,
+     *              Layer layer,
+     *              uint32_t layer_type,
+     *              uint32_t application_id)
+     *     generates(Error error);
+     */
+
+    enum VrCommand : int32_t {
+        OPCODE_SHIFT         = android.hardware.graphics.composer@2.1::IComposerClient.Command:OPCODE_SHIFT,
+
+        SET_LAYER_INFO = 0x800 << OPCODE_SHIFT,
+    };
+};
diff --git a/services/vr/vr_window_manager/composer/impl/sync_timeline.cpp b/services/vr/vr_window_manager/composer/impl/sync_timeline.cpp
new file mode 100644
index 0000000..aa55aed
--- /dev/null
+++ b/services/vr/vr_window_manager/composer/impl/sync_timeline.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "composer/impl/sync_timeline.h"
+
+#include <sys/cdefs.h>
+#include <sw_sync.h>
+#include <unistd.h>
+
+namespace android {
+namespace dvr {
+
+SyncTimeline::SyncTimeline() {}
+
+SyncTimeline::~SyncTimeline() {}
+
+bool SyncTimeline::Initialize() {
+  timeline_fd_.reset(sw_sync_timeline_create());
+  return timeline_fd_ >= 0;
+}
+
+int SyncTimeline::CreateFence(int time) {
+  return sw_sync_fence_create(timeline_fd_.get(), "dummy fence", time);
+}
+
+bool SyncTimeline::IncrementTimeline() {
+  return sw_sync_timeline_inc(timeline_fd_.get(), 1) == 0;
+}
+
+}  // namespace dvr
+}  // namespace android
diff --git a/services/vr/vr_window_manager/composer/impl/sync_timeline.h b/services/vr/vr_window_manager/composer/impl/sync_timeline.h
new file mode 100644
index 0000000..945acbd
--- /dev/null
+++ b/services/vr/vr_window_manager/composer/impl/sync_timeline.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef VR_WINDOW_MANAGER_COMPOSER_IMPL_SYNC_TIMELINE_H_
+#define VR_WINDOW_MANAGER_COMPOSER_IMPL_SYNC_TIMELINE_H_
+
+#include <android-base/unique_fd.h>
+
+namespace android {
+namespace dvr {
+
+// TODO(dnicoara): Remove this and move to EGL based fences.
+class SyncTimeline {
+ public:
+  SyncTimeline();
+  ~SyncTimeline();
+
+  bool Initialize();
+
+  int CreateFence(int time);
+  bool IncrementTimeline();
+
+ private:
+  base::unique_fd timeline_fd_;
+
+  SyncTimeline(const SyncTimeline&) = delete;
+  void operator=(const SyncTimeline&) = delete;
+};
+
+}  // namespace dvr
+}  // namespace android
+
+#endif  // VR_WINDOW_MANAGER_COMPOSER_IMPL_SYNC_TIMELINE_H_
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
new file mode 100644
index 0000000..367acb7
--- /dev/null
+++ b/services/vr/vr_window_manager/composer/impl/vr_composer_client.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/dvr/composer/1.0/IVrComposerClient.h>
+#include <hardware/gralloc.h>
+#include <hardware/gralloc1.h>
+#include <log/log.h>
+
+#include "vr_hwc.h"
+#include "vr_composer_client.h"
+
+namespace android {
+namespace dvr {
+
+using android::hardware::graphics::common::V1_0::PixelFormat;
+using android::dvr::composer::V1_0::IVrComposerClient;
+
+VrComposerClient::VrComposerClient(dvr::VrHwc& hal)
+    : ComposerClient(hal), mVrHal(hal) {}
+
+VrComposerClient::~VrComposerClient() {}
+
+std::unique_ptr<ComposerClient::CommandReader>
+VrComposerClient::createCommandReader() {
+  return std::unique_ptr<CommandReader>(new VrCommandReader(*this));
+}
+
+VrComposerClient::VrCommandReader::VrCommandReader(VrComposerClient& client)
+    : CommandReader(client), mVrClient(client), mVrHal(client.mVrHal) {}
+
+VrComposerClient::VrCommandReader::~VrCommandReader() {}
+
+bool VrComposerClient::VrCommandReader::parseCommand(
+    IComposerClient::Command command, uint16_t length) {
+  IVrComposerClient::VrCommand vrCommand =
+      static_cast<IVrComposerClient::VrCommand>(command);
+  switch (vrCommand) {
+    case IVrComposerClient::VrCommand::SET_LAYER_INFO:
+      return parseSetLayerInfo(length);
+    default:
+      return CommandReader::parseCommand(command, length);
+  }
+}
+
+bool VrComposerClient::VrCommandReader::parseSetLayerInfo(uint16_t length) {
+  if (length != 2) {
+    return false;
+  }
+
+  auto err = mVrHal.setLayerInfo(mDisplay, mLayer, read(), read());
+  if (err != Error::NONE) {
+    mWriter.setError(getCommandLoc(), err);
+  }
+
+  return true;
+}
+
+}  // 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
new file mode 100644
index 0000000..8f0c562
--- /dev/null
+++ b/services/vr/vr_window_manager/composer/impl/vr_composer_client.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef VR_WINDOW_MANAGER_COMPOSER_IMPL_VR_COMPOSER_CLIENT_H_
+#define VR_WINDOW_MANAGER_COMPOSER_IMPL_VR_COMPOSER_CLIENT_H_
+
+#include <ComposerClient.h>
+#include <IComposerCommandBuffer.h>
+
+namespace android {
+namespace dvr {
+
+class VrHwc;
+
+using hardware::graphics::common::V1_0::PixelFormat;
+using hardware::graphics::composer::V2_1::implementation::ComposerClient;
+
+class VrComposerClient : public ComposerClient {
+ public:
+  VrComposerClient(android::dvr::VrHwc& hal);
+  virtual ~VrComposerClient();
+
+ private:
+  class VrCommandReader : public ComposerClient::CommandReader {
+   public:
+    VrCommandReader(VrComposerClient& client);
+    ~VrCommandReader() override;
+
+    bool parseCommand(IComposerClient::Command command,
+                      uint16_t length) override;
+
+   private:
+    bool parseSetLayerInfo(uint16_t length);
+
+    VrComposerClient& mVrClient;
+    android::dvr::VrHwc& mVrHal;
+
+    VrCommandReader(const VrCommandReader&) = delete;
+    void operator=(const VrCommandReader&) = delete;
+  };
+
+  std::unique_ptr<CommandReader> createCommandReader() override;
+
+  dvr::VrHwc& mVrHal;
+
+  VrComposerClient(const VrComposerClient&) = delete;
+  void operator=(const VrComposerClient&) = delete;
+};
+
+} // namespace dvr
+} // namespace android
+
+#endif  // VR_WINDOW_MANAGER_COMPOSER_IMPL_VR_COMPOSER_CLIENT_H_
diff --git a/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp b/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp
new file mode 100644
index 0000000..d64a99a
--- /dev/null
+++ b/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp
@@ -0,0 +1,531 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "composer/impl/vr_hwc.h"
+
+#include <ui/Fence.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/GraphicBufferMapper.h>
+
+#include <mutex>
+
+#include "composer/impl/sync_timeline.h"
+#include "composer/impl/vr_composer_client.h"
+
+using namespace android::hardware::graphics::common::V1_0;
+using namespace android::hardware::graphics::composer::V2_1;
+
+using android::hardware::hidl_handle;
+using android::hardware::hidl_string;
+using android::hardware::hidl_vec;
+using android::hardware::Return;
+using android::hardware::Void;
+
+namespace android {
+namespace dvr {
+namespace {
+
+using android::hardware::graphics::common::V1_0::PixelFormat;
+
+const Display kDefaultDisplayId = 1;
+const Config kDefaultConfigId = 1;
+
+}  // namespace
+
+HwcDisplay::HwcDisplay() {}
+
+HwcDisplay::~HwcDisplay() {}
+
+bool HwcDisplay::Initialize() { return hwc_timeline_.Initialize(); }
+
+bool HwcDisplay::SetClientTarget(const native_handle_t* handle,
+                                 base::unique_fd fence) {
+  // OK, so this is where we cheat a lot because we don't have direct access to
+  // buffer information. Everything is hardcoded, but once gralloc1 is available
+  // we should use it to read buffer properties from the handle.
+  buffer_ = new GraphicBuffer(
+      1080, 1920, PIXEL_FORMAT_RGBA_8888, 1,
+      GraphicBuffer::USAGE_HW_COMPOSER | GraphicBuffer::USAGE_HW_TEXTURE, 1088,
+      native_handle_clone(handle), true);
+  if (GraphicBufferMapper::get().registerBuffer(buffer_.get()) != OK) {
+    ALOGE("Failed to set client target");
+    return false;
+  }
+
+  fence_ = new Fence(fence.release());
+  return true;
+}
+
+HwcLayer* HwcDisplay::CreateLayer() {
+  uint64_t layer_id = layer_ids_++;
+  layers_.push_back(HwcLayer(layer_id));
+  return &layers_.back();
+}
+
+HwcLayer* HwcDisplay::GetLayer(Layer id) {
+  for (size_t i = 0; i < layers_.size(); ++i)
+    if (layers_[i].id == id) return &layers_[i];
+
+  return nullptr;
+}
+
+bool HwcDisplay::DestroyLayer(Layer id) {
+  for (auto it = layers_.begin(); it != layers_.end(); ++it) {
+    if (it->id == id) {
+      layers_.erase(it);
+      return true;
+    }
+  }
+
+  return false;
+}
+
+void HwcDisplay::GetChangedCompositionTypes(
+    std::vector<Layer>* layer_ids,
+    std::vector<IComposerClient::Composition>* types) {
+  for (const auto& layer : layers_) {
+    layer_ids->push_back(layer.id);
+    types->push_back(IComposerClient::Composition::CLIENT);
+  }
+}
+
+std::vector<ComposerView::ComposerLayer> HwcDisplay::GetFrame() {
+  // Increment the time the fence is signalled every time we get the
+  // presentation frame. This ensures that calling ReleaseFrame() only affects
+  // the current frame.
+  fence_time_++;
+
+  // TODO(dnicoara): Send the actual layers when we process layers as overlays.
+  ComposerView::ComposerLayer layer = {
+      .buffer = buffer_,
+      .fence = fence_.get() ? fence_ : new Fence(-1),
+      .display_frame = {0, 0, 1080, 1920},
+      .crop = {0.0f, 0.0f, 1080.0f, 1920.0f},
+      .blend_mode = IComposerClient::BlendMode::NONE,
+  };
+  return std::vector<ComposerView::ComposerLayer>(1, layer);
+}
+
+void HwcDisplay::GetReleaseFences(std::vector<Layer>* layer_ids,
+                                  std::vector<int>* fences) {
+  for (const auto& layer : layers_) {
+    layer_ids->push_back(layer.id);
+    fences->push_back(hwc_timeline_.CreateFence(fence_time_));
+  }
+}
+
+void HwcDisplay::ReleaseFrame() { hwc_timeline_.IncrementTimeline(); }
+
+VrHwc::VrHwc() {}
+
+VrHwc::~VrHwc() {}
+
+bool VrHwc::Initialize() { return display_.Initialize(); }
+
+bool VrHwc::hasCapability(Capability capability) const { return false; }
+
+void VrHwc::removeClient() {
+  std::lock_guard<std::mutex> guard(mutex_);
+  client_ = nullptr;
+}
+
+void VrHwc::enableCallback(bool enable) {
+  std::lock_guard<std::mutex> guard(mutex_);
+  if (enable && client_ != nullptr) {
+    client_.promote()->onHotplug(kDefaultDisplayId,
+                                 IComposerCallback::Connection::CONNECTED);
+  }
+}
+
+uint32_t VrHwc::getMaxVirtualDisplayCount() { return 0; }
+
+Error VrHwc::createVirtualDisplay(uint32_t width, uint32_t height,
+                                  PixelFormat* format, Display* outDisplay) {
+  *format = PixelFormat::RGBA_8888;
+  *outDisplay = 0;
+  return Error::NONE;
+}
+
+Error VrHwc::destroyVirtualDisplay(Display display) { return Error::NONE; }
+
+Error VrHwc::createLayer(Display display, Layer* outLayer) {
+  if (display != kDefaultDisplayId) {
+    return Error::BAD_DISPLAY;
+  }
+
+  std::lock_guard<std::mutex> guard(mutex_);
+
+  HwcLayer* layer = display_.CreateLayer();
+  *outLayer = layer->id;
+  return Error::NONE;
+}
+
+Error VrHwc::destroyLayer(Display display, Layer layer) {
+  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
+
+  std::lock_guard<std::mutex> guard(mutex_);
+
+  return display_.DestroyLayer(layer) ? Error::NONE : Error::BAD_LAYER;
+}
+
+Error VrHwc::getActiveConfig(Display display, Config* outConfig) {
+  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
+
+  *outConfig = kDefaultConfigId;
+  return Error::NONE;
+}
+
+Error VrHwc::getClientTargetSupport(Display display, uint32_t width,
+                                    uint32_t height, PixelFormat format,
+                                    Dataspace dataspace) {
+  return Error::NONE;
+}
+
+Error VrHwc::getColorModes(Display display, hidl_vec<ColorMode>* outModes) {
+  std::vector<ColorMode> color_modes(1, ColorMode::NATIVE);
+  *outModes = hidl_vec<ColorMode>(color_modes);
+  return Error::NONE;
+}
+
+Error VrHwc::getDisplayAttribute(Display display, Config config,
+                                 IComposerClient::Attribute attribute,
+                                 int32_t* outValue) {
+  if (display != kDefaultDisplayId) {
+    return Error::BAD_DISPLAY;
+  }
+
+  if (config != kDefaultConfigId) {
+    return Error::BAD_CONFIG;
+  }
+
+  switch (attribute) {
+    case IComposerClient::Attribute::WIDTH:
+      *outValue = 1080;
+      break;
+    case IComposerClient::Attribute::HEIGHT:
+      *outValue = 1920;
+      break;
+    case IComposerClient::Attribute::VSYNC_PERIOD:
+      *outValue = 1000 * 1000 * 1000 / 30;  // 30fps
+      break;
+    case IComposerClient::Attribute::DPI_X:
+    case IComposerClient::Attribute::DPI_Y:
+      *outValue = 300 * 1000;  // 300dpi
+      break;
+    default:
+      return Error::BAD_PARAMETER;
+  }
+
+  return Error::NONE;
+}
+
+Error VrHwc::getDisplayConfigs(Display display, hidl_vec<Config>* outConfigs) {
+  if (display != kDefaultDisplayId) {
+    return Error::BAD_DISPLAY;
+  }
+
+  std::vector<Config> configs(1, kDefaultConfigId);
+  *outConfigs = hidl_vec<Config>(configs);
+  return Error::NONE;
+}
+
+Error VrHwc::getDisplayName(Display display, hidl_string* outName) {
+  *outName = hidl_string();
+  return Error::NONE;
+}
+
+Error VrHwc::getDisplayType(Display display,
+                            IComposerClient::DisplayType* outType) {
+  if (display != kDefaultDisplayId) {
+    *outType = IComposerClient::DisplayType::INVALID;
+    return Error::BAD_DISPLAY;
+  }
+
+  *outType = IComposerClient::DisplayType::PHYSICAL;
+  return Error::NONE;
+}
+
+Error VrHwc::getDozeSupport(Display display, bool* outSupport) {
+  *outSupport = false;
+  if (display == kDefaultDisplayId)
+    return Error::NONE;
+  else
+    return Error::BAD_DISPLAY;
+}
+
+Error VrHwc::getHdrCapabilities(Display display, hidl_vec<Hdr>* outTypes,
+                                float* outMaxLuminance,
+                                float* outMaxAverageLuminance,
+                                float* outMinLuminance) {
+  *outMaxLuminance = 0;
+  *outMaxAverageLuminance = 0;
+  *outMinLuminance = 0;
+  return Error::NONE;
+}
+
+Error VrHwc::setActiveConfig(Display display, Config config) {
+  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
+
+  if (config != kDefaultConfigId) return Error::BAD_CONFIG;
+
+  return Error::NONE;
+}
+
+Error VrHwc::setColorMode(Display display, ColorMode mode) {
+  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
+
+  return Error::NONE;
+}
+
+Error VrHwc::setPowerMode(Display display, IComposerClient::PowerMode mode) {
+  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
+
+  return Error::NONE;
+}
+
+Error VrHwc::setVsyncEnabled(Display display, IComposerClient::Vsync enabled) {
+  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
+
+  return Error::NONE;
+}
+
+Error VrHwc::setColorTransform(Display display, const float* matrix,
+                               int32_t hint) {
+  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
+
+  return Error::NONE;
+}
+
+Error VrHwc::setClientTarget(Display display, buffer_handle_t target,
+                             int32_t acquireFence, int32_t dataspace,
+                             const std::vector<hwc_rect_t>& damage) {
+  base::unique_fd fence(acquireFence);
+  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
+
+  if (target == nullptr) return Error::NONE;
+
+  std::lock_guard<std::mutex> guard(mutex_);
+
+  if (!display_.SetClientTarget(target, std::move(fence)))
+    return Error::BAD_PARAMETER;
+
+  return Error::NONE;
+}
+
+Error VrHwc::setOutputBuffer(Display display, buffer_handle_t buffer,
+                             int32_t releaseFence) {
+  base::unique_fd fence(releaseFence);
+  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
+
+  return Error::NONE;
+}
+
+Error VrHwc::validateDisplay(
+    Display display, std::vector<Layer>* outChangedLayers,
+    std::vector<IComposerClient::Composition>* outCompositionTypes,
+    uint32_t* outDisplayRequestMask, std::vector<Layer>* outRequestedLayers,
+    std::vector<uint32_t>* outRequestMasks) {
+  if (display != kDefaultDisplayId) {
+    return Error::BAD_DISPLAY;
+  }
+
+  std::lock_guard<std::mutex> guard(mutex_);
+
+  display_.GetChangedCompositionTypes(outChangedLayers, outCompositionTypes);
+  return Error::NONE;
+}
+
+Error VrHwc::acceptDisplayChanges(Display display) { return Error::NONE; }
+
+Error VrHwc::presentDisplay(Display display, int32_t* outPresentFence,
+                            std::vector<Layer>* outLayers,
+                            std::vector<int32_t>* outReleaseFences) {
+  *outPresentFence = -1;
+  if (display != kDefaultDisplayId) {
+    return Error::BAD_DISPLAY;
+  }
+
+  std::lock_guard<std::mutex> guard(mutex_);
+
+  if (observer_)
+    observer_->OnNewFrame(display_.GetFrame());
+  else
+    display_.ReleaseFrame();
+
+  display_.GetReleaseFences(outLayers, outReleaseFences);
+  return Error::NONE;
+}
+
+Error VrHwc::setLayerCursorPosition(Display display, Layer layer, int32_t x,
+                                    int32_t y) {
+  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
+
+  return Error::NONE;
+}
+
+Error VrHwc::setLayerBuffer(Display display, Layer layer,
+                            buffer_handle_t buffer, int32_t acquireFence) {
+  base::unique_fd fence(acquireFence);
+  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
+
+  return Error::NONE;
+}
+
+Error VrHwc::setLayerSurfaceDamage(Display display, Layer layer,
+                                   const std::vector<hwc_rect_t>& damage) {
+  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
+
+  return Error::NONE;
+}
+
+Error VrHwc::setLayerBlendMode(Display display, Layer layer, int32_t mode) {
+  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
+
+  return Error::NONE;
+}
+
+Error VrHwc::setLayerColor(Display display, Layer layer,
+                           IComposerClient::Color color) {
+  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
+
+  return Error::NONE;
+}
+
+Error VrHwc::setLayerCompositionType(Display display, Layer layer,
+                                     int32_t type) {
+  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
+
+  return Error::NONE;
+}
+
+Error VrHwc::setLayerDataspace(Display display, Layer layer,
+                               int32_t dataspace) {
+  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
+
+  return Error::NONE;
+}
+
+Error VrHwc::setLayerDisplayFrame(Display display, Layer layer,
+                                  const hwc_rect_t& frame) {
+  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
+
+  return Error::NONE;
+}
+
+Error VrHwc::setLayerPlaneAlpha(Display display, Layer layer, float alpha) {
+  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
+
+  return Error::NONE;
+}
+
+Error VrHwc::setLayerSidebandStream(Display display, Layer layer,
+                                    buffer_handle_t stream) {
+  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
+
+  return Error::NONE;
+}
+
+Error VrHwc::setLayerSourceCrop(Display display, Layer layer,
+                                const hwc_frect_t& crop) {
+  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
+
+  return Error::NONE;
+}
+
+Error VrHwc::setLayerTransform(Display display, Layer layer,
+                               int32_t transform) {
+  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
+
+  return Error::NONE;
+}
+
+Error VrHwc::setLayerVisibleRegion(Display display, Layer layer,
+                                   const std::vector<hwc_rect_t>& visible) {
+  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
+
+  return Error::NONE;
+}
+
+Error VrHwc::setLayerZOrder(Display display, Layer layer, uint32_t z) {
+  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
+
+  return Error::NONE;
+}
+
+Error VrHwc::setLayerInfo(Display display, Layer layer, uint32_t type,
+                          uint32_t appId) {
+  if (display != kDefaultDisplayId) return Error::BAD_DISPLAY;
+
+  return Error::NONE;
+}
+
+Return<void> VrHwc::getCapabilities(getCapabilities_cb hidl_cb) {
+  hidl_cb(hidl_vec<Capability>());
+  return Void();
+}
+
+Return<void> VrHwc::dumpDebugInfo(dumpDebugInfo_cb hidl_cb) {
+  hidl_cb(hidl_string());
+  return Void();
+}
+
+Return<void> VrHwc::createClient(createClient_cb hidl_cb) {
+  std::lock_guard<std::mutex> guard(mutex_);
+
+  Error status = Error::NONE;
+  sp<VrComposerClient> client;
+  if (client_ == nullptr) {
+    client = new VrComposerClient(*this);
+    client->initialize();
+  } else {
+    ALOGE("Already have a client");
+    status = Error::NO_RESOURCES;
+  }
+
+  client_ = client;
+  hidl_cb(status, client);
+  return Void();
+}
+
+void VrHwc::RegisterObserver(Observer* observer) {
+  std::lock_guard<std::mutex> guard(mutex_);
+  if (observer_)
+    ALOGE("Overwriting observer");
+  else
+    observer_ = observer;
+}
+
+void VrHwc::UnregisterObserver(Observer* observer) {
+  std::lock_guard<std::mutex> guard(mutex_);
+  if (observer != observer_)
+    ALOGE("Trying to unregister unknown observer");
+  else
+    observer_ = nullptr;
+}
+
+void VrHwc::ReleaseFrame() {
+  std::lock_guard<std::mutex> guard(mutex_);
+  display_.ReleaseFrame();
+}
+
+ComposerView* GetComposerViewFromIComposer(
+    hardware::graphics::composer::V2_1::IComposer* composer) {
+  return static_cast<VrHwc*>(composer);
+}
+
+IComposer* HIDL_FETCH_IComposer(const char*) { return new VrHwc(); }
+
+}  // namespace dvr
+}  // namespace android
diff --git a/services/vr/vr_window_manager/composer/impl/vr_hwc.h b/services/vr/vr_window_manager/composer/impl/vr_hwc.h
new file mode 100644
index 0000000..fbbf028
--- /dev/null
+++ b/services/vr/vr_window_manager/composer/impl/vr_hwc.h
@@ -0,0 +1,266 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef VR_WINDOW_MANAGER_COMPOSER_IMPL_VR_HWC_H_
+#define VR_WINDOW_MANAGER_COMPOSER_IMPL_VR_HWC_H_
+
+#include <android/hardware/graphics/composer/2.1/IComposer.h>
+#include <ComposerBase.h>
+#include <ui/GraphicBufferMapper.h>
+#include <utils/StrongPointer.h>
+
+#include <mutex>
+
+#include "composer/impl/sync_timeline.h"
+
+using namespace android::hardware::graphics::common::V1_0;
+using namespace android::hardware::graphics::composer::V2_1;
+
+using android::hardware::hidl_handle;
+using android::hardware::hidl_string;
+using android::hardware::hidl_vec;
+using android::hardware::Return;
+using android::hardware::Void;
+
+namespace android {
+
+class Fence;
+class GraphicBuffer;
+
+namespace dvr {
+
+class VrComposerClient;
+
+using android::hardware::graphics::common::V1_0::PixelFormat;
+using android::hardware::graphics::composer::V2_1::implementation::ComposerBase;
+
+class ComposerView {
+ public:
+  struct ComposerLayer {
+    using Recti = hardware::graphics::composer::V2_1::IComposerClient::Rect;
+    using Rectf = hardware::graphics::composer::V2_1::IComposerClient::FRect;
+    using BlendMode =
+        hardware::graphics::composer::V2_1::IComposerClient::BlendMode;
+
+    // TODO(dnicoara): Add all layer properties. For now just the basics to get
+    // it going.
+    sp<GraphicBuffer> buffer;
+    sp<Fence> fence;
+    Recti  display_frame;
+    Rectf crop;
+    BlendMode blend_mode;
+  };
+
+  using Frame = std::vector<ComposerLayer>;
+
+  class Observer {
+   public:
+    virtual ~Observer() {}
+
+    // Returns a list of layers that need to be shown together. Layers are
+    // returned in z-order, with the lowest layer first.
+    virtual void OnNewFrame(const Frame& frame) = 0;
+  };
+
+  virtual ~ComposerView() {}
+
+  virtual void RegisterObserver(Observer* observer) = 0;
+  virtual void UnregisterObserver(Observer* observer) = 0;
+
+  // Called to release the oldest frame received by the observer.
+  virtual void ReleaseFrame() = 0;
+};
+
+struct HwcLayer {
+  HwcLayer(Layer new_id) : id(new_id) {}
+
+  Layer id;
+};
+
+class HwcDisplay {
+ public:
+  HwcDisplay();
+  ~HwcDisplay();
+
+  bool Initialize();
+
+  HwcLayer* CreateLayer();
+  bool DestroyLayer(Layer id);
+  HwcLayer* GetLayer(Layer id);
+
+  bool SetClientTarget(const native_handle_t* handle, base::unique_fd fence);
+
+  void GetChangedCompositionTypes(
+      std::vector<Layer>* layer_ids,
+      std::vector<IComposerClient::Composition>* composition);
+
+  std::vector<ComposerView::ComposerLayer> GetFrame();
+
+  void GetReleaseFences(
+      std::vector<Layer>* layer_ids, std::vector<int>* fences);
+
+  void ReleaseFrame();
+
+ private:
+  // The client target buffer and the associated fence.
+  // TODO(dnicoara): Replace this with a list of ComposerView::ComposerLayer.
+  sp<GraphicBuffer> buffer_;
+  sp<Fence> fence_;
+
+  // List of currently active layers.
+  std::vector<HwcLayer> layers_;
+
+  // Layer ID generator.
+  uint64_t layer_ids_ = 1;
+
+  // Creates software sync fences used to signal releasing frames.
+  SyncTimeline hwc_timeline_;
+
+  // Keeps track of the current fence time. Used in conjunction with
+  // |hwc_timeline_| to properly signal frame release times. Allows the observer
+  // to receive multiple presentation frames without calling ReleaseFrame() in
+  // between each presentation. When the observer is ready to release a frame
+  // only the oldest presentation frame is affected by the release.
+  int fence_time_ = 0;
+
+  HwcDisplay(const HwcDisplay&) = delete;
+  void operator=(const HwcDisplay&) = delete;
+};
+
+class VrHwc : public IComposer, public ComposerBase, public ComposerView {
+ public:
+  VrHwc();
+  ~VrHwc() override;
+
+  bool Initialize();
+
+  bool hasCapability(Capability capability) const;
+
+  Error setLayerInfo(Display display, Layer layer, uint32_t type,
+                     uint32_t appId);
+
+  // ComposerBase
+  void removeClient() override;
+  void enableCallback(bool enable) override;
+
+  uint32_t getMaxVirtualDisplayCount() override;
+  Error createVirtualDisplay(uint32_t width, uint32_t height,
+      PixelFormat* format, Display* outDisplay) override;
+  Error destroyVirtualDisplay(Display display) override;
+
+  Error createLayer(Display display, Layer* outLayer) override;
+  Error destroyLayer(Display display, Layer layer) override;
+
+  Error getActiveConfig(Display display, Config* outConfig) override;
+  Error getClientTargetSupport(Display display,
+          uint32_t width, uint32_t height,
+          PixelFormat format, Dataspace dataspace) override;
+  Error getColorModes(Display display, hidl_vec<ColorMode>* outModes) override;
+  Error getDisplayAttribute(Display display, Config config,
+          IComposerClient::Attribute attribute, int32_t* outValue) override;
+  Error getDisplayConfigs(Display display, hidl_vec<Config>* outConfigs) override;
+  Error getDisplayName(Display display, hidl_string* outName) override;
+  Error getDisplayType(Display display,
+          IComposerClient::DisplayType* outType) override;
+  Error getDozeSupport(Display display, bool* outSupport) override;
+  Error getHdrCapabilities(Display display, hidl_vec<Hdr>* outTypes,
+          float* outMaxLuminance, float* outMaxAverageLuminance,
+          float* outMinLuminance) override;
+
+  Error setActiveConfig(Display display, Config config) override;
+  Error setColorMode(Display display, ColorMode mode) override;
+  Error setPowerMode(Display display, IComposerClient::PowerMode mode) override;
+  Error setVsyncEnabled(Display display, IComposerClient::Vsync enabled) override;
+
+  Error setColorTransform(Display display, const float* matrix,
+          int32_t hint) override;
+  Error setClientTarget(Display display, buffer_handle_t target,
+          int32_t acquireFence, int32_t dataspace,
+          const std::vector<hwc_rect_t>& damage) override;
+  Error setOutputBuffer(Display display, buffer_handle_t buffer,
+          int32_t releaseFence) override;
+  Error validateDisplay(Display display,
+          std::vector<Layer>* outChangedLayers,
+          std::vector<IComposerClient::Composition>* outCompositionTypes,
+          uint32_t* outDisplayRequestMask,
+          std::vector<Layer>* outRequestedLayers,
+          std::vector<uint32_t>* outRequestMasks) override;
+  Error acceptDisplayChanges(Display display) override;
+  Error presentDisplay(Display display, int32_t* outPresentFence,
+          std::vector<Layer>* outLayers,
+          std::vector<int32_t>* outReleaseFences) override;
+
+  Error setLayerCursorPosition(Display display, Layer layer,
+          int32_t x, int32_t y) override;
+  Error setLayerBuffer(Display display, Layer layer,
+          buffer_handle_t buffer, int32_t acquireFence) override;
+  Error setLayerSurfaceDamage(Display display, Layer layer,
+          const std::vector<hwc_rect_t>& damage) override;
+  Error setLayerBlendMode(Display display, Layer layer, int32_t mode) override;
+  Error setLayerColor(Display display, Layer layer,
+          IComposerClient::Color color) override;
+  Error setLayerCompositionType(Display display, Layer layer,
+          int32_t type) override;
+  Error setLayerDataspace(Display display, Layer layer,
+          int32_t dataspace) override;
+  Error setLayerDisplayFrame(Display display, Layer layer,
+          const hwc_rect_t& frame) override;
+  Error setLayerPlaneAlpha(Display display, Layer layer, float alpha) override;
+  Error setLayerSidebandStream(Display display, Layer layer,
+          buffer_handle_t stream) override;
+  Error setLayerSourceCrop(Display display, Layer layer,
+          const hwc_frect_t& crop) override;
+  Error setLayerTransform(Display display, Layer layer,
+          int32_t transform) override;
+  Error setLayerVisibleRegion(Display display, Layer layer,
+          const std::vector<hwc_rect_t>& visible) override;
+  Error setLayerZOrder(Display display, Layer layer, uint32_t z) override;
+
+  // IComposer:
+  Return<void> getCapabilities(getCapabilities_cb hidl_cb) override;
+  Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override;
+  Return<void> createClient(createClient_cb hidl_cb) override;
+
+  // ComposerView:
+  void RegisterObserver(Observer* observer) override;
+  void UnregisterObserver(Observer* observer) override;
+  void ReleaseFrame() override;
+
+ private:
+  wp<VrComposerClient> client_;
+  sp<IComposerCallback> callbacks_;
+
+  // Guard access to internal state from binder threads.
+  std::mutex mutex_;
+
+  HwcDisplay display_;
+
+  Observer* observer_ = nullptr;
+
+  VrHwc(const VrHwc&) = delete;
+  void operator=(const VrHwc&) = delete;
+};
+
+
+ComposerView* GetComposerViewFromIComposer(
+    hardware::graphics::composer::V2_1::IComposer* composer);
+
+hardware::graphics::composer::V2_1::IComposer* HIDL_FETCH_IComposer(
+    const char* name);
+
+}  // namespace dvr
+}  // namespace android
+
+#endif  // VR_WINDOW_MANAGER_COMPOSER_IMPL_VR_HWC_H_