diff --git a/graphics/composer/2.1/default/Android.bp b/graphics/composer/2.1/default/Android.bp
new file mode 100644
index 0000000..f91c9a2
--- /dev/null
+++ b/graphics/composer/2.1/default/Android.bp
@@ -0,0 +1,16 @@
+cc_library_shared {
+    name: "android.hardware.graphics.composer@2.1-impl",
+    relative_install_path: "hw",
+    srcs: ["Hwc.cpp"],
+    shared_libs: [
+        "android.hardware.graphics.allocator@2.0",
+        "android.hardware.graphics.composer@2.1",
+        "libbase",
+        "libcutils",
+        "libhardware",
+        "libhidl",
+        "libhwbinder",
+        "liblog",
+        "libutils",
+    ],
+}
diff --git a/graphics/composer/2.1/default/Hwc.cpp b/graphics/composer/2.1/default/Hwc.cpp
new file mode 100644
index 0000000..09c62f0
--- /dev/null
+++ b/graphics/composer/2.1/default/Hwc.cpp
@@ -0,0 +1,1292 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "HwcPassthrough"
+
+#include <mutex>
+#include <type_traits>
+#include <unordered_map>
+#include <unordered_set>
+#include <utility>
+#include <vector>
+
+#include <hardware/gralloc.h>
+#include <hardware/gralloc1.h>
+#include <hardware/hwcomposer2.h>
+#include <log/log.h>
+
+#include "Hwc.h"
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace composer {
+namespace V2_1 {
+namespace implementation {
+
+using android::hardware::graphics::allocator::V2_0::PixelFormat;
+
+namespace {
+
+class HandleImporter {
+public:
+    HandleImporter() : mInitialized(false) {}
+
+    bool initialize()
+    {
+        // allow only one client
+        if (mInitialized) {
+            return false;
+        }
+
+        if (!openGralloc()) {
+            return false;
+        }
+
+        mInitialized = true;
+        return true;
+    }
+
+    void cleanup()
+    {
+        if (!mInitialized) {
+            return;
+        }
+
+        closeGralloc();
+        mInitialized = false;
+    }
+
+    // In IComposer, any buffer_handle_t is owned by the caller and we need to
+    // make a clone for hwcomposer2.  We also need to translate empty handle
+    // to nullptr.  This function does that, in-place.
+    bool importBuffer(buffer_handle_t& handle)
+    {
+        if (!handle->numFds && !handle->numInts) {
+            handle = nullptr;
+            return true;
+        }
+
+        buffer_handle_t clone = cloneBuffer(handle);
+        if (!clone) {
+            return false;
+        }
+
+        handle = clone;
+        return true;
+    }
+
+    void freeBuffer(buffer_handle_t handle)
+    {
+        if (!handle) {
+            return;
+        }
+
+        releaseBuffer(handle);
+    }
+
+    bool importFence(const native_handle_t* handle, int& fd)
+    {
+        if (handle->numFds == 0) {
+            fd = -1;
+        } else if (handle->numFds == 1) {
+            fd = dup(handle->data[0]);
+            if (fd < 0) {
+                ALOGE("failed to dup fence fd %d", handle->data[0]);
+                return false;
+            }
+        } else {
+            ALOGE("invalid fence handle with %d file descriptors",
+                    handle->numFds);
+            return false;
+        }
+
+        return true;
+    }
+
+    void closeFence(int fd)
+    {
+        if (fd >= 0) {
+            close(fd);
+        }
+    }
+
+private:
+    bool mInitialized;
+
+    // Some existing gralloc drivers do not support retaining more than once,
+    // when we are in passthrough mode.
+#ifdef BINDERIZED
+    bool openGralloc()
+    {
+        const hw_module_t* module;
+        int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
+        if (err) {
+            ALOGE("failed to get gralloc module");
+            return false;
+        }
+
+        uint8_t major = (module->module_api_version >> 8) & 0xff;
+        if (major > 1) {
+            ALOGE("unknown gralloc module major version %d", major);
+            return false;
+        }
+
+        if (major == 1) {
+            err = gralloc1_open(module, &mDevice);
+            if (err) {
+                ALOGE("failed to open gralloc1 device");
+                return false;
+            }
+
+            mRetain = reinterpret_cast<GRALLOC1_PFN_RETAIN>(
+                    mDevice->getFunction(mDevice, GRALLOC1_FUNCTION_RETAIN));
+            mRelease = reinterpret_cast<GRALLOC1_PFN_RELEASE>(
+                    mDevice->getFunction(mDevice, GRALLOC1_FUNCTION_RELEASE));
+            if (!mRetain || !mRelease) {
+                ALOGE("invalid gralloc1 device");
+                gralloc1_close(mDevice);
+                return false;
+            }
+        } else {
+            mModule = reinterpret_cast<const gralloc_module_t*>(module);
+        }
+
+        return true;
+    }
+
+    void closeGralloc()
+    {
+        if (mDevice) {
+            gralloc1_close(mDevice);
+        }
+    }
+
+    buffer_handle_t cloneBuffer(buffer_handle_t handle)
+    {
+        native_handle_t* clone = native_handle_clone(handle);
+        if (!clone) {
+            ALOGE("failed to clone buffer %p", handle);
+            return nullptr;
+        }
+
+        bool err;
+        if (mDevice) {
+            err = (mRetain(mDevice, clone) != GRALLOC1_ERROR_NONE);
+        } else {
+            err = (mModule->registerBuffer(mModule, clone) != 0);
+        }
+
+        if (err) {
+            ALOGE("failed to retain/register buffer %p", clone);
+            native_handle_close(clone);
+            native_handle_delete(clone);
+            return nullptr;
+        }
+
+        return clone;
+    }
+
+    void releaseBuffer(buffer_handle_t handle)
+    {
+        if (mDevice) {
+            mRelease(mDevice, handle);
+        } else {
+            mModule->unregisterBuffer(mModule, handle);
+            native_handle_close(handle);
+            native_handle_delete(const_cast<native_handle_t*>(handle));
+        }
+    }
+
+    // gralloc1
+    gralloc1_device_t* mDevice;
+    GRALLOC1_PFN_RETAIN mRetain;
+    GRALLOC1_PFN_RELEASE mRelease;
+
+    // gralloc0
+    const gralloc_module_t* mModule;
+#else
+    bool openGralloc() { return true; }
+    void closeGralloc() {}
+    buffer_handle_t cloneBuffer(buffer_handle_t handle) { return handle; }
+    void releaseBuffer(buffer_handle_t) {}
+#endif
+};
+
+HandleImporter sHandleImporter;
+
+class BufferClone {
+public:
+    BufferClone() : mHandle(nullptr) {}
+
+    BufferClone(BufferClone&& other)
+    {
+        mHandle = other.mHandle;
+        other.mHandle = nullptr;
+    }
+
+    BufferClone(const BufferClone& other) = delete;
+    BufferClone& operator=(const BufferClone& other) = delete;
+
+    BufferClone& operator=(buffer_handle_t handle)
+    {
+        clear();
+        mHandle = handle;
+        return *this;
+    }
+
+    ~BufferClone()
+    {
+        clear();
+    }
+
+private:
+    void clear()
+    {
+        if (mHandle) {
+            sHandleImporter.freeBuffer(mHandle);
+        }
+    }
+
+    buffer_handle_t mHandle;
+};
+
+} // anonymous namespace
+
+class HwcHal : public IComposer {
+public:
+    HwcHal(const hw_module_t* module);
+    virtual ~HwcHal();
+
+    // IComposer interface
+    Return<void> getCapabilities(getCapabilities_cb hidl_cb) override;
+    Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override;
+    Return<void> registerCallback(const sp<IComposerCallback>& callback) override;
+    Return<uint32_t> getMaxVirtualDisplayCount() override;
+    Return<void> createVirtualDisplay(uint32_t width, uint32_t height,
+            PixelFormat formatHint, createVirtualDisplay_cb hidl_cb) override;
+    Return<Error> destroyVirtualDisplay(Display display) override;
+    Return<Error> acceptDisplayChanges(Display display) override;
+    Return<void> createLayer(Display display,
+            createLayer_cb hidl_cb) override;
+    Return<Error> destroyLayer(Display display, Layer layer) override;
+    Return<void> getActiveConfig(Display display,
+            getActiveConfig_cb hidl_cb) override;
+    Return<void> getChangedCompositionTypes(Display display,
+            getChangedCompositionTypes_cb hidl_cb) override;
+    Return<Error> getClientTargetSupport(Display display,
+            uint32_t width, uint32_t height,
+            PixelFormat format, Dataspace dataspace) override;
+    Return<void> getColorModes(Display display,
+            getColorModes_cb hidl_cb) override;
+    Return<void> getDisplayAttribute(Display display,
+            Config config, Attribute attribute,
+            getDisplayAttribute_cb hidl_cb) override;
+    Return<void> getDisplayConfigs(Display display,
+            getDisplayConfigs_cb hidl_cb) override;
+    Return<void> getDisplayName(Display display,
+            getDisplayName_cb hidl_cb) override;
+    Return<void> getDisplayRequests(Display display,
+            getDisplayRequests_cb hidl_cb) override;
+    Return<void> getDisplayType(Display display,
+            getDisplayType_cb hidl_cb) override;
+    Return<void> getDozeSupport(Display display,
+            getDozeSupport_cb hidl_cb) override;
+    Return<void> getHdrCapabilities(Display display,
+            getHdrCapabilities_cb hidl_cb) override;
+    Return<void> getReleaseFences(Display display,
+            getReleaseFences_cb hidl_cb) override;
+    Return<void> presentDisplay(Display display,
+            presentDisplay_cb hidl_cb) override;
+    Return<Error> setActiveConfig(Display display, Config config) override;
+    Return<Error> setClientTarget(Display display,
+            const native_handle_t* target,
+            const native_handle_t* acquireFence,
+            Dataspace dataspace, const hidl_vec<Rect>& damage) override;
+    Return<Error> setColorMode(Display display, ColorMode mode) override;
+    Return<Error> setColorTransform(Display display,
+            const hidl_vec<float>& matrix, ColorTransform hint) override;
+    Return<Error> setOutputBuffer(Display display,
+            const native_handle_t* buffer,
+            const native_handle_t* releaseFence) override;
+    Return<Error> setPowerMode(Display display, PowerMode mode) override;
+    Return<Error> setVsyncEnabled(Display display, Vsync enabled) override;
+    Return<void> validateDisplay(Display display,
+            validateDisplay_cb hidl_cb) override;
+    Return<Error> setCursorPosition(Display display,
+            Layer layer, int32_t x, int32_t y) override;
+    Return<Error> setLayerBuffer(Display display,
+            Layer layer, const native_handle_t* buffer,
+            const native_handle_t* acquireFence) override;
+    Return<Error> setLayerSurfaceDamage(Display display,
+            Layer layer, const hidl_vec<Rect>& damage) override;
+    Return<Error> setLayerBlendMode(Display display,
+            Layer layer, BlendMode mode) override;
+    Return<Error> setLayerColor(Display display,
+            Layer layer, const Color& color) override;
+    Return<Error> setLayerCompositionType(Display display,
+            Layer layer, Composition type) override;
+    Return<Error> setLayerDataspace(Display display,
+            Layer layer, Dataspace dataspace) override;
+    Return<Error> setLayerDisplayFrame(Display display,
+            Layer layer, const Rect& frame) override;
+    Return<Error> setLayerPlaneAlpha(Display display,
+            Layer layer, float alpha) override;
+    Return<Error> setLayerSidebandStream(Display display,
+            Layer layer, const native_handle_t* stream) override;
+    Return<Error> setLayerSourceCrop(Display display,
+            Layer layer, const FRect& crop) override;
+    Return<Error> setLayerTransform(Display display,
+            Layer layer, Transform transform) override;
+    Return<Error> setLayerVisibleRegion(Display display,
+            Layer layer, const hidl_vec<Rect>& visible) override;
+    Return<Error> setLayerZOrder(Display display,
+            Layer layer, uint32_t z) override;
+
+private:
+    void initCapabilities();
+
+    template<typename T>
+    void initDispatch(T& func, hwc2_function_descriptor_t desc);
+    void initDispatch();
+
+    bool hasCapability(Capability capability) const;
+
+    static void hotplugHook(hwc2_callback_data_t callbackData,
+        hwc2_display_t display, int32_t connected);
+    static void refreshHook(hwc2_callback_data_t callbackData,
+        hwc2_display_t display);
+    static void vsyncHook(hwc2_callback_data_t callbackData,
+        hwc2_display_t display, int64_t timestamp);
+
+    hwc2_device_t* mDevice;
+
+    std::unordered_set<Capability> mCapabilities;
+
+    struct {
+        HWC2_PFN_ACCEPT_DISPLAY_CHANGES acceptDisplayChanges;
+        HWC2_PFN_CREATE_LAYER createLayer;
+        HWC2_PFN_CREATE_VIRTUAL_DISPLAY createVirtualDisplay;
+        HWC2_PFN_DESTROY_LAYER destroyLayer;
+        HWC2_PFN_DESTROY_VIRTUAL_DISPLAY destroyVirtualDisplay;
+        HWC2_PFN_DUMP dump;
+        HWC2_PFN_GET_ACTIVE_CONFIG getActiveConfig;
+        HWC2_PFN_GET_CHANGED_COMPOSITION_TYPES getChangedCompositionTypes;
+        HWC2_PFN_GET_CLIENT_TARGET_SUPPORT getClientTargetSupport;
+        HWC2_PFN_GET_COLOR_MODES getColorModes;
+        HWC2_PFN_GET_DISPLAY_ATTRIBUTE getDisplayAttribute;
+        HWC2_PFN_GET_DISPLAY_CONFIGS getDisplayConfigs;
+        HWC2_PFN_GET_DISPLAY_NAME getDisplayName;
+        HWC2_PFN_GET_DISPLAY_REQUESTS getDisplayRequests;
+        HWC2_PFN_GET_DISPLAY_TYPE getDisplayType;
+        HWC2_PFN_GET_DOZE_SUPPORT getDozeSupport;
+        HWC2_PFN_GET_HDR_CAPABILITIES getHdrCapabilities;
+        HWC2_PFN_GET_MAX_VIRTUAL_DISPLAY_COUNT getMaxVirtualDisplayCount;
+        HWC2_PFN_GET_RELEASE_FENCES getReleaseFences;
+        HWC2_PFN_PRESENT_DISPLAY presentDisplay;
+        HWC2_PFN_REGISTER_CALLBACK registerCallback;
+        HWC2_PFN_SET_ACTIVE_CONFIG setActiveConfig;
+        HWC2_PFN_SET_CLIENT_TARGET setClientTarget;
+        HWC2_PFN_SET_COLOR_MODE setColorMode;
+        HWC2_PFN_SET_COLOR_TRANSFORM setColorTransform;
+        HWC2_PFN_SET_CURSOR_POSITION setCursorPosition;
+        HWC2_PFN_SET_LAYER_BLEND_MODE setLayerBlendMode;
+        HWC2_PFN_SET_LAYER_BUFFER setLayerBuffer;
+        HWC2_PFN_SET_LAYER_COLOR setLayerColor;
+        HWC2_PFN_SET_LAYER_COMPOSITION_TYPE setLayerCompositionType;
+        HWC2_PFN_SET_LAYER_DATASPACE setLayerDataspace;
+        HWC2_PFN_SET_LAYER_DISPLAY_FRAME setLayerDisplayFrame;
+        HWC2_PFN_SET_LAYER_PLANE_ALPHA setLayerPlaneAlpha;
+        HWC2_PFN_SET_LAYER_SIDEBAND_STREAM setLayerSidebandStream;
+        HWC2_PFN_SET_LAYER_SOURCE_CROP setLayerSourceCrop;
+        HWC2_PFN_SET_LAYER_SURFACE_DAMAGE setLayerSurfaceDamage;
+        HWC2_PFN_SET_LAYER_TRANSFORM setLayerTransform;
+        HWC2_PFN_SET_LAYER_VISIBLE_REGION setLayerVisibleRegion;
+        HWC2_PFN_SET_LAYER_Z_ORDER setLayerZOrder;
+        HWC2_PFN_SET_OUTPUT_BUFFER setOutputBuffer;
+        HWC2_PFN_SET_POWER_MODE setPowerMode;
+        HWC2_PFN_SET_VSYNC_ENABLED setVsyncEnabled;
+        HWC2_PFN_VALIDATE_DISPLAY validateDisplay;
+    } mDispatch;
+
+    // cloned buffers for a display
+    struct DisplayBuffers {
+        BufferClone ClientTarget;
+        BufferClone OutputBuffer;
+
+        std::unordered_map<Layer, BufferClone> LayerBuffers;
+        std::unordered_map<Layer, BufferClone> LayerSidebandStreams;
+    };
+
+    std::mutex mCallbackMutex;
+    sp<IComposerCallback> mCallback;
+
+    std::mutex mDisplayMutex;
+    std::unordered_map<Display, DisplayBuffers> mDisplays;
+};
+
+HwcHal::HwcHal(const hw_module_t* module)
+    : mDevice(nullptr), mDispatch()
+{
+    if (!sHandleImporter.initialize()) {
+        LOG_ALWAYS_FATAL("failed to initialize handle importer");
+    }
+
+    int status = hwc2_open(module, &mDevice);
+    if (status) {
+        LOG_ALWAYS_FATAL("failed to open hwcomposer2 device: %s",
+                strerror(-status));
+    }
+
+    initCapabilities();
+    initDispatch();
+}
+
+HwcHal::~HwcHal()
+{
+    hwc2_close(mDevice);
+    mDisplays.clear();
+    sHandleImporter.cleanup();
+}
+
+void HwcHal::initCapabilities()
+{
+    uint32_t count = 0;
+    mDevice->getCapabilities(mDevice, &count, nullptr);
+
+    std::vector<Capability> caps(count);
+    mDevice->getCapabilities(mDevice, &count, reinterpret_cast<
+              std::underlying_type<Capability>::type*>(caps.data()));
+    caps.resize(count);
+
+    mCapabilities.insert(caps.cbegin(), caps.cend());
+}
+
+template<typename T>
+void HwcHal::initDispatch(T& func, hwc2_function_descriptor_t desc)
+{
+    auto pfn = mDevice->getFunction(mDevice, desc);
+    if (!pfn) {
+        LOG_ALWAYS_FATAL("failed to get hwcomposer2 function %d", desc);
+    }
+
+    func = reinterpret_cast<T>(pfn);
+}
+
+void HwcHal::initDispatch()
+{
+    initDispatch(mDispatch.acceptDisplayChanges,
+            HWC2_FUNCTION_ACCEPT_DISPLAY_CHANGES);
+    initDispatch(mDispatch.createLayer, HWC2_FUNCTION_CREATE_LAYER);
+    initDispatch(mDispatch.createVirtualDisplay,
+            HWC2_FUNCTION_CREATE_VIRTUAL_DISPLAY);
+    initDispatch(mDispatch.destroyLayer, HWC2_FUNCTION_DESTROY_LAYER);
+    initDispatch(mDispatch.destroyVirtualDisplay,
+            HWC2_FUNCTION_DESTROY_VIRTUAL_DISPLAY);
+    initDispatch(mDispatch.dump, HWC2_FUNCTION_DUMP);
+    initDispatch(mDispatch.getActiveConfig, HWC2_FUNCTION_GET_ACTIVE_CONFIG);
+    initDispatch(mDispatch.getChangedCompositionTypes,
+            HWC2_FUNCTION_GET_CHANGED_COMPOSITION_TYPES);
+    initDispatch(mDispatch.getClientTargetSupport,
+            HWC2_FUNCTION_GET_CLIENT_TARGET_SUPPORT);
+    initDispatch(mDispatch.getColorModes, HWC2_FUNCTION_GET_COLOR_MODES);
+    initDispatch(mDispatch.getDisplayAttribute,
+            HWC2_FUNCTION_GET_DISPLAY_ATTRIBUTE);
+    initDispatch(mDispatch.getDisplayConfigs,
+            HWC2_FUNCTION_GET_DISPLAY_CONFIGS);
+    initDispatch(mDispatch.getDisplayName, HWC2_FUNCTION_GET_DISPLAY_NAME);
+    initDispatch(mDispatch.getDisplayRequests,
+            HWC2_FUNCTION_GET_DISPLAY_REQUESTS);
+    initDispatch(mDispatch.getDisplayType, HWC2_FUNCTION_GET_DISPLAY_TYPE);
+    initDispatch(mDispatch.getDozeSupport, HWC2_FUNCTION_GET_DOZE_SUPPORT);
+    initDispatch(mDispatch.getHdrCapabilities,
+            HWC2_FUNCTION_GET_HDR_CAPABILITIES);
+    initDispatch(mDispatch.getMaxVirtualDisplayCount,
+            HWC2_FUNCTION_GET_MAX_VIRTUAL_DISPLAY_COUNT);
+    initDispatch(mDispatch.getReleaseFences,
+            HWC2_FUNCTION_GET_RELEASE_FENCES);
+    initDispatch(mDispatch.presentDisplay, HWC2_FUNCTION_PRESENT_DISPLAY);
+    initDispatch(mDispatch.registerCallback, HWC2_FUNCTION_REGISTER_CALLBACK);
+    initDispatch(mDispatch.setActiveConfig, HWC2_FUNCTION_SET_ACTIVE_CONFIG);
+    initDispatch(mDispatch.setClientTarget, HWC2_FUNCTION_SET_CLIENT_TARGET);
+    initDispatch(mDispatch.setColorMode, HWC2_FUNCTION_SET_COLOR_MODE);
+    initDispatch(mDispatch.setColorTransform,
+            HWC2_FUNCTION_SET_COLOR_TRANSFORM);
+    initDispatch(mDispatch.setCursorPosition,
+            HWC2_FUNCTION_SET_CURSOR_POSITION);
+    initDispatch(mDispatch.setLayerBlendMode,
+            HWC2_FUNCTION_SET_LAYER_BLEND_MODE);
+    initDispatch(mDispatch.setLayerBuffer, HWC2_FUNCTION_SET_LAYER_BUFFER);
+    initDispatch(mDispatch.setLayerColor, HWC2_FUNCTION_SET_LAYER_COLOR);
+    initDispatch(mDispatch.setLayerCompositionType,
+            HWC2_FUNCTION_SET_LAYER_COMPOSITION_TYPE);
+    initDispatch(mDispatch.setLayerDataspace,
+            HWC2_FUNCTION_SET_LAYER_DATASPACE);
+    initDispatch(mDispatch.setLayerDisplayFrame,
+            HWC2_FUNCTION_SET_LAYER_DISPLAY_FRAME);
+    initDispatch(mDispatch.setLayerPlaneAlpha,
+            HWC2_FUNCTION_SET_LAYER_PLANE_ALPHA);
+
+    if (hasCapability(Capability::SIDEBAND_STREAM)) {
+        initDispatch(mDispatch.setLayerSidebandStream,
+                HWC2_FUNCTION_SET_LAYER_SIDEBAND_STREAM);
+    }
+
+    initDispatch(mDispatch.setLayerSourceCrop,
+            HWC2_FUNCTION_SET_LAYER_SOURCE_CROP);
+    initDispatch(mDispatch.setLayerSurfaceDamage,
+            HWC2_FUNCTION_SET_LAYER_SURFACE_DAMAGE);
+    initDispatch(mDispatch.setLayerTransform,
+            HWC2_FUNCTION_SET_LAYER_TRANSFORM);
+    initDispatch(mDispatch.setLayerVisibleRegion,
+            HWC2_FUNCTION_SET_LAYER_VISIBLE_REGION);
+    initDispatch(mDispatch.setLayerZOrder, HWC2_FUNCTION_SET_LAYER_Z_ORDER);
+    initDispatch(mDispatch.setOutputBuffer, HWC2_FUNCTION_SET_OUTPUT_BUFFER);
+    initDispatch(mDispatch.setPowerMode, HWC2_FUNCTION_SET_POWER_MODE);
+    initDispatch(mDispatch.setVsyncEnabled, HWC2_FUNCTION_SET_VSYNC_ENABLED);
+    initDispatch(mDispatch.validateDisplay, HWC2_FUNCTION_VALIDATE_DISPLAY);
+}
+
+bool HwcHal::hasCapability(Capability capability) const
+{
+    return (mCapabilities.count(capability) > 0);
+}
+
+Return<void> HwcHal::getCapabilities(getCapabilities_cb hidl_cb)
+{
+    std::vector<Capability> caps(
+            mCapabilities.cbegin(), mCapabilities.cend());
+
+    hidl_vec<Capability> caps_reply;
+    caps_reply.setToExternal(caps.data(), caps.size());
+    hidl_cb(caps_reply);
+
+    return Void();
+}
+
+Return<void> HwcHal::dumpDebugInfo(dumpDebugInfo_cb hidl_cb)
+{
+    uint32_t len;
+    mDispatch.dump(mDevice, &len, nullptr);
+
+    std::vector<char> buf(len + 1);
+    mDispatch.dump(mDevice, &len, buf.data());
+    buf.resize(len + 1);
+    buf[len] = '\0';
+
+    hidl_string buf_reply;
+    buf_reply.setToExternal(buf.data(), len);
+    hidl_cb(buf_reply);
+
+    return Void();
+}
+
+void HwcHal::hotplugHook(hwc2_callback_data_t callbackData,
+        hwc2_display_t display, int32_t connected)
+{
+    auto hal = reinterpret_cast<HwcHal*>(callbackData);
+
+    {
+        std::lock_guard<std::mutex> lock(hal->mDisplayMutex);
+
+        if (connected == HWC2_CONNECTION_CONNECTED) {
+            hal->mDisplays.emplace(display, DisplayBuffers());
+        } else if (connected == HWC2_CONNECTION_DISCONNECTED) {
+            hal->mDisplays.erase(display);
+        }
+    }
+
+    hal->mCallback->onHotplug(display,
+            static_cast<IComposerCallback::Connection>(connected));
+}
+
+void HwcHal::refreshHook(hwc2_callback_data_t callbackData,
+        hwc2_display_t display)
+{
+    auto hal = reinterpret_cast<HwcHal*>(callbackData);
+    hal->mCallback->onRefresh(display);
+}
+
+void HwcHal::vsyncHook(hwc2_callback_data_t callbackData,
+        hwc2_display_t display, int64_t timestamp)
+{
+    auto hal = reinterpret_cast<HwcHal*>(callbackData);
+    hal->mCallback->onVsync(display, timestamp);
+}
+
+Return<void> HwcHal::registerCallback(const sp<IComposerCallback>& callback)
+{
+    std::lock_guard<std::mutex> lock(mCallbackMutex);
+
+    mCallback = callback;
+
+    mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this,
+            reinterpret_cast<hwc2_function_pointer_t>(hotplugHook));
+    mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this,
+            reinterpret_cast<hwc2_function_pointer_t>(refreshHook));
+    mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC, this,
+            reinterpret_cast<hwc2_function_pointer_t>(vsyncHook));
+
+    return Void();
+}
+
+Return<uint32_t> HwcHal::getMaxVirtualDisplayCount()
+{
+    return mDispatch.getMaxVirtualDisplayCount(mDevice);
+}
+
+Return<void> HwcHal::createVirtualDisplay(uint32_t width, uint32_t height,
+        PixelFormat formatHint, createVirtualDisplay_cb hidl_cb)
+{
+    int32_t format = static_cast<int32_t>(formatHint);
+    hwc2_display_t display;
+    auto error = mDispatch.createVirtualDisplay(mDevice, width, height,
+            &format, &display);
+    if (error == HWC2_ERROR_NONE) {
+        std::lock_guard<std::mutex> lock(mDisplayMutex);
+
+        mDisplays.emplace(display, DisplayBuffers());
+    }
+
+    hidl_cb(static_cast<Error>(error), display,
+            static_cast<PixelFormat>(format));
+
+    return Void();
+}
+
+Return<Error> HwcHal::destroyVirtualDisplay(Display display)
+{
+    auto error = mDispatch.destroyVirtualDisplay(mDevice, display);
+    if (error == HWC2_ERROR_NONE) {
+        std::lock_guard<std::mutex> lock(mDisplayMutex);
+
+        mDisplays.erase(display);
+    }
+
+    return static_cast<Error>(error);
+}
+
+Return<Error> HwcHal::acceptDisplayChanges(Display display)
+{
+    auto error = mDispatch.acceptDisplayChanges(mDevice, display);
+    return static_cast<Error>(error);
+}
+
+Return<void> HwcHal::createLayer(Display display, createLayer_cb hidl_cb)
+{
+    hwc2_layer_t layer;
+    auto error = mDispatch.createLayer(mDevice, display, &layer);
+
+    hidl_cb(static_cast<Error>(error), layer);
+
+    return Void();
+}
+
+Return<Error> HwcHal::destroyLayer(Display display, Layer layer)
+{
+    auto error = mDispatch.destroyLayer(mDevice, display, layer);
+    return static_cast<Error>(error);
+}
+
+Return<void> HwcHal::getActiveConfig(Display display,
+        getActiveConfig_cb hidl_cb)
+{
+    hwc2_config_t config;
+    auto error = mDispatch.getActiveConfig(mDevice, display, &config);
+
+    hidl_cb(static_cast<Error>(error), config);
+
+    return Void();
+}
+
+Return<void> HwcHal::getChangedCompositionTypes(Display display,
+        getChangedCompositionTypes_cb hidl_cb)
+{
+    uint32_t count = 0;
+    auto error = mDispatch.getChangedCompositionTypes(mDevice, display,
+            &count, nullptr, nullptr);
+    if (error != HWC2_ERROR_NONE) {
+        count = 0;
+    }
+
+    std::vector<hwc2_layer_t> layers(count);
+    std::vector<Composition> types(count);
+    error = mDispatch.getChangedCompositionTypes(mDevice, display,
+            &count, layers.data(),
+            reinterpret_cast<std::underlying_type<Composition>::type*>(
+                types.data()));
+    if (error != HWC2_ERROR_NONE) {
+        count = 0;
+    }
+    layers.resize(count);
+    types.resize(count);
+
+    hidl_vec<Layer> layers_reply;
+    layers_reply.setToExternal(layers.data(), layers.size());
+
+    hidl_vec<Composition> types_reply;
+    types_reply.setToExternal(types.data(), types.size());
+
+    hidl_cb(static_cast<Error>(error), layers_reply, types_reply);
+
+    return Void();
+}
+
+Return<Error> HwcHal::getClientTargetSupport(Display display,
+        uint32_t width, uint32_t height,
+        PixelFormat format, Dataspace dataspace)
+{
+    auto error = mDispatch.getClientTargetSupport(mDevice, display,
+            width, height, static_cast<int32_t>(format),
+            static_cast<int32_t>(dataspace));
+    return static_cast<Error>(error);
+}
+
+Return<void> HwcHal::getColorModes(Display display, getColorModes_cb hidl_cb)
+{
+    uint32_t count = 0;
+    auto error = mDispatch.getColorModes(mDevice, display, &count, nullptr);
+    if (error != HWC2_ERROR_NONE) {
+        count = 0;
+    }
+
+    std::vector<ColorMode> modes(count);
+    error = mDispatch.getColorModes(mDevice, display, &count,
+            reinterpret_cast<std::underlying_type<ColorMode>::type*>(
+                modes.data()));
+    if (error != HWC2_ERROR_NONE) {
+        count = 0;
+    }
+    modes.resize(count);
+
+    hidl_vec<ColorMode> modes_reply;
+    modes_reply.setToExternal(modes.data(), modes.size());
+    hidl_cb(static_cast<Error>(error), modes_reply);
+
+    return Void();
+}
+
+Return<void> HwcHal::getDisplayAttribute(Display display,
+        Config config, Attribute attribute,
+        getDisplayAttribute_cb hidl_cb)
+{
+    int32_t value;
+    auto error = mDispatch.getDisplayAttribute(mDevice, display, config,
+            static_cast<int32_t>(attribute), &value);
+
+    hidl_cb(static_cast<Error>(error), value);
+
+    return Void();
+}
+
+Return<void> HwcHal::getDisplayConfigs(Display display,
+        getDisplayConfigs_cb hidl_cb)
+{
+    uint32_t count = 0;
+    auto error = mDispatch.getDisplayConfigs(mDevice, display,
+            &count, nullptr);
+    if (error != HWC2_ERROR_NONE) {
+        count = 0;
+    }
+
+    std::vector<hwc2_config_t> configs(count);
+    error = mDispatch.getDisplayConfigs(mDevice, display,
+            &count, configs.data());
+    if (error != HWC2_ERROR_NONE) {
+        count = 0;
+    }
+    configs.resize(count);
+
+    hidl_vec<Config> configs_reply;
+    configs_reply.setToExternal(configs.data(), configs.size());
+    hidl_cb(static_cast<Error>(error), configs_reply);
+
+    return Void();
+}
+
+Return<void> HwcHal::getDisplayName(Display display,
+        getDisplayName_cb hidl_cb)
+{
+    uint32_t count = 0;
+    auto error = mDispatch.getDisplayName(mDevice, display, &count, nullptr);
+    if (error != HWC2_ERROR_NONE) {
+        count = 0;
+    }
+
+    std::vector<char> name(count + 1);
+    error = mDispatch.getDisplayName(mDevice, display, &count, name.data());
+    if (error != HWC2_ERROR_NONE) {
+        count = 0;
+    }
+    name.resize(count + 1);
+    name[count] = '\0';
+
+    hidl_string name_reply;
+    name_reply.setToExternal(name.data(), count);
+    hidl_cb(static_cast<Error>(error), name_reply);
+
+    return Void();
+}
+
+Return<void> HwcHal::getDisplayRequests(Display display,
+        getDisplayRequests_cb hidl_cb)
+{
+    int32_t display_reqs;
+    uint32_t count = 0;
+    auto error = mDispatch.getDisplayRequests(mDevice, display,
+            &display_reqs, &count, nullptr, nullptr);
+    if (error != HWC2_ERROR_NONE) {
+        count = 0;
+    }
+
+    std::vector<hwc2_layer_t> layers(count);
+    std::vector<int32_t> layer_reqs(count);
+    error = mDispatch.getDisplayRequests(mDevice, display,
+            &display_reqs, &count, layers.data(), layer_reqs.data());
+    if (error != HWC2_ERROR_NONE) {
+        count = 0;
+    }
+    layers.resize(count);
+    layer_reqs.resize(count);
+
+    hidl_vec<Layer> layers_reply;
+    layers_reply.setToExternal(layers.data(), layers.size());
+
+    hidl_vec<uint32_t> layer_reqs_reply;
+    layer_reqs_reply.setToExternal(
+            reinterpret_cast<uint32_t*>(layer_reqs.data()),
+            layer_reqs.size());
+
+    hidl_cb(static_cast<Error>(error), display_reqs,
+            layers_reply, layer_reqs_reply);
+
+    return Void();
+}
+
+Return<void> HwcHal::getDisplayType(Display display,
+        getDisplayType_cb hidl_cb)
+{
+    int32_t type;
+    auto error = mDispatch.getDisplayType(mDevice, display, &type);
+
+    hidl_cb(static_cast<Error>(error), static_cast<DisplayType>(type));
+
+    return Void();
+}
+
+Return<void> HwcHal::getDozeSupport(Display display,
+        getDozeSupport_cb hidl_cb)
+{
+    int32_t support;
+    auto error = mDispatch.getDozeSupport(mDevice, display, &support);
+
+    hidl_cb(static_cast<Error>(error), support);
+
+    return Void();
+}
+
+Return<void> HwcHal::getHdrCapabilities(Display display,
+        getHdrCapabilities_cb hidl_cb)
+{
+    float max_lumi, max_avg_lumi, min_lumi;
+    uint32_t count = 0;
+    auto error = mDispatch.getHdrCapabilities(mDevice, display,
+            &count, nullptr, &max_lumi, &max_avg_lumi, &min_lumi);
+    if (error != HWC2_ERROR_NONE) {
+        count = 0;
+    }
+
+    std::vector<Hdr> types(count);
+    error = mDispatch.getHdrCapabilities(mDevice, display, &count,
+            reinterpret_cast<std::underlying_type<Hdr>::type*>(types.data()),
+            &max_lumi, &max_avg_lumi, &min_lumi);
+    if (error != HWC2_ERROR_NONE) {
+        count = 0;
+    }
+    types.resize(count);
+
+    hidl_vec<Hdr> types_reply;
+    types_reply.setToExternal(types.data(), types.size());
+    hidl_cb(static_cast<Error>(error), types_reply,
+            max_lumi, max_avg_lumi, min_lumi);
+
+    return Void();
+}
+
+Return<void> HwcHal::getReleaseFences(Display display,
+        getReleaseFences_cb hidl_cb)
+{
+    uint32_t count = 0;
+    auto error = mDispatch.getReleaseFences(mDevice, display,
+            &count, nullptr, nullptr);
+    if (error != HWC2_ERROR_NONE) {
+        count = 0;
+    }
+
+    std::vector<hwc2_layer_t> layers(count);
+    std::vector<int32_t> fences(count);
+    error = mDispatch.getReleaseFences(mDevice, display,
+            &count, layers.data(), fences.data());
+    if (error != HWC2_ERROR_NONE) {
+        count = 0;
+    }
+    layers.resize(count);
+    fences.resize(count);
+
+    // filter out layers with release fence -1
+    std::vector<hwc2_layer_t> filtered_layers;
+    std::vector<int> filtered_fences;
+    for (size_t i = 0; i < layers.size(); i++) {
+        if (fences[i] >= 0) {
+            filtered_layers.push_back(layers[i]);
+            filtered_fences.push_back(fences[i]);
+        }
+    }
+
+    hidl_vec<Layer> layers_reply;
+    native_handle_t* fences_reply =
+        native_handle_create(filtered_fences.size(), 0);
+    if (fences_reply) {
+        layers_reply.setToExternal(filtered_layers.data(),
+                filtered_layers.size());
+        memcpy(fences_reply->data, filtered_fences.data(),
+                sizeof(int) * filtered_fences.size());
+
+        hidl_cb(static_cast<Error>(error), layers_reply, fences_reply);
+
+        native_handle_close(fences_reply);
+        native_handle_delete(fences_reply);
+    } else {
+        NATIVE_HANDLE_DECLARE_STORAGE(fences_storage, 0, 0);
+        fences_reply = native_handle_init(fences_storage, 0, 0);
+
+        hidl_cb(Error::NO_RESOURCES, layers_reply, fences_reply);
+
+        for (auto fence : filtered_fences) {
+            close(fence);
+        }
+    }
+
+    return Void();
+}
+
+Return<void> HwcHal::presentDisplay(Display display,
+        presentDisplay_cb hidl_cb)
+{
+    int32_t fence = -1;
+    auto error = mDispatch.presentDisplay(mDevice, display, &fence);
+
+    NATIVE_HANDLE_DECLARE_STORAGE(fence_storage, 1, 0);
+    native_handle_t* fence_reply;
+    if (fence >= 0) {
+        fence_reply = native_handle_init(fence_storage, 1, 0);
+        fence_reply->data[0] = fence;
+    } else {
+        fence_reply = native_handle_init(fence_storage, 0, 0);
+    }
+
+    hidl_cb(static_cast<Error>(error), fence_reply);
+
+    if (fence >= 0) {
+        close(fence);
+    }
+
+    return Void();
+}
+
+Return<Error> HwcHal::setActiveConfig(Display display, Config config)
+{
+    auto error = mDispatch.setActiveConfig(mDevice, display, config);
+    return static_cast<Error>(error);
+}
+
+Return<Error> HwcHal::setClientTarget(Display display,
+        const native_handle_t* target,
+        const native_handle_t* acquireFence,
+        Dataspace dataspace, const hidl_vec<Rect>& damage)
+{
+    if (!sHandleImporter.importBuffer(target)) {
+        return Error::NO_RESOURCES;
+    }
+
+    int32_t fence;
+    if (!sHandleImporter.importFence(acquireFence, fence)) {
+        sHandleImporter.freeBuffer(target);
+        return Error::NO_RESOURCES;
+    }
+
+    hwc_region_t damage_region = { damage.size(),
+        reinterpret_cast<const hwc_rect_t*>(&damage[0]) };
+
+    int32_t error = mDispatch.setClientTarget(mDevice, display,
+            target, fence, static_cast<int32_t>(dataspace),
+            damage_region);
+    if (error == HWC2_ERROR_NONE) {
+        std::lock_guard<std::mutex> lock(mDisplayMutex);
+
+        auto dpy = mDisplays.find(display);
+        dpy->second.ClientTarget = target;
+    } else {
+        sHandleImporter.freeBuffer(target);
+        sHandleImporter.closeFence(fence);
+    }
+
+    return static_cast<Error>(error);
+}
+
+Return<Error> HwcHal::setColorMode(Display display, ColorMode mode)
+{
+    auto error = mDispatch.setColorMode(mDevice, display,
+            static_cast<int32_t>(mode));
+    return static_cast<Error>(error);
+}
+
+Return<Error> HwcHal::setColorTransform(Display display,
+        const hidl_vec<float>& matrix, ColorTransform hint)
+{
+    auto error = mDispatch.setColorTransform(mDevice, display,
+            &matrix[0], static_cast<int32_t>(hint));
+    return static_cast<Error>(error);
+}
+
+Return<Error> HwcHal::setOutputBuffer(Display display,
+        const native_handle_t* buffer,
+        const native_handle_t* releaseFence)
+{
+    if (!sHandleImporter.importBuffer(buffer)) {
+        return Error::NO_RESOURCES;
+    }
+
+    int32_t fence;
+    if (!sHandleImporter.importFence(releaseFence, fence)) {
+        sHandleImporter.freeBuffer(buffer);
+        return Error::NO_RESOURCES;
+    }
+
+    int32_t error = mDispatch.setOutputBuffer(mDevice,
+            display, buffer, fence);
+    if (error == HWC2_ERROR_NONE) {
+        std::lock_guard<std::mutex> lock(mDisplayMutex);
+
+        auto dpy = mDisplays.find(display);
+        dpy->second.OutputBuffer = buffer;
+    } else {
+        sHandleImporter.freeBuffer(buffer);
+    }
+
+    // unlike in setClientTarget, fence is owned by us and is always closed
+    sHandleImporter.closeFence(fence);
+
+    return static_cast<Error>(error);
+}
+
+Return<Error> HwcHal::setPowerMode(Display display, PowerMode mode)
+{
+    auto error = mDispatch.setPowerMode(mDevice, display,
+            static_cast<int32_t>(mode));
+    return static_cast<Error>(error);
+}
+
+Return<Error> HwcHal::setVsyncEnabled(Display display,
+        Vsync enabled)
+{
+    auto error = mDispatch.setVsyncEnabled(mDevice, display,
+            static_cast<int32_t>(enabled));
+    return static_cast<Error>(error);
+}
+
+Return<void> HwcHal::validateDisplay(Display display,
+        validateDisplay_cb hidl_cb)
+{
+    uint32_t types_count = 0;
+    uint32_t reqs_count = 0;
+    auto error = mDispatch.validateDisplay(mDevice, display,
+            &types_count, &reqs_count);
+
+    hidl_cb(static_cast<Error>(error), types_count, reqs_count);
+
+    return Void();
+}
+
+Return<Error> HwcHal::setCursorPosition(Display display,
+        Layer layer, int32_t x, int32_t y)
+{
+    auto error = mDispatch.setCursorPosition(mDevice, display, layer, x, y);
+    return static_cast<Error>(error);
+}
+
+Return<Error> HwcHal::setLayerBuffer(Display display,
+        Layer layer, const native_handle_t* buffer,
+        const native_handle_t* acquireFence)
+{
+    if (!sHandleImporter.importBuffer(buffer)) {
+        return Error::NO_RESOURCES;
+    }
+
+    int32_t fence;
+    if (!sHandleImporter.importFence(acquireFence, fence)) {
+        sHandleImporter.freeBuffer(buffer);
+        return Error::NO_RESOURCES;
+    }
+
+    int32_t error = mDispatch.setLayerBuffer(mDevice,
+            display, layer, buffer, fence);
+    if (error == HWC2_ERROR_NONE) {
+        std::lock_guard<std::mutex> lock(mDisplayMutex);
+
+        auto dpy = mDisplays.find(display);
+        dpy->second.LayerBuffers[layer] = buffer;
+    } else {
+        sHandleImporter.freeBuffer(buffer);
+        sHandleImporter.closeFence(fence);
+    }
+
+    return static_cast<Error>(error);
+}
+
+Return<Error> HwcHal::setLayerSurfaceDamage(Display display,
+        Layer layer, const hidl_vec<Rect>& damage)
+{
+    hwc_region_t damage_region = { damage.size(),
+        reinterpret_cast<const hwc_rect_t*>(&damage[0]) };
+
+    auto error = mDispatch.setLayerSurfaceDamage(mDevice, display, layer,
+            damage_region);
+    return static_cast<Error>(error);
+}
+
+Return<Error> HwcHal::setLayerBlendMode(Display display,
+        Layer layer, BlendMode mode)
+{
+    auto error = mDispatch.setLayerBlendMode(mDevice, display, layer,
+            static_cast<int32_t>(mode));
+    return static_cast<Error>(error);
+}
+
+Return<Error> HwcHal::setLayerColor(Display display,
+        Layer layer, const Color& color)
+{
+    hwc_color_t hwc_color{color.r, color.g, color.b, color.a};
+    auto error = mDispatch.setLayerColor(mDevice, display, layer, hwc_color);
+    return static_cast<Error>(error);
+}
+
+Return<Error> HwcHal::setLayerCompositionType(Display display,
+        Layer layer, Composition type)
+{
+    auto error = mDispatch.setLayerCompositionType(mDevice, display, layer,
+            static_cast<int32_t>(type));
+    return static_cast<Error>(error);
+}
+
+Return<Error> HwcHal::setLayerDataspace(Display display,
+        Layer layer, Dataspace dataspace)
+{
+    auto error = mDispatch.setLayerDataspace(mDevice, display, layer,
+            static_cast<int32_t>(dataspace));
+    return static_cast<Error>(error);
+}
+
+Return<Error> HwcHal::setLayerDisplayFrame(Display display,
+        Layer layer, const Rect& frame)
+{
+    hwc_rect_t hwc_frame{frame.left, frame.top, frame.right, frame.bottom};
+    auto error = mDispatch.setLayerDisplayFrame(mDevice, display, layer,
+            hwc_frame);
+    return static_cast<Error>(error);
+}
+
+Return<Error> HwcHal::setLayerPlaneAlpha(Display display,
+        Layer layer, float alpha)
+{
+    auto error = mDispatch.setLayerPlaneAlpha(mDevice, display, layer, alpha);
+    return static_cast<Error>(error);
+}
+
+Return<Error> HwcHal::setLayerSidebandStream(Display display,
+        Layer layer, const native_handle_t* stream)
+{
+    if (!sHandleImporter.importBuffer(stream)) {
+        return Error::NO_RESOURCES;
+    }
+
+    int32_t error = mDispatch.setLayerSidebandStream(mDevice,
+            display, layer, stream);
+    if (error == HWC2_ERROR_NONE) {
+        std::lock_guard<std::mutex> lock(mDisplayMutex);
+
+        auto dpy = mDisplays.find(display);
+        dpy->second.LayerSidebandStreams[layer] = stream;
+    } else {
+        sHandleImporter.freeBuffer(stream);
+    }
+
+    return static_cast<Error>(error);
+}
+
+Return<Error> HwcHal::setLayerSourceCrop(Display display,
+        Layer layer, const FRect& crop)
+{
+    hwc_frect_t hwc_crop{crop.left, crop.top, crop.right, crop.bottom};
+    auto error = mDispatch.setLayerSourceCrop(mDevice, display, layer,
+            hwc_crop);
+    return static_cast<Error>(error);
+}
+
+Return<Error> HwcHal::setLayerTransform(Display display,
+        Layer layer, Transform transform)
+{
+    auto error = mDispatch.setLayerTransform(mDevice, display, layer,
+            static_cast<int32_t>(transform));
+    return static_cast<Error>(error);
+}
+
+Return<Error> HwcHal::setLayerVisibleRegion(Display display,
+        Layer layer, const hidl_vec<Rect>& visible)
+{
+    hwc_region_t visible_region = { visible.size(),
+        reinterpret_cast<const hwc_rect_t*>(&visible[0]) };
+
+    auto error = mDispatch.setLayerVisibleRegion(mDevice, display, layer,
+            visible_region);
+    return static_cast<Error>(error);
+}
+
+Return<Error> HwcHal::setLayerZOrder(Display display,
+        Layer layer, uint32_t z)
+{
+    auto error = mDispatch.setLayerZOrder(mDevice, display, layer, z);
+    return static_cast<Error>(error);
+}
+
+IComposer* HIDL_FETCH_IComposer(const char*)
+{
+    const hw_module_t* module;
+    int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &module);
+    if (err) {
+        ALOGE("failed to get hwcomposer module");
+        return nullptr;
+    }
+
+    return new HwcHal(module);
+}
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace composer
+} // namespace graphics
+} // namespace hardware
+} // namespace android
diff --git a/graphics/composer/2.1/default/Hwc.h b/graphics/composer/2.1/default/Hwc.h
new file mode 100644
index 0000000..de69417
--- /dev/null
+++ b/graphics/composer/2.1/default/Hwc.h
@@ -0,0 +1,38 @@
+/*
+ * 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 ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_HWC_H
+#define ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_HWC_H
+
+#include <android/hardware/graphics/composer/2.1/IComposer.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace composer {
+namespace V2_1 {
+namespace implementation {
+
+extern "C" IComposer* HIDL_FETCH_IComposer(const char* name);
+
+} // namespace implementation
+} // namespace V2_1
+} // namespace composer
+} // namespace graphics
+} // namespace hardware
+} // namespace android
+
+#endif  // ANDROID_HARDWARE_GRAPHICS_COMPOSER_V2_1_HWC_H
