diff --git a/include/ui/Gralloc1.h b/include/ui/Gralloc1.h
new file mode 100644
index 0000000..cf8c173
--- /dev/null
+++ b/include/ui/Gralloc1.h
@@ -0,0 +1,238 @@
+/*
+ * 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_GRALLOC1_H
+#define ANDROID_UI_GRALLOC1_H
+
+#define GRALLOC1_LOG_TAG "Gralloc1"
+
+#include <ui/Gralloc1On0Adapter.h>
+
+#include <unordered_set>
+
+namespace std {
+    template <>
+    struct hash<gralloc1_capability_t> {
+        size_t operator()(gralloc1_capability_t capability) const {
+            return std::hash<int32_t>()(static_cast<int32_t>(capability));
+        }
+    };
+}
+
+namespace android {
+
+class Fence;
+class GraphicBuffer;
+
+namespace Gralloc1 {
+
+class Device;
+
+class Descriptor {
+public:
+    Descriptor(Device& device, gralloc1_buffer_descriptor_t deviceId)
+      : mShimDevice(device),
+        mDeviceId(deviceId),
+        mWidth(0),
+        mHeight(0),
+        mFormat(static_cast<android_pixel_format_t>(0)),
+        mProducerUsage(GRALLOC1_PRODUCER_USAGE_NONE),
+        mConsumerUsage(GRALLOC1_CONSUMER_USAGE_NONE) {}
+
+    ~Descriptor();
+
+    gralloc1_buffer_descriptor_t getDeviceId() const { return mDeviceId; }
+
+    gralloc1_error_t setDimensions(uint32_t width, uint32_t height);
+    gralloc1_error_t setFormat(android_pixel_format_t format);
+    gralloc1_error_t setProducerUsage(gralloc1_producer_usage_t usage);
+    gralloc1_error_t setConsumerUsage(gralloc1_consumer_usage_t usage);
+
+private:
+    Device& mShimDevice;
+    const gralloc1_buffer_descriptor_t mDeviceId;
+
+    uint32_t mWidth;
+    uint32_t mHeight;
+    android_pixel_format_t mFormat;
+    gralloc1_producer_usage_t mProducerUsage;
+    gralloc1_consumer_usage_t mConsumerUsage;
+
+}; // Descriptor
+
+class Device {
+    friend class Gralloc1::Descriptor;
+
+public:
+    Device(gralloc1_device_t* device);
+
+    bool hasCapability(gralloc1_capability_t capability) const;
+
+    std::string dump();
+
+    std::shared_ptr<Descriptor> createDescriptor();
+
+    gralloc1_error_t getStride(buffer_handle_t buffer, uint32_t* outStride);
+
+    gralloc1_error_t allocate(
+            const std::vector<std::shared_ptr<const Descriptor>>& descriptors,
+            std::vector<buffer_handle_t>* outBuffers);
+    gralloc1_error_t allocate(
+            const std::shared_ptr<const Descriptor>& descriptor,
+            gralloc1_backing_store_t id, buffer_handle_t* outBuffer);
+
+    gralloc1_error_t retain(buffer_handle_t buffer);
+    gralloc1_error_t retain(const GraphicBuffer* buffer);
+
+    gralloc1_error_t release(buffer_handle_t buffer);
+
+    gralloc1_error_t getNumFlexPlanes(buffer_handle_t buffer,
+            uint32_t* outNumPlanes);
+
+    gralloc1_error_t lock(buffer_handle_t 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(buffer_handle_t 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);
+    gralloc1_error_t lockYCbCr(buffer_handle_t buffer,
+            gralloc1_producer_usage_t producerUsage,
+            gralloc1_consumer_usage_t consumerUsage,
+            const gralloc1_rect_t* accessRegion, struct android_ycbcr* outData,
+            const sp<Fence>& acquireFence);
+
+    gralloc1_error_t unlock(buffer_handle_t buffer, sp<Fence>* outFence);
+
+private:
+    std::unordered_set<gralloc1_capability_t> loadCapabilities();
+
+    bool loadFunctions();
+
+    template <typename LockType, typename OutType>
+    gralloc1_error_t lockHelper(LockType pfn, buffer_handle_t buffer,
+            gralloc1_producer_usage_t producerUsage,
+            gralloc1_consumer_usage_t consumerUsage,
+            const gralloc1_rect_t* accessRegion, OutType* outData,
+            const sp<Fence>& acquireFence) {
+        int32_t intError = pfn(mDevice, buffer,
+                static_cast<uint64_t>(producerUsage),
+                static_cast<uint64_t>(consumerUsage), accessRegion, outData,
+                acquireFence->dup());
+        return static_cast<gralloc1_error_t>(intError);
+    }
+
+    gralloc1_device_t* const mDevice;
+
+    const std::unordered_set<gralloc1_capability_t> mCapabilities;
+
+    template <typename PFN, gralloc1_function_descriptor_t descriptor>
+    struct FunctionLoader {
+        FunctionLoader() : pfn(nullptr) {}
+
+        bool load(gralloc1_device_t* device, bool errorIfNull) {
+            gralloc1_function_pointer_t rawPointer =
+                    device->getFunction(device, descriptor);
+            pfn = reinterpret_cast<PFN>(rawPointer);
+            if (errorIfNull && !rawPointer) {
+                ALOG(LOG_ERROR, GRALLOC1_LOG_TAG,
+                        "Failed to load function pointer %d", descriptor);
+            }
+            return rawPointer != nullptr;
+        }
+
+        template <typename ...Args>
+        typename std::result_of<PFN(Args...)>::type operator()(Args... args) {
+            return pfn(args...);
+        }
+
+        PFN pfn;
+    };
+
+    // Function pointers
+    struct Functions {
+        FunctionLoader<GRALLOC1_PFN_DUMP, GRALLOC1_FUNCTION_DUMP> dump;
+        FunctionLoader<GRALLOC1_PFN_CREATE_DESCRIPTOR,
+                GRALLOC1_FUNCTION_CREATE_DESCRIPTOR> createDescriptor;
+        FunctionLoader<GRALLOC1_PFN_DESTROY_DESCRIPTOR,
+                GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR> destroyDescriptor;
+        FunctionLoader<GRALLOC1_PFN_SET_CONSUMER_USAGE,
+                GRALLOC1_FUNCTION_SET_CONSUMER_USAGE> setConsumerUsage;
+        FunctionLoader<GRALLOC1_PFN_SET_DIMENSIONS,
+                GRALLOC1_FUNCTION_SET_DIMENSIONS> setDimensions;
+        FunctionLoader<GRALLOC1_PFN_SET_FORMAT,
+                GRALLOC1_FUNCTION_SET_FORMAT> setFormat;
+        FunctionLoader<GRALLOC1_PFN_SET_PRODUCER_USAGE,
+                GRALLOC1_FUNCTION_SET_PRODUCER_USAGE> setProducerUsage;
+        FunctionLoader<GRALLOC1_PFN_GET_BACKING_STORE,
+                GRALLOC1_FUNCTION_GET_BACKING_STORE> getBackingStore;
+        FunctionLoader<GRALLOC1_PFN_GET_CONSUMER_USAGE,
+                GRALLOC1_FUNCTION_GET_CONSUMER_USAGE> getConsumerUsage;
+        FunctionLoader<GRALLOC1_PFN_GET_DIMENSIONS,
+                GRALLOC1_FUNCTION_GET_DIMENSIONS> getDimensions;
+        FunctionLoader<GRALLOC1_PFN_GET_FORMAT,
+                GRALLOC1_FUNCTION_GET_FORMAT> getFormat;
+        FunctionLoader<GRALLOC1_PFN_GET_PRODUCER_USAGE,
+                GRALLOC1_FUNCTION_GET_PRODUCER_USAGE> getProducerUsage;
+        FunctionLoader<GRALLOC1_PFN_GET_STRIDE,
+                GRALLOC1_FUNCTION_GET_STRIDE> getStride;
+        FunctionLoader<GRALLOC1_PFN_ALLOCATE,
+                GRALLOC1_FUNCTION_ALLOCATE> allocate;
+        FunctionLoader<GRALLOC1_PFN_RETAIN,
+                GRALLOC1_FUNCTION_RETAIN> retain;
+        FunctionLoader<GRALLOC1_PFN_RELEASE,
+                GRALLOC1_FUNCTION_RELEASE> release;
+        FunctionLoader<GRALLOC1_PFN_GET_NUM_FLEX_PLANES,
+                GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES> getNumFlexPlanes;
+        FunctionLoader<GRALLOC1_PFN_LOCK,
+                GRALLOC1_FUNCTION_LOCK> lock;
+        FunctionLoader<GRALLOC1_PFN_LOCK_FLEX,
+                GRALLOC1_FUNCTION_LOCK_FLEX> lockFlex;
+        FunctionLoader<GRALLOC1_PFN_LOCK_YCBCR,
+                GRALLOC1_FUNCTION_LOCK_YCBCR> lockYCbCr;
+        FunctionLoader<GRALLOC1_PFN_UNLOCK,
+                GRALLOC1_FUNCTION_UNLOCK> unlock;
+
+        // Adapter-only functions
+        FunctionLoader<GRALLOC1_PFN_RETAIN_GRAPHIC_BUFFER,
+                GRALLOC1_FUNCTION_RETAIN_GRAPHIC_BUFFER> retainGraphicBuffer;
+        FunctionLoader<GRALLOC1_PFN_ALLOCATE_WITH_ID,
+                GRALLOC1_FUNCTION_ALLOCATE_WITH_ID> allocateWithId;
+    } mFunctions;
+
+}; // class android::Gralloc1::Device
+
+class Loader
+{
+public:
+    Loader();
+    ~Loader();
+
+    std::unique_ptr<Device> getDevice();
+
+private:
+    static std::unique_ptr<Gralloc1On0Adapter> mAdapter;
+    std::unique_ptr<Device> mDevice;
+};
+
+} // namespace android::Gralloc1
+
+} // namespace android
+
+#endif
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/include/ui/GraphicBufferAllocator.h b/include/ui/GraphicBufferAllocator.h
index 5443f09..62ebbd5 100644
--- a/include/ui/GraphicBufferAllocator.h
+++ b/include/ui/GraphicBufferAllocator.h
@@ -27,42 +27,41 @@
 #include <utils/threads.h>
 #include <utils/Singleton.h>
 
+#include <ui/Gralloc1.h>
 #include <ui/PixelFormat.h>
 
-#include <hardware/gralloc.h>
-
-
 namespace android {
-// ---------------------------------------------------------------------------
 
+class Gralloc1Loader;
 class String8;
 
 class GraphicBufferAllocator : public Singleton<GraphicBufferAllocator>
 {
 public:
     enum {
-        USAGE_SW_READ_NEVER     = GRALLOC_USAGE_SW_READ_NEVER,
-        USAGE_SW_READ_RARELY    = GRALLOC_USAGE_SW_READ_RARELY,
-        USAGE_SW_READ_OFTEN     = GRALLOC_USAGE_SW_READ_OFTEN,
-        USAGE_SW_READ_MASK      = GRALLOC_USAGE_SW_READ_MASK,
+        USAGE_SW_READ_NEVER     = GRALLOC1_CONSUMER_USAGE_CPU_READ_NEVER,
+        USAGE_SW_READ_RARELY    = GRALLOC1_CONSUMER_USAGE_CPU_READ,
+        USAGE_SW_READ_OFTEN     = GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN,
+        USAGE_SW_READ_MASK      = GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN,
 
-        USAGE_SW_WRITE_NEVER    = GRALLOC_USAGE_SW_WRITE_NEVER,
-        USAGE_SW_WRITE_RARELY   = GRALLOC_USAGE_SW_WRITE_RARELY,
-        USAGE_SW_WRITE_OFTEN    = GRALLOC_USAGE_SW_WRITE_OFTEN,
-        USAGE_SW_WRITE_MASK     = GRALLOC_USAGE_SW_WRITE_MASK,
+        USAGE_SW_WRITE_NEVER    = GRALLOC1_PRODUCER_USAGE_CPU_WRITE_NEVER,
+        USAGE_SW_WRITE_RARELY   = GRALLOC1_PRODUCER_USAGE_CPU_WRITE,
+        USAGE_SW_WRITE_OFTEN    = GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN,
+        USAGE_SW_WRITE_MASK     = GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN,
 
         USAGE_SOFTWARE_MASK     = USAGE_SW_READ_MASK|USAGE_SW_WRITE_MASK,
 
-        USAGE_HW_TEXTURE        = GRALLOC_USAGE_HW_TEXTURE,
-        USAGE_HW_RENDER         = GRALLOC_USAGE_HW_RENDER,
-        USAGE_HW_2D             = GRALLOC_USAGE_HW_2D,
-        USAGE_HW_MASK           = GRALLOC_USAGE_HW_MASK
+        USAGE_HW_TEXTURE        = GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE,
+        USAGE_HW_RENDER         = GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET,
+        USAGE_HW_2D             = 0x00000400, // Deprecated
+        USAGE_HW_MASK           = 0x00071F00, // Deprecated
     };
 
     static inline GraphicBufferAllocator& get() { return getInstance(); }
 
-    status_t alloc(uint32_t w, uint32_t h, PixelFormat format, uint32_t usage,
-            buffer_handle_t* handle, uint32_t* stride);
+    status_t allocate(uint32_t w, uint32_t h, PixelFormat format,
+            uint32_t usage, buffer_handle_t* handle, uint32_t* stride,
+            uint64_t graphicBufferId);
 
     status_t free(buffer_handle_t handle);
 
@@ -86,7 +85,8 @@
     GraphicBufferAllocator();
     ~GraphicBufferAllocator();
 
-    alloc_device_t  *mAllocDev;
+    std::unique_ptr<Gralloc1::Loader> mLoader;
+    std::unique_ptr<Gralloc1::Device> mDevice;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/include/ui/GraphicBufferMapper.h b/include/ui/GraphicBufferMapper.h
index 6099548..a25809c 100644
--- a/include/ui/GraphicBufferMapper.h
+++ b/include/ui/GraphicBufferMapper.h
@@ -20,13 +20,10 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+#include <ui/Gralloc1.h>
+
 #include <utils/Singleton.h>
 
-#include <hardware/gralloc.h>
-
-
-struct gralloc_module_t;
-
 namespace android {
 
 // ---------------------------------------------------------------------------
@@ -39,6 +36,7 @@
     static inline GraphicBufferMapper& get() { return getInstance(); }
 
     status_t registerBuffer(buffer_handle_t handle);
+    status_t registerBuffer(const GraphicBuffer* buffer);
 
     status_t unregisterBuffer(buffer_handle_t handle);
 
@@ -59,13 +57,13 @@
 
     status_t unlockAsync(buffer_handle_t handle, int *fenceFd);
 
-    // dumps information about the mapping of this handle
-    void dump(buffer_handle_t handle);
-
 private:
     friend class Singleton<GraphicBufferMapper>;
+
     GraphicBufferMapper();
-    gralloc_module_t const *mAllocMod;
+
+    std::unique_ptr<Gralloc1::Loader> mLoader;
+    std::unique_ptr<Gralloc1::Device> mDevice;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
index ee6c093..e690ede 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,8 @@
 LOCAL_SRC_FILES := \
 	Fence.cpp \
 	FrameStats.cpp \
+	Gralloc1.cpp \
+	Gralloc1On0Adapter.cpp \
 	GraphicBuffer.cpp \
 	GraphicBufferAllocator.cpp \
 	GraphicBufferMapper.cpp \
diff --git a/libs/ui/Gralloc1.cpp b/libs/ui/Gralloc1.cpp
new file mode 100644
index 0000000..4c73ce4
--- /dev/null
+++ b/libs/ui/Gralloc1.cpp
@@ -0,0 +1,402 @@
+/*
+ * 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_NDEBUG 0
+
+#include <ui/Gralloc1.h>
+
+#include <vector>
+
+#undef LOG_TAG
+#define LOG_TAG GRALLOC1_LOG_TAG
+
+namespace android {
+
+namespace Gralloc1 {
+
+Descriptor::~Descriptor()
+{
+    int32_t intError = mShimDevice.mFunctions.destroyDescriptor(
+            mShimDevice.mDevice, mDeviceId);
+    auto error = static_cast<gralloc1_error_t>(intError);
+    if (error != GRALLOC1_ERROR_NONE) {
+        ALOGE("destroyDescriptor failed: %d", intError);
+    }
+}
+
+gralloc1_error_t Descriptor::setDimensions(uint32_t width, uint32_t height)
+{
+    int32_t intError = mShimDevice.mFunctions.setDimensions(mShimDevice.mDevice,
+            mDeviceId, width, height);
+    auto error = static_cast<gralloc1_error_t>(intError);
+    if (error != GRALLOC1_ERROR_NONE) {
+        return error;
+    }
+    mWidth = width;
+    mHeight = height;
+    return error;
+}
+
+template <typename ApiType>
+struct Setter {
+    typedef int32_t (*Type)(gralloc1_device_t*, gralloc1_buffer_descriptor_t,
+            ApiType);
+};
+
+template <typename ApiType, typename ValueType>
+static inline gralloc1_error_t setHelper(
+        typename Setter<ApiType>::Type setter, gralloc1_device_t* device,
+        gralloc1_buffer_descriptor_t id, ValueType newValue,
+        ValueType* cacheVariable)
+{
+    int32_t intError = setter(device, id, static_cast<ApiType>(newValue));
+    auto error = static_cast<gralloc1_error_t>(intError);
+    if (error != GRALLOC1_ERROR_NONE) {
+        return error;
+    }
+    *cacheVariable = newValue;
+    return error;
+}
+
+gralloc1_error_t Descriptor::setFormat(android_pixel_format_t format)
+{
+    return setHelper<int32_t>(mShimDevice.mFunctions.setFormat.pfn,
+            mShimDevice.mDevice, mDeviceId, format, &mFormat);
+}
+
+gralloc1_error_t Descriptor::setProducerUsage(gralloc1_producer_usage_t usage)
+{
+    return setHelper<uint64_t>(mShimDevice.mFunctions.setProducerUsage.pfn,
+            mShimDevice.mDevice, mDeviceId, usage, &mProducerUsage);
+}
+
+gralloc1_error_t Descriptor::setConsumerUsage(gralloc1_consumer_usage_t usage)
+{
+    return setHelper<uint64_t>(mShimDevice.mFunctions.setConsumerUsage.pfn,
+            mShimDevice.mDevice, mDeviceId, usage, &mConsumerUsage);
+}
+
+Device::Device(gralloc1_device_t* device)
+  : mDevice(device),
+    mCapabilities(loadCapabilities()),
+    mFunctions()
+{
+    if (!loadFunctions()) {
+        ALOGE("Failed to load a required function, aborting");
+        abort();
+    }
+}
+
+bool Device::hasCapability(gralloc1_capability_t capability) const
+{
+    return mCapabilities.count(capability) > 0;
+}
+
+std::string Device::dump()
+{
+    uint32_t length = 0;
+    mFunctions.dump(mDevice, &length, nullptr);
+
+    std::vector<char> output;
+    output.resize(length);
+    mFunctions.dump(mDevice, &length, output.data());
+
+    return std::string(output.cbegin(), output.cend());
+}
+
+std::shared_ptr<Descriptor> Device::createDescriptor()
+{
+    gralloc1_buffer_descriptor_t descriptorId;
+    int32_t intError = mFunctions.createDescriptor(mDevice, &descriptorId);
+    auto error = static_cast<gralloc1_error_t>(intError);
+    if (error != GRALLOC1_ERROR_NONE) {
+        return nullptr;
+    }
+    auto descriptor = std::make_shared<Descriptor>(*this, descriptorId);
+    return descriptor;
+}
+
+gralloc1_error_t Device::getStride(buffer_handle_t buffer, uint32_t* outStride)
+{
+    int32_t intError = mFunctions.getStride(mDevice, buffer, outStride);
+    return static_cast<gralloc1_error_t>(intError);
+}
+
+static inline bool allocationSucceded(gralloc1_error_t error)
+{
+    return error == GRALLOC1_ERROR_NONE || error == GRALLOC1_ERROR_NOT_SHARED;
+}
+
+gralloc1_error_t Device::allocate(
+        const std::vector<std::shared_ptr<const Descriptor>>& descriptors,
+        std::vector<buffer_handle_t>* outBuffers)
+{
+    if (mFunctions.allocate.pfn == nullptr) {
+        // Allocation is not supported on this device
+        return GRALLOC1_ERROR_UNSUPPORTED;
+    }
+
+    std::vector<gralloc1_buffer_descriptor_t> deviceIds;
+    for (const auto& descriptor : descriptors) {
+        deviceIds.emplace_back(descriptor->getDeviceId());
+    }
+
+    std::vector<buffer_handle_t> buffers(descriptors.size());
+    int32_t intError = mFunctions.allocate(mDevice,
+            static_cast<uint32_t>(descriptors.size()), deviceIds.data(),
+            buffers.data());
+    auto error = static_cast<gralloc1_error_t>(intError);
+    if (allocationSucceded(error)) {
+        *outBuffers = std::move(buffers);
+    }
+
+    return error;
+}
+
+gralloc1_error_t Device::allocate(
+        const std::shared_ptr<const Descriptor>& descriptor,
+        gralloc1_backing_store_t id, buffer_handle_t* outBuffer)
+{
+    gralloc1_error_t error = GRALLOC1_ERROR_NONE;
+
+    if (hasCapability(GRALLOC1_CAPABILITY_ON_ADAPTER)) {
+        buffer_handle_t buffer = nullptr;
+        int32_t intError = mFunctions.allocateWithId(mDevice,
+                descriptor->getDeviceId(), id, &buffer);
+        error = static_cast<gralloc1_error_t>(intError);
+        if (allocationSucceded(error)) {
+            *outBuffer = buffer;
+        }
+    } else {
+        std::vector<std::shared_ptr<const Descriptor>> descriptors;
+        descriptors.emplace_back(descriptor);
+        std::vector<buffer_handle_t> buffers;
+        error = allocate(descriptors, &buffers);
+        if (allocationSucceded(error)) {
+            *outBuffer = buffers[0];
+        }
+    }
+
+    return error;
+}
+
+gralloc1_error_t Device::retain(buffer_handle_t buffer)
+{
+    int32_t intError = mFunctions.retain(mDevice, buffer);
+    return static_cast<gralloc1_error_t>(intError);
+}
+
+gralloc1_error_t Device::retain(const GraphicBuffer* buffer)
+{
+    if (hasCapability(GRALLOC1_CAPABILITY_ON_ADAPTER)) {
+        return mFunctions.retainGraphicBuffer(mDevice, buffer);
+    } else {
+        return retain(buffer->getNativeBuffer()->handle);
+    }
+}
+
+gralloc1_error_t Device::release(buffer_handle_t buffer)
+{
+    int32_t intError = mFunctions.release(mDevice, buffer);
+    return static_cast<gralloc1_error_t>(intError);
+}
+
+gralloc1_error_t Device::getNumFlexPlanes(buffer_handle_t buffer,
+        uint32_t* outNumPlanes)
+{
+    uint32_t numPlanes = 0;
+    int32_t intError = mFunctions.getNumFlexPlanes(mDevice, buffer, &numPlanes);
+    auto error = static_cast<gralloc1_error_t>(intError);
+    if (error == GRALLOC1_ERROR_NONE) {
+        *outNumPlanes = numPlanes;
+    }
+    return error;
+}
+
+gralloc1_error_t Device::lock(buffer_handle_t buffer,
+        gralloc1_producer_usage_t producerUsage,
+        gralloc1_consumer_usage_t consumerUsage,
+        const gralloc1_rect_t* accessRegion, void** outData,
+        const sp<Fence>& acquireFence)
+{
+    ALOGV("Calling lock(%p)", buffer);
+    return lockHelper(mFunctions.lock.pfn, buffer, producerUsage,
+            consumerUsage, accessRegion, outData, acquireFence);
+}
+
+gralloc1_error_t Device::lockFlex(buffer_handle_t 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)
+{
+    ALOGV("Calling lockFlex(%p)", buffer);
+    return lockHelper(mFunctions.lockFlex.pfn, buffer, producerUsage,
+            consumerUsage, accessRegion, outData, acquireFence);
+}
+
+gralloc1_error_t Device::lockYCbCr(buffer_handle_t buffer,
+        gralloc1_producer_usage_t producerUsage,
+        gralloc1_consumer_usage_t consumerUsage,
+        const gralloc1_rect_t* accessRegion,
+        struct android_ycbcr* outData,
+        const sp<Fence>& acquireFence)
+{
+    ALOGV("Calling lockYCbCr(%p)", buffer);
+    return lockHelper(mFunctions.lockYCbCr.pfn, buffer, producerUsage,
+            consumerUsage, accessRegion, outData, acquireFence);
+}
+
+gralloc1_error_t Device::unlock(buffer_handle_t buffer, sp<Fence>* outFence)
+{
+    int32_t fenceFd = -1;
+    int32_t intError = mFunctions.unlock(mDevice, buffer, &fenceFd);
+    auto error = static_cast<gralloc1_error_t>(intError);
+    if (error == GRALLOC1_ERROR_NONE) {
+        *outFence = new Fence(fenceFd);
+    }
+    return error;
+}
+
+std::unordered_set<gralloc1_capability_t> Device::loadCapabilities()
+{
+    std::vector<int32_t> intCapabilities;
+    uint32_t numCapabilities = 0;
+    mDevice->getCapabilities(mDevice, &numCapabilities, nullptr);
+
+    intCapabilities.resize(numCapabilities);
+    mDevice->getCapabilities(mDevice, &numCapabilities, intCapabilities.data());
+
+    std::unordered_set<gralloc1_capability_t> capabilities;
+    for (const auto intCapability : intCapabilities) {
+        capabilities.emplace(static_cast<gralloc1_capability_t>(intCapability));
+    }
+    return capabilities;
+}
+
+bool Device::loadFunctions()
+{
+    // Functions which must always be present
+    if (!mFunctions.dump.load(mDevice, true)) {
+        return false;
+    }
+    if (!mFunctions.createDescriptor.load(mDevice, true)) {
+        return false;
+    }
+    if (!mFunctions.destroyDescriptor.load(mDevice, true)) {
+        return false;
+    }
+    if (!mFunctions.setConsumerUsage.load(mDevice, true)) {
+        return false;
+    }
+    if (!mFunctions.setDimensions.load(mDevice, true)) {
+        return false;
+    }
+    if (!mFunctions.setFormat.load(mDevice, true)) {
+        return false;
+    }
+    if (!mFunctions.setProducerUsage.load(mDevice, true)) {
+        return false;
+    }
+    if (!mFunctions.getBackingStore.load(mDevice, true)) {
+        return false;
+    }
+    if (!mFunctions.getConsumerUsage.load(mDevice, true)) {
+        return false;
+    }
+    if (!mFunctions.getDimensions.load(mDevice, true)) {
+        return false;
+    }
+    if (!mFunctions.getFormat.load(mDevice, true)) {
+        return false;
+    }
+    if (!mFunctions.getProducerUsage.load(mDevice, true)) {
+        return false;
+    }
+    if (!mFunctions.getStride.load(mDevice, true)) {
+        return false;
+    }
+    if (!mFunctions.retain.load(mDevice, true)) {
+        return false;
+    }
+    if (!mFunctions.release.load(mDevice, true)) {
+        return false;
+    }
+    if (!mFunctions.getNumFlexPlanes.load(mDevice, true)) {
+        return false;
+    }
+    if (!mFunctions.lock.load(mDevice, true)) {
+        return false;
+    }
+    if (!mFunctions.lockFlex.load(mDevice, true)) {
+        return false;
+    }
+    if (!mFunctions.unlock.load(mDevice, true)) {
+        return false;
+    }
+
+    if (hasCapability(GRALLOC1_CAPABILITY_ON_ADAPTER)) {
+        // These should always be present on the adapter
+        if (!mFunctions.retainGraphicBuffer.load(mDevice, true)) {
+            return false;
+        }
+        if (!mFunctions.lockYCbCr.load(mDevice, true)) {
+            return false;
+        }
+
+        // allocateWithId may not be present if we're only able to map in this
+        // process
+        mFunctions.allocateWithId.load(mDevice, false);
+    } else {
+        // allocate may not be present if we're only able to map in this process
+        mFunctions.allocate.load(mDevice, false);
+    }
+
+    return true;
+}
+
+std::unique_ptr<Gralloc1On0Adapter> Loader::mAdapter = nullptr;
+
+Loader::Loader()
+  : mDevice(nullptr)
+{
+    hw_module_t const* module;
+    int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
+    uint8_t majorVersion = (module->module_api_version >> 8) & 0xFF;
+    uint8_t minorVersion = module->module_api_version & 0xFF;
+    gralloc1_device_t* device = nullptr;
+    if (majorVersion == 1) {
+        gralloc1_open(module, &device);
+    } else {
+        if (!mAdapter) {
+            mAdapter = std::make_unique<Gralloc1On0Adapter>(module);
+        }
+        device = mAdapter->getDevice();
+    }
+    mDevice = std::make_unique<Gralloc1::Device>(device);
+}
+
+Loader::~Loader() {}
+
+std::unique_ptr<Device> Loader::getDevice()
+{
+    return std::move(mDevice);
+}
+
+} // namespace android::Gralloc1
+
+} // namespace android
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
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index 4fe0946..f28af6e 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -169,8 +169,8 @@
 {
     GraphicBufferAllocator& allocator = GraphicBufferAllocator::get();
     uint32_t outStride = 0;
-    status_t err = allocator.alloc(inWidth, inHeight, inFormat, inUsage,
-            &handle, &outStride);
+    status_t err = allocator.allocate(inWidth, inHeight, inFormat, inUsage,
+            &handle, &outStride, mId);
     if (err == NO_ERROR) {
         width = static_cast<int>(inWidth);
         height = static_cast<int>(inHeight);
@@ -390,7 +390,7 @@
     mOwner = ownHandle;
 
     if (handle != 0) {
-        status_t err = mBufferMapper.registerBuffer(handle);
+        status_t err = mBufferMapper.registerBuffer(this);
         if (err != NO_ERROR) {
             width = height = stride = format = usage = 0;
             handle = NULL;
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index 9b265af..3b83fb6 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -25,6 +25,7 @@
 #include <utils/Trace.h>
 
 #include <ui/GraphicBufferAllocator.h>
+#include <ui/Gralloc1On0Adapter.h>
 
 namespace android {
 // ---------------------------------------------------------------------------
@@ -36,20 +37,10 @@
     GraphicBufferAllocator::alloc_rec_t> GraphicBufferAllocator::sAllocList;
 
 GraphicBufferAllocator::GraphicBufferAllocator()
-    : mAllocDev(0)
-{
-    hw_module_t const* module;
-    int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
-    ALOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID);
-    if (err == 0) {
-        gralloc_open(module, &mAllocDev);
-    }
-}
+  : mLoader(std::make_unique<Gralloc1::Loader>()),
+    mDevice(mLoader->getDevice()) {}
 
-GraphicBufferAllocator::~GraphicBufferAllocator()
-{
-    gralloc_close(mAllocDev);
-}
+GraphicBufferAllocator::~GraphicBufferAllocator() {}
 
 void GraphicBufferAllocator::dump(String8& result) const
 {
@@ -77,10 +68,8 @@
     }
     snprintf(buffer, SIZE, "Total allocated (estimate): %.2f KB\n", total/1024.0f);
     result.append(buffer);
-    if (mAllocDev->common.version >= 1 && mAllocDev->dump) {
-        mAllocDev->dump(mAllocDev, buffer, SIZE);
-        result.append(buffer);
-    }
+    std::string deviceDump = mDevice->dump();
+    result.append(deviceDump.c_str(), deviceDump.size());
 }
 
 void GraphicBufferAllocator::dumpToSystemLog()
@@ -90,9 +79,9 @@
     ALOGD("%s", s.string());
 }
 
-status_t GraphicBufferAllocator::alloc(uint32_t width, uint32_t height,
+status_t GraphicBufferAllocator::allocate(uint32_t width, uint32_t height,
         PixelFormat format, uint32_t usage, buffer_handle_t* handle,
-        uint32_t* stride)
+        uint32_t* stride, uint64_t graphicBufferId)
 {
     ATRACE_CALL();
 
@@ -101,22 +90,46 @@
     if (!width || !height)
         width = height = 1;
 
-    // we have a h/w allocator and h/w buffer is requested
-    status_t err;
-
     // Filter out any usage bits that should not be passed to the gralloc module
     usage &= GRALLOC_USAGE_ALLOC_MASK;
 
-    int outStride = 0;
-    err = mAllocDev->alloc(mAllocDev, static_cast<int>(width),
-            static_cast<int>(height), format, static_cast<int>(usage), handle,
-            &outStride);
-    *stride = static_cast<uint32_t>(outStride);
+    auto descriptor = mDevice->createDescriptor();
+    auto error = descriptor->setDimensions(width, height);
+    if (error != GRALLOC1_ERROR_NONE) {
+        ALOGE("Failed to set dimensions to (%u, %u): %d", width, height, error);
+        return BAD_VALUE;
+    }
+    error = descriptor->setFormat(static_cast<android_pixel_format_t>(format));
+    if (error != GRALLOC1_ERROR_NONE) {
+        ALOGE("Failed to set format to %d: %d", format, error);
+        return BAD_VALUE;
+    }
+    error = descriptor->setProducerUsage(
+            static_cast<gralloc1_producer_usage_t>(usage));
+    if (error != GRALLOC1_ERROR_NONE) {
+        ALOGE("Failed to set producer usage to %u: %d", usage, error);
+        return BAD_VALUE;
+    }
+    error = descriptor->setConsumerUsage(
+            static_cast<gralloc1_consumer_usage_t>(usage));
+    if (error != GRALLOC1_ERROR_NONE) {
+        ALOGE("Failed to set consumer usage to %u: %d", usage, error);
+        return BAD_VALUE;
+    }
 
-    ALOGW_IF(err, "alloc(%u, %u, %d, %08x, ...) failed %d (%s)",
-            width, height, format, usage, err, strerror(-err));
+    error = mDevice->allocate(descriptor, graphicBufferId, handle);
+    if (error != GRALLOC1_ERROR_NONE) {
+        ALOGE("Failed to allocate (%u x %u) format %d usage %u: %d",
+                width, height, format, usage, error);
+        return NO_MEMORY;
+    }
 
-    if (err == NO_ERROR) {
+    error = mDevice->getStride(*handle, stride);
+    if (error != GRALLOC1_ERROR_NONE) {
+        ALOGW("Failed to get stride from buffer: %d", error);
+    }
+
+    if (error == NO_ERROR) {
         Mutex::Autolock _l(sLock);
         KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
         uint32_t bpp = bytesPerPixel(format);
@@ -130,24 +143,23 @@
         list.add(*handle, rec);
     }
 
-    return err;
+    return NO_ERROR;
 }
 
 status_t GraphicBufferAllocator::free(buffer_handle_t handle)
 {
     ATRACE_CALL();
-    status_t err;
 
-    err = mAllocDev->free(mAllocDev, handle);
-
-    ALOGW_IF(err, "free(...) failed %d (%s)", err, strerror(-err));
-    if (err == NO_ERROR) {
-        Mutex::Autolock _l(sLock);
-        KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
-        list.removeItem(handle);
+    auto error = mDevice->release(handle);
+    if (error != GRALLOC1_ERROR_NONE) {
+        ALOGE("Failed to free buffer: %d", error);
     }
 
-    return err;
+    Mutex::Autolock _l(sLock);
+    KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
+    list.removeItem(handle);
+
+    return NO_ERROR;
 }
 
 // ---------------------------------------------------------------------------
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
index 90a1c11..481d43c 100644
--- a/libs/ui/GraphicBufferMapper.cpp
+++ b/libs/ui/GraphicBufferMapper.cpp
@@ -16,6 +16,7 @@
 
 #define LOG_TAG "GraphicBufferMapper"
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
+//#define LOG_NDEBUG 0
 
 #include <stdint.h>
 #include <errno.h>
@@ -31,11 +32,11 @@
 #include <utils/Log.h>
 #include <utils/Trace.h>
 
+#include <ui/Gralloc1On0Adapter.h>
 #include <ui/GraphicBufferMapper.h>
 #include <ui/Rect.h>
 
-#include <hardware/gralloc.h>
-
+#include <system/graphics.h>
 
 namespace android {
 // ---------------------------------------------------------------------------
@@ -43,151 +44,247 @@
 ANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferMapper )
 
 GraphicBufferMapper::GraphicBufferMapper()
-    : mAllocMod(0)
-{
-    hw_module_t const* module;
-    int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
-    ALOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID);
-    if (err == 0) {
-        mAllocMod = reinterpret_cast<gralloc_module_t const *>(module);
-    }
-}
+  : mLoader(std::make_unique<Gralloc1::Loader>()),
+    mDevice(mLoader->getDevice()) {}
+
+
 
 status_t GraphicBufferMapper::registerBuffer(buffer_handle_t handle)
 {
     ATRACE_CALL();
-    status_t err;
 
-    err = mAllocMod->registerBuffer(mAllocMod, handle);
+    gralloc1_error_t error = mDevice->retain(handle);
+    ALOGW_IF(error != GRALLOC1_ERROR_NONE, "registerBuffer(%p) failed: %d",
+            handle, error);
 
-    ALOGW_IF(err, "registerBuffer(%p) failed %d (%s)",
-            handle, err, strerror(-err));
-    return err;
+    return error;
+}
+
+status_t GraphicBufferMapper::registerBuffer(const GraphicBuffer* buffer)
+{
+    ATRACE_CALL();
+
+    gralloc1_error_t error = mDevice->retain(buffer);
+    ALOGW_IF(error != GRALLOC1_ERROR_NONE, "registerBuffer(%p) failed: %d",
+            buffer->getNativeBuffer()->handle, error);
+
+    return error;
 }
 
 status_t GraphicBufferMapper::unregisterBuffer(buffer_handle_t handle)
 {
     ATRACE_CALL();
-    status_t err;
 
-    err = mAllocMod->unregisterBuffer(mAllocMod, handle);
+    gralloc1_error_t error = mDevice->release(handle);
+    ALOGW_IF(error != GRALLOC1_ERROR_NONE, "unregisterBuffer(%p): failed %d",
+            handle, error);
 
-    ALOGW_IF(err, "unregisterBuffer(%p) failed %d (%s)",
-            handle, err, strerror(-err));
-    return err;
+    return error;
 }
 
-status_t GraphicBufferMapper::lock(buffer_handle_t handle,
-        uint32_t usage, const Rect& bounds, void** vaddr)
-{
-    ATRACE_CALL();
-    status_t err;
-
-    err = mAllocMod->lock(mAllocMod, handle, static_cast<int>(usage),
-            bounds.left, bounds.top, bounds.width(), bounds.height(),
-            vaddr);
-
-    ALOGW_IF(err, "lock(...) failed %d (%s)", err, strerror(-err));
-    return err;
+static inline gralloc1_rect_t asGralloc1Rect(const Rect& rect) {
+    gralloc1_rect_t outRect{};
+    outRect.left = rect.left;
+    outRect.top = rect.top;
+    outRect.width = rect.width();
+    outRect.height = rect.height();
+    return outRect;
 }
 
-status_t GraphicBufferMapper::lockYCbCr(buffer_handle_t handle,
-        uint32_t usage, const Rect& bounds, android_ycbcr *ycbcr)
+status_t GraphicBufferMapper::lock(buffer_handle_t handle, uint32_t usage,
+        const Rect& bounds, void** vaddr)
 {
-    ATRACE_CALL();
-    status_t err;
+    return lockAsync(handle, usage, bounds, vaddr, -1);
+}
 
-    if (mAllocMod->lock_ycbcr == NULL) {
-        return -EINVAL; // do not log failure
-    }
-
-    err = mAllocMod->lock_ycbcr(mAllocMod, handle, static_cast<int>(usage),
-            bounds.left, bounds.top, bounds.width(), bounds.height(),
-            ycbcr);
-
-    ALOGW_IF(err, "lock(...) failed %d (%s)", err, strerror(-err));
-    return err;
+status_t GraphicBufferMapper::lockYCbCr(buffer_handle_t handle, uint32_t usage,
+        const Rect& bounds, android_ycbcr *ycbcr)
+{
+    return lockAsyncYCbCr(handle, usage, bounds, ycbcr, -1);
 }
 
 status_t GraphicBufferMapper::unlock(buffer_handle_t handle)
 {
-    ATRACE_CALL();
-    status_t err;
-
-    err = mAllocMod->unlock(mAllocMod, handle);
-
-    ALOGW_IF(err, "unlock(...) failed %d (%s)", err, strerror(-err));
-    return err;
+    int32_t fenceFd = -1;
+    status_t error = unlockAsync(handle, &fenceFd);
+    if (error == NO_ERROR) {
+        sync_wait(fenceFd, -1);
+        close(fenceFd);
+    }
+    return error;
 }
 
 status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle,
         uint32_t usage, const Rect& bounds, void** vaddr, int fenceFd)
 {
     ATRACE_CALL();
-    status_t err;
 
-    if (mAllocMod->common.module_api_version >= GRALLOC_MODULE_API_VERSION_0_3) {
-        err = mAllocMod->lockAsync(mAllocMod, handle, static_cast<int>(usage),
-                bounds.left, bounds.top, bounds.width(), bounds.height(),
-                vaddr, fenceFd);
-    } else {
-        if (fenceFd >= 0) {
-            sync_wait(fenceFd, -1);
-            close(fenceFd);
-        }
-        err = mAllocMod->lock(mAllocMod, handle, static_cast<int>(usage),
-                bounds.left, bounds.top, bounds.width(), bounds.height(),
-                vaddr);
+    gralloc1_rect_t accessRegion = asGralloc1Rect(bounds);
+    sp<Fence> fence = new Fence(fenceFd);
+    gralloc1_error_t error = mDevice->lock(handle,
+            static_cast<gralloc1_producer_usage_t>(usage),
+            static_cast<gralloc1_consumer_usage_t>(usage),
+            &accessRegion, vaddr, fence);
+    ALOGW_IF(error != GRALLOC1_ERROR_NONE, "lock(%p, ...) failed: %d", handle,
+            error);
+
+    return error;
+}
+
+static inline bool isValidYCbCrPlane(const android_flex_plane_t& plane) {
+    if (plane.bits_per_component != 8) {
+        ALOGV("Invalid number of bits per component: %d",
+                plane.bits_per_component);
+        return false;
+    }
+    if (plane.bits_used != 8) {
+        ALOGV("Invalid number of bits used: %d", plane.bits_used);
+        return false;
     }
 
-    ALOGW_IF(err, "lockAsync(...) failed %d (%s)", err, strerror(-err));
-    return err;
+    bool hasValidIncrement = plane.h_increment == 1 ||
+            (plane.component != FLEX_COMPONENT_Y && plane.h_increment == 2);
+    hasValidIncrement = hasValidIncrement && plane.v_increment > 0;
+    if (!hasValidIncrement) {
+        ALOGV("Invalid increment: h %d v %d", plane.h_increment,
+                plane.v_increment);
+        return false;
+    }
+
+    return true;
 }
 
 status_t GraphicBufferMapper::lockAsyncYCbCr(buffer_handle_t handle,
         uint32_t usage, const Rect& bounds, android_ycbcr *ycbcr, int fenceFd)
 {
     ATRACE_CALL();
-    status_t err;
 
-    if (mAllocMod->common.module_api_version >= GRALLOC_MODULE_API_VERSION_0_3
-            && mAllocMod->lockAsync_ycbcr != NULL) {
-        err = mAllocMod->lockAsync_ycbcr(mAllocMod, handle,
-                static_cast<int>(usage), bounds.left, bounds.top,
-                bounds.width(), bounds.height(), ycbcr, fenceFd);
-    } else if (mAllocMod->lock_ycbcr != NULL) {
-        if (fenceFd >= 0) {
-            sync_wait(fenceFd, -1);
-            close(fenceFd);
-        }
-        err = mAllocMod->lock_ycbcr(mAllocMod, handle, static_cast<int>(usage),
-                bounds.left, bounds.top, bounds.width(), bounds.height(),
-                ycbcr);
-    } else {
-        if (fenceFd >= 0) {
-            close(fenceFd);
-        }
-        return -EINVAL; // do not log failure
+    gralloc1_rect_t accessRegion = asGralloc1Rect(bounds);
+    sp<Fence> fence = new Fence(fenceFd);
+
+    if (mDevice->hasCapability(GRALLOC1_CAPABILITY_ON_ADAPTER)) {
+        gralloc1_error_t error = mDevice->lockYCbCr(handle,
+                static_cast<gralloc1_producer_usage_t>(usage),
+                static_cast<gralloc1_consumer_usage_t>(usage),
+                &accessRegion, ycbcr, fence);
+        ALOGW_IF(error != GRALLOC1_ERROR_NONE, "lockYCbCr(%p, ...) failed: %d",
+                handle, error);
+        return error;
     }
 
-    ALOGW_IF(err, "lock(...) failed %d (%s)", err, strerror(-err));
-    return err;
+    uint32_t numPlanes = 0;
+    gralloc1_error_t error = mDevice->getNumFlexPlanes(handle, &numPlanes);
+    if (error != GRALLOC1_ERROR_NONE) {
+        ALOGV("Failed to retrieve number of flex planes: %d", error);
+        return error;
+    }
+    if (numPlanes < 3) {
+        ALOGV("Not enough planes for YCbCr (%u found)", numPlanes);
+        return GRALLOC1_ERROR_UNSUPPORTED;
+    }
+
+    std::vector<android_flex_plane_t> planes(numPlanes);
+    android_flex_layout_t flexLayout{};
+    flexLayout.num_planes = numPlanes;
+    flexLayout.planes = planes.data();
+
+    error = mDevice->lockFlex(handle,
+            static_cast<gralloc1_producer_usage_t>(usage),
+            static_cast<gralloc1_consumer_usage_t>(usage),
+            &accessRegion, &flexLayout, fence);
+    if (error != GRALLOC1_ERROR_NONE) {
+        ALOGW("lockFlex(%p, ...) failed: %d", handle, error);
+        return error;
+    }
+    if (flexLayout.format != FLEX_FORMAT_YCbCr) {
+        ALOGV("Unable to convert flex-format buffer to YCbCr");
+        unlock(handle);
+        return GRALLOC1_ERROR_UNSUPPORTED;
+    }
+
+    // Find planes
+    auto yPlane = planes.cend();
+    auto cbPlane = planes.cend();
+    auto crPlane = planes.cend();
+    for (auto planeIter = planes.cbegin(); planeIter != planes.cend();
+            ++planeIter) {
+        if (planeIter->component == FLEX_COMPONENT_Y) {
+            yPlane = planeIter;
+        } else if (planeIter->component == FLEX_COMPONENT_Cb) {
+            cbPlane = planeIter;
+        } else if (planeIter->component == FLEX_COMPONENT_Cr) {
+            crPlane = planeIter;
+        }
+    }
+    if (yPlane == planes.cend()) {
+        ALOGV("Unable to find Y plane");
+        unlock(handle);
+        return GRALLOC1_ERROR_UNSUPPORTED;
+    }
+    if (cbPlane == planes.cend()) {
+        ALOGV("Unable to find Cb plane");
+        unlock(handle);
+        return GRALLOC1_ERROR_UNSUPPORTED;
+    }
+    if (crPlane == planes.cend()) {
+        ALOGV("Unable to find Cr plane");
+        unlock(handle);
+        return GRALLOC1_ERROR_UNSUPPORTED;
+    }
+
+    // Validate planes
+    if (!isValidYCbCrPlane(*yPlane)) {
+        ALOGV("Y plane is invalid");
+        unlock(handle);
+        return GRALLOC1_ERROR_UNSUPPORTED;
+    }
+    if (!isValidYCbCrPlane(*cbPlane)) {
+        ALOGV("Cb plane is invalid");
+        unlock(handle);
+        return GRALLOC1_ERROR_UNSUPPORTED;
+    }
+    if (!isValidYCbCrPlane(*crPlane)) {
+        ALOGV("Cr plane is invalid");
+        unlock(handle);
+        return GRALLOC1_ERROR_UNSUPPORTED;
+    }
+    if (cbPlane->v_increment != crPlane->v_increment) {
+        ALOGV("Cb and Cr planes have different step (%d vs. %d)",
+                cbPlane->v_increment, crPlane->v_increment);
+        unlock(handle);
+        return GRALLOC1_ERROR_UNSUPPORTED;
+    }
+    if (cbPlane->h_increment != crPlane->h_increment) {
+        ALOGV("Cb and Cr planes have different stride (%d vs. %d)",
+                cbPlane->h_increment, crPlane->h_increment);
+        unlock(handle);
+        return GRALLOC1_ERROR_UNSUPPORTED;
+    }
+
+    // Pack plane data into android_ycbcr struct
+    ycbcr->y = yPlane->top_left;
+    ycbcr->cb = cbPlane->top_left;
+    ycbcr->cr = crPlane->top_left;
+    ycbcr->ystride = static_cast<size_t>(yPlane->v_increment);
+    ycbcr->cstride = static_cast<size_t>(cbPlane->v_increment);
+    ycbcr->chroma_step = static_cast<size_t>(cbPlane->h_increment);
+
+    return error;
 }
 
 status_t GraphicBufferMapper::unlockAsync(buffer_handle_t handle, int *fenceFd)
 {
     ATRACE_CALL();
-    status_t err;
 
-    if (mAllocMod->common.module_api_version >= GRALLOC_MODULE_API_VERSION_0_3) {
-        err = mAllocMod->unlockAsync(mAllocMod, handle, fenceFd);
-    } else {
-        *fenceFd = -1;
-        err = mAllocMod->unlock(mAllocMod, handle);
+    sp<Fence> fence = Fence::NO_FENCE;
+    gralloc1_error_t error = mDevice->unlock(handle, &fence);
+    if (error != GRALLOC1_ERROR_NONE) {
+        ALOGE("unlock(%p) failed: %d", handle, error);
+        return error;
     }
 
-    ALOGW_IF(err, "unlockAsync(...) failed %d (%s)", err, strerror(-err));
-    return err;
+    *fenceFd = fence->dup();
+    return error;
 }
 
 // ---------------------------------------------------------------------------
