diff --git a/graphics/allocator/2.0/default/Android.bp b/graphics/allocator/2.0/default/Android.bp
index 994feb3..f0c736c 100644
--- a/graphics/allocator/2.0/default/Android.bp
+++ b/graphics/allocator/2.0/default/Android.bp
@@ -34,7 +34,7 @@
 
 cc_library_static {
     name: "libgralloc1-adapter",
-    srcs: ["gralloc1-adapter.c"],
+    srcs: ["gralloc1-adapter.cpp", "Gralloc1On0Adapter.cpp"],
     include_dirs: ["system/core/libsync/include"],
     cflags: ["-Wall", "-Wextra", "-Wno-unused-parameter"],
     export_include_dirs: ["."],
diff --git a/graphics/allocator/2.0/default/Gralloc1On0Adapter.cpp b/graphics/allocator/2.0/default/Gralloc1On0Adapter.cpp
new file mode 100644
index 0000000..4b9c9e1
--- /dev/null
+++ b/graphics/allocator/2.0/default/Gralloc1On0Adapter.cpp
@@ -0,0 +1,560 @@
+/*
+ * 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.
+ */
+
+#undef LOG_TAG
+#define LOG_TAG "Gralloc1On0Adapter"
+//#define LOG_NDEBUG 0
+
+#include "Gralloc1On0Adapter.h"
+#include "gralloc1-adapter.h"
+
+#include <hardware/gralloc.h>
+
+#include <utils/Log.h>
+#include <sync/sync.h>
+
+#include <inttypes.h>
+
+template <typename PFN, typename T>
+static gralloc1_function_pointer_t asFP(T function)
+{
+    static_assert(std::is_same<PFN, T>::value, "Incompatible function pointer");
+    return reinterpret_cast<gralloc1_function_pointer_t>(function);
+}
+
+namespace android {
+namespace hardware {
+
+Gralloc1On0Adapter::Gralloc1On0Adapter(const hw_module_t* module)
+  : gralloc1_device_t(),
+    mModule(reinterpret_cast<const gralloc_module_t*>(module)),
+    mDevice(nullptr)
+{
+    ALOGV("Constructing");
+
+    int minor = 0;
+    mModule->perform(mModule,
+            GRALLOC1_ADAPTER_PERFORM_GET_REAL_MODULE_API_VERSION_MINOR,
+            &minor);
+    mMinorVersion = minor;
+
+    common.tag = HARDWARE_DEVICE_TAG,
+    common.version = HARDWARE_DEVICE_API_VERSION(0, 0),
+    common.module = const_cast<struct hw_module_t*>(module),
+    common.close = closeHook,
+
+    getCapabilities = getCapabilitiesHook;
+    getFunction = getFunctionHook;
+    int error = ::gralloc_open(&(mModule->common), &mDevice);
+    if (error) {
+        ALOGE("Failed to open gralloc0 module: %d", error);
+    }
+    ALOGV("Opened gralloc0 device %p", mDevice);
+}
+
+Gralloc1On0Adapter::~Gralloc1On0Adapter()
+{
+    ALOGV("Destructing");
+    if (mDevice) {
+        ALOGV("Closing gralloc0 device %p", mDevice);
+        ::gralloc_close(mDevice);
+    }
+}
+
+void Gralloc1On0Adapter::doGetCapabilities(uint32_t* outCount,
+        int32_t* outCapabilities)
+{
+    *outCount = 0;
+}
+
+gralloc1_function_pointer_t Gralloc1On0Adapter::doGetFunction(
+        int32_t intDescriptor)
+{
+    constexpr auto lastDescriptor =
+            static_cast<int32_t>(GRALLOC1_LAST_FUNCTION);
+    if (intDescriptor < 0 || intDescriptor > lastDescriptor) {
+        ALOGE("Invalid function descriptor");
+        return nullptr;
+    }
+
+    auto descriptor =
+            static_cast<gralloc1_function_descriptor_t>(intDescriptor);
+    switch (descriptor) {
+        case GRALLOC1_FUNCTION_DUMP:
+            return asFP<GRALLOC1_PFN_DUMP>(dumpHook);
+        case GRALLOC1_FUNCTION_CREATE_DESCRIPTOR:
+            return asFP<GRALLOC1_PFN_CREATE_DESCRIPTOR>(createDescriptorHook);
+        case GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR:
+            return asFP<GRALLOC1_PFN_DESTROY_DESCRIPTOR>(destroyDescriptorHook);
+        case GRALLOC1_FUNCTION_SET_CONSUMER_USAGE:
+            return asFP<GRALLOC1_PFN_SET_CONSUMER_USAGE>(setConsumerUsageHook);
+        case GRALLOC1_FUNCTION_SET_DIMENSIONS:
+            return asFP<GRALLOC1_PFN_SET_DIMENSIONS>(setDimensionsHook);
+        case GRALLOC1_FUNCTION_SET_FORMAT:
+            return asFP<GRALLOC1_PFN_SET_FORMAT>(setFormatHook);
+        case GRALLOC1_FUNCTION_SET_LAYER_COUNT:
+            return asFP<GRALLOC1_PFN_SET_LAYER_COUNT>(setLayerCountHook);
+        case GRALLOC1_FUNCTION_SET_PRODUCER_USAGE:
+            return asFP<GRALLOC1_PFN_SET_PRODUCER_USAGE>(setProducerUsageHook);
+        case GRALLOC1_FUNCTION_GET_BACKING_STORE:
+            return asFP<GRALLOC1_PFN_GET_BACKING_STORE>(
+                    bufferHook<decltype(&Buffer::getBackingStore),
+                    &Buffer::getBackingStore, gralloc1_backing_store_t*>);
+        case GRALLOC1_FUNCTION_GET_CONSUMER_USAGE:
+            return asFP<GRALLOC1_PFN_GET_CONSUMER_USAGE>(getConsumerUsageHook);
+        case GRALLOC1_FUNCTION_GET_DIMENSIONS:
+            return asFP<GRALLOC1_PFN_GET_DIMENSIONS>(
+                    bufferHook<decltype(&Buffer::getDimensions),
+                    &Buffer::getDimensions, uint32_t*, uint32_t*>);
+        case GRALLOC1_FUNCTION_GET_FORMAT:
+            return asFP<GRALLOC1_PFN_GET_FORMAT>(
+                    bufferHook<decltype(&Buffer::getFormat),
+                    &Buffer::getFormat, int32_t*>);
+        case GRALLOC1_FUNCTION_GET_LAYER_COUNT:
+            return asFP<GRALLOC1_PFN_GET_LAYER_COUNT>(
+                    bufferHook<decltype(&Buffer::getLayerCount),
+                    &Buffer::getLayerCount, uint32_t*>);
+        case GRALLOC1_FUNCTION_GET_PRODUCER_USAGE:
+            return asFP<GRALLOC1_PFN_GET_PRODUCER_USAGE>(getProducerUsageHook);
+        case GRALLOC1_FUNCTION_GET_STRIDE:
+            return asFP<GRALLOC1_PFN_GET_STRIDE>(
+                    bufferHook<decltype(&Buffer::getStride),
+                    &Buffer::getStride, uint32_t*>);
+        case GRALLOC1_FUNCTION_ALLOCATE:
+            if (mDevice != nullptr) {
+                return asFP<GRALLOC1_PFN_ALLOCATE>(allocateHook);
+            } else {
+                return nullptr;
+            }
+        case GRALLOC1_FUNCTION_RETAIN:
+            return asFP<GRALLOC1_PFN_RETAIN>(retainHook);
+        case GRALLOC1_FUNCTION_RELEASE:
+            return asFP<GRALLOC1_PFN_RELEASE>(releaseHook);
+        case GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES:
+            return asFP<GRALLOC1_PFN_GET_NUM_FLEX_PLANES>(
+                    bufferHook<decltype(&Buffer::getNumFlexPlanes),
+                    &Buffer::getNumFlexPlanes, uint32_t*>);
+        case GRALLOC1_FUNCTION_LOCK:
+            return asFP<GRALLOC1_PFN_LOCK>(
+                    lockHook<void*, &Gralloc1On0Adapter::lock>);
+        case GRALLOC1_FUNCTION_LOCK_FLEX:
+            return asFP<GRALLOC1_PFN_LOCK_FLEX>(
+                    lockHook<struct android_flex_layout,
+                    &Gralloc1On0Adapter::lockFlex>);
+        case GRALLOC1_FUNCTION_UNLOCK:
+            return asFP<GRALLOC1_PFN_UNLOCK>(unlockHook);
+        case GRALLOC1_FUNCTION_INVALID:
+            ALOGE("Invalid function descriptor");
+            return nullptr;
+    }
+
+    ALOGE("Unknown function descriptor: %d", intDescriptor);
+    return nullptr;
+}
+
+void Gralloc1On0Adapter::dump(uint32_t* outSize, char* outBuffer)
+{
+    ALOGV("dump(%u (%p), %p", outSize ? *outSize : 0, outSize, outBuffer);
+
+    if (!mDevice->dump) {
+        // dump is optional on gralloc0 implementations
+        *outSize = 0;
+        return;
+    }
+
+    if (!outBuffer) {
+        constexpr int32_t BUFFER_LENGTH = 4096;
+        char buffer[BUFFER_LENGTH] = {};
+        mDevice->dump(mDevice, buffer, BUFFER_LENGTH);
+        buffer[BUFFER_LENGTH - 1] = 0; // Ensure the buffer is null-terminated
+        size_t actualLength = std::strlen(buffer);
+        mCachedDump.resize(actualLength);
+        std::copy_n(buffer, actualLength, mCachedDump.begin());
+        *outSize = static_cast<uint32_t>(actualLength);
+    } else {
+        *outSize = std::min(*outSize,
+                static_cast<uint32_t>(mCachedDump.size()));
+        outBuffer = std::copy_n(mCachedDump.cbegin(), *outSize, outBuffer);
+    }
+}
+
+gralloc1_error_t Gralloc1On0Adapter::createDescriptor(
+        gralloc1_buffer_descriptor_t* outDescriptor)
+{
+    auto descriptorId = sNextBufferDescriptorId++;
+    std::lock_guard<std::mutex> lock(mDescriptorMutex);
+    mDescriptors.emplace(descriptorId, std::make_shared<Descriptor>());
+
+    ALOGV("Created descriptor %" PRIu64, descriptorId);
+
+    *outDescriptor = descriptorId;
+    return GRALLOC1_ERROR_NONE;
+}
+
+gralloc1_error_t Gralloc1On0Adapter::destroyDescriptor(
+        gralloc1_buffer_descriptor_t descriptor)
+{
+    ALOGV("Destroying descriptor %" PRIu64, descriptor);
+
+    std::lock_guard<std::mutex> lock(mDescriptorMutex);
+    if (mDescriptors.count(descriptor) == 0) {
+        return GRALLOC1_ERROR_BAD_DESCRIPTOR;
+    }
+
+    mDescriptors.erase(descriptor);
+    return GRALLOC1_ERROR_NONE;
+}
+
+Gralloc1On0Adapter::Buffer::Buffer(buffer_handle_t handle,
+        gralloc1_backing_store_t store, const Descriptor& descriptor,
+        uint32_t stride, uint32_t numFlexPlanes, bool wasAllocated)
+  : mHandle(handle),
+    mReferenceCount(1),
+    mStore(store),
+    mDescriptor(descriptor),
+    mStride(stride),
+    mNumFlexPlanes(numFlexPlanes),
+    mWasAllocated(wasAllocated) {}
+
+gralloc1_error_t Gralloc1On0Adapter::allocate(
+        gralloc1_buffer_descriptor_t id,
+        const std::shared_ptr<Descriptor>& descriptor,
+        buffer_handle_t* outBufferHandle)
+{
+    ALOGV("allocate(%" PRIu64 ")", id);
+
+    // If this function is being called, it's because we handed out its function
+    // pointer, which only occurs when mDevice has been loaded successfully and
+    // we are permitted to allocate
+
+    int usage = static_cast<int>(descriptor->producerUsage) |
+            static_cast<int>(descriptor->consumerUsage);
+    buffer_handle_t handle = nullptr;
+    int stride = 0;
+    ALOGV("Calling alloc(%p, %u, %u, %i, %u)", mDevice, descriptor->width,
+            descriptor->height, descriptor->format, usage);
+    auto error = mDevice->alloc(mDevice,
+            static_cast<int>(descriptor->width),
+            static_cast<int>(descriptor->height), descriptor->format,
+            usage, &handle, &stride);
+    if (error != 0) {
+        ALOGE("gralloc0 allocation failed: %d (%s)", error,
+                strerror(-error));
+        return GRALLOC1_ERROR_NO_RESOURCES;
+    }
+
+    mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_SET_USAGES,
+            handle,
+            static_cast<int>(descriptor->producerUsage),
+            static_cast<int>(descriptor->consumerUsage));
+
+    uint64_t backingStore = 0;
+    mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_BACKING_STORE,
+            handle, &backingStore);
+    int numFlexPlanes = 0;
+    mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_NUM_FLEX_PLANES,
+            handle, &numFlexPlanes);
+
+    *outBufferHandle = handle;
+    auto buffer = std::make_shared<Buffer>(handle, backingStore,
+            *descriptor, stride, numFlexPlanes, true);
+
+    std::lock_guard<std::mutex> lock(mBufferMutex);
+    mBuffers.emplace(handle, std::move(buffer));
+
+    return GRALLOC1_ERROR_NONE;
+}
+
+int32_t Gralloc1On0Adapter::allocateHook(gralloc1_device* device,
+        uint32_t numDescriptors,
+        const gralloc1_buffer_descriptor_t* descriptors,
+        buffer_handle_t* outBuffers)
+{
+    if (!outBuffers) {
+        return GRALLOC1_ERROR_UNDEFINED;
+    }
+
+    auto adapter = getAdapter(device);
+
+    gralloc1_error_t error = GRALLOC1_ERROR_NONE;
+    uint32_t i;
+    for (i = 0; i < numDescriptors; i++) {
+        auto descriptor = adapter->getDescriptor(descriptors[i]);
+        if (!descriptor) {
+            error = GRALLOC1_ERROR_BAD_DESCRIPTOR;
+            break;
+        }
+
+        buffer_handle_t bufferHandle = nullptr;
+        error = adapter->allocate(descriptors[i], descriptor, &bufferHandle);
+        if (error != GRALLOC1_ERROR_NONE) {
+            break;
+        }
+
+        outBuffers[i] = bufferHandle;
+    }
+
+    if (error == GRALLOC1_ERROR_NONE) {
+        if (numDescriptors > 1) {
+            error = GRALLOC1_ERROR_NOT_SHARED;
+        }
+    } else {
+        for (uint32_t j = 0; j < i; j++) {
+            adapter->release(adapter->getBuffer(outBuffers[j]));
+            outBuffers[j] = nullptr;
+        }
+    }
+
+    return error;
+}
+
+gralloc1_error_t Gralloc1On0Adapter::retain(
+        const std::shared_ptr<Buffer>& buffer)
+{
+    std::lock_guard<std::mutex> lock(mBufferMutex);
+    buffer->retain();
+    return GRALLOC1_ERROR_NONE;
+}
+
+gralloc1_error_t Gralloc1On0Adapter::release(
+        const std::shared_ptr<Buffer>& buffer)
+{
+    std::lock_guard<std::mutex> lock(mBufferMutex);
+    if (!buffer->release()) {
+        return GRALLOC1_ERROR_NONE;
+    }
+
+    buffer_handle_t handle = buffer->getHandle();
+    if (buffer->wasAllocated()) {
+        ALOGV("Calling free(%p)", handle);
+        int result = mDevice->free(mDevice, handle);
+        if (result != 0) {
+            ALOGE("gralloc0 free failed: %d", result);
+        }
+    } else {
+        ALOGV("Calling unregisterBuffer(%p)", handle);
+        int result = mModule->unregisterBuffer(mModule, handle);
+        if (result != 0) {
+            ALOGE("gralloc0 unregister failed: %d", result);
+        }
+    }
+
+    mBuffers.erase(handle);
+    return GRALLOC1_ERROR_NONE;
+}
+
+gralloc1_error_t Gralloc1On0Adapter::retain(buffer_handle_t bufferHandle)
+{
+    ALOGV("retain(%p)", bufferHandle);
+
+    std::lock_guard<std::mutex> lock(mBufferMutex);
+
+    if (mBuffers.count(bufferHandle) != 0) {
+        mBuffers[bufferHandle]->retain();
+        return GRALLOC1_ERROR_NONE;
+    }
+
+    ALOGV("Calling registerBuffer(%p)", bufferHandle);
+    int result = mModule->registerBuffer(mModule, bufferHandle);
+    if (result != 0) {
+        ALOGE("gralloc0 register failed: %d", result);
+        return GRALLOC1_ERROR_NO_RESOURCES;
+    }
+
+    uint64_t backingStore = 0;
+    mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_BACKING_STORE,
+            bufferHandle, &backingStore);
+
+    int numFlexPlanes = 0;
+    mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_NUM_FLEX_PLANES,
+            bufferHandle, &numFlexPlanes);
+
+    int stride = 0;
+    mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_STRIDE,
+            bufferHandle, &stride);
+
+    int width = 0;
+    int height = 0;
+    int format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
+    int producerUsage = 0;
+    int consumerUsage = 0;
+    mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_DIMENSIONS,
+            bufferHandle, &width, &height);
+    mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_FORMAT,
+            bufferHandle, &format);
+    mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_PRODUCER_USAGE,
+            bufferHandle, &producerUsage);
+    mModule->perform(mModule, GRALLOC1_ADAPTER_PERFORM_GET_CONSUMER_USAGE,
+            bufferHandle, &consumerUsage);
+
+    Descriptor descriptor;
+    descriptor.setDimensions(width, height);
+    descriptor.setFormat(format);
+    descriptor.setProducerUsage(
+            static_cast<gralloc1_producer_usage_t>(producerUsage));
+    descriptor.setConsumerUsage(
+            static_cast<gralloc1_consumer_usage_t>(consumerUsage));
+
+    auto buffer = std::make_shared<Buffer>(bufferHandle, backingStore,
+            descriptor, stride, numFlexPlanes, false);
+    mBuffers.emplace(bufferHandle, std::move(buffer));
+    return GRALLOC1_ERROR_NONE;
+}
+
+static void syncWaitForever(int fd, const char* logname)
+{
+    if (fd < 0) {
+        return;
+    }
+
+    const int warningTimeout = 3500;
+    const int error = sync_wait(fd, warningTimeout);
+    if (error < 0 && errno == ETIME) {
+        ALOGE("%s: fence %d didn't signal in %u ms", logname, fd,
+                warningTimeout);
+        sync_wait(fd, -1);
+    }
+}
+
+gralloc1_error_t Gralloc1On0Adapter::lock(
+        const std::shared_ptr<Buffer>& buffer,
+        gralloc1_producer_usage_t producerUsage,
+        gralloc1_consumer_usage_t consumerUsage,
+        const gralloc1_rect_t& accessRegion, void** outData,
+        int acquireFence)
+{
+    if (mMinorVersion >= 3) {
+        int result = mModule->lockAsync(mModule, buffer->getHandle(),
+                static_cast<int32_t>(producerUsage | consumerUsage),
+                accessRegion.left, accessRegion.top, accessRegion.width,
+                accessRegion.height, outData, acquireFence);
+        if (result != 0) {
+            return GRALLOC1_ERROR_UNSUPPORTED;
+        }
+    } else {
+        syncWaitForever(acquireFence, "Gralloc1On0Adapter::lock");
+
+        int result = mModule->lock(mModule, buffer->getHandle(),
+                static_cast<int32_t>(producerUsage | consumerUsage),
+                accessRegion.left, accessRegion.top, accessRegion.width,
+                accessRegion.height, outData);
+        ALOGV("gralloc0 lock returned %d", result);
+        if (result != 0) {
+            return GRALLOC1_ERROR_UNSUPPORTED;
+        } else if (acquireFence >= 0) {
+            close(acquireFence);
+        }
+    }
+    return GRALLOC1_ERROR_NONE;
+}
+
+gralloc1_error_t Gralloc1On0Adapter::lockFlex(
+        const std::shared_ptr<Buffer>& buffer,
+        gralloc1_producer_usage_t producerUsage,
+        gralloc1_consumer_usage_t consumerUsage,
+        const gralloc1_rect_t& accessRegion,
+        struct android_flex_layout* outFlex,
+        int acquireFence)
+{
+    if (mMinorVersion >= 3) {
+        int result = mModule->perform(mModule,
+                GRALLOC1_ADAPTER_PERFORM_LOCK_FLEX,
+                buffer->getHandle(),
+                static_cast<int>(producerUsage),
+                static_cast<int>(consumerUsage),
+                accessRegion.left,
+                accessRegion.top,
+                accessRegion.width,
+                accessRegion.height,
+                outFlex, acquireFence);
+        if (result != 0) {
+            return GRALLOC1_ERROR_UNSUPPORTED;
+        }
+    } else {
+        syncWaitForever(acquireFence, "Gralloc1On0Adapter::lockFlex");
+
+        int result = mModule->perform(mModule,
+                GRALLOC1_ADAPTER_PERFORM_LOCK_FLEX,
+                buffer->getHandle(),
+                static_cast<int>(producerUsage),
+                static_cast<int>(consumerUsage),
+                accessRegion.left,
+                accessRegion.top,
+                accessRegion.width,
+                accessRegion.height,
+                outFlex, -1);
+        if (result != 0) {
+            return GRALLOC1_ERROR_UNSUPPORTED;
+        } else if (acquireFence >= 0) {
+            close(acquireFence);
+        }
+    }
+
+    return GRALLOC1_ERROR_NONE;
+}
+
+gralloc1_error_t Gralloc1On0Adapter::unlock(
+        const std::shared_ptr<Buffer>& buffer,
+        int* outReleaseFence)
+{
+    if (mMinorVersion >= 3) {
+        int fenceFd = -1;
+        int result = mModule->unlockAsync(mModule, buffer->getHandle(),
+                &fenceFd);
+        if (result != 0) {
+            close(fenceFd);
+            ALOGE("gralloc0 unlockAsync failed: %d", result);
+        } else {
+            *outReleaseFence = fenceFd;
+        }
+    } else {
+        int result = mModule->unlock(mModule, buffer->getHandle());
+        if (result != 0) {
+            ALOGE("gralloc0 unlock failed: %d", result);
+        } else {
+            *outReleaseFence = -1;
+        }
+    }
+    return GRALLOC1_ERROR_NONE;
+}
+
+std::shared_ptr<Gralloc1On0Adapter::Descriptor>
+Gralloc1On0Adapter::getDescriptor(gralloc1_buffer_descriptor_t descriptorId)
+{
+    std::lock_guard<std::mutex> lock(mDescriptorMutex);
+    if (mDescriptors.count(descriptorId) == 0) {
+        return nullptr;
+    }
+
+    return mDescriptors[descriptorId];
+}
+
+std::shared_ptr<Gralloc1On0Adapter::Buffer> Gralloc1On0Adapter::getBuffer(
+        buffer_handle_t bufferHandle)
+{
+    std::lock_guard<std::mutex> lock(mBufferMutex);
+    if (mBuffers.count(bufferHandle) == 0) {
+        return nullptr;
+    }
+
+    return mBuffers[bufferHandle];
+}
+
+std::atomic<gralloc1_buffer_descriptor_t>
+        Gralloc1On0Adapter::sNextBufferDescriptorId(1);
+
+} // namespace hardware
+} // namespace android
diff --git a/graphics/allocator/2.0/default/Gralloc1On0Adapter.h b/graphics/allocator/2.0/default/Gralloc1On0Adapter.h
new file mode 100644
index 0000000..180015d
--- /dev/null
+++ b/graphics/allocator/2.0/default/Gralloc1On0Adapter.h
@@ -0,0 +1,458 @@
+/*
+ * 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_GRALLOC_1_ON_0_ADAPTER_H
+#define ANDROID_HARDWARE_GRALLOC_1_ON_0_ADAPTER_H
+
+#include <hardware/gralloc1.h>
+#include <log/log.h>
+
+#include <atomic>
+#include <memory>
+#include <mutex>
+#include <string>
+#include <unordered_map>
+#include <utility>
+
+struct gralloc_module_t;
+struct alloc_device_t;
+
+namespace android {
+namespace hardware {
+
+class Gralloc1On0Adapter : public gralloc1_device_t
+{
+public:
+    Gralloc1On0Adapter(const hw_module_t* module);
+    ~Gralloc1On0Adapter();
+
+    gralloc1_device_t* getDevice() {
+        return static_cast<gralloc1_device_t*>(this);
+    }
+
+private:
+    static inline Gralloc1On0Adapter* getAdapter(gralloc1_device_t* device) {
+        return static_cast<Gralloc1On0Adapter*>(device);
+    }
+
+    static int closeHook(struct hw_device_t* device) {
+        delete getAdapter(reinterpret_cast<gralloc1_device_t*>(device));
+        return 0;
+    }
+
+    // getCapabilities
+
+    void doGetCapabilities(uint32_t* outCount,
+            int32_t* /*gralloc1_capability_t*/ outCapabilities);
+    static void getCapabilitiesHook(gralloc1_device_t* device,
+            uint32_t* outCount,
+            int32_t* /*gralloc1_capability_t*/ outCapabilities) {
+        getAdapter(device)->doGetCapabilities(outCount, outCapabilities);
+    }
+
+    // getFunction
+
+    gralloc1_function_pointer_t doGetFunction(
+            int32_t /*gralloc1_function_descriptor_t*/ descriptor);
+    static gralloc1_function_pointer_t getFunctionHook(
+            gralloc1_device_t* device,
+            int32_t /*gralloc1_function_descriptor_t*/ descriptor) {
+        return getAdapter(device)->doGetFunction(descriptor);
+    }
+
+    // dump
+
+    void dump(uint32_t* outSize, char* outBuffer);
+    static void dumpHook(gralloc1_device_t* device, uint32_t* outSize,
+            char* outBuffer) {
+        return getAdapter(device)->dump(outSize, outBuffer);
+    }
+    std::string mCachedDump;
+
+    // Buffer descriptor lifecycle functions
+
+    struct Descriptor;
+
+    gralloc1_error_t createDescriptor(
+            gralloc1_buffer_descriptor_t* outDescriptor);
+    static int32_t createDescriptorHook(gralloc1_device_t* device,
+            gralloc1_buffer_descriptor_t* outDescriptor) {
+        auto error = getAdapter(device)->createDescriptor(outDescriptor);
+        return static_cast<int32_t>(error);
+    }
+
+    gralloc1_error_t destroyDescriptor(gralloc1_buffer_descriptor_t descriptor);
+    static int32_t destroyDescriptorHook(gralloc1_device_t* device,
+            gralloc1_buffer_descriptor_t descriptor) {
+        auto error = getAdapter(device)->destroyDescriptor(descriptor);
+        return static_cast<int32_t>(error);
+    }
+
+    // Buffer descriptor modification functions
+
+    struct Descriptor : public std::enable_shared_from_this<Descriptor> {
+        Descriptor()
+          : width(0),
+            height(0),
+            format(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED),
+            layerCount(1),
+            producerUsage(GRALLOC1_PRODUCER_USAGE_NONE),
+            consumerUsage(GRALLOC1_CONSUMER_USAGE_NONE) {}
+
+        gralloc1_error_t setDimensions(uint32_t w, uint32_t h) {
+            width = w;
+            height = h;
+            return GRALLOC1_ERROR_NONE;
+        }
+
+        gralloc1_error_t setFormat(int32_t f) {
+            format = f;
+            return GRALLOC1_ERROR_NONE;
+        }
+
+        gralloc1_error_t setLayerCount(uint32_t lc) {
+            layerCount = lc;
+            return GRALLOC1_ERROR_NONE;
+        }
+
+        gralloc1_error_t setProducerUsage(gralloc1_producer_usage_t usage) {
+            producerUsage = usage;
+            return GRALLOC1_ERROR_NONE;
+        }
+
+        gralloc1_error_t setConsumerUsage(gralloc1_consumer_usage_t usage) {
+            consumerUsage = usage;
+            return GRALLOC1_ERROR_NONE;
+        }
+
+        uint32_t width;
+        uint32_t height;
+        int32_t format;
+        uint32_t layerCount;
+        gralloc1_producer_usage_t producerUsage;
+        gralloc1_consumer_usage_t consumerUsage;
+    };
+
+    template <typename ...Args>
+    static int32_t callDescriptorFunction(gralloc1_device_t* device,
+            gralloc1_buffer_descriptor_t descriptorId,
+            gralloc1_error_t (Descriptor::*member)(Args...), Args... args) {
+        auto descriptor = getAdapter(device)->getDescriptor(descriptorId);
+        if (!descriptor) {
+            return static_cast<int32_t>(GRALLOC1_ERROR_BAD_DESCRIPTOR);
+        }
+        auto error = ((*descriptor).*member)(std::forward<Args>(args)...);
+        return static_cast<int32_t>(error);
+    }
+
+    static int32_t setConsumerUsageHook(gralloc1_device_t* device,
+            gralloc1_buffer_descriptor_t descriptorId, uint64_t intUsage) {
+        auto usage = static_cast<gralloc1_consumer_usage_t>(intUsage);
+        return callDescriptorFunction(device, descriptorId,
+                &Descriptor::setConsumerUsage, usage);
+    }
+
+    static int32_t setDimensionsHook(gralloc1_device_t* device,
+            gralloc1_buffer_descriptor_t descriptorId, uint32_t width,
+            uint32_t height) {
+        return callDescriptorFunction(device, descriptorId,
+                &Descriptor::setDimensions, width, height);
+    }
+
+    static int32_t setFormatHook(gralloc1_device_t* device,
+            gralloc1_buffer_descriptor_t descriptorId, int32_t format) {
+        return callDescriptorFunction(device, descriptorId,
+                &Descriptor::setFormat, format);
+    }
+
+    static int32_t setLayerCountHook(gralloc1_device_t* device,
+            gralloc1_buffer_descriptor_t descriptorId, uint32_t layerCount) {
+        return callDescriptorFunction(device, descriptorId,
+                &Descriptor::setLayerCount, layerCount);
+    }
+
+    static int32_t setProducerUsageHook(gralloc1_device_t* device,
+            gralloc1_buffer_descriptor_t descriptorId, uint64_t intUsage) {
+        auto usage = static_cast<gralloc1_producer_usage_t>(intUsage);
+        return callDescriptorFunction(device, descriptorId,
+                &Descriptor::setProducerUsage, usage);
+    }
+
+    // Buffer handle query functions
+
+    class Buffer {
+    public:
+        Buffer(buffer_handle_t handle, gralloc1_backing_store_t store,
+                const Descriptor& descriptor, uint32_t stride,
+                uint32_t numFlexPlanes, bool wasAllocated);
+
+        buffer_handle_t getHandle() const { return mHandle; }
+
+        void retain() { ++mReferenceCount; }
+
+        // Returns true if the reference count has dropped to 0, indicating that
+        // the buffer needs to be released
+        bool release() { return --mReferenceCount == 0; }
+
+        bool wasAllocated() const { return mWasAllocated; }
+
+        gralloc1_error_t getBackingStore(
+                gralloc1_backing_store_t* outStore) const {
+            *outStore = mStore;
+            return GRALLOC1_ERROR_NONE;
+        }
+
+        gralloc1_error_t getConsumerUsage(
+                gralloc1_consumer_usage_t* outUsage) const {
+            *outUsage = mDescriptor.consumerUsage;
+            return GRALLOC1_ERROR_NONE;
+        }
+
+        gralloc1_error_t getDimensions(uint32_t* outWidth,
+                uint32_t* outHeight) const {
+            *outWidth = mDescriptor.width;
+            *outHeight = mDescriptor.height;
+            return GRALLOC1_ERROR_NONE;
+        }
+
+        gralloc1_error_t getFormat(int32_t* outFormat) const {
+            *outFormat = mDescriptor.format;
+            return GRALLOC1_ERROR_NONE;
+        }
+
+        gralloc1_error_t getLayerCount(uint32_t* outLayerCount) const {
+            *outLayerCount = mDescriptor.layerCount;
+            return GRALLOC1_ERROR_NONE;
+        }
+
+        gralloc1_error_t getNumFlexPlanes(uint32_t* outNumPlanes) const {
+            *outNumPlanes = mNumFlexPlanes;
+            return GRALLOC1_ERROR_NONE;
+        }
+
+        gralloc1_error_t getProducerUsage(
+                gralloc1_producer_usage_t* outUsage) const {
+            *outUsage = mDescriptor.producerUsage;
+            return GRALLOC1_ERROR_NONE;
+        }
+
+        gralloc1_error_t getStride(uint32_t* outStride) const {
+            *outStride = mStride;
+            return GRALLOC1_ERROR_NONE;
+        }
+
+    private:
+
+        const buffer_handle_t mHandle;
+        size_t mReferenceCount;
+
+        const gralloc1_backing_store_t mStore;
+        const Descriptor mDescriptor;
+        const uint32_t mStride;
+        const uint32_t mNumFlexPlanes;
+
+        // Whether this buffer allocated in this process (as opposed to just
+        // being retained here), which determines whether to free or unregister
+        // the buffer when this Buffer is released
+        const bool mWasAllocated;
+    };
+
+    template <typename ...Args>
+    static int32_t callBufferFunction(gralloc1_device_t* device,
+            buffer_handle_t bufferHandle,
+            gralloc1_error_t (Buffer::*member)(Args...) const, Args... args) {
+        auto buffer = getAdapter(device)->getBuffer(bufferHandle);
+        if (!buffer) {
+            return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
+        }
+        auto error = ((*buffer).*member)(std::forward<Args>(args)...);
+        return static_cast<int32_t>(error);
+    }
+
+    template <typename MF, MF memFunc, typename ...Args>
+    static int32_t bufferHook(gralloc1_device_t* device,
+            buffer_handle_t bufferHandle, Args... args) {
+        return Gralloc1On0Adapter::callBufferFunction(device, bufferHandle,
+                memFunc, std::forward<Args>(args)...);
+    }
+
+    static int32_t getConsumerUsageHook(gralloc1_device_t* device,
+            buffer_handle_t bufferHandle, uint64_t* outUsage) {
+        auto usage = GRALLOC1_CONSUMER_USAGE_NONE;
+        auto error = callBufferFunction(device, bufferHandle,
+                &Buffer::getConsumerUsage, &usage);
+        if (error == GRALLOC1_ERROR_NONE) {
+            *outUsage = static_cast<uint64_t>(usage);
+        }
+        return error;
+    }
+
+    static int32_t getProducerUsageHook(gralloc1_device_t* device,
+            buffer_handle_t bufferHandle, uint64_t* outUsage) {
+        auto usage = GRALLOC1_PRODUCER_USAGE_NONE;
+        auto error = callBufferFunction(device, bufferHandle,
+                &Buffer::getProducerUsage, &usage);
+        if (error == GRALLOC1_ERROR_NONE) {
+            *outUsage = static_cast<uint64_t>(usage);
+        }
+        return error;
+    }
+
+    // Buffer management functions
+
+    gralloc1_error_t allocate(
+            gralloc1_buffer_descriptor_t id,
+            const std::shared_ptr<Descriptor>& descriptor,
+            buffer_handle_t* outBufferHandle);
+    static int32_t allocateHook(gralloc1_device* device,
+            uint32_t numDescriptors,
+            const gralloc1_buffer_descriptor_t* descriptors,
+            buffer_handle_t* outBuffers);
+
+    gralloc1_error_t retain(const std::shared_ptr<Buffer>& buffer);
+    gralloc1_error_t retain(buffer_handle_t bufferHandle);
+    static int32_t retainHook(gralloc1_device_t* device,
+            buffer_handle_t bufferHandle)
+    {
+        auto adapter = getAdapter(device);
+        return adapter->retain(bufferHandle);
+    }
+
+    gralloc1_error_t release(const std::shared_ptr<Buffer>& buffer);
+    static int32_t releaseHook(gralloc1_device_t* device,
+            buffer_handle_t bufferHandle) {
+        auto adapter = getAdapter(device);
+
+        auto buffer = adapter->getBuffer(bufferHandle);
+        if (!buffer) {
+            return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
+        }
+
+        auto error = adapter->release(buffer);
+        return static_cast<int32_t>(error);
+    }
+
+    // Buffer access functions
+
+    gralloc1_error_t lock(const std::shared_ptr<Buffer>& buffer,
+            gralloc1_producer_usage_t producerUsage,
+            gralloc1_consumer_usage_t consumerUsage,
+            const gralloc1_rect_t& accessRegion, void** outData,
+            int acquireFence);
+    gralloc1_error_t lockFlex(const std::shared_ptr<Buffer>& buffer,
+            gralloc1_producer_usage_t producerUsage,
+            gralloc1_consumer_usage_t consumerUsage,
+            const gralloc1_rect_t& accessRegion,
+            struct android_flex_layout* outFlex,
+            int acquireFence);
+
+    template <typename OUT, gralloc1_error_t (Gralloc1On0Adapter::*member)(
+            const std::shared_ptr<Buffer>&, gralloc1_producer_usage_t,
+            gralloc1_consumer_usage_t, const gralloc1_rect_t&, OUT*,
+            int)>
+    static int32_t lockHook(gralloc1_device_t* device,
+            buffer_handle_t bufferHandle,
+            uint64_t /*gralloc1_producer_usage_t*/ uintProducerUsage,
+            uint64_t /*gralloc1_consumer_usage_t*/ uintConsumerUsage,
+            const gralloc1_rect_t* accessRegion, OUT* outData,
+            int32_t acquireFenceFd) {
+        auto adapter = getAdapter(device);
+
+        // Exactly one of producer and consumer usage must be *_USAGE_NONE,
+        // but we can't check this until the upper levels of the framework
+        // correctly distinguish between producer and consumer usage
+        /*
+        bool hasProducerUsage =
+                uintProducerUsage != GRALLOC1_PRODUCER_USAGE_NONE;
+        bool hasConsumerUsage =
+                uintConsumerUsage != GRALLOC1_CONSUMER_USAGE_NONE;
+        if (hasProducerUsage && hasConsumerUsage ||
+                !hasProducerUsage && !hasConsumerUsage) {
+            return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
+        }
+        */
+
+        auto producerUsage =
+                static_cast<gralloc1_producer_usage_t>(uintProducerUsage);
+        auto consumerUsage =
+                static_cast<gralloc1_consumer_usage_t>(uintConsumerUsage);
+
+        if (!outData) {
+            const auto producerCpuUsage = GRALLOC1_PRODUCER_USAGE_CPU_READ |
+                    GRALLOC1_PRODUCER_USAGE_CPU_WRITE;
+            if ((producerUsage & producerCpuUsage) != 0) {
+                return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
+            }
+            if ((consumerUsage & GRALLOC1_CONSUMER_USAGE_CPU_READ) != 0) {
+                return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
+            }
+        }
+
+        auto buffer = adapter->getBuffer(bufferHandle);
+        if (!buffer) {
+            return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
+        }
+
+        if (!accessRegion) {
+            ALOGE("accessRegion is null");
+            return static_cast<int32_t>(GRALLOC1_ERROR_BAD_VALUE);
+        }
+
+        auto error = ((*adapter).*member)(buffer, producerUsage, consumerUsage,
+                *accessRegion, outData, acquireFenceFd);
+        return static_cast<int32_t>(error);
+    }
+
+    gralloc1_error_t unlock(const std::shared_ptr<Buffer>& buffer,
+            int* outReleaseFence);
+    static int32_t unlockHook(gralloc1_device_t* device,
+            buffer_handle_t bufferHandle, int32_t* outReleaseFenceFd) {
+        auto adapter = getAdapter(device);
+
+        auto buffer = adapter->getBuffer(bufferHandle);
+        if (!buffer) {
+            return static_cast<int32_t>(GRALLOC1_ERROR_BAD_HANDLE);
+        }
+
+        int releaseFence = -1;
+        auto error = adapter->unlock(buffer, &releaseFence);
+        if (error == GRALLOC1_ERROR_NONE) {
+            *outReleaseFenceFd = releaseFence;
+        }
+        return static_cast<int32_t>(error);
+    }
+
+    // Adapter internals
+    const gralloc_module_t* mModule;
+    uint8_t mMinorVersion;
+    alloc_device_t* mDevice;
+
+    std::shared_ptr<Descriptor> getDescriptor(
+            gralloc1_buffer_descriptor_t descriptorId);
+    std::shared_ptr<Buffer> getBuffer(buffer_handle_t bufferHandle);
+
+    static std::atomic<gralloc1_buffer_descriptor_t> sNextBufferDescriptorId;
+    std::mutex mDescriptorMutex;
+    std::unordered_map<gralloc1_buffer_descriptor_t,
+            std::shared_ptr<Descriptor>> mDescriptors;
+    std::mutex mBufferMutex;
+    std::unordered_map<buffer_handle_t, std::shared_ptr<Buffer>> mBuffers;
+};
+
+} // namespace hardware
+} // namespace android
+
+#endif // ANDROID_HARDWARE_GRALLOC_1_ON_0_ADAPTER_H
diff --git a/graphics/allocator/2.0/default/gralloc1-adapter.c b/graphics/allocator/2.0/default/gralloc1-adapter.c
deleted file mode 100644
index 724cd47..0000000
--- a/graphics/allocator/2.0/default/gralloc1-adapter.c
+++ /dev/null
@@ -1,660 +0,0 @@
-/*
- * 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 "Gralloc1Adapter"
-
-#include <stdatomic.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <pthread.h>
-
-#include <cutils/native_handle.h>
-#include <hardware/gralloc1.h>
-#include <sync/sync.h>
-#include <log/log.h>
-
-#include "gralloc1-adapter.h"
-
-struct gralloc1_adapter_module {
-    struct gralloc_module_t base;
-    struct gralloc1_adapter adapter;
-};
-
-struct gralloc1_adapter_device {
-    struct gralloc1_device base;
-
-    struct alloc_device_t* alloc_dev;
-
-    /* fixed size for thread safety */
-    char saved_dump[4096];
-    size_t saved_dump_size;
-};
-
-/* additional data associated with registered buffer_handle_t */
-struct gralloc1_adapter_buffer_data {
-    struct gralloc1_adapter_buffer_info info;
-
-    atomic_int refcount;
-    bool owned;
-};
-
-struct gralloc1_adapter_buffer_descriptor {
-    int width;
-    int height;
-    int format;
-    int producer_usage;
-    int consumer_usage;
-};
-
-static const struct gralloc1_adapter_module* gralloc1_adapter_module(
-        struct gralloc1_device* dev)
-{
-    return (const struct gralloc1_adapter_module*) dev->common.module;
-}
-
-static struct gralloc1_adapter_device* gralloc1_adapter_device(
-        struct gralloc1_device* dev)
-{
-    return (struct gralloc1_adapter_device*) dev;
-}
-
-static struct gralloc1_adapter_buffer_data* lookup_buffer_data(
-        struct gralloc1_device* dev, buffer_handle_t buffer)
-{
-    const struct gralloc1_adapter_module* mod = gralloc1_adapter_module(dev);
-    if (!mod->adapter.is_registered(&mod->base, buffer))
-        return NULL;
-
-    return mod->adapter.get_data(&mod->base, buffer);
-}
-
-static struct gralloc1_adapter_buffer_descriptor* lookup_buffer_descriptor(
-        struct gralloc1_device* dev, gralloc1_buffer_descriptor_t id)
-{
-    /* do we want to validate? */
-    return (struct gralloc1_adapter_buffer_descriptor*) ((uintptr_t) id);
-}
-
-static void device_dump(struct gralloc1_device* device,
-        uint32_t* outSize, char* outBuffer)
-{
-    struct gralloc1_adapter_device* dev = gralloc1_adapter_device(device);
-
-    if (outBuffer) {
-        uint32_t copy = (uint32_t) dev->saved_dump_size;
-        if (*outSize < copy) {
-            copy = *outSize;
-        } else {
-            *outSize = copy;
-        }
-
-        memcpy(outBuffer, dev->saved_dump, copy);
-    } else {
-        /* dump is optional and may not null-terminate */
-        if (dev->alloc_dev->dump) {
-            dev->alloc_dev->dump(dev->alloc_dev, dev->saved_dump,
-                    sizeof(dev->saved_dump) - 1);
-            dev->saved_dump_size = strlen(dev->saved_dump);
-        }
-
-        *outSize = (uint32_t) dev->saved_dump_size;
-    }
-}
-
-static int32_t device_create_descriptor(struct gralloc1_device* device,
-        gralloc1_buffer_descriptor_t* outDescriptor)
-{
-    struct gralloc1_adapter_buffer_descriptor* desc;
-
-    desc = calloc(1, sizeof(*desc));
-    if (!desc) {
-        return GRALLOC1_ERROR_NO_RESOURCES;
-    }
-
-    *outDescriptor = (gralloc1_buffer_descriptor_t) (uintptr_t) desc;
-
-    return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_destroy_descriptor(struct gralloc1_device* device,
-        gralloc1_buffer_descriptor_t descriptor)
-{
-    struct gralloc1_adapter_buffer_descriptor* desc =
-        lookup_buffer_descriptor(device, descriptor);
-    if (!desc) {
-        return GRALLOC1_ERROR_BAD_DESCRIPTOR;
-    }
-
-    free(desc);
-
-    return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_set_consumer_usage(struct gralloc1_device* device,
-        gralloc1_buffer_descriptor_t descriptor, uint64_t usage)
-{
-    struct gralloc1_adapter_buffer_descriptor* desc =
-        lookup_buffer_descriptor(device, descriptor);
-    if (!desc) {
-        return GRALLOC1_ERROR_BAD_DESCRIPTOR;
-    }
-
-    desc->consumer_usage = (int) usage;
-
-    return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_set_dimensions(struct gralloc1_device* device,
-        gralloc1_buffer_descriptor_t descriptor,
-        uint32_t width, uint32_t height)
-{
-    struct gralloc1_adapter_buffer_descriptor* desc =
-        lookup_buffer_descriptor(device, descriptor);
-    if (!desc) {
-        return GRALLOC1_ERROR_BAD_DESCRIPTOR;
-    }
-
-    desc->width = (int) width;
-    desc->height = (int) height;
-
-    return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_set_format(struct gralloc1_device* device,
-        gralloc1_buffer_descriptor_t descriptor, int32_t format)
-{
-    struct gralloc1_adapter_buffer_descriptor* desc =
-        lookup_buffer_descriptor(device, descriptor);
-    if (!desc) {
-        return GRALLOC1_ERROR_BAD_DESCRIPTOR;
-    }
-
-    desc->format = format;
-
-    return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_set_producer_usage(struct gralloc1_device* device,
-        gralloc1_buffer_descriptor_t descriptor, uint64_t usage)
-{
-    struct gralloc1_adapter_buffer_descriptor* desc =
-        lookup_buffer_descriptor(device, descriptor);
-    if (!desc) {
-        return GRALLOC1_ERROR_BAD_DESCRIPTOR;
-    }
-
-    desc->producer_usage = (int) usage;
-
-    return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_get_backing_store(struct gralloc1_device* device,
-        buffer_handle_t buffer, gralloc1_backing_store_t* outStore)
-{
-    /* we never share backing store */
-    *outStore = (gralloc1_backing_store_t) (uintptr_t) buffer;
-
-    return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_get_consumer_usage(struct gralloc1_device* device,
-        buffer_handle_t buffer, uint64_t* outUsage)
-{
-    const struct gralloc1_adapter_buffer_data* data =
-        lookup_buffer_data(device, buffer);
-    if (!data) {
-        return GRALLOC1_ERROR_BAD_HANDLE;
-    }
-
-    *outUsage = data->info.usage;
-
-    return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_get_dimensions(struct gralloc1_device* device,
-        buffer_handle_t buffer, uint32_t* outWidth, uint32_t* outHeight)
-{
-    const struct gralloc1_adapter_buffer_data* data =
-        lookup_buffer_data(device, buffer);
-    if (!data) {
-        return GRALLOC1_ERROR_BAD_HANDLE;
-    }
-
-    *outWidth = data->info.width;
-    *outHeight = data->info.height;
-
-    return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_get_format(struct gralloc1_device* device,
-        buffer_handle_t buffer, int32_t* outFormat)
-{
-    const struct gralloc1_adapter_buffer_data* data =
-        lookup_buffer_data(device, buffer);
-    if (!data) {
-        return GRALLOC1_ERROR_BAD_HANDLE;
-    }
-
-    *outFormat = data->info.format;
-
-    return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_get_producer_usage(struct gralloc1_device* device,
-        buffer_handle_t buffer, uint64_t* outUsage)
-{
-    const struct gralloc1_adapter_buffer_data* data =
-        lookup_buffer_data(device, buffer);
-    if (!data) {
-        return GRALLOC1_ERROR_BAD_HANDLE;
-    }
-
-    *outUsage = data->info.usage;
-
-    return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_get_stride(struct gralloc1_device* device,
-        buffer_handle_t buffer, uint32_t* outStride)
-{
-    const struct gralloc1_adapter_buffer_data* data =
-        lookup_buffer_data(device, buffer);
-    if (!data) {
-        return GRALLOC1_ERROR_BAD_HANDLE;
-    }
-
-    *outStride = data->info.stride;
-
-    return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_allocate(struct gralloc1_device* device,
-        uint32_t numDescriptors,
-        const gralloc1_buffer_descriptor_t* descriptors,
-        buffer_handle_t* outBuffers)
-{
-    const struct gralloc1_adapter_module* mod =
-        gralloc1_adapter_module(device);
-    struct gralloc1_adapter_device* dev = gralloc1_adapter_device(device);
-    gralloc1_error_t err = GRALLOC1_ERROR_NONE;
-    uint32_t i;
-
-    for (i = 0; i < numDescriptors; i++) {
-        const struct gralloc1_adapter_buffer_descriptor* desc =
-            lookup_buffer_descriptor(device, descriptors[i]);
-        struct gralloc1_adapter_buffer_data* data;
-        buffer_handle_t buffer;
-        int dummy_stride;
-        int ret;
-
-        if (!desc) {
-            err = GRALLOC1_ERROR_BAD_DESCRIPTOR;
-            break;
-        }
-
-        data = calloc(1, sizeof(*data));
-        if (!data) {
-            err = GRALLOC1_ERROR_NO_RESOURCES;
-            break;
-        }
-
-        ret = dev->alloc_dev->alloc(dev->alloc_dev, desc->width, desc->height,
-                desc->format, desc->producer_usage | desc->consumer_usage,
-                &buffer, &dummy_stride);
-        if (ret) {
-            free(data);
-            err = GRALLOC1_ERROR_NO_RESOURCES;
-            break;
-        }
-
-        mod->adapter.get_info(&mod->base, buffer, &data->info);
-        data->refcount = 1;
-        data->owned = true;
-
-        mod->adapter.set_data(&mod->base, buffer, data);
-
-        outBuffers[i] = buffer;
-    }
-
-    if (err != GRALLOC1_ERROR_NONE) {
-        uint32_t j;
-        for (j = 0; j < i; j++) {
-            free(mod->adapter.get_data(&mod->base, outBuffers[i]));
-            dev->alloc_dev->free(dev->alloc_dev, outBuffers[i]);
-        }
-
-        return err;
-    }
-
-    return (numDescriptors > 1) ?
-        GRALLOC1_ERROR_NOT_SHARED : GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_retain(struct gralloc1_device* device,
-        buffer_handle_t buffer)
-{
-    static pthread_mutex_t register_mutex = PTHREAD_MUTEX_INITIALIZER;
-    const struct gralloc1_adapter_module* mod =
-        gralloc1_adapter_module(device);
-    struct gralloc1_adapter_buffer_data* data;
-
-    pthread_mutex_lock(&register_mutex);
-
-    if (mod->adapter.is_registered(&mod->base, buffer)) {
-        data = mod->adapter.get_data(&mod->base, buffer);
-        data->refcount++;
-    } else {
-        int ret;
-
-        data = calloc(1, sizeof(*data));
-        if (!data) {
-            pthread_mutex_unlock(&register_mutex);
-            return GRALLOC1_ERROR_NO_RESOURCES;
-        }
-
-        ret = mod->base.registerBuffer(&mod->base, buffer);
-        if (ret) {
-            pthread_mutex_unlock(&register_mutex);
-            free(data);
-
-            return GRALLOC1_ERROR_NO_RESOURCES;
-        }
-
-        mod->adapter.get_info(&mod->base, buffer, &data->info);
-        data->refcount = 1;
-        data->owned = false;
-
-        mod->adapter.set_data(&mod->base, buffer, data);
-    }
-
-    pthread_mutex_unlock(&register_mutex);
-
-    return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_release(struct gralloc1_device* device,
-        buffer_handle_t buffer)
-{
-    struct gralloc1_adapter_buffer_data* data =
-        lookup_buffer_data(device, buffer);
-    if (!data) {
-        ALOGE("unable to release unregistered buffer %p", buffer);
-        return GRALLOC1_ERROR_BAD_HANDLE;
-    }
-
-    data->refcount--;
-    if (!data->refcount) {
-        if (data->owned) {
-            struct gralloc1_adapter_device* dev =
-                gralloc1_adapter_device(device);
-            dev->alloc_dev->free(dev->alloc_dev, buffer);
-        } else {
-            const struct gralloc1_adapter_module* mod =
-                gralloc1_adapter_module(device);
-            mod->base.unregisterBuffer(&mod->base, buffer);
-
-            native_handle_close(buffer);
-            native_handle_delete((native_handle_t*) buffer);
-        }
-
-        free(data);
-    }
-
-    return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_get_num_flex_planes(struct gralloc1_device* device,
-        buffer_handle_t buffer, uint32_t* outNumPlanes)
-{
-    const struct gralloc1_adapter_buffer_data* data =
-        lookup_buffer_data(device, buffer);
-    if (!data) {
-        return GRALLOC1_ERROR_BAD_HANDLE;
-    }
-
-    *outNumPlanes = data->info.num_flex_planes;
-
-    return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_lock(struct gralloc1_device* device,
-        buffer_handle_t buffer,
-        uint64_t producerUsage, uint64_t consumerUsage,
-        const gralloc1_rect_t* accessRegion, void** outData,
-        int32_t acquireFence)
-{
-    const struct gralloc1_adapter_module* mod =
-        gralloc1_adapter_module(device);
-    const int usage = (int) (producerUsage | consumerUsage);
-    const struct gralloc1_adapter_buffer_data* data =
-        lookup_buffer_data(device, buffer);
-    int ret;
-
-    if (!data) {
-        ALOGE("unable to lock unregistered buffer %p", buffer);
-        return GRALLOC1_ERROR_BAD_HANDLE;
-    }
-
-    if (mod->adapter.real_module_api_version >=
-            GRALLOC_MODULE_API_VERSION_0_3) {
-        ret = mod->base.lockAsync(&mod->base,
-                buffer, usage,
-                accessRegion->left,
-                accessRegion->top,
-                accessRegion->width,
-                accessRegion->height,
-                outData, acquireFence);
-    } else {
-        if (acquireFence >= 0) {
-            sync_wait(acquireFence, -1);
-        }
-
-        ret = mod->base.lock(&mod->base,
-                buffer, usage,
-                accessRegion->left,
-                accessRegion->top,
-                accessRegion->width,
-                accessRegion->height,
-                outData);
-
-        if (acquireFence >= 0 && !ret) {
-            close(acquireFence);
-        }
-    }
-
-    return (ret) ? GRALLOC1_ERROR_NO_RESOURCES : GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_lock_flex(struct gralloc1_device* device,
-        buffer_handle_t buffer,
-        uint64_t producerUsage, uint64_t consumerUsage,
-        const gralloc1_rect_t* accessRegion,
-        struct android_flex_layout* outFlexLayout,
-        int32_t acquireFence)
-{
-    const struct gralloc1_adapter_module* mod =
-        gralloc1_adapter_module(device);
-    const int usage = (int) (producerUsage | consumerUsage);
-    const struct gralloc1_adapter_buffer_data* data =
-        lookup_buffer_data(device, buffer);
-    struct android_ycbcr ycbcr;
-    int ret;
-
-    if (!data) {
-        ALOGE("unable to lockFlex unregistered buffer %p", buffer);
-        return GRALLOC1_ERROR_BAD_HANDLE;
-    }
-
-    if (outFlexLayout->num_planes < data->info.num_flex_planes) {
-        return GRALLOC1_ERROR_BAD_VALUE;
-    }
-
-    if (mod->adapter.real_module_api_version >=
-            GRALLOC_MODULE_API_VERSION_0_3 && mod->base.lockAsync_ycbcr) {
-        ret = mod->base.lockAsync_ycbcr(&mod->base,
-                buffer, usage,
-                accessRegion->left,
-                accessRegion->top,
-                accessRegion->width,
-                accessRegion->height,
-                &ycbcr, acquireFence);
-    } else if (mod->base.lock_ycbcr) {
-        if (acquireFence >= 0) {
-            sync_wait(acquireFence, -1);
-        }
-
-        ret = mod->base.lock_ycbcr(&mod->base,
-                buffer, usage,
-                accessRegion->left,
-                accessRegion->top,
-                accessRegion->width,
-                accessRegion->height,
-                &ycbcr);
-
-        if (acquireFence >= 0 && !ret) {
-            close(acquireFence);
-        }
-    } else {
-        return GRALLOC1_ERROR_UNSUPPORTED;
-    }
-
-    if (ret) {
-        return GRALLOC1_ERROR_NO_RESOURCES;
-    }
-
-    mod->adapter.get_flexible_layout(&mod->base, buffer,
-            &ycbcr, outFlexLayout);
-
-    return GRALLOC1_ERROR_NONE;
-}
-
-static int32_t device_unlock(struct gralloc1_device* device,
-        buffer_handle_t buffer, int32_t* outReleaseFence)
-{
-    const struct gralloc1_adapter_module* mod =
-        gralloc1_adapter_module(device);
-    int ret;
-
-    if (mod->adapter.real_module_api_version >=
-            GRALLOC_MODULE_API_VERSION_0_3) {
-        ret = mod->base.unlockAsync(&mod->base, buffer, outReleaseFence);
-    } else {
-        ret = mod->base.unlock(&mod->base, buffer);
-        if (!ret) {
-            *outReleaseFence = -1;
-        }
-    }
-
-    return (ret) ? GRALLOC1_ERROR_BAD_HANDLE : GRALLOC1_ERROR_NONE;
-}
-
-static gralloc1_function_pointer_t device_get_function(
-        struct gralloc1_device* device, int32_t descriptor)
-{
-    switch ((gralloc1_function_descriptor_t) descriptor) {
-#define CASE(id, ptr)              \
-    case GRALLOC1_FUNCTION_ ## id: \
-        return (gralloc1_function_pointer_t) device_ ## ptr
-    CASE(DUMP, dump);
-    CASE(CREATE_DESCRIPTOR, create_descriptor);
-    CASE(DESTROY_DESCRIPTOR, destroy_descriptor);
-    CASE(SET_CONSUMER_USAGE, set_consumer_usage);
-    CASE(SET_DIMENSIONS, set_dimensions);
-    CASE(SET_FORMAT, set_format);
-    CASE(SET_PRODUCER_USAGE, set_producer_usage);
-    CASE(GET_BACKING_STORE, get_backing_store);
-    CASE(GET_CONSUMER_USAGE, get_consumer_usage);
-    CASE(GET_DIMENSIONS, get_dimensions);
-    CASE(GET_FORMAT, get_format);
-    CASE(GET_PRODUCER_USAGE, get_producer_usage);
-    CASE(GET_STRIDE, get_stride);
-    CASE(ALLOCATE, allocate);
-    CASE(RETAIN, retain);
-    CASE(RELEASE, release);
-    CASE(GET_NUM_FLEX_PLANES, get_num_flex_planes);
-    CASE(LOCK, lock);
-    CASE(LOCK_FLEX, lock_flex);
-    CASE(UNLOCK, unlock);
-#undef CASE
-    default: return NULL;
-    }
-}
-
-static void device_get_capabilities(struct gralloc1_device* device,
-        uint32_t* outCount, int32_t* outCapabilities)
-{
-    *outCount = 0;
-}
-
-static int device_close(struct hw_device_t* device)
-{
-    struct gralloc1_adapter_device* dev =
-        (struct gralloc1_adapter_device*) device;
-    int ret;
-
-    ret = dev->alloc_dev->common.close(&dev->alloc_dev->common);
-    if (!ret) {
-        free(dev);
-    }
-
-    return ret;
-}
-
-int gralloc1_adapter_device_open(const struct hw_module_t* module,
-        const char* id, struct hw_device_t** device)
-{
-    const struct gralloc1_adapter_module* mod =
-        (const struct gralloc1_adapter_module*) module;
-    struct alloc_device_t* alloc_dev;
-    struct gralloc1_adapter_device* dev;
-    int ret;
-
-    if (strcmp(id, GRALLOC_HARDWARE_MODULE_ID) != 0) {
-        ALOGE("unknown gralloc1 device id: %s", id);
-        return -EINVAL;
-    }
-
-    ret = module->methods->open(module, GRALLOC_HARDWARE_GPU0,
-            (struct hw_device_t**) &alloc_dev);
-    if (ret) {
-        return ret;
-    }
-
-    dev = malloc(sizeof(*dev));
-    if (!dev) {
-        alloc_dev->common.close(&alloc_dev->common);
-        return -ENOMEM;
-    }
-
-    *dev = (struct gralloc1_adapter_device) {
-        .base = {
-            .common = {
-                .tag = HARDWARE_DEVICE_TAG,
-                .version = HARDWARE_DEVICE_API_VERSION(0, 0),
-                .module = (struct hw_module_t*) mod,
-                .close = device_close,
-            },
-            .getCapabilities = device_get_capabilities,
-            .getFunction = device_get_function,
-        },
-        .alloc_dev = alloc_dev,
-    };
-
-    *device = (struct hw_device_t*) dev;
-
-    return 0;
-}
diff --git a/graphics/allocator/2.0/default/gralloc1-adapter.cpp b/graphics/allocator/2.0/default/gralloc1-adapter.cpp
new file mode 100644
index 0000000..fcc59cd
--- /dev/null
+++ b/graphics/allocator/2.0/default/gralloc1-adapter.cpp
@@ -0,0 +1,32 @@
+/*
+ * 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 "Gralloc1On0Adapter.h"
+#include "gralloc1-adapter.h"
+
+int gralloc1_adapter_device_open(const struct hw_module_t* module,
+        const char* id, struct hw_device_t** device)
+{
+    if (strcmp(id, GRALLOC_HARDWARE_MODULE_ID) != 0) {
+        ALOGE("unknown gralloc1 device id: %s", id);
+        return -EINVAL;
+    }
+
+    auto adapter_device = new android::hardware::Gralloc1On0Adapter(module);
+    *device = &adapter_device->common;
+
+    return 0;
+}
diff --git a/graphics/allocator/2.0/default/gralloc1-adapter.h b/graphics/allocator/2.0/default/gralloc1-adapter.h
index f48cd9e..b912ef6 100644
--- a/graphics/allocator/2.0/default/gralloc1-adapter.h
+++ b/graphics/allocator/2.0/default/gralloc1-adapter.h
@@ -16,52 +16,69 @@
 #ifndef ANDROID_HARDWARE_GRALLOC1_ADAPTER_H
 #define ANDROID_HARDWARE_GRALLOC1_ADAPTER_H
 
-#include <stdbool.h>
-#include <hardware/gralloc.h>
+#include <hardware/hardware.h>
 
 __BEGIN_DECLS
 
-struct gralloc1_adapter_buffer_info {
-    int width;
-    int height;
-    int format;
-    int usage;
+#define GRALLOC1_ADAPTER_MODULE_API_VERSION_1_0 \
+    HARDWARE_MODULE_API_VERSION(1, 0)
 
-    int stride;
-    uint32_t num_flex_planes;
-};
+enum {
+    GRALLOC1_ADAPTER_PERFORM_FIRST = 10000,
 
-/* This struct must be embedded in the HAL's HAL_MODULE_INFO_SYM and must
- * follow gralloc_module_t immediately. */
-struct gralloc1_adapter {
-    uint16_t real_module_api_version;
+    // void getRealModuleApiVersionMinor(..., int* outMinorVersion);
+    GRALLOC1_ADAPTER_PERFORM_GET_REAL_MODULE_API_VERSION_MINOR =
+        GRALLOC1_ADAPTER_PERFORM_FIRST,
 
-    /* Return true if the buffer is registered.  A locally allocated buffer is
-     * always registered.
-     *
-     * This function is called frequently.  It must be thread safe just like
-     * other functions are.
-     */
-    bool (*is_registered)(const struct gralloc_module_t* mod,
-            buffer_handle_t buffer);
+    // void setUsages(..., buffer_handle_t buffer,
+    //                     int producerUsage,
+    //                     int consumerUsage);
+    GRALLOC1_ADAPTER_PERFORM_SET_USAGES =
+        GRALLOC1_ADAPTER_PERFORM_FIRST + 1,
 
-    /* Set the adapter data for a registered buffer. */
-    void (*set_data)(const struct gralloc_module_t* mod,
-            buffer_handle_t buffer, void* data);
+    // void getDimensions(..., buffer_handle_t buffer,
+    //                         int* outWidth,
+    //                         int* outHeight);
+    GRALLOC1_ADAPTER_PERFORM_GET_DIMENSIONS =
+        GRALLOC1_ADAPTER_PERFORM_FIRST + 2,
 
-    /* Get the adapter data for a registered buffer. */
-    void* (*get_data)(const struct gralloc_module_t* mod,
-            buffer_handle_t buffer);
+    // void getFormat(..., buffer_handle_t buffer, int* outFormat);
+    GRALLOC1_ADAPTER_PERFORM_GET_FORMAT =
+        GRALLOC1_ADAPTER_PERFORM_FIRST + 3,
 
-    /* Get the buffer info, such as width, height, etc. */
-    void (*get_info)(const struct gralloc_module_t* mod,
-            buffer_handle_t buffer,
-            struct gralloc1_adapter_buffer_info* info);
+    // void getProducerUsage(..., buffer_handle_t buffer, int* outUsage);
+    GRALLOC1_ADAPTER_PERFORM_GET_PRODUCER_USAGE =
+        GRALLOC1_ADAPTER_PERFORM_FIRST + 4,
 
-    /* Get the flexilble layout matching ycbcr. */
-    void (*get_flexible_layout)(const struct gralloc_module_t* mod,
-            buffer_handle_t buffer, const struct android_ycbcr* ycbcr,
-            struct android_flex_layout* layout);
+    // void getConsumerUsage(..., buffer_handle_t buffer, int* outUsage);
+    GRALLOC1_ADAPTER_PERFORM_GET_CONSUMER_USAGE =
+        GRALLOC1_ADAPTER_PERFORM_FIRST + 5,
+
+    // void getBackingStore(..., buffer_handle_t buffer,
+    //                           uint64_t* outBackingStore);
+    GRALLOC1_ADAPTER_PERFORM_GET_BACKING_STORE =
+        GRALLOC1_ADAPTER_PERFORM_FIRST + 6,
+
+    // void getNumFlexPlanes(..., buffer_handle_t buffer,
+    //                            int* outNumFlexPlanes);
+    GRALLOC1_ADAPTER_PERFORM_GET_NUM_FLEX_PLANES =
+        GRALLOC1_ADAPTER_PERFORM_FIRST + 7,
+
+    // void getStride(..., buffer_handle_t buffer, int* outStride);
+    GRALLOC1_ADAPTER_PERFORM_GET_STRIDE =
+        GRALLOC1_ADAPTER_PERFORM_FIRST + 8,
+
+    // void lockFlex(..., buffer_handle_t buffer,
+    //                    int producerUsage,
+    //                    int consumerUsage,
+    //                    int left,
+    //                    int top,
+    //                    int width,
+    //                    int height,
+    //                    android_flex_layout* outLayout,
+    //                    int acquireFence);
+    GRALLOC1_ADAPTER_PERFORM_LOCK_FLEX =
+        GRALLOC1_ADAPTER_PERFORM_FIRST + 9,
 };
 
 int gralloc1_adapter_device_open(const struct hw_module_t* module,
diff --git a/graphics/composer/2.1/default/HwcClient.cpp b/graphics/composer/2.1/default/HwcClient.cpp
index 8c2dd6d..54dfd89 100644
--- a/graphics/composer/2.1/default/HwcClient.cpp
+++ b/graphics/composer/2.1/default/HwcClient.cpp
@@ -176,9 +176,9 @@
             mRelease(mDevice, handle);
         } else {
             mModule->unregisterBuffer(mModule, handle);
-            native_handle_close(handle);
-            native_handle_delete(const_cast<native_handle_t*>(handle));
         }
+        native_handle_close(handle);
+        native_handle_delete(const_cast<native_handle_t*>(handle));
     }
 
     // gralloc1
diff --git a/graphics/mapper/2.0/default/Android.bp b/graphics/mapper/2.0/default/Android.bp
index 02ed877..c3d2281 100644
--- a/graphics/mapper/2.0/default/Android.bp
+++ b/graphics/mapper/2.0/default/Android.bp
@@ -19,6 +19,7 @@
     srcs: ["GrallocMapper.cpp"],
     cppflags: ["-Wall", "-Wextra"],
     shared_libs: [
+        "android.hardware.graphics.allocator@2.0",
         "android.hardware.graphics.mapper@2.0",
         "libbase",
         "libcutils",
diff --git a/graphics/mapper/2.0/default/GrallocMapper.cpp b/graphics/mapper/2.0/default/GrallocMapper.cpp
index cd9db38..3b6460a 100644
--- a/graphics/mapper/2.0/default/GrallocMapper.cpp
+++ b/graphics/mapper/2.0/default/GrallocMapper.cpp
@@ -17,7 +17,9 @@
 
 #include "GrallocMapper.h"
 
+#include <mutex>
 #include <vector>
+#include <unordered_map>
 
 #include <string.h>
 
@@ -100,6 +102,9 @@
         GRALLOC1_PFN_LOCK_FLEX lockFlex;
         GRALLOC1_PFN_UNLOCK unlock;
     } mDispatch;
+
+    std::mutex mMutex;
+    std::unordered_map<buffer_handle_t, size_t> mBufferReferenceCounts;
 };
 
 GrallocMapperHal::GrallocMapperHal(const hw_module_t* module)
@@ -201,12 +206,34 @@
 Return<Error> GrallocMapperHal::retain(const hidl_handle& bufferHandle)
 {
     int32_t err = mDispatch.retain(mDevice, bufferHandle);
+    if (err == GRALLOC1_ERROR_NONE) {
+        auto nativeHandle = bufferHandle.getNativeHandle();
+        std::lock_guard<std::mutex> lock(mMutex);
+
+        ++mBufferReferenceCounts[nativeHandle];
+    }
     return static_cast<Error>(err);
 }
 
 Return<Error> GrallocMapperHal::release(const hidl_handle& bufferHandle)
 {
     int32_t err = mDispatch.release(mDevice, bufferHandle);
+    if (err == GRALLOC1_ERROR_NONE) {
+        auto nativeHandle = bufferHandle.getNativeHandle();
+        std::lock_guard<std::mutex> lock(mMutex);
+
+        auto iter = mBufferReferenceCounts.find(bufferHandle);
+        if (iter == mBufferReferenceCounts.end()) {
+            // this should never happen
+            err = GRALLOC1_ERROR_BAD_HANDLE;
+        } else if (--iter->second == 0) {
+            native_handle_close(nativeHandle);
+            native_handle_delete(const_cast<native_handle_t*>(nativeHandle));
+
+            mBufferReferenceCounts.erase(iter);
+        }
+    }
+
     return static_cast<Error>(err);
 }
 
