diff --git a/include/ui/Gralloc1On0Adapter.h b/include/ui/Gralloc1On0Adapter.h
new file mode 100644
index 0000000..edcfb65
--- /dev/null
+++ b/include/ui/Gralloc1On0Adapter.h
@@ -0,0 +1,478 @@
+/*
+ * 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_UI_GRALLOC_1_ON_0_ADAPTER_H
+#define ANDROID_UI_GRALLOC_1_ON_0_ADAPTER_H
+
+#include <ui/Fence.h>
+#include <ui/GraphicBuffer.h>
+
+#include <hardware/gralloc1.h>
+
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+struct gralloc_module_t;
+
+// This is not an "official" capability (i.e., it is not found in gralloc1.h),
+// but we will use it to detect that we are running through the adapter, which
+// is capable of collaborating with GraphicBuffer such that queries on a
+// buffer_handle_t succeed
+static const auto GRALLOC1_CAPABILITY_ON_ADAPTER =
+        static_cast<gralloc1_capability_t>(GRALLOC1_LAST_CAPABILITY + 1);
+
+static const auto GRALLOC1_FUNCTION_RETAIN_GRAPHIC_BUFFER =
+        static_cast<gralloc1_function_descriptor_t>(GRALLOC1_LAST_FUNCTION + 1);
+static const auto GRALLOC1_FUNCTION_ALLOCATE_WITH_ID =
+        static_cast<gralloc1_function_descriptor_t>(GRALLOC1_LAST_FUNCTION + 2);
+static const auto GRALLOC1_FUNCTION_LOCK_YCBCR =
+        static_cast<gralloc1_function_descriptor_t>(GRALLOC1_LAST_FUNCTION + 3);
+static const auto GRALLOC1_LAST_ADAPTER_FUNCTION = GRALLOC1_FUNCTION_LOCK_YCBCR;
+
+typedef gralloc1_error_t (*GRALLOC1_PFN_RETAIN_GRAPHIC_BUFFER)(
+        gralloc1_device_t* device, const android::GraphicBuffer* buffer);
+typedef gralloc1_error_t (*GRALLOC1_PFN_ALLOCATE_WITH_ID)(
+        gralloc1_device_t* device, gralloc1_buffer_descriptor_t descriptor,
+        gralloc1_backing_store_t id, buffer_handle_t* outBuffer);
+typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_LOCK_YCBCR)(
+        gralloc1_device_t* device, buffer_handle_t buffer,
+        uint64_t /*gralloc1_producer_usage_t*/ producerUsage,
+        uint64_t /*gralloc1_consumer_usage_t*/ consumerUsage,
+        const gralloc1_rect_t* accessRegion, struct android_ycbcr* outYCbCr,
+        int32_t acquireFence);
+
+namespace android {
+
+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);
+    }
+
+    // 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
+
+    class 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(Gralloc1On0Adapter* adapter,
+                gralloc1_buffer_descriptor_t id)
+          : adapter(adapter),
+            id(id),
+            width(0),
+            height(0),
+            format(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED),
+            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 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;
+        }
+
+        Gralloc1On0Adapter* const adapter;
+        const gralloc1_buffer_descriptor_t id;
+
+        uint32_t width;
+        uint32_t height;
+        int32_t format;
+        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 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,
+                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 getNumFlexPlanes(uint32_t* outNumPlanes) const {
+            // TODO: This is conservative, and we could do better by examining
+            // the format, but it won't hurt anything for now
+            *outNumPlanes = 4;
+            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;
+
+        // Since we're adapting to gralloc0, there will always be a 1:1
+        // correspondence between buffer handles and backing stores, and the
+        // backing store ID will be the same as the GraphicBuffer unique ID
+        const gralloc1_backing_store_t mStore;
+
+        const Descriptor mDescriptor;
+        const uint32_t mStride;
+
+        // 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
+
+    // We don't provide GRALLOC1_FUNCTION_ALLOCATE, since this should always be
+    // called through GRALLOC1_FUNCTION_ALLOCATE_WITH_ID
+    gralloc1_error_t allocate(
+            const std::shared_ptr<Descriptor>& descriptor,
+            gralloc1_backing_store_t id,
+            buffer_handle_t* outBufferHandle);
+    static gralloc1_error_t allocateWithIdHook(gralloc1_device_t* device,
+            gralloc1_buffer_descriptor_t descriptors,
+            gralloc1_backing_store_t id, buffer_handle_t* outBuffer);
+
+    gralloc1_error_t retain(const std::shared_ptr<Buffer>& buffer);
+    gralloc1_error_t release(const std::shared_ptr<Buffer>& buffer);
+
+    // Member function pointer 'member' will either be retain or release
+    template <gralloc1_error_t (Gralloc1On0Adapter::*member)(
+            const std::shared_ptr<Buffer>& buffer)>
+    static int32_t managementHook(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).*member)(buffer);
+        return static_cast<int32_t>(error);
+    }
+
+    gralloc1_error_t retain(const GraphicBuffer* buffer);
+    static gralloc1_error_t retainGraphicBufferHook(gralloc1_device_t* device,
+            const GraphicBuffer* buffer) {
+        auto adapter = getAdapter(device);
+        return adapter->retain(buffer);
+    }
+
+    // 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,
+            const sp<Fence>& 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,
+            const sp<Fence>& acquireFence);
+    gralloc1_error_t lockYCbCr(const std::shared_ptr<Buffer>& buffer,
+            gralloc1_producer_usage_t producerUsage,
+            gralloc1_consumer_usage_t consumerUsage,
+            const gralloc1_rect_t& accessRegion,
+            struct android_ycbcr* outFlex,
+            const sp<Fence>& 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*,
+            const sp<Fence>&)>
+    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);
+        }
+
+        sp<Fence> acquireFence{new Fence(acquireFenceFd)};
+        auto error = ((*adapter).*member)(buffer, producerUsage, consumerUsage,
+                *accessRegion, outData, acquireFence);
+        return static_cast<int32_t>(error);
+    }
+
+    gralloc1_error_t unlock(const std::shared_ptr<Buffer>& buffer,
+            sp<Fence>* 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);
+        }
+
+        sp<Fence> releaseFence = Fence::NO_FENCE;
+        auto error = adapter->unlock(buffer, &releaseFence);
+        if (error == GRALLOC1_ERROR_NONE) {
+            *outReleaseFenceFd = releaseFence->dup();
+        }
+        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::unordered_map<gralloc1_buffer_descriptor_t,
+            std::shared_ptr<Descriptor>> mDescriptors;
+    std::unordered_map<buffer_handle_t, std::shared_ptr<Buffer>> mBuffers;
+};
+
+} // namespace android
+
+#endif
diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
index ee6c093..85ad36d 100644
--- a/libs/ui/Android.mk
+++ b/libs/ui/Android.mk
@@ -17,7 +17,7 @@
 
 LOCAL_CLANG := true
 LOCAL_CPPFLAGS := -std=c++1y -Weverything -Werror
-LOCAL_SANITIZE := integer
+# LOCAL_SANITIZE := integer
 
 # The static constructors and destructors in this library have not been noted to
 # introduce significant overheads
@@ -37,6 +37,7 @@
 LOCAL_SRC_FILES := \
 	Fence.cpp \
 	FrameStats.cpp \
+	Gralloc1On0Adapter.cpp \
 	GraphicBuffer.cpp \
 	GraphicBufferAllocator.cpp \
 	GraphicBufferMapper.cpp \
diff --git a/libs/ui/Gralloc1On0Adapter.cpp b/libs/ui/Gralloc1On0Adapter.cpp
new file mode 100644
index 0000000..6e69df1
--- /dev/null
+++ b/libs/ui/Gralloc1On0Adapter.cpp
@@ -0,0 +1,469 @@
+/*
+ * 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 <hardware/gralloc.h>
+
+#include <ui/Gralloc1On0Adapter.h>
+
+#include <utils/Log.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 {
+
+Gralloc1On0Adapter::Gralloc1On0Adapter(const hw_module_t* module)
+  : mModule(reinterpret_cast<const gralloc_module_t*>(module)),
+    mMinorVersion(mModule->common.module_api_version & 0xFF),
+    mDevice(nullptr)
+{
+    ALOGV("Constructing");
+    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)
+{
+    if (outCapabilities == nullptr) {
+        *outCount = 1;
+        return;
+    }
+    if (*outCount >= 1) {
+        *outCapabilities = GRALLOC1_CAPABILITY_ON_ADAPTER;
+        *outCount = 1;
+    }
+}
+
+gralloc1_function_pointer_t Gralloc1On0Adapter::doGetFunction(
+        int32_t intDescriptor)
+{
+    constexpr auto lastDescriptor =
+            static_cast<int32_t>(GRALLOC1_LAST_ADAPTER_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_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_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:
+            // Not provided, since we'll use ALLOCATE_WITH_ID
+            return nullptr;
+        case GRALLOC1_FUNCTION_ALLOCATE_WITH_ID:
+            if (mDevice != nullptr) {
+                return asFP<GRALLOC1_PFN_ALLOCATE_WITH_ID>(allocateWithIdHook);
+            } else {
+                return nullptr;
+            }
+        case GRALLOC1_FUNCTION_RETAIN:
+            return asFP<GRALLOC1_PFN_RETAIN>(
+                    managementHook<&Gralloc1On0Adapter::retain>);
+        case GRALLOC1_FUNCTION_RELEASE:
+            return asFP<GRALLOC1_PFN_RELEASE>(
+                    managementHook<&Gralloc1On0Adapter::release>);
+        case GRALLOC1_FUNCTION_RETAIN_GRAPHIC_BUFFER:
+            return asFP<GRALLOC1_PFN_RETAIN_GRAPHIC_BUFFER>(
+                    retainGraphicBufferHook);
+        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_LOCK_YCBCR:
+            return asFP<GRALLOC1_PFN_LOCK_YCBCR>(
+                    lockHook<struct android_ycbcr,
+                    &Gralloc1On0Adapter::lockYCbCr>);
+        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++;
+    mDescriptors.emplace(descriptorId,
+            std::make_shared<Descriptor>(this, descriptorId));
+
+    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);
+
+    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, bool wasAllocated)
+  : mHandle(handle),
+    mReferenceCount(1),
+    mStore(store),
+    mDescriptor(descriptor),
+    mStride(stride),
+    mWasAllocated(wasAllocated) {}
+
+gralloc1_error_t Gralloc1On0Adapter::allocate(
+        const std::shared_ptr<Descriptor>& descriptor,
+        gralloc1_backing_store_t store,
+        buffer_handle_t* outBufferHandle)
+{
+    ALOGV("allocate(%" PRIu64 ", %#" PRIx64 ")", descriptor->id, store);
+
+    // 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;
+    }
+
+    *outBufferHandle = handle;
+    auto buffer = std::make_shared<Buffer>(handle, store, *descriptor, stride,
+            true);
+    mBuffers.emplace(handle, std::move(buffer));
+
+    return GRALLOC1_ERROR_NONE;
+}
+
+gralloc1_error_t Gralloc1On0Adapter::allocateWithIdHook(
+        gralloc1_device_t* device, gralloc1_buffer_descriptor_t descriptorId,
+        gralloc1_backing_store_t store, buffer_handle_t* outBuffer)
+{
+    auto adapter = getAdapter(device);
+
+    auto descriptor = adapter->getDescriptor(descriptorId);
+    if (!descriptor) {
+        return GRALLOC1_ERROR_BAD_DESCRIPTOR;
+    }
+
+    buffer_handle_t bufferHandle = nullptr;
+    auto error = adapter->allocate(descriptor, store, &bufferHandle);
+    if (error != GRALLOC1_ERROR_NONE) {
+        return error;
+    }
+
+    *outBuffer = bufferHandle;
+    return error;
+}
+
+gralloc1_error_t Gralloc1On0Adapter::retain(
+        const std::shared_ptr<Buffer>& buffer)
+{
+    buffer->retain();
+    return GRALLOC1_ERROR_NONE;
+}
+
+gralloc1_error_t Gralloc1On0Adapter::release(
+        const std::shared_ptr<Buffer>& buffer)
+{
+    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(
+        const android::GraphicBuffer* graphicBuffer)
+{
+    ALOGV("retainGraphicBuffer(%p, %#" PRIx64 ")",
+            graphicBuffer->getNativeBuffer()->handle, graphicBuffer->getId());
+
+    buffer_handle_t handle = graphicBuffer->getNativeBuffer()->handle;
+    if (mBuffers.count(handle) != 0) {
+        mBuffers[handle]->retain();
+        return GRALLOC1_ERROR_NONE;
+    }
+
+    ALOGV("Calling registerBuffer(%p)", handle);
+    int result = mModule->registerBuffer(mModule, handle);
+    if (result != 0) {
+        ALOGE("gralloc0 register failed: %d", result);
+        return GRALLOC1_ERROR_NO_RESOURCES;
+    }
+
+    Descriptor descriptor{this, sNextBufferDescriptorId++};
+    descriptor.setDimensions(graphicBuffer->getWidth(),
+            graphicBuffer->getHeight());
+    descriptor.setFormat(graphicBuffer->getPixelFormat());
+    descriptor.setProducerUsage(
+            static_cast<gralloc1_producer_usage_t>(graphicBuffer->getUsage()));
+    descriptor.setConsumerUsage(
+            static_cast<gralloc1_consumer_usage_t>(graphicBuffer->getUsage()));
+    auto buffer = std::make_shared<Buffer>(handle,
+            static_cast<gralloc1_backing_store_t>(graphicBuffer->getId()),
+            descriptor, graphicBuffer->getStride(), false);
+    mBuffers.emplace(handle, std::move(buffer));
+    return GRALLOC1_ERROR_NONE;
+}
+
+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,
+        const sp<Fence>& 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->dup());
+        if (result != 0) {
+            return GRALLOC1_ERROR_UNSUPPORTED;
+        }
+    } else {
+        acquireFence->waitForever("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;
+        }
+    }
+    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* /*outData*/,
+        const sp<Fence>& /*acquireFence*/)
+{
+    // TODO
+    return GRALLOC1_ERROR_UNSUPPORTED;
+}
+
+gralloc1_error_t Gralloc1On0Adapter::lockYCbCr(
+        const std::shared_ptr<Buffer>& buffer,
+        gralloc1_producer_usage_t producerUsage,
+        gralloc1_consumer_usage_t consumerUsage,
+        const gralloc1_rect_t& accessRegion, struct android_ycbcr* outData,
+        const sp<Fence>& acquireFence)
+{
+    if (mMinorVersion >= 3 && mModule->lockAsync_ycbcr) {
+        int result = mModule->lockAsync_ycbcr(mModule, buffer->getHandle(),
+                static_cast<int>(producerUsage | consumerUsage),
+                accessRegion.left, accessRegion.top, accessRegion.width,
+                accessRegion.height, outData, acquireFence->dup());
+        if (result != 0) {
+            return GRALLOC1_ERROR_UNSUPPORTED;
+        }
+    } else if (mModule->lock_ycbcr) {
+        acquireFence->waitForever("Gralloc1On0Adapter::lockYCbCr");
+        int result = mModule->lock_ycbcr(mModule, buffer->getHandle(),
+                static_cast<int>(producerUsage | consumerUsage),
+                accessRegion.left, accessRegion.top, accessRegion.width,
+                accessRegion.height, outData);
+        ALOGV("gralloc0 lockYCbCr returned %d", result);
+        if (result != 0) {
+            return GRALLOC1_ERROR_UNSUPPORTED;
+        }
+    } else {
+        return GRALLOC1_ERROR_UNSUPPORTED;
+    }
+
+    return GRALLOC1_ERROR_NONE;
+}
+
+gralloc1_error_t Gralloc1On0Adapter::unlock(
+        const std::shared_ptr<Buffer>& buffer,
+        sp<Fence>* 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 = new Fence(fenceFd);
+        }
+    } else {
+        int result = mModule->unlock(mModule, buffer->getHandle());
+        if (result != 0) {
+            ALOGE("gralloc0 unlock failed: %d", result);
+        }
+    }
+    return GRALLOC1_ERROR_NONE;
+}
+
+std::shared_ptr<Gralloc1On0Adapter::Descriptor>
+Gralloc1On0Adapter::getDescriptor(gralloc1_buffer_descriptor_t descriptorId)
+{
+    if (mDescriptors.count(descriptorId) == 0) {
+        return nullptr;
+    }
+
+    return mDescriptors[descriptorId];
+}
+
+std::shared_ptr<Gralloc1On0Adapter::Buffer> Gralloc1On0Adapter::getBuffer(
+        buffer_handle_t bufferHandle)
+{
+    if (mBuffers.count(bufferHandle) == 0) {
+        return nullptr;
+    }
+
+    return mBuffers[bufferHandle];
+}
+
+std::atomic<gralloc1_buffer_descriptor_t>
+        Gralloc1On0Adapter::sNextBufferDescriptorId(1);
+
+} // namespace android
