Merge "graphics: revise gralloc interfaces" into oc-dev
diff --git a/automotive/evs/1.0/vts/functional/FrameHandler.cpp b/automotive/evs/1.0/vts/functional/FrameHandler.cpp
index 01d9a0e..58c2f26 100644
--- a/automotive/evs/1.0/vts/functional/FrameHandler.cpp
+++ b/automotive/evs/1.0/vts/functional/FrameHandler.cpp
@@ -23,7 +23,6 @@
 
 #include <android/log.h>
 #include <cutils/native_handle.h>
-#include <ui/GraphicBufferMapper.h>
 #include <ui/GraphicBuffer.h>
 
 #include <algorithm>    // std::min
@@ -135,11 +134,7 @@
     // Local flag we use to keep track of when the stream is stopping
     bool timeToStop = false;
 
-    // TODO:  Why do we get a gralloc crash if we don't clone the buffer here?
-    BufferDesc buffer(bufferArg);
-    ALOGD("Clone the received frame as %p", buffer.memHandle.getNativeHandle());
-
-    if (buffer.memHandle.getNativeHandle() == nullptr) {
+    if (bufferArg.memHandle.getNativeHandle() == nullptr) {
         // Signal that the last frame has been received and the stream is stopped
         timeToStop = true;
     } else {
@@ -157,13 +152,8 @@
                 printf("Didn't get target buffer - frame lost\n");
                 ALOGE("Didn't get requested output buffer -- skipping this frame.");
             } else {
-                // In order for the handles passed through HIDL and stored in the BufferDesc to
-                // be lockable, we must register them with GraphicBufferMapper
-                registerBufferHelper(tgtBuffer);
-                registerBufferHelper(buffer);
-
                 // Copy the contents of the of buffer.memHandle into tgtBuffer
-                copyBufferContents(tgtBuffer, buffer);
+                copyBufferContents(tgtBuffer, bufferArg);
 
                 // Send the target buffer back for display
                 Return <EvsResult> result = mDisplay->returnTargetBufferForDisplay(tgtBuffer);
@@ -183,10 +173,6 @@
                     mFramesDisplayed++;
                     mLock.unlock();
                 }
-
-                // Now tell GraphicBufferMapper we won't be using these handles anymore
-                unregisterBufferHelper(tgtBuffer);
-                unregisterBufferHelper(buffer);
             }
         }
 
@@ -233,24 +219,22 @@
     const unsigned height    = std::min(tgtBuffer.height,
                                         srcBuffer.height);
 
-    android::GraphicBufferMapper &mapper = android::GraphicBufferMapper::get();
-
+    sp<android::GraphicBuffer> tgt = new android::GraphicBuffer(
+        tgtBuffer.memHandle, android::GraphicBuffer::CLONE_HANDLE,
+        tgtBuffer.width, tgtBuffer.height, tgtBuffer.format, 1, tgtBuffer.usage,
+        tgtBuffer.stride);
+    sp<android::GraphicBuffer> src = new android::GraphicBuffer(
+        srcBuffer.memHandle, android::GraphicBuffer::CLONE_HANDLE,
+        srcBuffer.width, srcBuffer.height, srcBuffer.format, 1, srcBuffer.usage,
+        srcBuffer.stride);
 
     // Lock our source buffer for reading
     unsigned char* srcPixels = nullptr;
-    mapper.registerBuffer(srcBuffer.memHandle);
-    mapper.lock(srcBuffer.memHandle,
-                GRALLOC_USAGE_SW_READ_OFTEN,
-                android::Rect(width, height),
-                (void **) &srcPixels);
+    src->lock(GRALLOC_USAGE_SW_READ_OFTEN, (void**)&srcPixels);
 
     // Lock our target buffer for writing
     unsigned char* tgtPixels = nullptr;
-    mapper.registerBuffer(tgtBuffer.memHandle);
-    mapper.lock(tgtBuffer.memHandle,
-                GRALLOC_USAGE_SW_WRITE_OFTEN,
-                android::Rect(width, height),
-                (void **) &tgtPixels);
+    tgt->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)&tgtPixels);
 
     if (srcPixels && tgtPixels) {
         for (unsigned row = 0; row < height; row++) {
@@ -267,45 +251,11 @@
     }
 
     if (srcPixels) {
-        mapper.unlock(srcBuffer.memHandle);
+        src->unlock();
     }
     if (tgtPixels) {
-        mapper.unlock(tgtBuffer.memHandle);
+        tgt->unlock();
     }
-    mapper.unregisterBuffer(srcBuffer.memHandle);
-    mapper.unregisterBuffer(tgtBuffer.memHandle);
 
     return success;
 }
-
-
-void FrameHandler::registerBufferHelper(const BufferDesc& buffer)
-{
-    // In order for the handles passed through HIDL and stored in the BufferDesc to
-    // be lockable, we must register them with GraphicBufferMapper.
-    // If the device upon which we're running supports gralloc1, we could just call
-    // registerBuffer directly with the handle.  But that call  is broken for gralloc0 devices
-    // (which we care about, at least for now).  As a result, we have to synthesize a GraphicBuffer
-    // object around the buffer handle in order to make a call to the overloaded alternate
-    // version of the registerBuffer call that does happen to work on gralloc0 devices.
-#if REGISTER_BUFFER_ALWAYS_WORKS
-    android::GraphicBufferMapper::get().registerBuffer(buffer.memHandle);
-#else
-    android::sp<android::GraphicBuffer> pGfxBuff = new android::GraphicBuffer(
-            buffer.width, buffer.height, buffer.format,
-            1, /* we always use exactly one layer */
-            buffer.usage, buffer.stride,
-            const_cast<native_handle_t*>(buffer.memHandle.getNativeHandle()),
-            false /* GraphicBuffer should not try to free the handle */
-    );
-
-    android::GraphicBufferMapper::get().registerBuffer(pGfxBuff.get());
-#endif
-}
-
-
-void FrameHandler::unregisterBufferHelper(const BufferDesc& buffer)
-{
-    // Now tell GraphicBufferMapper we won't be using these handles anymore
-    android::GraphicBufferMapper::get().unregisterBuffer(buffer.memHandle);
-}
diff --git a/automotive/evs/1.0/vts/functional/FrameHandler.h b/automotive/evs/1.0/vts/functional/FrameHandler.h
index d5c3f6b..17a3980 100644
--- a/automotive/evs/1.0/vts/functional/FrameHandler.h
+++ b/automotive/evs/1.0/vts/functional/FrameHandler.h
@@ -68,8 +68,6 @@
 
     // Local implementation details
     bool copyBufferContents(const BufferDesc& tgtBuffer, const BufferDesc& srcBuffer);
-    void registerBufferHelper(const BufferDesc& buffer);
-    void unregisterBufferHelper(const BufferDesc& buffer);
 
     // Values initialized as startup
     android::sp <IEvsCamera>    mCamera;
diff --git a/camera/device/1.0/Android.bp b/camera/device/1.0/Android.bp
index 44a108c..81e41aa 100644
--- a/camera/device/1.0/Android.bp
+++ b/camera/device/1.0/Android.bp
@@ -66,7 +66,6 @@
         "libutils",
         "libcutils",
         "android.hardware.camera.common@1.0",
-        "android.hardware.graphics.allocator@2.0",
         "android.hardware.graphics.common@1.0",
         "android.hidl.base@1.0",
     ],
@@ -76,7 +75,6 @@
         "libhwbinder",
         "libutils",
         "android.hardware.camera.common@1.0",
-        "android.hardware.graphics.allocator@2.0",
         "android.hardware.graphics.common@1.0",
         "android.hidl.base@1.0",
     ],
diff --git a/camera/device/1.0/ICameraDevicePreviewCallback.hal b/camera/device/1.0/ICameraDevicePreviewCallback.hal
index 4c9b517..5421981 100644
--- a/camera/device/1.0/ICameraDevicePreviewCallback.hal
+++ b/camera/device/1.0/ICameraDevicePreviewCallback.hal
@@ -17,7 +17,6 @@
 package android.hardware.camera.device@1.0;
 
 import android.hardware.camera.common@1.0::types;
-import android.hardware.graphics.allocator@2.0::types;
 import android.hardware.graphics.common@1.0::types;
 
 /**
@@ -89,7 +88,7 @@
      *
      * @return Status The status code for this operation.
      */
-    setUsage(ProducerUsage usage) generates (Status status);
+    setUsage(BufferUsage usage) generates (Status status);
 
     /**
      * Set the expected buffering mode for the preview output.
diff --git a/camera/device/1.0/default/CameraDevice.cpp b/camera/device/1.0/default/CameraDevice.cpp
index 6495f30..cb20fec 100644
--- a/camera/device/1.0/default/CameraDevice.cpp
+++ b/camera/device/1.0/default/CameraDevice.cpp
@@ -30,7 +30,7 @@
 namespace V1_0 {
 namespace implementation {
 
-using ::android::hardware::graphics::allocator::V2_0::ProducerUsage;
+using ::android::hardware::graphics::common::V1_0::BufferUsage;
 using ::android::hardware::graphics::common::V1_0::PixelFormat;
 
 HandleImporter& CameraDevice::sHandleImporter = HandleImporter::getInstance();
@@ -259,7 +259,7 @@
     }
 
     object->cleanUpCirculatingBuffers();
-    return getStatusT(object->mPreviewCallback->setUsage((ProducerUsage) usage));
+    return getStatusT(object->mPreviewCallback->setUsage((BufferUsage)usage));
 }
 
 int CameraDevice::sSetSwapInterval(struct preview_stream_ops *w, int interval) {
diff --git a/camera/device/3.2/Android.bp b/camera/device/3.2/Android.bp
index fd7276f..7807a85 100644
--- a/camera/device/3.2/Android.bp
+++ b/camera/device/3.2/Android.bp
@@ -66,7 +66,6 @@
         "libutils",
         "libcutils",
         "android.hardware.camera.common@1.0",
-        "android.hardware.graphics.allocator@2.0",
         "android.hardware.graphics.common@1.0",
         "android.hidl.base@1.0",
     ],
@@ -76,7 +75,6 @@
         "libhwbinder",
         "libutils",
         "android.hardware.camera.common@1.0",
-        "android.hardware.graphics.allocator@2.0",
         "android.hardware.graphics.common@1.0",
         "android.hidl.base@1.0",
     ],
diff --git a/camera/device/3.2/default/CameraDeviceSession.cpp b/camera/device/3.2/default/CameraDeviceSession.cpp
index 5b3024b..5bb53c7 100644
--- a/camera/device/3.2/default/CameraDeviceSession.cpp
+++ b/camera/device/3.2/default/CameraDeviceSession.cpp
@@ -650,7 +650,8 @@
         mVideoStreamIds.clear();
         for (const auto& stream : requestedConfiguration.streams) {
             if (stream.streamType == StreamType::OUTPUT &&
-                    stream.usage & graphics::allocator::V2_0::ConsumerUsage::VIDEO_ENCODER) {
+                stream.usage &
+                    graphics::common::V1_0::BufferUsage::VIDEO_ENCODER) {
                 mVideoStreamIds.push_back(stream.id);
             }
         }
diff --git a/camera/device/3.2/default/convert.cpp b/camera/device/3.2/default/convert.cpp
index c7cc75a..d878deb 100644
--- a/camera/device/3.2/default/convert.cpp
+++ b/camera/device/3.2/default/convert.cpp
@@ -28,8 +28,7 @@
 
 using ::android::hardware::graphics::common::V1_0::Dataspace;
 using ::android::hardware::graphics::common::V1_0::PixelFormat;
-using ::android::hardware::camera::device::V3_2::ConsumerUsageFlags;
-using ::android::hardware::camera::device::V3_2::ProducerUsageFlags;
+using ::android::hardware::camera::device::V3_2::BufferUsageFlags;
 
 bool convertFromHidl(const CameraMetadata &src, const camera_metadata_t** dst) {
     if (src.size() == 0) {
@@ -78,11 +77,11 @@
     dst->overrideFormat = (PixelFormat) src->format;
     dst->maxBuffers = src->max_buffers;
     if (src->stream_type == CAMERA3_STREAM_OUTPUT) {
-        dst->consumerUsage = (ConsumerUsageFlags) 0;
-        dst->producerUsage = (ProducerUsageFlags) src->usage;
+        dst->consumerUsage = (BufferUsageFlags)0;
+        dst->producerUsage = (BufferUsageFlags)src->usage;
     } else if (src->stream_type == CAMERA3_STREAM_INPUT) {
-        dst->producerUsage = (ProducerUsageFlags) 0;
-        dst->consumerUsage = (ConsumerUsageFlags) src->usage;
+        dst->producerUsage = (BufferUsageFlags)0;
+        dst->consumerUsage = (BufferUsageFlags)src->usage;
     } else {
         //Should not reach here per current HIDL spec, but we might end up adding
         // bi-directional stream to HIDL.
diff --git a/camera/device/3.2/types.hal b/camera/device/3.2/types.hal
index 5ae7a18..1632570 100644
--- a/camera/device/3.2/types.hal
+++ b/camera/device/3.2/types.hal
@@ -16,12 +16,10 @@
 
 package android.hardware.camera.device@3.2;
 
-import android.hardware.graphics.allocator@2.0::types;
 import android.hardware.graphics.common@1.0::types;
 
 typedef vec<uint8_t> CameraMetadata;
-typedef bitfield<ProducerUsage> ProducerUsageFlags;
-typedef bitfield<ConsumerUsage> ConsumerUsageFlags;
+typedef bitfield<BufferUsage> BufferUsageFlags;
 typedef bitfield<Dataspace> DataspaceFlags;
 
 /**
@@ -255,7 +253,7 @@
      * with ILLEGAL_ARGUMENT if the combined flags cannot be supported due to
      * imcompatible buffer format, dataSpace, or other hardware limitations.
      */
-    ConsumerUsageFlags usage;
+    BufferUsageFlags usage;
 
     /**
      * A field that describes the contents of the buffer. The format and buffer
@@ -373,8 +371,8 @@
      * consumerUsage must be set. For other types, producerUsage must be set,
      * and consumerUsage must be 0.
      */
-    ProducerUsageFlags producerUsage;
-    ConsumerUsageFlags consumerUsage;
+    BufferUsageFlags producerUsage;
+    BufferUsageFlags consumerUsage;
 
     /**
      * The maximum number of buffers the HAL device may need to have dequeued at
diff --git a/camera/provider/2.4/Android.bp b/camera/provider/2.4/Android.bp
index 1656325..d295f3e 100644
--- a/camera/provider/2.4/Android.bp
+++ b/camera/provider/2.4/Android.bp
@@ -57,7 +57,6 @@
         "android.hardware.camera.common@1.0",
         "android.hardware.camera.device@1.0",
         "android.hardware.camera.device@3.2",
-        "android.hardware.graphics.allocator@2.0",
         "android.hardware.graphics.common@1.0",
         "android.hidl.base@1.0",
     ],
@@ -69,7 +68,6 @@
         "android.hardware.camera.common@1.0",
         "android.hardware.camera.device@1.0",
         "android.hardware.camera.device@3.2",
-        "android.hardware.graphics.allocator@2.0",
         "android.hardware.graphics.common@1.0",
         "android.hidl.base@1.0",
     ],
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index 74e6efe..e37f989 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -52,8 +52,8 @@
 using ::android::BufferItemConsumer;
 using ::android::Surface;
 using ::android::CameraParameters;
+using ::android::hardware::graphics::common::V1_0::BufferUsage;
 using ::android::hardware::graphics::common::V1_0::PixelFormat;
-using ::android::hardware::graphics::allocator::V2_0::ProducerUsage;
 using ::android::hardware::camera::common::V1_0::Status;
 using ::android::hardware::camera::common::V1_0::CameraDeviceStatus;
 using ::android::hardware::camera::common::V1_0::TorchMode;
@@ -233,7 +233,7 @@
     Return<Status> setCrop(int32_t left, int32_t top,
             int32_t right, int32_t bottom) override;
 
-    Return<Status> setUsage(ProducerUsage usage) override;
+    Return<Status> setUsage(BufferUsage usage) override;
 
     Return<Status> setSwapInterval(int32_t interval) override;
 
@@ -408,7 +408,7 @@
     return mapToStatus(rc);
 }
 
-Return<Status> PreviewWindowCb::setUsage(ProducerUsage usage) {
+Return<Status> PreviewWindowCb::setUsage(BufferUsage usage) {
     auto rc = native_window_set_usage(mAnw.get(), static_cast<int>(usage));
     if (rc == ::android::OK) {
         mPreviewUsage =  static_cast<int>(usage);
diff --git a/graphics/Android.bp b/graphics/Android.bp
index f4f7db4..9aea85f 100644
--- a/graphics/Android.bp
+++ b/graphics/Android.bp
@@ -2,7 +2,6 @@
 subdirs = [
     "allocator/2.0",
     "allocator/2.0/default",
-    "allocator/2.0/vts/functional",
     "bufferqueue/1.0",
     "common/1.0",
     "composer/2.1",
diff --git a/graphics/allocator/2.0/Android.bp b/graphics/allocator/2.0/Android.bp
index 271f2ce..f707468 100644
--- a/graphics/allocator/2.0/Android.bp
+++ b/graphics/allocator/2.0/Android.bp
@@ -3,9 +3,7 @@
 filegroup {
     name: "android.hardware.graphics.allocator@2.0_hal",
     srcs: [
-        "types.hal",
         "IAllocator.hal",
-        "IAllocatorClient.hal",
     ],
 }
 
@@ -17,9 +15,7 @@
         ":android.hardware.graphics.allocator@2.0_hal",
     ],
     out: [
-        "android/hardware/graphics/allocator/2.0/types.cpp",
         "android/hardware/graphics/allocator/2.0/AllocatorAll.cpp",
-        "android/hardware/graphics/allocator/2.0/AllocatorClientAll.cpp",
     ],
 }
 
@@ -31,18 +27,11 @@
         ":android.hardware.graphics.allocator@2.0_hal",
     ],
     out: [
-        "android/hardware/graphics/allocator/2.0/types.h",
-        "android/hardware/graphics/allocator/2.0/hwtypes.h",
         "android/hardware/graphics/allocator/2.0/IAllocator.h",
         "android/hardware/graphics/allocator/2.0/IHwAllocator.h",
         "android/hardware/graphics/allocator/2.0/BnHwAllocator.h",
         "android/hardware/graphics/allocator/2.0/BpHwAllocator.h",
         "android/hardware/graphics/allocator/2.0/BsAllocator.h",
-        "android/hardware/graphics/allocator/2.0/IAllocatorClient.h",
-        "android/hardware/graphics/allocator/2.0/IHwAllocatorClient.h",
-        "android/hardware/graphics/allocator/2.0/BnHwAllocatorClient.h",
-        "android/hardware/graphics/allocator/2.0/BpHwAllocatorClient.h",
-        "android/hardware/graphics/allocator/2.0/BsAllocatorClient.h",
     ],
 }
 
@@ -59,6 +48,7 @@
         "libutils",
         "libcutils",
         "android.hardware.graphics.common@1.0",
+        "android.hardware.graphics.mapper@2.0",
         "android.hidl.base@1.0",
     ],
     export_shared_lib_headers: [
@@ -67,6 +57,7 @@
         "libhwbinder",
         "libutils",
         "android.hardware.graphics.common@1.0",
+        "android.hardware.graphics.mapper@2.0",
         "android.hidl.base@1.0",
     ],
 }
diff --git a/graphics/allocator/2.0/IAllocator.hal b/graphics/allocator/2.0/IAllocator.hal
index bf0e141..43a3916 100644
--- a/graphics/allocator/2.0/IAllocator.hal
+++ b/graphics/allocator/2.0/IAllocator.hal
@@ -16,38 +16,9 @@
 
 package android.hardware.graphics.allocator@2.0;
 
-import IAllocatorClient;
+import android.hardware.graphics.mapper@2.0;
 
 interface IAllocator {
-    enum Capability : int32_t {
-        /** reserved */
-        INVALID = 0,
-
-        /**
-         * IAllocatorClient::testAllocate must always return UNDEFINED unless
-         * this capability is supported.
-         */
-        TEST_ALLOCATE = 1,
-
-        /**
-         * IAllocatorClient::BufferDescriptorInfo::layerCount must be 1 unless
-         * this capability is supported.
-         */
-        LAYERED_BUFFERS = 2,
-    };
-
-    /**
-     * Provides a list of supported capabilities (as described in the
-     * definition of Capability above). This list must not change after
-     * initialization.
-     *
-     * @return capabilities is a list of supported capabilities.
-     */
-    @entry
-    @exit
-    @callflow(next="*")
-    getCapabilities() generates (vec<Capability> capabilities);
-
     /**
      * Retrieves implementation-defined debug information, which will be
      * displayed during, for example, `dumpsys SurfaceFlinger`.
@@ -60,15 +31,27 @@
     dumpDebugInfo() generates (string debugInfo);
 
     /**
-     * Creates a client of the allocator. All resources created by the client
-     * are owned by the client and are only visible to the client, unless they
-     * are exported by exportHandle.
+     * Allocates buffers with the properties specified by the descriptor.
      *
+     * @param descriptor specifies the properties of the buffers to allocate.
+     * @param count is the number of buffers to allocate.
      * @return error is NONE upon success. Otherwise,
-     *         NO_RESOURCES when no more client can currently be created.
-     * @return client is the newly created client.
+     *         BAD_DESCRIPTOR when the descriptor is invalid.
+     *         NO_RESOURCES when the allocation cannot be fulfilled at this
+     *                      time.
+     *         UNSUPPORTED when any of the property encoded in the descriptor
+     *                     is not supported.
+     * @return stride is the number of pixels between two consecutive rows of
+     *         the buffers, when the concept of consecutive rows is defined.
+     *         Otherwise, it has no meaning.
+     * @return buffers is an array of raw handles to the newly allocated
+     *         buffers.
      */
     @entry
+    @exit
     @callflow(next="*")
-    createClient() generates (Error error, IAllocatorClient client);
+    allocate(BufferDescriptor descriptor, uint32_t count)
+        generates (Error error,
+                   uint32_t stride,
+                   vec<handle> buffers);
 };
diff --git a/graphics/allocator/2.0/IAllocatorClient.hal b/graphics/allocator/2.0/IAllocatorClient.hal
deleted file mode 100644
index 8ca568f..0000000
--- a/graphics/allocator/2.0/IAllocatorClient.hal
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.graphics.allocator@2.0;
-
-import android.hardware.graphics.common@1.0::PixelFormat;
-
-interface IAllocatorClient {
-    struct BufferDescriptorInfo {
-        /**
-         * The width specifies how many columns of pixels must be in the
-         * allocated buffer, but does not necessarily represent the offset in
-         * columns between the same column in adjacent rows. The rows may be
-         * padded.
-         */
-        uint32_t width;
-
-       /**
-        * The height specifies how many rows of pixels must be in the
-        * allocated buffer.
-        */
-        uint32_t height;
-
-       /**
-        * The number of image layers that must be in the allocated buffer.
-        */
-        uint32_t layerCount;
-
-        /** Buffer pixel format. */
-        PixelFormat format;
-
-        /**
-         * Buffer producer usage mask; valid flags can be found in the
-         * definition of ProducerUsage.
-         */
-        uint64_t producerUsageMask;
-
-        /**
-         * Buffer consumer usage mask; valid flags can be found in the
-         * definition of ConsumerUsage.
-         */
-        uint64_t consumerUsageMask;
-    };
-
-    /**
-     * Creates a new, opaque buffer descriptor.
-     *
-     * @param descriptorInfo specifies the attributes of the buffer
-     *        descriptor.
-     * @return error is NONE upon success. Otherwise,
-     *         BAD_VALUE when any attribute in descriptorInfo is invalid.
-     *         NO_RESOURCES when no more descriptors can currently be created.
-     * @return descriptor is the newly created buffer descriptor.
-     */
-    @entry
-    @callflow(next="*")
-    createDescriptor(BufferDescriptorInfo descriptorInfo)
-          generates (Error error,
-                     BufferDescriptor descriptor);
-
-    /**
-     * Destroys an existing buffer descriptor.
-     *
-     * @param descriptor is the descriptor to destroy.
-     * @return error is either NONE or BAD_DESCRIPTOR.
-     */
-    @exit
-    @callflow(next="*")
-    destroyDescriptor(BufferDescriptor descriptor) generates (Error error);
-
-    /**
-     * Tests whether a buffer allocation can succeed, ignoring potential
-     * resource contention which might lead to a NO_RESOURCES error.
-     *
-     * @param descriptors is a list of buffer descriptors.
-     * @return error is NONE or NOT_SHARED upon success;
-     *         NONE when buffers can be created and share a backing store.
-     *         NOT_SHARED when buffers can be created but require more than a
-     *                    backing store.
-     *         Otherwise,
-     *         BAD_DESCRIPTOR when any of the descriptors is invalid.
-     *         UNSUPPORTED when any of the descriptors can never be satisfied.
-     *         UNDEFINED when TEST_ALLOCATE is not listed in getCapabilities.
-     */
-    @callflow(next="allocate")
-    testAllocate(vec<BufferDescriptor> descriptors) generates (Error error);
-
-    /**
-     * Attempts to allocate a list of buffers sharing a backing store.
-     *
-     * Each buffer must correspond to one of the descriptors passed into the
-     * function and must hold a reference to its backing store. If the device
-     * is unable to share the backing store between the buffers, it must
-     * attempt to allocate the buffers with different backing stores and
-     * return NOT_SHARED if it is successful.
-     *
-     * @param descriptors is the buffer descriptors to attempt to allocate.
-     * @return error is NONE or NOT_SHARED upon success;
-     *         NONE when buffers can be created and share a backing store.
-     *         NOT_SHARED when buffers can be created but require more than a
-     *                    backing store.
-     *         Otherwise,
-     *         BAD_DESCRIPTOR when any of the descriptors is invalid.
-     *         UNSUPPORTED when any of the descriptors can never be satisfied.
-     *         NO_RESOURCES when any of the buffers cannot be created at this
-     *                      time.
-     * @return buffers is the allocated buffers.
-     */
-    @callflow(next="exportHandle")
-    allocate(vec<BufferDescriptor> descriptors)
-        generates (Error error,
-                   vec<Buffer> buffers);
-
-    /**
-     * Frees a buffer.
-     *
-     * @param buffer is the buffer to be freed.
-     * @return error is NONE upon success. Otherwise,
-     *         BAD_BUFFER when the buffer is invalid.
-     */
-    @exit
-    @callflow(next="*")
-    free(Buffer buffer) generates (Error error);
-
-    /**
-     * Exports a buffer for use in other client libraries or for cross-process
-     * sharing.
-     *
-     * The exported handle is a handle to the backing store of the buffer, not
-     * to the buffer itself. It however may not hold any reference to the
-     * backing store and may be considered invalid by client libraries. To use
-     * it and, in most cases, to save it for later use, a client must make a
-     * clone of the handle and have the cloned handle hold a reference to the
-     * backing store. Such a cloned handle will stay valid even after the
-     * original buffer is freed. Refer to native_handle_clone and IMapper for
-     * how a handle is cloned and how a reference is added.
-     *
-     * @param descriptor is the descriptor used to allocate the buffer.
-     * @param buffer is the buffer to be exported.
-     * @return error is NONE upon success. Otherwise,
-     *         BAD_DESCRIPTOR when the descriptor is invalid.
-     *         BAD_BUFFER when the buffer is invalid.
-     *         BAD_VALUE when descriptor and buffer do not match.
-     *         NO_RESOURCES when the buffer cannot be exported at this time.
-     * @return bufferHandle is the exported handle.
-     */
-    @callflow(next="free")
-    exportHandle(BufferDescriptor descriptor,
-                 Buffer buffer)
-      generates (Error error,
-                 handle bufferHandle);
-};
diff --git a/graphics/allocator/2.0/default/Android.bp b/graphics/allocator/2.0/default/Android.bp
index 0baef89..6adfa71 100644
--- a/graphics/allocator/2.0/default/Android.bp
+++ b/graphics/allocator/2.0/default/Android.bp
@@ -3,7 +3,7 @@
     defaults: ["hidl_defaults"],
     proprietary: true,
     relative_install_path: "hw",
-    srcs: ["Gralloc.cpp"],
+    srcs: ["Gralloc.cpp", "Gralloc0Allocator.cpp", "Gralloc1Allocator.cpp"],
     cppflags: ["-Wall", "-Wextra"],
     shared_libs: [
         "android.hardware.graphics.allocator@2.0",
@@ -15,6 +15,7 @@
         "liblog",
         "libutils",
     ],
+    static_libs: ["libgrallocmapperincludes"],
 }
 
 cc_binary {
diff --git a/graphics/allocator/2.0/default/Gralloc.cpp b/graphics/allocator/2.0/default/Gralloc.cpp
index 0b9e863..273d3f5 100644
--- a/graphics/allocator/2.0/default/Gralloc.cpp
+++ b/graphics/allocator/2.0/default/Gralloc.cpp
@@ -16,17 +16,11 @@
 
 #define LOG_TAG "GrallocPassthrough"
 
-#include <mutex>
-#include <type_traits>
-#include <unordered_set>
-#include <vector>
-
-#include <string.h>
-
-#include <hardware/gralloc1.h>
-#include <log/log.h>
-
 #include "Gralloc.h"
+#include "Gralloc0Allocator.h"
+#include "Gralloc1Allocator.h"
+
+#include <log/log.h>
 
 namespace android {
 namespace hardware {
@@ -35,417 +29,6 @@
 namespace V2_0 {
 namespace implementation {
 
-class GrallocHal : public IAllocator {
-public:
-    GrallocHal(const hw_module_t* module);
-    virtual ~GrallocHal();
-
-    // IAllocator interface
-    Return<void> getCapabilities(getCapabilities_cb hidl_cb) override;
-    Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override;
-    Return<void> createClient(createClient_cb hidl_cb) override;
-
-    Error createDescriptor(
-            const IAllocatorClient::BufferDescriptorInfo& descriptorInfo,
-            BufferDescriptor* outDescriptor);
-    Error destroyDescriptor(BufferDescriptor descriptor);
-
-    Error testAllocate(const hidl_vec<BufferDescriptor>& descriptors);
-    Error allocate(const hidl_vec<BufferDescriptor>& descriptors,
-            hidl_vec<Buffer>* outBuffers);
-    Error free(Buffer buffer);
-
-    Error exportHandle(Buffer buffer, const native_handle_t** outHandle);
-
-private:
-    void initCapabilities();
-
-    template<typename T>
-    void initDispatch(gralloc1_function_descriptor_t desc, T* outPfn);
-    void initDispatch();
-
-    bool hasCapability(Capability capability) const;
-
-    gralloc1_device_t* mDevice;
-
-    std::unordered_set<Capability> mCapabilities;
-
-    struct {
-        GRALLOC1_PFN_DUMP dump;
-        GRALLOC1_PFN_CREATE_DESCRIPTOR createDescriptor;
-        GRALLOC1_PFN_DESTROY_DESCRIPTOR destroyDescriptor;
-        GRALLOC1_PFN_SET_DIMENSIONS setDimensions;
-        GRALLOC1_PFN_SET_FORMAT setFormat;
-        GRALLOC1_PFN_SET_LAYER_COUNT setLayerCount;
-        GRALLOC1_PFN_SET_CONSUMER_USAGE setConsumerUsage;
-        GRALLOC1_PFN_SET_PRODUCER_USAGE setProducerUsage;
-        GRALLOC1_PFN_ALLOCATE allocate;
-        GRALLOC1_PFN_RELEASE release;
-    } mDispatch;
-};
-
-class GrallocClient : public IAllocatorClient {
-public:
-    GrallocClient(GrallocHal& hal);
-    virtual ~GrallocClient();
-
-    // IAllocatorClient interface
-    Return<void> createDescriptor(const BufferDescriptorInfo& descriptorInfo,
-            createDescriptor_cb hidl_cb) override;
-    Return<Error> destroyDescriptor(BufferDescriptor descriptor) override;
-
-    Return<Error> testAllocate(
-            const hidl_vec<BufferDescriptor>& descriptors) override;
-    Return<void> allocate(const hidl_vec<BufferDescriptor>& descriptors,
-            allocate_cb hidl_cb) override;
-    Return<Error> free(Buffer buffer) override;
-
-    Return<void> exportHandle(BufferDescriptor descriptor,
-            Buffer buffer, exportHandle_cb hidl_cb) override;
-
-private:
-    GrallocHal& mHal;
-
-    std::mutex mMutex;
-    std::unordered_set<BufferDescriptor> mDescriptors;
-    std::unordered_set<Buffer> mBuffers;
-};
-
-GrallocHal::GrallocHal(const hw_module_t* module)
-    : mDevice(nullptr), mDispatch()
-{
-    int status = gralloc1_open(module, &mDevice);
-    if (status) {
-        LOG_ALWAYS_FATAL("failed to open gralloc1 device: %s",
-                strerror(-status));
-    }
-
-    initCapabilities();
-    initDispatch();
-}
-
-GrallocHal::~GrallocHal()
-{
-    gralloc1_close(mDevice);
-}
-
-void GrallocHal::initCapabilities()
-{
-    uint32_t count = 0;
-    mDevice->getCapabilities(mDevice, &count, nullptr);
-
-    std::vector<Capability> caps(count);
-    mDevice->getCapabilities(mDevice, &count, reinterpret_cast<
-              std::underlying_type<Capability>::type*>(caps.data()));
-    caps.resize(count);
-
-    mCapabilities.insert(caps.cbegin(), caps.cend());
-}
-
-template<typename T>
-void GrallocHal::initDispatch(gralloc1_function_descriptor_t desc, T* outPfn)
-{
-    auto pfn = mDevice->getFunction(mDevice, desc);
-    if (!pfn) {
-        LOG_ALWAYS_FATAL("failed to get gralloc1 function %d", desc);
-    }
-
-    *outPfn = reinterpret_cast<T>(pfn);
-}
-
-void GrallocHal::initDispatch()
-{
-    initDispatch(GRALLOC1_FUNCTION_DUMP, &mDispatch.dump);
-    initDispatch(GRALLOC1_FUNCTION_CREATE_DESCRIPTOR,
-            &mDispatch.createDescriptor);
-    initDispatch(GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR,
-            &mDispatch.destroyDescriptor);
-    initDispatch(GRALLOC1_FUNCTION_SET_DIMENSIONS, &mDispatch.setDimensions);
-    initDispatch(GRALLOC1_FUNCTION_SET_FORMAT, &mDispatch.setFormat);
-    if (hasCapability(Capability::LAYERED_BUFFERS)) {
-        initDispatch(GRALLOC1_FUNCTION_SET_LAYER_COUNT,
-                &mDispatch.setLayerCount);
-    }
-    initDispatch(GRALLOC1_FUNCTION_SET_CONSUMER_USAGE,
-            &mDispatch.setConsumerUsage);
-    initDispatch(GRALLOC1_FUNCTION_SET_PRODUCER_USAGE,
-            &mDispatch.setProducerUsage);
-    initDispatch(GRALLOC1_FUNCTION_ALLOCATE, &mDispatch.allocate);
-    initDispatch(GRALLOC1_FUNCTION_RELEASE, &mDispatch.release);
-}
-
-bool GrallocHal::hasCapability(Capability capability) const
-{
-    return (mCapabilities.count(capability) > 0);
-}
-
-Return<void> GrallocHal::getCapabilities(getCapabilities_cb hidl_cb)
-{
-    std::vector<Capability> caps(
-            mCapabilities.cbegin(), mCapabilities.cend());
-
-    hidl_vec<Capability> reply;
-    reply.setToExternal(caps.data(), caps.size());
-    hidl_cb(reply);
-
-    return Void();
-}
-
-Return<void> GrallocHal::dumpDebugInfo(dumpDebugInfo_cb hidl_cb)
-{
-    uint32_t len = 0;
-    mDispatch.dump(mDevice, &len, nullptr);
-
-    std::vector<char> buf(len + 1);
-    mDispatch.dump(mDevice, &len, buf.data());
-    buf.resize(len + 1);
-    buf[len] = '\0';
-
-    hidl_string reply;
-    reply.setToExternal(buf.data(), len);
-    hidl_cb(reply);
-
-    return Void();
-}
-
-Return<void> GrallocHal::createClient(createClient_cb hidl_cb)
-{
-    sp<IAllocatorClient> client = new GrallocClient(*this);
-    hidl_cb(Error::NONE, client);
-
-    return Void();
-}
-
-Error GrallocHal::createDescriptor(
-        const IAllocatorClient::BufferDescriptorInfo& descriptorInfo,
-        BufferDescriptor* outDescriptor)
-{
-    gralloc1_buffer_descriptor_t descriptor;
-    int32_t err = mDispatch.createDescriptor(mDevice, &descriptor);
-    if (err != GRALLOC1_ERROR_NONE) {
-        return static_cast<Error>(err);
-    }
-
-    err = mDispatch.setDimensions(mDevice, descriptor,
-            descriptorInfo.width, descriptorInfo.height);
-    if (err == GRALLOC1_ERROR_NONE) {
-        err = mDispatch.setFormat(mDevice, descriptor,
-                static_cast<int32_t>(descriptorInfo.format));
-    }
-    if (err == GRALLOC1_ERROR_NONE) {
-        if (hasCapability(Capability::LAYERED_BUFFERS)) {
-            err = mDispatch.setLayerCount(mDevice, descriptor,
-                    descriptorInfo.layerCount);
-        } else if (descriptorInfo.layerCount != 1) {
-            err = GRALLOC1_ERROR_BAD_VALUE;
-        }
-    }
-    if (err == GRALLOC1_ERROR_NONE) {
-        uint64_t producerUsageMask = descriptorInfo.producerUsageMask;
-        if (producerUsageMask & GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN) {
-            producerUsageMask |= GRALLOC1_PRODUCER_USAGE_CPU_READ;
-        }
-        if (producerUsageMask & GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN) {
-            producerUsageMask |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE;
-        }
-        err = mDispatch.setProducerUsage(mDevice, descriptor,
-                descriptorInfo.producerUsageMask);
-    }
-    if (err == GRALLOC1_ERROR_NONE) {
-        uint64_t consumerUsageMask = descriptorInfo.consumerUsageMask;
-        if (consumerUsageMask & GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN) {
-            consumerUsageMask |= GRALLOC1_CONSUMER_USAGE_CPU_READ;
-        }
-        err = mDispatch.setConsumerUsage(mDevice, descriptor,
-                consumerUsageMask);
-    }
-
-    if (err == GRALLOC1_ERROR_NONE) {
-        *outDescriptor = descriptor;
-    } else {
-        mDispatch.destroyDescriptor(mDevice, descriptor);
-    }
-
-    return static_cast<Error>(err);
-}
-
-Error GrallocHal::destroyDescriptor(BufferDescriptor descriptor)
-{
-    int32_t err = mDispatch.destroyDescriptor(mDevice, descriptor);
-    return static_cast<Error>(err);
-}
-
-Error GrallocHal::testAllocate(const hidl_vec<BufferDescriptor>& descriptors)
-{
-    if (!hasCapability(Capability::TEST_ALLOCATE)) {
-        return Error::UNDEFINED;
-    }
-
-    int32_t err = mDispatch.allocate(mDevice, descriptors.size(),
-            descriptors.data(), nullptr);
-    return static_cast<Error>(err);
-}
-
-Error GrallocHal::allocate(const hidl_vec<BufferDescriptor>& descriptors,
-        hidl_vec<Buffer>* outBuffers)
-{
-    std::vector<buffer_handle_t> buffers(descriptors.size());
-    int32_t err = mDispatch.allocate(mDevice, descriptors.size(),
-            descriptors.data(), buffers.data());
-    if (err == GRALLOC1_ERROR_NONE || err == GRALLOC1_ERROR_NOT_SHARED) {
-        outBuffers->resize(buffers.size());
-        for (size_t i = 0; i < outBuffers->size(); i++) {
-            (*outBuffers)[i] = static_cast<Buffer>(
-                    reinterpret_cast<uintptr_t>(buffers[i]));
-        }
-    }
-
-    return static_cast<Error>(err);
-}
-
-Error GrallocHal::free(Buffer buffer)
-{
-    buffer_handle_t handle = reinterpret_cast<buffer_handle_t>(
-            static_cast<uintptr_t>(buffer));
-
-    int32_t err = mDispatch.release(mDevice, handle);
-    return static_cast<Error>(err);
-}
-
-Error GrallocHal::exportHandle(Buffer buffer,
-        const native_handle_t** outHandle)
-{
-    // we rely on the caller to validate buffer here
-    *outHandle = reinterpret_cast<buffer_handle_t>(
-            static_cast<uintptr_t>(buffer));
-    return Error::NONE;
-}
-
-GrallocClient::GrallocClient(GrallocHal& hal)
-    : mHal(hal)
-{
-}
-
-GrallocClient::~GrallocClient()
-{
-    if (!mBuffers.empty()) {
-        ALOGW("client destroyed with valid buffers");
-        for (auto buf : mBuffers) {
-            mHal.free(buf);
-        }
-    }
-
-    if (!mDescriptors.empty()) {
-        ALOGW("client destroyed with valid buffer descriptors");
-        for (auto desc : mDescriptors) {
-            mHal.destroyDescriptor(desc);
-        }
-    }
-}
-
-Return<void> GrallocClient::createDescriptor(
-        const BufferDescriptorInfo& descriptorInfo,
-        createDescriptor_cb hidl_cb)
-{
-    BufferDescriptor descriptor = 0;
-    Error err = mHal.createDescriptor(descriptorInfo, &descriptor);
-
-    if (err == Error::NONE) {
-        std::lock_guard<std::mutex> lock(mMutex);
-
-        auto result = mDescriptors.insert(descriptor);
-        if (!result.second) {
-            ALOGW("duplicated buffer descriptor id returned");
-            mHal.destroyDescriptor(descriptor);
-            err = Error::NO_RESOURCES;
-        }
-    }
-
-    hidl_cb(err, descriptor);
-    return Void();
-}
-
-Return<Error> GrallocClient::destroyDescriptor(BufferDescriptor descriptor)
-{
-    {
-        std::lock_guard<std::mutex> lock(mMutex);
-        if (!mDescriptors.erase(descriptor)) {
-            return Error::BAD_DESCRIPTOR;
-        }
-    }
-
-    return mHal.destroyDescriptor(descriptor);
-}
-
-Return<Error> GrallocClient::testAllocate(
-        const hidl_vec<BufferDescriptor>& descriptors)
-{
-    return mHal.testAllocate(descriptors);
-}
-
-Return<void> GrallocClient::allocate(
-        const hidl_vec<BufferDescriptor>& descriptors,
-        allocate_cb hidl_cb) {
-    hidl_vec<Buffer> buffers;
-    Error err = mHal.allocate(descriptors, &buffers);
-
-    if (err == Error::NONE || err == Error::NOT_SHARED) {
-        std::lock_guard<std::mutex> lock(mMutex);
-
-        for (size_t i = 0; i < buffers.size(); i++) {
-            auto result = mBuffers.insert(buffers[i]);
-            if (!result.second) {
-                ALOGW("duplicated buffer id returned");
-
-                for (size_t j = 0; j < buffers.size(); j++) {
-                    if (j < i) {
-                        mBuffers.erase(buffers[i]);
-                    }
-                    mHal.free(buffers[i]);
-                }
-
-                buffers = hidl_vec<Buffer>();
-                err = Error::NO_RESOURCES;
-                break;
-            }
-        }
-    }
-
-    hidl_cb(err, buffers);
-    return Void();
-}
-
-Return<Error> GrallocClient::free(Buffer buffer)
-{
-    {
-        std::lock_guard<std::mutex> lock(mMutex);
-        if (!mBuffers.erase(buffer)) {
-            return Error::BAD_BUFFER;
-        }
-    }
-
-    return mHal.free(buffer);
-}
-
-Return<void> GrallocClient::exportHandle(BufferDescriptor /*descriptor*/,
-        Buffer buffer, exportHandle_cb hidl_cb)
-{
-    const native_handle_t* handle = nullptr;
-
-    {
-        std::lock_guard<std::mutex> lock(mMutex);
-        if (mBuffers.count(buffer) == 0) {
-            hidl_cb(Error::BAD_BUFFER, handle);
-            return Void();
-        }
-    }
-
-    Error err = mHal.exportHandle(buffer, &handle);
-
-    hidl_cb(err, handle);
-    return Void();
-}
-
 IAllocator* HIDL_FETCH_IAllocator(const char* /* name */) {
     const hw_module_t* module = nullptr;
     int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
@@ -455,12 +38,15 @@
     }
 
     uint8_t major = (module->module_api_version >> 8) & 0xff;
-    if (major != 1) {
-        ALOGE("unknown gralloc module major version %d", major);
-        return nullptr;
+    switch (major) {
+        case 1:
+            return new Gralloc1Allocator(module);
+        case 0:
+            return new Gralloc0Allocator(module);
+        default:
+            ALOGE("unknown gralloc module major version %d", major);
+            return nullptr;
     }
-
-    return new GrallocHal(module);
 }
 
 } // namespace implementation
diff --git a/graphics/allocator/2.0/default/Gralloc0Allocator.cpp b/graphics/allocator/2.0/default/Gralloc0Allocator.cpp
new file mode 100644
index 0000000..3b62bb3
--- /dev/null
+++ b/graphics/allocator/2.0/default/Gralloc0Allocator.cpp
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Gralloc0Allocator"
+
+#include "Gralloc0Allocator.h"
+#include "GrallocBufferDescriptor.h"
+
+#include <vector>
+
+#include <string.h>
+
+#include <log/log.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace allocator {
+namespace V2_0 {
+namespace implementation {
+
+using android::hardware::graphics::mapper::V2_0::implementation::
+    grallocDecodeBufferDescriptor;
+
+Gralloc0Allocator::Gralloc0Allocator(const hw_module_t* module) {
+    int result = gralloc_open(module, &mDevice);
+    if (result) {
+        LOG_ALWAYS_FATAL("failed to open gralloc0 device: %s",
+                         strerror(-result));
+    }
+}
+
+Gralloc0Allocator::~Gralloc0Allocator() {
+    gralloc_close(mDevice);
+}
+
+Return<void> Gralloc0Allocator::dumpDebugInfo(dumpDebugInfo_cb hidl_cb) {
+    char buf[4096] = {};
+    if (mDevice->dump) {
+        mDevice->dump(mDevice, buf, sizeof(buf));
+        buf[sizeof(buf) - 1] = '\0';
+    }
+
+    hidl_cb(hidl_string(buf));
+
+    return Void();
+}
+
+Return<void> Gralloc0Allocator::allocate(const BufferDescriptor& descriptor,
+                                         uint32_t count, allocate_cb hidl_cb) {
+    IMapper::BufferDescriptorInfo descriptorInfo;
+    if (!grallocDecodeBufferDescriptor(descriptor, &descriptorInfo)) {
+        hidl_cb(Error::BAD_DESCRIPTOR, 0, hidl_vec<hidl_handle>());
+        return Void();
+    }
+
+    Error error = Error::NONE;
+    uint32_t stride = 0;
+    std::vector<hidl_handle> buffers;
+    buffers.reserve(count);
+
+    // allocate the buffers
+    for (uint32_t i = 0; i < count; i++) {
+        buffer_handle_t tmpBuffer;
+        uint32_t tmpStride;
+        error = allocateOne(descriptorInfo, &tmpBuffer, &tmpStride);
+        if (error != Error::NONE) {
+            break;
+        }
+
+        if (stride == 0) {
+            stride = tmpStride;
+        } else if (stride != tmpStride) {
+            // non-uniform strides
+            mDevice->free(mDevice, tmpBuffer);
+            stride = 0;
+            error = Error::UNSUPPORTED;
+            break;
+        }
+
+        buffers.emplace_back(hidl_handle(tmpBuffer));
+    }
+
+    // return the buffers
+    hidl_vec<hidl_handle> hidl_buffers;
+    if (error == Error::NONE) {
+        hidl_buffers.setToExternal(buffers.data(), buffers.size());
+    }
+    hidl_cb(error, stride, hidl_buffers);
+
+    // free the buffers
+    for (const auto& buffer : buffers) {
+        mDevice->free(mDevice, buffer.getNativeHandle());
+    }
+
+    return Void();
+}
+
+Error Gralloc0Allocator::allocateOne(const IMapper::BufferDescriptorInfo& info,
+                                     buffer_handle_t* outBuffer,
+                                     uint32_t* outStride) {
+    if (info.layerCount > 1 || (info.usage >> 32) != 0) {
+        return Error::BAD_VALUE;
+    }
+
+    buffer_handle_t buffer = nullptr;
+    int stride = 0;
+    int result = mDevice->alloc(mDevice, info.width, info.height,
+                                static_cast<int>(info.format), info.usage,
+                                &buffer, &stride);
+    if (result) {
+        switch (result) {
+            case -EINVAL:
+                return Error::BAD_VALUE;
+            default:
+                return Error::NO_RESOURCES;
+        }
+    }
+
+    *outBuffer = buffer;
+    *outStride = stride;
+
+    return Error::NONE;
+}
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace allocator
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
diff --git a/graphics/allocator/2.0/default/Gralloc0Allocator.h b/graphics/allocator/2.0/default/Gralloc0Allocator.h
new file mode 100644
index 0000000..0e90527
--- /dev/null
+++ b/graphics/allocator/2.0/default/Gralloc0Allocator.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V2_0_GRALLOC0ALLOCATOR_H
+#define ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V2_0_GRALLOC0ALLOCATOR_H
+
+#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <hardware/gralloc.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace allocator {
+namespace V2_0 {
+namespace implementation {
+
+using android::hardware::graphics::mapper::V2_0::IMapper;
+using android::hardware::graphics::mapper::V2_0::BufferDescriptor;
+using android::hardware::graphics::mapper::V2_0::Error;
+
+class Gralloc0Allocator : public IAllocator {
+   public:
+    Gralloc0Allocator(const hw_module_t* module);
+    virtual ~Gralloc0Allocator();
+
+    // IAllocator interface
+    Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override;
+    Return<void> allocate(const BufferDescriptor& descriptor, uint32_t count,
+                          allocate_cb hidl_cb) override;
+
+   private:
+    Error allocateOne(const IMapper::BufferDescriptorInfo& info,
+                      buffer_handle_t* outBuffer, uint32_t* outStride);
+
+    alloc_device_t* mDevice;
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace allocator
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V2_0_GRALLOC0ALLOCATOR_H
diff --git a/graphics/allocator/2.0/default/Gralloc1Allocator.cpp b/graphics/allocator/2.0/default/Gralloc1Allocator.cpp
new file mode 100644
index 0000000..c0a5e1e
--- /dev/null
+++ b/graphics/allocator/2.0/default/Gralloc1Allocator.cpp
@@ -0,0 +1,321 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Gralloc1Allocator"
+
+#include "Gralloc1Allocator.h"
+#include "GrallocBufferDescriptor.h"
+
+#include <vector>
+
+#include <string.h>
+
+#include <log/log.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace allocator {
+namespace V2_0 {
+namespace implementation {
+
+using android::hardware::graphics::common::V1_0::BufferUsage;
+using android::hardware::graphics::mapper::V2_0::implementation::
+    grallocDecodeBufferDescriptor;
+
+Gralloc1Allocator::Gralloc1Allocator(const hw_module_t* module)
+    : mDevice(nullptr), mCapabilities(), mDispatch() {
+    int result = gralloc1_open(module, &mDevice);
+    if (result) {
+        LOG_ALWAYS_FATAL("failed to open gralloc1 device: %s",
+                         strerror(-result));
+    }
+
+    initCapabilities();
+    initDispatch();
+}
+
+Gralloc1Allocator::~Gralloc1Allocator() {
+    gralloc1_close(mDevice);
+}
+
+void Gralloc1Allocator::initCapabilities() {
+    uint32_t count = 0;
+    mDevice->getCapabilities(mDevice, &count, nullptr);
+
+    std::vector<int32_t> capabilities(count);
+    mDevice->getCapabilities(mDevice, &count, capabilities.data());
+    capabilities.resize(count);
+
+    for (auto capability : capabilities) {
+        if (capability == GRALLOC1_CAPABILITY_LAYERED_BUFFERS) {
+            mCapabilities.layeredBuffers = true;
+            break;
+        }
+    }
+}
+
+template <typename T>
+void Gralloc1Allocator::initDispatch(gralloc1_function_descriptor_t desc,
+                                     T* outPfn) {
+    auto pfn = mDevice->getFunction(mDevice, desc);
+    if (!pfn) {
+        LOG_ALWAYS_FATAL("failed to get gralloc1 function %d", desc);
+    }
+
+    *outPfn = reinterpret_cast<T>(pfn);
+}
+
+void Gralloc1Allocator::initDispatch() {
+    initDispatch(GRALLOC1_FUNCTION_DUMP, &mDispatch.dump);
+    initDispatch(GRALLOC1_FUNCTION_CREATE_DESCRIPTOR,
+                 &mDispatch.createDescriptor);
+    initDispatch(GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR,
+                 &mDispatch.destroyDescriptor);
+    initDispatch(GRALLOC1_FUNCTION_SET_DIMENSIONS, &mDispatch.setDimensions);
+    initDispatch(GRALLOC1_FUNCTION_SET_FORMAT, &mDispatch.setFormat);
+    if (mCapabilities.layeredBuffers) {
+        initDispatch(GRALLOC1_FUNCTION_SET_LAYER_COUNT,
+                     &mDispatch.setLayerCount);
+    }
+    initDispatch(GRALLOC1_FUNCTION_SET_CONSUMER_USAGE,
+                 &mDispatch.setConsumerUsage);
+    initDispatch(GRALLOC1_FUNCTION_SET_PRODUCER_USAGE,
+                 &mDispatch.setProducerUsage);
+    initDispatch(GRALLOC1_FUNCTION_GET_STRIDE, &mDispatch.getStride);
+    initDispatch(GRALLOC1_FUNCTION_ALLOCATE, &mDispatch.allocate);
+    initDispatch(GRALLOC1_FUNCTION_RELEASE, &mDispatch.release);
+}
+
+Return<void> Gralloc1Allocator::dumpDebugInfo(dumpDebugInfo_cb hidl_cb) {
+    uint32_t len = 0;
+    mDispatch.dump(mDevice, &len, nullptr);
+
+    std::vector<char> buf(len + 1);
+    mDispatch.dump(mDevice, &len, buf.data());
+    buf.resize(len + 1);
+    buf[len] = '\0';
+
+    hidl_string reply;
+    reply.setToExternal(buf.data(), len);
+    hidl_cb(reply);
+
+    return Void();
+}
+
+Return<void> Gralloc1Allocator::allocate(const BufferDescriptor& descriptor,
+                                         uint32_t count, allocate_cb hidl_cb) {
+    IMapper::BufferDescriptorInfo descriptorInfo;
+    if (!grallocDecodeBufferDescriptor(descriptor, &descriptorInfo)) {
+        hidl_cb(Error::BAD_DESCRIPTOR, 0, hidl_vec<hidl_handle>());
+        return Void();
+    }
+
+    gralloc1_buffer_descriptor_t desc;
+    Error error = createDescriptor(descriptorInfo, &desc);
+    if (error != Error::NONE) {
+        hidl_cb(error, 0, hidl_vec<hidl_handle>());
+        return Void();
+    }
+
+    uint32_t stride = 0;
+    std::vector<hidl_handle> buffers;
+    buffers.reserve(count);
+
+    // allocate the buffers
+    for (uint32_t i = 0; i < count; i++) {
+        buffer_handle_t tmpBuffer;
+        uint32_t tmpStride;
+        error = allocateOne(desc, &tmpBuffer, &tmpStride);
+        if (error != Error::NONE) {
+            break;
+        }
+
+        if (stride == 0) {
+            stride = tmpStride;
+        } else if (stride != tmpStride) {
+            // non-uniform strides
+            mDispatch.release(mDevice, tmpBuffer);
+            stride = 0;
+            error = Error::UNSUPPORTED;
+            break;
+        }
+
+        buffers.emplace_back(hidl_handle(tmpBuffer));
+    }
+
+    mDispatch.destroyDescriptor(mDevice, desc);
+
+    // return the buffers
+    hidl_vec<hidl_handle> hidl_buffers;
+    if (error == Error::NONE) {
+        hidl_buffers.setToExternal(buffers.data(), buffers.size());
+    }
+    hidl_cb(error, stride, hidl_buffers);
+
+    // free the buffers
+    for (const auto& buffer : buffers) {
+        mDispatch.release(mDevice, buffer.getNativeHandle());
+    }
+
+    return Void();
+}
+
+Error Gralloc1Allocator::toError(int32_t error) {
+    switch (error) {
+        case GRALLOC1_ERROR_NONE:
+            return Error::NONE;
+        case GRALLOC1_ERROR_BAD_DESCRIPTOR:
+            return Error::BAD_DESCRIPTOR;
+        case GRALLOC1_ERROR_BAD_HANDLE:
+            return Error::BAD_BUFFER;
+        case GRALLOC1_ERROR_BAD_VALUE:
+            return Error::BAD_VALUE;
+        case GRALLOC1_ERROR_NOT_SHARED:
+            return Error::NONE;  // this is fine
+        case GRALLOC1_ERROR_NO_RESOURCES:
+            return Error::NO_RESOURCES;
+        case GRALLOC1_ERROR_UNDEFINED:
+        case GRALLOC1_ERROR_UNSUPPORTED:
+        default:
+            return Error::UNSUPPORTED;
+    }
+}
+
+uint64_t Gralloc1Allocator::toProducerUsage(uint64_t usage) {
+    // this is potentially broken as we have no idea which private flags
+    // should be filtered out
+    uint64_t producerUsage =
+        usage &
+        ~static_cast<uint64_t>(BufferUsage::CPU_READ_MASK |
+                               BufferUsage::CPU_WRITE_MASK);
+
+    switch (usage & BufferUsage::CPU_WRITE_MASK) {
+        case static_cast<uint64_t>(BufferUsage::CPU_WRITE_RARELY):
+            producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE;
+            break;
+        case static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN):
+            producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN;
+            break;
+        default:
+            break;
+    }
+
+    switch (usage & BufferUsage::CPU_READ_MASK) {
+        case static_cast<uint64_t>(BufferUsage::CPU_READ_RARELY):
+            producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_READ;
+            break;
+        case static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN):
+            producerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN;
+            break;
+        default:
+            break;
+    }
+
+    return producerUsage;
+}
+
+uint64_t Gralloc1Allocator::toConsumerUsage(uint64_t usage) {
+    // this is potentially broken as we have no idea which private flags
+    // should be filtered out
+    uint64_t consumerUsage =
+        usage &
+        ~static_cast<uint64_t>(BufferUsage::CPU_READ_MASK |
+                               BufferUsage::CPU_WRITE_MASK);
+
+    switch (usage & BufferUsage::CPU_READ_MASK) {
+        case static_cast<uint64_t>(BufferUsage::CPU_READ_RARELY):
+            consumerUsage |= GRALLOC1_CONSUMER_USAGE_CPU_READ;
+            break;
+        case static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN):
+            consumerUsage |= GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN;
+            break;
+        default:
+            break;
+    }
+
+    return consumerUsage;
+}
+
+Error Gralloc1Allocator::createDescriptor(
+    const IMapper::BufferDescriptorInfo& info,
+    gralloc1_buffer_descriptor_t* outDescriptor) {
+    gralloc1_buffer_descriptor_t descriptor;
+
+    int32_t error = mDispatch.createDescriptor(mDevice, &descriptor);
+
+    if (error == GRALLOC1_ERROR_NONE) {
+        error = mDispatch.setDimensions(mDevice, descriptor, info.width,
+                                        info.height);
+    }
+    if (error == GRALLOC1_ERROR_NONE) {
+        error = mDispatch.setFormat(mDevice, descriptor,
+                                    static_cast<int32_t>(info.format));
+    }
+    if (error == GRALLOC1_ERROR_NONE) {
+        if (mCapabilities.layeredBuffers) {
+            error =
+                mDispatch.setLayerCount(mDevice, descriptor, info.layerCount);
+        } else if (info.layerCount > 1) {
+            error = GRALLOC1_ERROR_UNSUPPORTED;
+        }
+    }
+    if (error == GRALLOC1_ERROR_NONE) {
+        error = mDispatch.setProducerUsage(mDevice, descriptor,
+                                           toProducerUsage(info.usage));
+    }
+    if (error == GRALLOC1_ERROR_NONE) {
+        error = mDispatch.setConsumerUsage(mDevice, descriptor,
+                                           toConsumerUsage(info.usage));
+    }
+
+    if (error == GRALLOC1_ERROR_NONE) {
+        *outDescriptor = descriptor;
+    } else {
+        mDispatch.destroyDescriptor(mDevice, descriptor);
+    }
+
+    return toError(error);
+}
+
+Error Gralloc1Allocator::allocateOne(gralloc1_buffer_descriptor_t descriptor,
+                                     buffer_handle_t* outBuffer,
+                                     uint32_t* outStride) {
+    buffer_handle_t buffer = nullptr;
+    int32_t error = mDispatch.allocate(mDevice, 1, &descriptor, &buffer);
+    if (error != GRALLOC1_ERROR_NONE && error != GRALLOC1_ERROR_NOT_SHARED) {
+        return toError(error);
+    }
+
+    uint32_t stride = 0;
+    error = mDispatch.getStride(mDevice, buffer, &stride);
+    if (error != GRALLOC1_ERROR_NONE && error != GRALLOC1_ERROR_UNDEFINED) {
+        mDispatch.release(mDevice, buffer);
+        return toError(error);
+    }
+
+    *outBuffer = buffer;
+    *outStride = stride;
+
+    return Error::NONE;
+}
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace allocator
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
diff --git a/graphics/allocator/2.0/default/Gralloc1Allocator.h b/graphics/allocator/2.0/default/Gralloc1Allocator.h
new file mode 100644
index 0000000..7b5a966
--- /dev/null
+++ b/graphics/allocator/2.0/default/Gralloc1Allocator.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V2_0_GRALLOC1ALLOCATOR_H
+#define ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V2_0_GRALLOC1ALLOCATOR_H
+
+#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <hardware/gralloc1.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace allocator {
+namespace V2_0 {
+namespace implementation {
+
+using android::hardware::graphics::mapper::V2_0::IMapper;
+using android::hardware::graphics::mapper::V2_0::BufferDescriptor;
+using android::hardware::graphics::mapper::V2_0::Error;
+
+class Gralloc1Allocator : public IAllocator {
+   public:
+    Gralloc1Allocator(const hw_module_t* module);
+    virtual ~Gralloc1Allocator();
+
+    // IAllocator interface
+    Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override;
+    Return<void> allocate(const BufferDescriptor& descriptor, uint32_t count,
+                          allocate_cb hidl_cb) override;
+
+   private:
+    void initCapabilities();
+
+    template <typename T>
+    void initDispatch(gralloc1_function_descriptor_t desc, T* outPfn);
+    void initDispatch();
+
+    static Error toError(int32_t error);
+    static uint64_t toProducerUsage(uint64_t usage);
+    static uint64_t toConsumerUsage(uint64_t usage);
+
+    Error createDescriptor(const IMapper::BufferDescriptorInfo& info,
+                           gralloc1_buffer_descriptor_t* outDescriptor);
+    Error allocateOne(gralloc1_buffer_descriptor_t descriptor,
+                      buffer_handle_t* outBuffer, uint32_t* outStride);
+
+    gralloc1_device_t* mDevice;
+
+    struct {
+        bool layeredBuffers;
+    } mCapabilities;
+
+    struct {
+        GRALLOC1_PFN_DUMP dump;
+        GRALLOC1_PFN_CREATE_DESCRIPTOR createDescriptor;
+        GRALLOC1_PFN_DESTROY_DESCRIPTOR destroyDescriptor;
+        GRALLOC1_PFN_SET_DIMENSIONS setDimensions;
+        GRALLOC1_PFN_SET_FORMAT setFormat;
+        GRALLOC1_PFN_SET_LAYER_COUNT setLayerCount;
+        GRALLOC1_PFN_SET_CONSUMER_USAGE setConsumerUsage;
+        GRALLOC1_PFN_SET_PRODUCER_USAGE setProducerUsage;
+        GRALLOC1_PFN_GET_STRIDE getStride;
+        GRALLOC1_PFN_ALLOCATE allocate;
+        GRALLOC1_PFN_RELEASE release;
+    } mDispatch;
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace allocator
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_GRAPHICS_ALLOCATOR_V2_0_GRALLOC1ALLOCATOR_H
diff --git a/graphics/allocator/2.0/types.hal b/graphics/allocator/2.0/types.hal
deleted file mode 100644
index d9b184b..0000000
--- a/graphics/allocator/2.0/types.hal
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.hardware.graphics.allocator@2.0;
-
-enum Error : int32_t {
-    NONE            = 0, /** no error */
-    BAD_DESCRIPTOR  = 1, /** invalid BufferDescriptor */
-    BAD_BUFFER      = 2, /** invalid Buffer */
-    BAD_VALUE       = 3, /** invalid width, height, etc. */
-    NOT_SHARED      = 4, /** buffers not sharing backing store */
-    NO_RESOURCES    = 5, /** temporary failure due to resource contention */
-    UNDEFINED       = 6, /** an operation has no defined meaning */
-    UNSUPPORTED     = 7, /** permanent failure */
-};
-
-enum ProducerUsage : uint64_t {
-    /** bit 0 is reserved */
-
-    /** buffer is read by CPU occasionally */
-    CPU_READ        = 1ULL << 1,
-    /** buffer is read by CPU frequently */
-    CPU_READ_OFTEN  = 1ULL << 2,
-
-    /** bit 3 is reserved */
-    /** bit 4 is reserved */
-
-    /** buffer is written by CPU occasionally */
-    CPU_WRITE       = 1ULL << 5,
-    /** buffer is written by CPU frequently */
-    CPU_WRITE_OFTEN = 1ULL << 6,
-
-    /** bit 7 is reserved */
-    /** bit 8 is reserved */
-
-    /** buffer is used as a GPU render target */
-    GPU_RENDER_TARGET = 1ULL << 9,
-
-    /** bit 10 is reserved */
-    /** bit 11 is reserved */
-    /** bit 12 is reserved */
-    /** bit 13 is reserved */
-
-    /**
-     * Buffer is allocated with hardware-level protection against copying the
-     * contents (or information derived from the contents) into unprotected
-     * memory.
-     */
-    PROTECTED         = 1ULL << 14,
-
-    /** bit 15 is reserved */
-    /** bit 16 is reserved */
-
-    /** buffer is used as a camera HAL output */
-    CAMERA            = 1ULL << 17,
-
-    /** bit 18 is reserved */
-    /** bit 19 is reserved */
-    /** bit 20 is reserved */
-    /** bit 21 is reserved */
-
-    /** buffer is used as a video decoder output */
-    VIDEO_DECODER     = 1ULL << 22,
-
-    /** buffer is used as a sensor direct report output */
-    SENSOR_DIRECT_DATA = 1ULL << 23,
-
-    /** bits 24-27 are reserved for future versions */
-    /** bits 28-31 are reserved for vendor extensions */
-
-    /** bits 32-47 are reserved for future versions */
-    /** bits 48-63 are reserved for vendor extensions */
-};
-
-enum ConsumerUsage : uint64_t {
-    /** bit 0 is reserved */
-
-    /** buffer is read by CPU occasionally */
-    CPU_READ          = 1ULL << 1,
-    /** buffer is read by CPU frequently */
-    CPU_READ_OFTEN    = 1ULL << 2,
-
-    /** bit 3 is reserved */
-    /** bit 4 is reserved */
-    /** bit 5 is reserved */
-    /** bit 6 is reserved */
-    /** bit 7 is reserved */
-
-    /** buffer is used as a GPU texture */
-    GPU_TEXTURE       = 1ULL << 8,
-
-    /** bit 9 is reserved */
-    /** bit 10 is reserved */
-
-    /** buffer is used by hwcomposer HAL */
-    HWCOMPOSER        = 1ULL << 11,
-    /** buffer is a hwcomposer HAL client target */
-    CLIENT_TARGET     = 1ULL << 12,
-
-    /** bit 13 is reserved */
-    /** bit 14 is reserved */
-
-    /** buffer is used as a hwcomposer HAL cursor */
-    CURSOR            = 1ULL << 15,
-
-    /** buffer is used as a video encoder input */
-    VIDEO_ENCODER     = 1ULL << 16,
-
-    /** bit 17 is reserved */
-
-    /** buffer is used as a camera HAL input */
-    CAMERA            = 1ULL << 18,
-
-    /** bit 19 is reserved */
-
-    /** buffer is used as a renderscript allocation */
-    RENDERSCRIPT      = 1ULL << 20,
-
-    /** bit 21 is reserved */
-    /** bit 22 is reserved */
-
-    /**
-     * buffer is used as as an OpenGL shader storage or uniform
-       buffer object */
-    GPU_DATA_BUFFER    = 1ULL << 23,
-
-    /** bits 24-27 are reserved for future versions */
-    /** bits 28-31 are reserved for vendor extensions */
-
-    /** bits 32-47 are reserved for future versions */
-    /** bits 48-63 are reserved for vendor extensions */
-};
-
-typedef uint64_t BufferDescriptor;
-typedef uint64_t Buffer;
diff --git a/graphics/allocator/2.0/vts/functional/Android.bp b/graphics/allocator/2.0/vts/functional/Android.bp
deleted file mode 100644
index fb77ab3..0000000
--- a/graphics/allocator/2.0/vts/functional/Android.bp
+++ /dev/null
@@ -1,62 +0,0 @@
-//
-// Copyright (C) 2016 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-cc_library_static {
-    name: "libVtsHalGraphicsAllocatorTestUtils",
-    defaults: ["hidl_defaults"],
-    srcs: ["VtsHalGraphicsAllocatorTestUtils.cpp"],
-    shared_libs: [
-        "android.hardware.graphics.allocator@2.0",
-    ],
-    static_libs: [
-        "VtsHalHidlTargetTestBase",
-    ],
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-        "-O0",
-        "-g",
-    ],
-    export_include_dirs: ["."],
-}
-
-cc_test {
-    name: "VtsHalGraphicsAllocatorV2_0TargetTest",
-    defaults: ["hidl_defaults"],
-    srcs: ["VtsHalGraphicsAllocatorV2_0TargetTest.cpp"],
-    shared_libs: [
-        "libbase",
-        "liblog",
-        "libcutils",
-        "libhidlbase",
-        "libhidltransport",
-        "libnativehelper",
-        "libutils",
-        "android.hardware.graphics.allocator@2.0",
-    ],
-    static_libs: [
-        "libVtsHalGraphicsAllocatorTestUtils",
-        "VtsHalHidlTargetTestBase",
-    ],
-    cflags: [
-        "-Wall",
-        "-Wextra",
-        "-Werror",
-        "-O0",
-        "-g",
-    ]
-}
diff --git a/graphics/allocator/2.0/vts/functional/VtsHalGraphicsAllocatorTestUtils.cpp b/graphics/allocator/2.0/vts/functional/VtsHalGraphicsAllocatorTestUtils.cpp
deleted file mode 100644
index 0dc43be..0000000
--- a/graphics/allocator/2.0/vts/functional/VtsHalGraphicsAllocatorTestUtils.cpp
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <VtsHalHidlTargetTestBase.h>
-
-#include "VtsHalGraphicsAllocatorTestUtils.h"
-
-namespace android {
-namespace hardware {
-namespace graphics {
-namespace allocator {
-namespace V2_0 {
-namespace tests {
-
-Allocator::Allocator() { init(); }
-
-void Allocator::init() {
-  mAllocator = ::testing::VtsHalHidlTargetTestBase::getService<IAllocator>();
-  ASSERT_NE(nullptr, mAllocator.get()) << "failed to get allocator service";
-
-  std::vector<IAllocator::Capability> capabilities = getCapabilities();
-  mCapabilities.insert(capabilities.begin(), capabilities.end());
-}
-
-sp<IAllocator> Allocator::getRaw() const { return mAllocator; }
-
-bool Allocator::hasCapability(IAllocator::Capability capability) const {
-  return mCapabilities.count(capability) > 0;
-}
-
-std::vector<IAllocator::Capability> Allocator::getCapabilities() {
-  std::vector<IAllocator::Capability> capabilities;
-  mAllocator->getCapabilities(
-      [&](const auto& tmpCapabilities) { capabilities = tmpCapabilities; });
-
-  return capabilities;
-}
-
-std::string Allocator::dumpDebugInfo() {
-  std::string debugInfo;
-  mAllocator->dumpDebugInfo(
-      [&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); });
-
-  return debugInfo;
-}
-
-std::unique_ptr<AllocatorClient> Allocator::createClient() {
-  std::unique_ptr<AllocatorClient> client;
-  mAllocator->createClient([&](const auto& tmpError, const auto& tmpClient) {
-    ASSERT_EQ(Error::NONE, tmpError) << "failed to create client";
-    client = std::make_unique<AllocatorClient>(tmpClient);
-  });
-
-  return client;
-}
-
-AllocatorClient::AllocatorClient(const sp<IAllocatorClient>& client)
-    : mClient(client) {}
-
-AllocatorClient::~AllocatorClient() {
-  for (auto buffer : mBuffers) {
-    EXPECT_EQ(Error::NONE, mClient->free(buffer))
-        << "failed to free buffer " << buffer;
-  }
-  mBuffers.clear();
-
-  for (auto descriptor : mDescriptors) {
-    EXPECT_EQ(Error::NONE, mClient->destroyDescriptor(descriptor))
-        << "failed to destroy descriptor " << descriptor;
-  }
-  mDescriptors.clear();
-}
-
-sp<IAllocatorClient> AllocatorClient::getRaw() const { return mClient; }
-
-BufferDescriptor AllocatorClient::createDescriptor(
-    const IAllocatorClient::BufferDescriptorInfo& info) {
-  BufferDescriptor descriptor = 0;
-  mClient->createDescriptor(
-      info, [&](const auto& tmpError, const auto& tmpDescriptor) {
-        ASSERT_EQ(Error::NONE, tmpError) << "failed to create descriptor";
-        descriptor = tmpDescriptor;
-
-        EXPECT_TRUE(mDescriptors.insert(descriptor).second)
-            << "duplicated descriptor id " << descriptor;
-      });
-
-  return descriptor;
-}
-
-void AllocatorClient::destroyDescriptor(BufferDescriptor descriptor) {
-  ASSERT_EQ(Error::NONE, mClient->destroyDescriptor(descriptor))
-      << "failed to destroy descriptor " << descriptor;
-
-  mDescriptors.erase(descriptor);
-}
-
-Error AllocatorClient::testAllocate(
-    const std::vector<BufferDescriptor>& descriptors) {
-  return mClient->testAllocate(descriptors);
-}
-
-bool AllocatorClient::testAllocate(BufferDescriptor descriptor) {
-  std::vector<BufferDescriptor> descriptors(1, descriptor);
-  Error error = testAllocate(descriptors);
-  return (error == Error::NONE || error == Error::NOT_SHARED);
-}
-
-Error AllocatorClient::allocate(
-    const std::vector<BufferDescriptor>& descriptors,
-    std::vector<Buffer>& buffers) {
-  Error error = Error::NO_RESOURCES;
-  mClient->allocate(descriptors, [&](const auto& tmpError,
-                                     const auto& tmpBuffers) {
-    ASSERT_TRUE(tmpError == Error::NONE || tmpError == Error::NOT_SHARED)
-        << "failed to allocate buffer";
-    ASSERT_EQ(descriptors.size(), tmpBuffers.size()) << "invalid buffer count";
-
-    error = tmpError;
-    buffers = tmpBuffers;
-
-    for (auto buffer : buffers) {
-      EXPECT_TRUE(mBuffers.insert(buffer).second)
-          << "duplicated buffer id " << buffer;
-    }
-  });
-
-  return error;
-}
-
-Buffer AllocatorClient::allocate(BufferDescriptor descriptor) {
-  std::vector<BufferDescriptor> descriptors(1, descriptor);
-  std::vector<Buffer> buffers;
-  allocate(descriptors, buffers);
-  if (::testing::Test::HasFatalFailure()) {
-    return 0;
-  }
-
-  return buffers[0];
-}
-
-void AllocatorClient::free(Buffer buffer) {
-  ASSERT_EQ(Error::NONE, mClient->free(buffer))
-      << "failed to free buffer " << buffer;
-
-  mBuffers.erase(buffer);
-}
-
-native_handle_t* AllocatorClient::exportHandle(BufferDescriptor descriptor,
-                                               Buffer buffer) {
-  native_handle_t* handle;
-  mClient->exportHandle(
-      descriptor, buffer, [&](const auto& tmpError, const auto& tmpHandle) {
-        ASSERT_EQ(Error::NONE, tmpError) << "failed to export buffer handle";
-        ASSERT_NE(nullptr, tmpHandle.getNativeHandle())
-            << "invalid buffer handle";
-
-        handle = native_handle_clone(tmpHandle.getNativeHandle());
-        ASSERT_NE(nullptr, handle) << "failed to clone handle";
-      });
-
-  return handle;
-}
-
-}  // namespace tests
-}  // namespace V2_0
-}  // namespace allocator
-}  // namespace graphics
-}  // namespace hardware
-}  // namespace android
diff --git a/graphics/allocator/2.0/vts/functional/VtsHalGraphicsAllocatorTestUtils.h b/graphics/allocator/2.0/vts/functional/VtsHalGraphicsAllocatorTestUtils.h
deleted file mode 100644
index c9bfe8f..0000000
--- a/graphics/allocator/2.0/vts/functional/VtsHalGraphicsAllocatorTestUtils.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef VTS_HAL_GRAPHICS_ALLOCATOR_UTILS
-#define VTS_HAL_GRAPHICS_ALLOCATOR_UTILS
-
-#include <memory>
-#include <string>
-#include <unordered_set>
-#include <vector>
-
-#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
-#include <utils/StrongPointer.h>
-
-namespace android {
-namespace hardware {
-namespace graphics {
-namespace allocator {
-namespace V2_0 {
-namespace tests {
-
-class AllocatorClient;
-
-// A wrapper to IAllocator.
-class Allocator {
- public:
-  Allocator();
-
-  sp<IAllocator> getRaw() const;
-
-  // Returns true when the allocator supports the specified capability.
-  bool hasCapability(IAllocator::Capability capability) const;
-
-  std::vector<IAllocator::Capability> getCapabilities();
-  std::string dumpDebugInfo();
-  std::unique_ptr<AllocatorClient> createClient();
-
- private:
-  void init();
-
-  sp<IAllocator> mAllocator;
-  std::unordered_set<IAllocator::Capability> mCapabilities;
-};
-
-// A wrapper to IAllocatorClient.
-class AllocatorClient {
- public:
-  AllocatorClient(const sp<IAllocatorClient>& client);
-  ~AllocatorClient();
-
-  sp<IAllocatorClient> getRaw() const;
-
-  BufferDescriptor createDescriptor(
-      const IAllocatorClient::BufferDescriptorInfo& info);
-  void destroyDescriptor(BufferDescriptor descriptor);
-
-  Error testAllocate(const std::vector<BufferDescriptor>& descriptors);
-  bool testAllocate(BufferDescriptor descriptor);
-
-  Error allocate(const std::vector<BufferDescriptor>& descriptors,
-                 std::vector<Buffer>& buffers);
-  Buffer allocate(BufferDescriptor descriptor);
-  void free(Buffer buffer);
-
-  // Returns a handle to the buffer.  The ownership of the handle is
-  // transferred to the caller.
-  native_handle_t* exportHandle(BufferDescriptor descriptor, Buffer buffer);
-
- private:
-  sp<IAllocatorClient> mClient;
-
-  // Keep track of all descriptors and buffers.  When a test fails with
-  // ASSERT_*, the destructor will clean up the resources for the test.
-  std::unordered_set<BufferDescriptor> mDescriptors;
-  std::unordered_set<Buffer> mBuffers;
-};
-
-}  // namespace tests
-}  // namespace V2_0
-}  // namespace allocator
-}  // namespace graphics
-}  // namespace hardware
-}  // namespace android
-
-#endif  // VTS_HAL_GRAPHICS_ALLOCATOR_UTILS
diff --git a/graphics/allocator/2.0/vts/functional/VtsHalGraphicsAllocatorV2_0TargetTest.cpp b/graphics/allocator/2.0/vts/functional/VtsHalGraphicsAllocatorV2_0TargetTest.cpp
deleted file mode 100644
index b1c764f..0000000
--- a/graphics/allocator/2.0/vts/functional/VtsHalGraphicsAllocatorV2_0TargetTest.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "graphics_allocator_hidl_hal_test"
-
-#include <android-base/logging.h>
-#include <VtsHalHidlTargetTestBase.h>
-
-#include "VtsHalGraphicsAllocatorTestUtils.h"
-
-namespace android {
-namespace hardware {
-namespace graphics {
-namespace allocator {
-namespace V2_0 {
-namespace tests {
-namespace {
-
-using android::hardware::graphics::common::V1_0::PixelFormat;
-
-#define CHECK_FEATURE_OR_SKIP(FEATURE_NAME)                 \
-  do {                                                      \
-    if (!mAllocator->hasCapability(FEATURE_NAME)) {         \
-      std::cout << "[  SKIPPED ] Feature " << #FEATURE_NAME \
-                << " not supported" << std::endl;           \
-      return;                                               \
-    }                                                       \
-  } while (0)
-
-class GraphicsAllocatorHidlTest : public ::testing::VtsHalHidlTargetTestBase {
- protected:
-  void SetUp() override {
-    ASSERT_NO_FATAL_FAILURE(mAllocator = std::make_unique<Allocator>());
-    ASSERT_NO_FATAL_FAILURE(mClient = mAllocator->createClient());
-
-    mDummyDescriptorInfo.width = 64;
-    mDummyDescriptorInfo.height = 64;
-    mDummyDescriptorInfo.layerCount = 1;
-    mDummyDescriptorInfo.format = PixelFormat::RGBA_8888;
-    mDummyDescriptorInfo.producerUsageMask =
-        static_cast<uint64_t>(ProducerUsage::CPU_WRITE);
-    mDummyDescriptorInfo.consumerUsageMask =
-        static_cast<uint64_t>(ConsumerUsage::CPU_READ);
-  }
-
-  void TearDown() override {}
-
-  std::unique_ptr<Allocator> mAllocator;
-  std::unique_ptr<AllocatorClient> mClient;
-  IAllocatorClient::BufferDescriptorInfo mDummyDescriptorInfo{};
-};
-
-TEST_F(GraphicsAllocatorHidlTest, GetCapabilities) {
-  auto capabilities = mAllocator->getCapabilities();
-  for (auto cap : capabilities) {
-    EXPECT_NE(IAllocator::Capability::INVALID, cap);
-  }
-}
-
-TEST_F(GraphicsAllocatorHidlTest, DumpDebugInfo) {
-  mAllocator->dumpDebugInfo();
-}
-
-TEST_F(GraphicsAllocatorHidlTest, CreateDestroyDescriptor) {
-  BufferDescriptor descriptor;
-  ASSERT_NO_FATAL_FAILURE(descriptor =
-                              mClient->createDescriptor(mDummyDescriptorInfo));
-  mClient->destroyDescriptor(descriptor);
-}
-
-/**
- * Test testAllocate with a single buffer descriptor.
- */
-TEST_F(GraphicsAllocatorHidlTest, TestAllocateBasic) {
-  CHECK_FEATURE_OR_SKIP(IAllocator::Capability::TEST_ALLOCATE);
-
-  BufferDescriptor descriptor;
-  ASSERT_NO_FATAL_FAILURE(descriptor =
-                              mClient->createDescriptor(mDummyDescriptorInfo));
-
-  ASSERT_TRUE(mClient->testAllocate(descriptor));
-}
-
-/**
- * Test testAllocate with two buffer descriptors.
- */
-TEST_F(GraphicsAllocatorHidlTest, TestAllocateArray) {
-  CHECK_FEATURE_OR_SKIP(IAllocator::Capability::TEST_ALLOCATE);
-
-  BufferDescriptor descriptor;
-  ASSERT_NO_FATAL_FAILURE(descriptor =
-                              mClient->createDescriptor(mDummyDescriptorInfo));
-
-  hidl_vec<BufferDescriptor> descriptors;
-  descriptors.resize(2);
-  descriptors[0] = descriptor;
-  descriptors[1] = descriptor;
-
-  auto error = mClient->testAllocate(descriptors);
-  ASSERT_TRUE(error == Error::NONE || error == Error::NOT_SHARED);
-}
-
-/**
- * Test allocate/free with a single buffer descriptor.
- */
-TEST_F(GraphicsAllocatorHidlTest, AllocateFreeBasic) {
-  BufferDescriptor descriptor;
-  ASSERT_NO_FATAL_FAILURE(descriptor =
-                              mClient->createDescriptor(mDummyDescriptorInfo));
-
-  Buffer buffer;
-  ASSERT_NO_FATAL_FAILURE(buffer = mClient->allocate(descriptor));
-
-  mClient->free(buffer);
-}
-
-/**
- * Test allocate/free with an array of buffer descriptors.
- */
-TEST_F(GraphicsAllocatorHidlTest, AllocateFreeArray) {
-  BufferDescriptor descriptor1;
-  ASSERT_NO_FATAL_FAILURE(descriptor1 =
-                              mClient->createDescriptor(mDummyDescriptorInfo));
-
-  BufferDescriptor descriptor2;
-  ASSERT_NO_FATAL_FAILURE(descriptor2 =
-                              mClient->createDescriptor(mDummyDescriptorInfo));
-
-  hidl_vec<BufferDescriptor> descriptors;
-  descriptors.resize(3);
-  descriptors[0] = descriptor1;
-  descriptors[1] = descriptor1;
-  descriptors[2] = descriptor2;
-
-  std::vector<Buffer> buffers;
-  ASSERT_NO_FATAL_FAILURE(mClient->allocate(descriptors, buffers));
-
-  for (auto buf : buffers) {
-    mClient->free(buf);
-  }
-}
-
-TEST_F(GraphicsAllocatorHidlTest, ExportHandle) {
-  BufferDescriptor descriptor;
-  ASSERT_NO_FATAL_FAILURE(descriptor =
-                              mClient->createDescriptor(mDummyDescriptorInfo));
-
-  Buffer buffer;
-  ASSERT_NO_FATAL_FAILURE(buffer = mClient->allocate(descriptor));
-
-  native_handle_t* handle;
-  ASSERT_NO_FATAL_FAILURE(handle = mClient->exportHandle(descriptor, buffer));
-
-  native_handle_close(handle);
-  native_handle_delete(handle);
-}
-
-}  // namespace anonymous
-}  // namespace tests
-}  // namespace V2_0
-}  // namespace allocator
-}  // namespace graphics
-}  // namespace hardware
-}  // namespace android
-
-int main(int argc, char** argv) {
-  ::testing::InitGoogleTest(&argc, argv);
-
-  int status = RUN_ALL_TESTS();
-  LOG(INFO) << "Test result = " << status;
-
-  return status;
-}
diff --git a/graphics/common/1.0/Android.mk b/graphics/common/1.0/Android.mk
index c08053d..ae80c6a 100644
--- a/graphics/common/1.0/Android.mk
+++ b/graphics/common/1.0/Android.mk
@@ -13,6 +13,25 @@
 HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
 
 #
+# Build types.hal (BufferUsage)
+#
+GEN := $(intermediates)/android/hardware/graphics/common/V1_0/BufferUsage.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.graphics.common@1.0::types.BufferUsage
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
 # Build types.hal (ColorMode)
 #
 GEN := $(intermediates)/android/hardware/graphics/common/V1_0/ColorMode.java
@@ -139,6 +158,25 @@
 HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
 
 #
+# Build types.hal (BufferUsage)
+#
+GEN := $(intermediates)/android/hardware/graphics/common/V1_0/BufferUsage.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.graphics.common@1.0::types.BufferUsage
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
 # Build types.hal (ColorMode)
 #
 GEN := $(intermediates)/android/hardware/graphics/common/V1_0/ColorMode.java
diff --git a/graphics/common/1.0/types.hal b/graphics/common/1.0/types.hal
index 8aa0779..3bd1ec1 100644
--- a/graphics/common/1.0/types.hal
+++ b/graphics/common/1.0/types.hal
@@ -450,6 +450,90 @@
 };
 
 /**
+ * Buffer usage definitions.
+ */
+enum BufferUsage : uint64_t {
+    /** bit 0-3 is an enum */
+    CPU_READ_MASK   = 0xfULL,
+    /** buffer is never read by CPU */
+    CPU_READ_NEVER  = 0,
+    /** buffer is rarely read by CPU */
+    CPU_READ_RARELY = 2,
+    /** buffer is often read by CPU */
+    CPU_READ_OFTEN  = 3,
+
+    /** bit 4-7 is an enum */
+    CPU_WRITE_MASK   = 0xfULL << 4,
+    /** buffer is never written by CPU */
+    CPU_WRITE_NEVER  = 0 << 4,
+    /** buffer is rarely written by CPU */
+    CPU_WRITE_RARELY = 2 << 4,
+    /** buffer is often written by CPU */
+    CPU_WRITE_OFTEN  = 3 << 4,
+
+    /** buffer is used as a GPU texture */
+    GPU_TEXTURE       = 1ULL << 8,
+
+    /** buffer is used as a GPU render target */
+    GPU_RENDER_TARGET = 1ULL << 9,
+
+    /** bit 10 must be zero */
+
+    /** buffer is used as a composer HAL overlay layer */
+    COMPOSER_OVERLAY  = 1ULL << 11,
+    /** buffer is used as a composer HAL client target */
+    COMPOSER_CLIENT_TARGET = 1ULL << 12,
+
+    /** bit 13 must be zero */
+
+    /**
+     * Buffer is allocated with hardware-level protection against copying the
+     * contents (or information derived from the contents) into unprotected
+     * memory.
+     */
+    PROTECTED         = 1ULL << 14,
+
+    /** buffer is used as a hwcomposer HAL cursor layer */
+    COMPOSER_CURSOR   = 1ULL << 15,
+
+    /** buffer is used as a video encoder input */
+    VIDEO_ENCODER     = 1ULL << 16,
+
+    /** buffer is used as a camera HAL output */
+    CAMERA_OUTPUT     = 1ULL << 17,
+
+    /** buffer is used as a camera HAL input */
+    CAMERA_INPUT      = 1ULL << 18,
+
+    /** bit 19 must be zero */
+
+    /** buffer is used as a renderscript allocation */
+    RENDERSCRIPT      = 1ULL << 20,
+
+    /** bit 21 must be zero */
+
+    /** buffer is used as a video decoder output */
+    VIDEO_DECODER     = 1ULL << 22,
+
+    /** buffer is used as a sensor direct report output */
+    SENSOR_DIRECT_DATA = 1ULL << 23,
+
+    /**
+     * buffer is used as as an OpenGL shader storage or uniform
+     * buffer object
+     */
+    GPU_DATA_BUFFER   = 1ULL << 24,
+
+    /** bits 25-27 must be zero and are reserved for future versions */
+    /** bits 28-31 are reserved for vendor extensions */
+    VENDOR_MASK       = 0xfULL << 28,
+
+    /** bits 32-47 must be zero and are reserved for future versions */
+    /** bits 48-63 are reserved for vendor extensions */
+    VENDOR_MASK_HI    = 0xffffULL << 48,
+};
+
+/**
  * Transformation definitions
  *
  * IMPORTANT NOTE:
diff --git a/graphics/composer/2.1/vts/functional/Android.bp b/graphics/composer/2.1/vts/functional/Android.bp
index 8e1f925..66323d4 100644
--- a/graphics/composer/2.1/vts/functional/Android.bp
+++ b/graphics/composer/2.1/vts/functional/Android.bp
@@ -52,7 +52,6 @@
     ],
     static_libs: [
         "libhwcomposer-command-buffer",
-        "libVtsHalGraphicsAllocatorTestUtils",
         "libVtsHalGraphicsComposerTestUtils",
         "libVtsHalGraphicsMapperTestUtils",
         "VtsHalHidlTargetTestBase",
diff --git a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
index 0da3a33..387222f 100644
--- a/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
+++ b/graphics/composer/2.1/vts/functional/VtsHalGraphicsComposerV2_1TargetTest.cpp
@@ -18,7 +18,6 @@
 
 #include <IComposerCommandBuffer.h>
 #include <android-base/logging.h>
-#include "VtsHalGraphicsAllocatorTestUtils.h"
 #include "VtsHalGraphicsComposerTestUtils.h"
 #include "VtsHalGraphicsMapperTestUtils.h"
 
@@ -40,22 +39,15 @@
 namespace tests {
 namespace {
 
-using android::hardware::graphics::allocator::V2_0::Buffer;
-using android::hardware::graphics::allocator::V2_0::BufferDescriptor;
-using android::hardware::graphics::allocator::V2_0::ConsumerUsage;
-using android::hardware::graphics::allocator::V2_0::IAllocator;
-using android::hardware::graphics::allocator::V2_0::IAllocatorClient;
-using android::hardware::graphics::allocator::V2_0::ProducerUsage;
-using android::hardware::graphics::allocator::V2_0::tests::Allocator;
-using android::hardware::graphics::allocator::V2_0::tests::AllocatorClient;
+using android::hardware::graphics::common::V1_0::BufferUsage;
 using android::hardware::graphics::common::V1_0::ColorMode;
 using android::hardware::graphics::common::V1_0::ColorTransform;
 using android::hardware::graphics::common::V1_0::Dataspace;
 using android::hardware::graphics::common::V1_0::PixelFormat;
 using android::hardware::graphics::common::V1_0::Transform;
 using android::hardware::graphics::mapper::V2_0::IMapper;
-using android::hardware::graphics::mapper::V2_0::tests::Mapper;
-using GrallocError = android::hardware::graphics::allocator::V2_0::Error;
+using android::hardware::graphics::mapper::V2_0::tests::Gralloc;
+using GrallocError = android::hardware::graphics::mapper::V2_0::Error;
 
 // IComposerCallback to be installed with IComposerClient::registerCallback.
 class GraphicsComposerCallback : public IComposerCallback {
@@ -409,9 +401,7 @@
   void SetUp() override {
     ASSERT_NO_FATAL_FAILURE(GraphicsComposerHidlTest::SetUp());
 
-    ASSERT_NO_FATAL_FAILURE(mAllocator = std::make_unique<Allocator>());
-    ASSERT_NO_FATAL_FAILURE(mAllocatorClient = mAllocator->createClient());
-    ASSERT_NO_FATAL_FAILURE(mMapper = std::make_unique<Mapper>());
+    ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>());
 
     mWriter = std::make_unique<CommandWriterBase>(1024);
     mReader = std::make_unique<CommandReader>();
@@ -422,15 +412,15 @@
   }
 
   const native_handle_t* allocate() {
-    IAllocatorClient::BufferDescriptorInfo info{};
-    info.width = 64;
-    info.height = 64;
-    info.layerCount = 1;
-    info.format = PixelFormat::RGBA_8888;
-    info.producerUsageMask = static_cast<uint64_t>(ProducerUsage::CPU_WRITE);
-    info.consumerUsageMask = static_cast<uint64_t>(ConsumerUsage::CPU_READ);
+      IMapper::BufferDescriptorInfo info{};
+      info.width = 64;
+      info.height = 64;
+      info.layerCount = 1;
+      info.format = PixelFormat::RGBA_8888;
+      info.usage = static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN |
+                                         BufferUsage::CPU_READ_OFTEN);
 
-    return mMapper->allocate(mAllocatorClient, info);
+      return mGralloc->allocate(info);
   }
 
   void execute() {
@@ -507,9 +497,7 @@
   std::unique_ptr<CommandReader> mReader;
 
  private:
-  std::unique_ptr<Allocator> mAllocator;
-  std::unique_ptr<AllocatorClient> mAllocatorClient;
-  std::unique_ptr<Mapper> mMapper;
+  std::unique_ptr<Gralloc> mGralloc;
 };
 
 /**
diff --git a/graphics/mapper/2.0/Android.bp b/graphics/mapper/2.0/Android.bp
index 98a509b..cc2bd73 100644
--- a/graphics/mapper/2.0/Android.bp
+++ b/graphics/mapper/2.0/Android.bp
@@ -51,7 +51,6 @@
         "liblog",
         "libutils",
         "libcutils",
-        "android.hardware.graphics.allocator@2.0",
         "android.hardware.graphics.common@1.0",
         "android.hidl.base@1.0",
     ],
@@ -60,7 +59,6 @@
         "libhidltransport",
         "libhwbinder",
         "libutils",
-        "android.hardware.graphics.allocator@2.0",
         "android.hardware.graphics.common@1.0",
         "android.hidl.base@1.0",
     ],
diff --git a/graphics/mapper/2.0/IMapper.hal b/graphics/mapper/2.0/IMapper.hal
index 573dcd0..246be24 100644
--- a/graphics/mapper/2.0/IMapper.hal
+++ b/graphics/mapper/2.0/IMapper.hal
@@ -16,10 +16,39 @@
 
 package android.hardware.graphics.mapper@2.0;
 
-import android.hardware.graphics.common@1.0::PixelFormat;
-import android.hardware.graphics.allocator@2.0;
+import android.hardware.graphics.common@1.0;
 
 interface IMapper {
+    struct BufferDescriptorInfo {
+        /**
+         * The width specifies how many columns of pixels must be in the
+         * allocated buffer, but does not necessarily represent the offset in
+         * columns between the same column in adjacent rows. The rows may be
+         * padded.
+         */
+        uint32_t width;
+
+       /**
+        * The height specifies how many rows of pixels must be in the
+        * allocated buffer.
+        */
+        uint32_t height;
+
+       /**
+        * The number of image layers that must be in the allocated buffer.
+        */
+        uint32_t layerCount;
+
+        /** Buffer pixel format. */
+        PixelFormat format;
+
+        /**
+         * Buffer usage mask; valid flags can be found in the definition of
+         * BufferUsage.
+         */
+        bitfield<BufferUsage> usage;
+    };
+
     struct Rect {
         int32_t left;
         int32_t top;
@@ -28,170 +57,76 @@
     };
 
     /**
-     * Adds a reference to the given buffer handle.
+     * Creates a buffer descriptor. The descriptor can be used with IAllocator
+     * to allocate buffers.
      *
-     * A buffer handle received from a remote process or exported by
-     * IAllocator::exportHandle is unknown to the mapper. There is also no
-     * guarantee that the buffer's backing store will stay alive. This
-     * function must be called at least once in both cases to intrdouce the
-     * buffer handle to the mapper and to secure the backing store. It may
-     * also be called more than once to increase the reference count if two
-     * components in the same process want to interact with the buffer
-     * independently.
+     * Since the buffer descriptor fully describes a buffer, any device
+     * dependent or device independent checks must be performed here whenever
+     * possible. Specifically, when layered buffers are not supported, this
+     * function must return UNSUPPORTED if layerCount is great than 1.
      *
-     * @param bufferHandle is the buffer to which a reference must be added.
+     * @param descriptorInfo specifies the attributes of the descriptor.
      * @return error is NONE upon success. Otherwise,
-     *                  BAD_BUFFER when the buffer handle is invalid
-     *                  NO_RESOURCES when it is not possible to add a
-     *                               reference to this buffer at this time
+     *                  BAD_VALUE when any of the specified attributes is
+     *                            invalid or conflicting.
+     *                  NO_RESOURCES when the creation cannot be fullfilled at
+     *                               this time.
+     *                  UNSUPPORTED when any of the specified attributes is
+     *                              not supported.
+     * @return descriptor is the newly created buffer descriptor.
      */
     @entry
     @callflow(next="*")
-    retain(handle bufferHandle) generates (Error error);
+    createDescriptor(BufferDescriptorInfo descriptorInfo)
+          generates (Error error,
+                     BufferDescriptor descriptor);
 
     /**
-     * Removes a reference from the given buffer buffer.
+     * Imports a raw buffer handle to create an imported buffer handle for use
+     * with the rest of the mapper or with other in-process libraries.
      *
-     * If no references remain, the buffer handle must be freed with
-     * native_handle_close/native_handle_delete by the mapper. When the last
-     * buffer handle referring to a particular backing store is freed, that
-     * backing store must also be freed.
+     * A buffer handle is considered raw when it is cloned or when it is
+     * received from another HAL or another process. A raw buffer handle must
+     * not be used to access the underlying graphics buffer. It must be
+     * imported to create an imported handle first.
      *
-     * @param bufferHandle is the buffer from which a reference must be
-     *        removed.
+     * This function must at least validate the raw handle before creating the
+     * imported handle. It must also support importing the same raw handle
+     * multiple times to create multiple imported handles. The imported handle
+     * must be considered valid everywhere in the process, including in
+     * another instance of the mapper.
+     *
+     * @param rawHandle is the raw buffer handle to import.
      * @return error is NONE upon success. Otherwise,
-     *                  BAD_BUFFER when the buffer handle is invalid.
+     *                  BAD_BUFFER when the raw handle is invalid.
+     *                  NO_RESOURCES when the raw handle cannot be imported at
+     *                               this time.
+     * @return buffer is the imported buffer handle and has the type
+     *         buffer_handle_t.
+     */
+    @entry
+    @callflow(next="*")
+    importBuffer(handle rawHandle) generates (Error error, pointer buffer);
+
+    /**
+     * Frees a buffer handle. Buffer handles returned by importBuffer must be
+     * freed with this function when no longer needed.
+     *
+     * This function must free up all resources allocated by importBuffer for
+     * the imported handle. For example, if the imported handle was created
+     * with native_handle_create, this function must call native_handle_close
+     * and native_handle_delete.
+     *
+     * @return error is NONE upon success. Otherwise,
+     *                  BAD_BUFFER when the buffer is invalid.
      */
     @exit
-    release(handle bufferHandle) generates (Error error);
-
-    /**
-     * Gets the width and height of the buffer in pixels.
-     *
-     * See IAllocator::BufferDescriptorInfo for more information.
-     *
-     * @param bufferHandle is the buffer from which to get the dimensions.
-     * @return error is NONE upon success. Otherwise,
-     *                  BAD_BUFFER when the buffer handle is invalid.
-     * @return width is the width of the buffer in pixels.
-     * @return height is the height of the buffer in pixels.
-     */
     @callflow(next="*")
-    getDimensions(handle bufferHandle)
-       generates (Error error,
-                  uint32_t width,
-                  uint32_t height);
-
-    /**
-     * Gets the format of the buffer.
-     *
-     * See IAllocator::BufferDescriptorInfo for more information.
-     *
-     * @param bufferHandle is the buffer from which to get format.
-     * @return error is NONE upon success. Otherwise,
-     *                  BAD_BUFFER when the buffer handle is invalid.
-     * @return format is the format of the buffer.
-     */
-    @callflow(next="*")
-    getFormat(handle bufferHandle)
-        generates (Error error,
-                   PixelFormat format);
-
-    /**
-     * Gets the number of layers of the buffer.
-     *
-     * See IAllocator::BufferDescriptorInfo for more information.
-     *
-     * @param bufferHandle is the buffer from which to get format.
-     * @return error is NONE upon success. Otherwise,
-     *                  BAD_BUFFER when the buffer handle is invalid.
-     * @return layerCount is the number of layers of the buffer.
-     */
-    @callflow(next="*")
-    getLayerCount(handle bufferHandle)
-       generates (Error error,
-                  uint32_t layerCount);
-
-    /**
-     * Gets the producer usage flags which were used to allocate this buffer.
-     *
-     * See IAllocator::BufferDescriptorInfo for more information.
-     *
-     * @param bufferHandle is the buffer from which to get the producer usage
-     *        flags.
-     * @return error is NONE upon success. Otherwise,
-     *                  BAD_BUFFER when the buffer handle is invalid.
-     * @return usageMask contains the producer usage flags of the buffer.
-     */
-    @callflow(next="*")
-    getProducerUsageMask(handle bufferHandle)
-              generates (Error error,
-                         uint64_t usageMask);
-
-    /**
-     * Gets the consumer usage flags which were used to allocate this buffer.
-     *
-     * See IAllocator::BufferDescriptorInfo for more information.
-     *
-     * @param bufferHandle is the buffer from which to get the consumer usage
-     *        flags.
-     * @return error is NONE upon success. Otherwise,
-     *                  BAD_BUFFER when the buffer handle is invalid.
-     * @return usageMask contains the consumer usage flags of the buffer.
-     */
-    @callflow(next="*")
-    getConsumerUsageMask(handle bufferHandle)
-              generates (Error error,
-                         uint64_t usageMask);
-
-    /**
-     * Gets a value that uniquely identifies the backing store of the given
-     * buffer.
-     *
-     * Buffers which share a backing store should return the same value from
-     * this function. If the buffer is present in more than one process, the
-     * backing store value for that buffer is not required to be the same in
-     * every process.
-     *
-     * @param device is the mapper device.
-     * @param bufferHandle is the buffer from which to get the backing store
-     *        identifier.
-     * @return error is NONE upon success. Otherwise,
-     *                  BAD_BUFFER when the buffer handle is invalid.
-     * @return store is the backing store identifier for this buffer.
-     */
-    @callflow(next="*")
-    getBackingStore(handle bufferHandle)
-         generates (Error error,
-                    BackingStore store);
-
-    /**
-     * Gets the stride of the buffer in pixels.
-     *
-     * The stride is the offset in pixel-sized elements between the same
-     * column in two adjacent rows of pixels. This may not be equal to the
-     * width of the buffer.
-     *
-     * @param device is the mapper device.
-     * @param bufferHandle is the buffer from which to get the stride.
-     * @return error is NONE upon success. Otherwise,
-     *                  BAD_BUFFER when the buffer handle is invalid.
-     *                  UNDEFINED when the notion of a stride is not
-     *                            meaningful for the buffer format.
-     * @return store is the stride in pixels.
-     */
-    @callflow(next="*")
-    getStride(handle bufferHandle)
-        generates (Error error,
-                   uint32_t stride);
+    freeBuffer(pointer buffer) generates (Error error);
 
     /**
      * Locks the given buffer for the specified CPU usage.
      *
-     * Exactly one of producerUsageMask and consumerUsageMask must be 0. The
-     * usage which is not 0 must be one of the *Usage::CPU* values, as
-     * applicable. Locking a buffer for a non-CPU usage is not supported.
-     *
      * Locking the same buffer simultaneously from multiple threads is
      * permitted, but if any of the threads attempt to lock the buffer for
      * writing, the behavior is undefined, except that it must not cause
@@ -209,39 +144,27 @@
      * address will represent the top-left corner of the entire buffer, even
      * if accessRegion does not begin at the top-left corner.
      *
-     * acquireFence is a file descriptor referring to a acquire sync fence
-     * object, which will be signaled when it is safe for the device to access
-     * the contents of the buffer (prior to locking). If it is already safe to
-     * access the buffer contents, -1 may be passed instead.
-     *
-     * @param bufferHandle is the buffer to lock.
-     * @param producerUsageMask contains the producer usage flags to request;
-     *        either this or consumerUsagemask must be 0, and the other must
-     *        be a CPU usage.
-     * @param consumerUsageMask contains the consumer usage flags to request;
-     *        either this or producerUsageMask must be 0, and the other must
-     *        be a CPU usage.
+     * @param buffer is the buffer to lock.
+     * @param cpuUsage specifies one or more CPU usage flags to request.
      * @param accessRegion is the portion of the buffer that the client
      *        intends to access.
-     * @param acquireFence is a sync fence file descriptor as described above.
+     * @param acquireFence, when non-empty, is a handle containing a file
+     *        descriptor referring to a sync fence object, which will be
+     *        signaled when it is safe for the mapper to lock the buffer. If
+     *        it is already safe to lock, acquireFence is empty.
      * @return error is NONE upon success. Otherwise,
-     *                  BAD_BUFFER when the buffer handle is invalid.
-     *                  BAD_VALUE when neither or both of producerUsageMask
-     *                            and consumerUsageMask were 0, or the usage
-     *                            which was not 0 was not a CPU usage.
+     *                  BAD_BUFFER when the buffer is invalid or is
+     *                             incompatible with this function.
+     *                  BAD_VALUE when cpuUsage is 0, contains non-CPU usage
+     *                            flags, or is incompatible with the buffer.
      *                  NO_RESOURCES when the buffer cannot be locked at this
      *                               time, but locking may succeed at a future
      *                               time.
-     *                  UNSUPPORTED when the buffer cannot be locked with the
-     *                              given usage, and any future attempts at
-     *                              locking will also fail.
-     * @return data will be filled with a CPU-accessible pointer to the buffer
-     *         data.
+     * @return data is a CPU-accessible pointer to the buffer data.
      */
     @callflow(next="unlock")
-    lock(handle bufferHandle,
-         uint64_t producerUsageMask,
-         uint64_t consumerUsageMask,
+    lock(pointer buffer,
+         bitfield<BufferUsage> cpuUsage,
          Rect accessRegion,
          handle acquireFence)
         generates (Error error,
@@ -249,7 +172,7 @@
 
     /**
      * This is largely the same as lock(), except that instead of returning a
-     * pointer directly to the buffer data, it returns an FlexLayout struct
+     * pointer directly to the buffer data, it returns an YCbCrLayout struct
      * describing how to access the data planes.
      *
      * This function must work on buffers with PixelFormat::YCbCr_*_888 if
@@ -257,67 +180,46 @@
      * multimedia codecs when they are configured with a
      * flexible-YUV-compatible color format.
      *
-     * This function may also be called on buffers of other formats, including
-     * non-YUV formats, but if the buffer format is not compatible with a
-     * flexible representation, it may return UNSUPPORTED.
-     *
-     * @param device is the mapper device.
-     * @param bufferHandle is the buffer to lock.
-     * @param producerUsageMask contains the producer usage flags to request;
-     *        either this or consumerUsagemask must be 0, and the other must
-     *        be a CPU usage.
-     * @param consumerUsageMask contains the consumer usage flags to request;
-     *        either this or producerUsageMask must be 0, and the other must
-     *        be a CPU usage.
+     * @param buffer is the buffer to lock.
+     * @param cpuUsage specifies one or more CPU usage flags to request.
      * @param accessRegion is the portion of the buffer that the client
      *        intends to access.
-     * @param acquireFence is a sync fence file descriptor as described in
-     *        lock().
+     * @param acquireFence, when non-empty, is a handle containing a file
+     *        descriptor referring to a sync fence object, which will be
+     *        signaled when it is safe for the mapper to lock the buffer. If
+     *        it is already safe to lock, acquireFence is empty.
      * @return error is NONE upon success. Otherwise,
-     *                  BAD_BUFFER when the buffer handle is invalid.
-     *                  BAD_VALUE when neither or both of producerUsageMask
-     *                            and consumerUsageMask were 0, or the usage
-     *                            which was not 0 was not a CPU usage.
+     *                  BAD_BUFFER when the buffer is invalid or is
+     *                             incompatible with this function.
+     *                  BAD_VALUE when cpuUsage is 0, contains non-CPU usage
+     *                            flags, or is incompatible with the buffer.
      *                  NO_RESOURCES when the buffer cannot be locked at this
      *                               time, but locking may succeed at a future
      *                               time.
-     *                  UNSUPPORTED when the buffer cannot be locked with the
-     *                              given usage, and any future attempts at
-     *                              locking will also fail.
-     * @return flexLayout will be filled with the description of the planes in
-     *         the buffer.
+     * @return layout is the data layout of the buffer.
      */
     @callflow(next="unlock")
-    lockFlex(handle bufferHandle,
-             uint64_t producerUsageMask,
-             uint64_t consumerUsageMask,
-             Rect accessRegion,
-             handle acquireFence)
+    lockYCbCr(pointer buffer,
+              bitfield<BufferUsage> cpuUsage,
+              Rect accessRegion,
+              handle acquireFence)
         generates (Error error,
-                   FlexLayout layout);
+                   YCbCrLayout layout);
 
     /**
-     * This function indicates to the device that the client will be done with
-     * the buffer when releaseFence signals.
+     * Unlocks a buffer to indicate all CPU accesses to the buffer have
+     * completed.
      *
-     * releaseFence will be filled with a file descriptor referring to a
-     * release sync fence object, which will be signaled when it is safe to
-     * access the contents of the buffer (after the buffer has been unlocked).
-     * If it is already safe to access the buffer contents, then -1 may be
-     * returned instead.
-     *
-     * This function is used to unlock both buffers locked by lock() and those
-     * locked by lockFlex().
-     *
-     * @param device is the mapper device.
-     * @param bufferHandle is the buffer to unlock.
+     * @param buffer is the buffer to unlock.
      * @return error is NONE upon success. Otherwise,
-     *                  BAD_BUFFER when the buffer handle is invalid.
-     * @return releaseFence is a sync fence file descriptor as described
-     *         above.
+     *                  BAD_BUFFER when the buffer is invalid or not locked.
+     * @return releaseFence, when non-empty, is a handle containing a file
+     *         descriptor referring to a sync fence object. The sync fence
+     *         object will be signaled when the mapper has completed any
+     *         pending work.
      */
     @callflow(next="*")
-    unlock(handle bufferHandle)
+    unlock(pointer buffer)
         generates (Error error,
                    handle releaseFence);
 };
diff --git a/graphics/mapper/2.0/default/Android.bp b/graphics/mapper/2.0/default/Android.bp
index 1dc5aea..090c61f 100644
--- a/graphics/mapper/2.0/default/Android.bp
+++ b/graphics/mapper/2.0/default/Android.bp
@@ -18,10 +18,9 @@
     defaults: ["hidl_defaults"],
     proprietary: true,
     relative_install_path: "hw",
-    srcs: ["GrallocMapper.cpp"],
+    srcs: ["GrallocMapper.cpp", "Gralloc0Mapper.cpp", "Gralloc1Mapper.cpp"],
     cppflags: ["-Wall", "-Wextra"],
     shared_libs: [
-        "android.hardware.graphics.allocator@2.0",
         "android.hardware.graphics.mapper@2.0",
         "libbase",
         "libcutils",
@@ -29,6 +28,12 @@
         "libhidlbase",
         "libhidltransport",
         "liblog",
+        "libsync",
         "libutils",
     ],
 }
+
+cc_library_static {
+    name: "libgrallocmapperincludes",
+    export_include_dirs: ["."],
+}
diff --git a/graphics/mapper/2.0/default/Gralloc0Mapper.cpp b/graphics/mapper/2.0/default/Gralloc0Mapper.cpp
new file mode 100644
index 0000000..28f5016
--- /dev/null
+++ b/graphics/mapper/2.0/default/Gralloc0Mapper.cpp
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Gralloc0Mapper"
+
+#include "Gralloc0Mapper.h"
+
+#include <log/log.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace mapper {
+namespace V2_0 {
+namespace implementation {
+
+Gralloc0Mapper::Gralloc0Mapper(const hw_module_t* module)
+    : mModule(reinterpret_cast<const gralloc_module_t*>(module)),
+      mMinor(module->module_api_version & 0xff) {
+    mCapabilities.highUsageBits = false;
+    mCapabilities.layeredBuffers = false;
+    mCapabilities.unregisterImplyDelete = false;
+}
+
+Error Gralloc0Mapper::registerBuffer(buffer_handle_t bufferHandle) {
+    int result = mModule->registerBuffer(mModule, bufferHandle);
+    return result ? Error::BAD_BUFFER : Error::NONE;
+}
+
+void Gralloc0Mapper::unregisterBuffer(buffer_handle_t bufferHandle) {
+    mModule->unregisterBuffer(mModule, bufferHandle);
+}
+
+Error Gralloc0Mapper::lockBuffer(buffer_handle_t bufferHandle,
+                                 uint64_t cpuUsage,
+                                 const IMapper::Rect& accessRegion, int fenceFd,
+                                 void** outData) {
+    int result;
+    void* data = nullptr;
+    if (mMinor >= 3 && mModule->lockAsync) {
+        // Dup fenceFd as it is going to be owned by gralloc.  Note that it is
+        // gralloc's responsibility to close it, even on locking errors.
+        if (fenceFd >= 0) {
+            fenceFd = dup(fenceFd);
+            if (fenceFd < 0) {
+                return Error::NO_RESOURCES;
+            }
+        }
+
+        result = mModule->lockAsync(mModule, bufferHandle, cpuUsage,
+                                    accessRegion.left, accessRegion.top,
+                                    accessRegion.width, accessRegion.height,
+                                    &data, fenceFd);
+    } else {
+        waitFenceFd(fenceFd, "Gralloc0Mapper::lock");
+
+        result = mModule->lock(mModule, bufferHandle, cpuUsage,
+                               accessRegion.left, accessRegion.top,
+                               accessRegion.width, accessRegion.height, &data);
+    }
+
+    if (result) {
+        return Error::BAD_VALUE;
+    } else {
+        *outData = data;
+        return Error::NONE;
+    }
+}
+
+Error Gralloc0Mapper::lockBuffer(buffer_handle_t bufferHandle,
+                                 uint64_t cpuUsage,
+                                 const IMapper::Rect& accessRegion, int fenceFd,
+                                 YCbCrLayout* outLayout) {
+    int result;
+    android_ycbcr ycbcr = {};
+    if (mMinor >= 3 && mModule->lockAsync_ycbcr) {
+        // Dup fenceFd as it is going to be owned by gralloc.  Note that it is
+        // gralloc's responsibility to close it, even on locking errors.
+        if (fenceFd >= 0) {
+            fenceFd = dup(fenceFd);
+            if (fenceFd < 0) {
+                return Error::NO_RESOURCES;
+            }
+        }
+
+        result = mModule->lockAsync_ycbcr(mModule, bufferHandle, cpuUsage,
+                                          accessRegion.left, accessRegion.top,
+                                          accessRegion.width,
+                                          accessRegion.height, &ycbcr, fenceFd);
+    } else {
+        waitFenceFd(fenceFd, "Gralloc0Mapper::lockYCbCr");
+
+        if (mModule->lock_ycbcr) {
+            result = mModule->lock_ycbcr(mModule, bufferHandle, cpuUsage,
+                                         accessRegion.left, accessRegion.top,
+                                         accessRegion.width,
+                                         accessRegion.height, &ycbcr);
+        } else {
+            result = -EINVAL;
+        }
+    }
+
+    if (result) {
+        return Error::BAD_VALUE;
+    } else {
+        outLayout->y = ycbcr.y;
+        outLayout->cb = ycbcr.cb;
+        outLayout->cr = ycbcr.cr;
+        outLayout->yStride = ycbcr.ystride;
+        outLayout->cStride = ycbcr.cstride;
+        outLayout->chromaStep = ycbcr.chroma_step;
+        return Error::NONE;
+    }
+}
+
+Error Gralloc0Mapper::unlockBuffer(buffer_handle_t bufferHandle,
+                                   int* outFenceFd) {
+    int result;
+    int fenceFd = -1;
+    if (mMinor >= 3 && mModule->unlockAsync) {
+        result = mModule->unlockAsync(mModule, bufferHandle, &fenceFd);
+    } else {
+        result = mModule->unlock(mModule, bufferHandle);
+    }
+
+    if (result) {
+        // we always own the fenceFd even when unlock failed
+        if (fenceFd >= 0) {
+            close(fenceFd);
+        }
+
+        return Error::BAD_VALUE;
+    } else {
+        *outFenceFd = fenceFd;
+        return Error::NONE;
+    }
+}
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace mapper
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
diff --git a/graphics/mapper/2.0/default/Gralloc0Mapper.h b/graphics/mapper/2.0/default/Gralloc0Mapper.h
new file mode 100644
index 0000000..e792a69
--- /dev/null
+++ b/graphics/mapper/2.0/default/Gralloc0Mapper.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOC0MAPPER_H
+#define ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOC0MAPPER_H
+
+#include "GrallocMapper.h"
+
+#include <hardware/gralloc.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace mapper {
+namespace V2_0 {
+namespace implementation {
+
+class Gralloc0Mapper : public GrallocMapper {
+   public:
+    Gralloc0Mapper(const hw_module_t* module);
+
+   private:
+    Error registerBuffer(buffer_handle_t bufferHandle) override;
+    void unregisterBuffer(buffer_handle_t bufferHandle) override;
+    Error lockBuffer(buffer_handle_t bufferHandle, uint64_t cpuUsage,
+                     const IMapper::Rect& accessRegion, int fenceFd,
+                     void** outData) override;
+    Error lockBuffer(buffer_handle_t bufferHandle, uint64_t cpuUsage,
+                     const IMapper::Rect& accessRegion, int fenceFd,
+                     YCbCrLayout* outLayout) override;
+    Error unlockBuffer(buffer_handle_t bufferHandle, int* outFenceFd) override;
+
+    const gralloc_module_t* mModule;
+    uint8_t mMinor;
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace mapper
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOC0MAPPER_H
diff --git a/graphics/mapper/2.0/default/Gralloc1Mapper.cpp b/graphics/mapper/2.0/default/Gralloc1Mapper.cpp
new file mode 100644
index 0000000..c1e5adc
--- /dev/null
+++ b/graphics/mapper/2.0/default/Gralloc1Mapper.cpp
@@ -0,0 +1,273 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Gralloc1Mapper"
+
+#include "Gralloc1Mapper.h"
+
+#include <vector>
+
+#include <log/log.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace mapper {
+namespace V2_0 {
+namespace implementation {
+
+using android::hardware::graphics::common::V1_0::BufferUsage;
+
+Gralloc1Mapper::Gralloc1Mapper(const hw_module_t* module)
+    : mDevice(nullptr), mDispatch() {
+    int result = gralloc1_open(module, &mDevice);
+    if (result) {
+        LOG_ALWAYS_FATAL("failed to open gralloc1 device: %s",
+                         strerror(-result));
+    }
+
+    initCapabilities();
+    initDispatch();
+}
+
+Gralloc1Mapper::~Gralloc1Mapper() {
+    gralloc1_close(mDevice);
+}
+
+void Gralloc1Mapper::initCapabilities() {
+    mCapabilities.highUsageBits = true;
+    mCapabilities.layeredBuffers = false;
+    mCapabilities.unregisterImplyDelete = false;
+
+    uint32_t count = 0;
+    mDevice->getCapabilities(mDevice, &count, nullptr);
+
+    std::vector<int32_t> capabilities(count);
+    mDevice->getCapabilities(mDevice, &count, capabilities.data());
+    capabilities.resize(count);
+
+    for (auto capability : capabilities) {
+        switch (capability) {
+            case GRALLOC1_CAPABILITY_LAYERED_BUFFERS:
+                mCapabilities.layeredBuffers = true;
+                break;
+            case GRALLOC1_CAPABILITY_RELEASE_IMPLY_DELETE:
+                mCapabilities.unregisterImplyDelete = true;
+                break;
+        }
+    }
+}
+
+template <typename T>
+void Gralloc1Mapper::initDispatch(gralloc1_function_descriptor_t desc,
+                                  T* outPfn) {
+    auto pfn = mDevice->getFunction(mDevice, desc);
+    if (!pfn) {
+        LOG_ALWAYS_FATAL("failed to get gralloc1 function %d", desc);
+    }
+
+    *outPfn = reinterpret_cast<T>(pfn);
+}
+
+void Gralloc1Mapper::initDispatch() {
+    initDispatch(GRALLOC1_FUNCTION_RETAIN, &mDispatch.retain);
+    initDispatch(GRALLOC1_FUNCTION_RELEASE, &mDispatch.release);
+    initDispatch(GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES,
+                 &mDispatch.getNumFlexPlanes);
+    initDispatch(GRALLOC1_FUNCTION_LOCK, &mDispatch.lock);
+    initDispatch(GRALLOC1_FUNCTION_LOCK_FLEX, &mDispatch.lockFlex);
+    initDispatch(GRALLOC1_FUNCTION_UNLOCK, &mDispatch.unlock);
+}
+
+Error Gralloc1Mapper::toError(int32_t error) {
+    switch (error) {
+        case GRALLOC1_ERROR_NONE:
+            return Error::NONE;
+        case GRALLOC1_ERROR_BAD_DESCRIPTOR:
+            return Error::BAD_DESCRIPTOR;
+        case GRALLOC1_ERROR_BAD_HANDLE:
+            return Error::BAD_BUFFER;
+        case GRALLOC1_ERROR_BAD_VALUE:
+            return Error::BAD_VALUE;
+        case GRALLOC1_ERROR_NOT_SHARED:
+            return Error::NONE;  // this is fine
+        case GRALLOC1_ERROR_NO_RESOURCES:
+            return Error::NO_RESOURCES;
+        case GRALLOC1_ERROR_UNDEFINED:
+        case GRALLOC1_ERROR_UNSUPPORTED:
+        default:
+            return Error::UNSUPPORTED;
+    }
+}
+
+bool Gralloc1Mapper::toYCbCrLayout(const android_flex_layout& flex,
+                                   YCbCrLayout* outLayout) {
+    // must be YCbCr
+    if (flex.format != FLEX_FORMAT_YCbCr || flex.num_planes < 3) {
+        return false;
+    }
+
+    for (int i = 0; i < 3; i++) {
+        const auto& plane = flex.planes[i];
+        // must have 8-bit depth
+        if (plane.bits_per_component != 8 || plane.bits_used != 8) {
+            return false;
+        }
+
+        if (plane.component == FLEX_COMPONENT_Y) {
+            // Y must not be interleaved
+            if (plane.h_increment != 1) {
+                return false;
+            }
+        } else {
+            // Cb and Cr can be interleaved
+            if (plane.h_increment != 1 && plane.h_increment != 2) {
+                return false;
+            }
+        }
+
+        if (!plane.v_increment) {
+            return false;
+        }
+    }
+
+    if (flex.planes[0].component != FLEX_COMPONENT_Y ||
+        flex.planes[1].component != FLEX_COMPONENT_Cb ||
+        flex.planes[2].component != FLEX_COMPONENT_Cr) {
+        return false;
+    }
+
+    const auto& y = flex.planes[0];
+    const auto& cb = flex.planes[1];
+    const auto& cr = flex.planes[2];
+
+    if (cb.h_increment != cr.h_increment || cb.v_increment != cr.v_increment) {
+        return false;
+    }
+
+    outLayout->y = y.top_left;
+    outLayout->cb = cb.top_left;
+    outLayout->cr = cr.top_left;
+    outLayout->yStride = y.v_increment;
+    outLayout->cStride = cb.v_increment;
+    outLayout->chromaStep = cb.h_increment;
+
+    return true;
+}
+
+gralloc1_rect_t Gralloc1Mapper::asGralloc1Rect(const IMapper::Rect& rect) {
+    return gralloc1_rect_t{rect.left, rect.top, rect.width, rect.height};
+}
+
+Error Gralloc1Mapper::registerBuffer(buffer_handle_t bufferHandle) {
+    return toError(mDispatch.retain(mDevice, bufferHandle));
+}
+
+void Gralloc1Mapper::unregisterBuffer(buffer_handle_t bufferHandle) {
+    mDispatch.release(mDevice, bufferHandle);
+}
+
+Error Gralloc1Mapper::lockBuffer(buffer_handle_t bufferHandle,
+                                 uint64_t cpuUsage,
+                                 const IMapper::Rect& accessRegion, int fenceFd,
+                                 void** outData) {
+    // Dup fenceFd as it is going to be owned by gralloc.  Note that it is
+    // gralloc's responsibility to close it, even on locking errors.
+    if (fenceFd >= 0) {
+        fenceFd = dup(fenceFd);
+        if (fenceFd < 0) {
+            return Error::NO_RESOURCES;
+        }
+    }
+
+    const uint64_t consumerUsage =
+        cpuUsage & ~static_cast<uint64_t>(BufferUsage::CPU_WRITE_MASK);
+    const auto accessRect = asGralloc1Rect(accessRegion);
+    void* data = nullptr;
+    int32_t error = mDispatch.lock(mDevice, bufferHandle, cpuUsage,
+                                   consumerUsage, &accessRect, &data, fenceFd);
+
+    if (error == GRALLOC1_ERROR_NONE) {
+        *outData = data;
+    }
+
+    return toError(error);
+}
+
+Error Gralloc1Mapper::lockBuffer(buffer_handle_t bufferHandle,
+                                 uint64_t cpuUsage,
+                                 const IMapper::Rect& accessRegion, int fenceFd,
+                                 YCbCrLayout* outLayout) {
+    // prepare flex layout
+    android_flex_layout flex = {};
+    int32_t error =
+        mDispatch.getNumFlexPlanes(mDevice, bufferHandle, &flex.num_planes);
+    if (error != GRALLOC1_ERROR_NONE) {
+        return toError(error);
+    }
+    std::vector<android_flex_plane_t> flexPlanes(flex.num_planes);
+    flex.planes = flexPlanes.data();
+
+    // Dup fenceFd as it is going to be owned by gralloc.  Note that it is
+    // gralloc's responsibility to close it, even on locking errors.
+    if (fenceFd >= 0) {
+        fenceFd = dup(fenceFd);
+        if (fenceFd < 0) {
+            return Error::NO_RESOURCES;
+        }
+    }
+
+    const uint64_t consumerUsage =
+        cpuUsage & ~static_cast<uint64_t>(BufferUsage::CPU_WRITE_MASK);
+    const auto accessRect = asGralloc1Rect(accessRegion);
+    error = mDispatch.lockFlex(mDevice, bufferHandle, cpuUsage, consumerUsage,
+                               &accessRect, &flex, fenceFd);
+    if (error == GRALLOC1_ERROR_NONE && !toYCbCrLayout(flex, outLayout)) {
+        ALOGD("unable to convert android_flex_layout to YCbCrLayout");
+
+        // undo the lock
+        fenceFd = -1;
+        mDispatch.unlock(mDevice, bufferHandle, &fenceFd);
+        if (fenceFd >= 0) {
+            close(fenceFd);
+        }
+
+        error = GRALLOC1_ERROR_BAD_HANDLE;
+    }
+
+    return toError(error);
+}
+
+Error Gralloc1Mapper::unlockBuffer(buffer_handle_t bufferHandle,
+                                   int* outFenceFd) {
+    int fenceFd = -1;
+    int32_t error = mDispatch.unlock(mDevice, bufferHandle, &fenceFd);
+
+    if (error == GRALLOC1_ERROR_NONE) {
+        *outFenceFd = fenceFd;
+    } else if (fenceFd >= 0) {
+        // we always own the fenceFd even when unlock failed
+        close(fenceFd);
+    }
+
+    return toError(error);
+}
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace mapper
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
diff --git a/graphics/mapper/2.0/default/Gralloc1Mapper.h b/graphics/mapper/2.0/default/Gralloc1Mapper.h
new file mode 100644
index 0000000..452afdf
--- /dev/null
+++ b/graphics/mapper/2.0/default/Gralloc1Mapper.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ * * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOC1MAPPER_H
+#define ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOC1MAPPER_H
+
+#include "GrallocMapper.h"
+
+#include <hardware/gralloc1.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace mapper {
+namespace V2_0 {
+namespace implementation {
+
+class Gralloc1Mapper : public GrallocMapper {
+   public:
+    Gralloc1Mapper(const hw_module_t* module);
+    ~Gralloc1Mapper();
+
+   private:
+    void initCapabilities();
+
+    template <typename T>
+    void initDispatch(gralloc1_function_descriptor_t desc, T* outPfn);
+    void initDispatch();
+
+    static Error toError(int32_t error);
+    static bool toYCbCrLayout(const android_flex_layout& flex,
+                              YCbCrLayout* outLayout);
+    static gralloc1_rect_t asGralloc1Rect(const IMapper::Rect& rect);
+
+    Error registerBuffer(buffer_handle_t bufferHandle) override;
+    void unregisterBuffer(buffer_handle_t bufferHandle) override;
+    Error lockBuffer(buffer_handle_t bufferHandle, uint64_t cpuUsage,
+                     const IMapper::Rect& accessRegion, int fenceFd,
+                     void** outData) override;
+    Error lockBuffer(buffer_handle_t bufferHandle, uint64_t cpuUsage,
+                     const IMapper::Rect& accessRegion, int fenceFd,
+                     YCbCrLayout* outLayout) override;
+    Error unlockBuffer(buffer_handle_t bufferHandle, int* outFenceFd) override;
+
+    gralloc1_device_t* mDevice;
+
+    struct {
+        GRALLOC1_PFN_RETAIN retain;
+        GRALLOC1_PFN_RELEASE release;
+        GRALLOC1_PFN_GET_NUM_FLEX_PLANES getNumFlexPlanes;
+        GRALLOC1_PFN_LOCK lock;
+        GRALLOC1_PFN_LOCK_FLEX lockFlex;
+        GRALLOC1_PFN_UNLOCK unlock;
+    } mDispatch;
+};
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace mapper
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOC1MAPPER_H
diff --git a/graphics/mapper/2.0/default/GrallocBufferDescriptor.h b/graphics/mapper/2.0/default/GrallocBufferDescriptor.h
new file mode 100644
index 0000000..9b5ab04
--- /dev/null
+++ b/graphics/mapper/2.0/default/GrallocBufferDescriptor.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOCBUFFERDESCRIPTOR_H
+#define ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOCBUFFERDESCRIPTOR_H
+
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+
+namespace android {
+namespace hardware {
+namespace graphics {
+namespace mapper {
+namespace V2_0 {
+namespace implementation {
+
+using android::hardware::graphics::common::V1_0::PixelFormat;
+
+/**
+ * BufferDescriptor is created by IMapper and consumed by IAllocator. It is
+ * versioned so that IMapper and IAllocator can be updated independently.
+ */
+constexpr uint32_t grallocBufferDescriptorSize = 7;
+constexpr uint32_t grallocBufferDescriptorMagicVersion = ((0x9487 << 16) | 0);
+
+inline BufferDescriptor grallocEncodeBufferDescriptor(
+    const IMapper::BufferDescriptorInfo& descriptorInfo) {
+    BufferDescriptor descriptor;
+    descriptor.resize(grallocBufferDescriptorSize);
+    descriptor[0] = grallocBufferDescriptorMagicVersion;
+    descriptor[1] = descriptorInfo.width;
+    descriptor[2] = descriptorInfo.height;
+    descriptor[3] = descriptorInfo.layerCount;
+    descriptor[4] = static_cast<uint32_t>(descriptorInfo.format);
+    descriptor[5] = static_cast<uint32_t>(descriptorInfo.usage);
+    descriptor[6] = static_cast<uint32_t>(descriptorInfo.usage >> 32);
+
+    return descriptor;
+}
+
+inline bool grallocDecodeBufferDescriptor(
+    const BufferDescriptor& descriptor,
+    IMapper::BufferDescriptorInfo* outDescriptorInfo) {
+    if (descriptor.size() != grallocBufferDescriptorSize ||
+        descriptor[0] != grallocBufferDescriptorMagicVersion) {
+        return false;
+    }
+
+    *outDescriptorInfo = IMapper::BufferDescriptorInfo{
+        descriptor[1],
+        descriptor[2],
+        descriptor[3],
+        static_cast<PixelFormat>(descriptor[4]),
+        (static_cast<uint64_t>(descriptor[6]) << 32) | descriptor[5],
+    };
+
+    return true;
+}
+
+}  // namespace implementation
+}  // namespace V2_0
+}  // namespace mapper
+}  // namespace graphics
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOCBUFFERDESCRIPTOR_H
diff --git a/graphics/mapper/2.0/default/GrallocMapper.cpp b/graphics/mapper/2.0/default/GrallocMapper.cpp
index 526aca2..339317a 100644
--- a/graphics/mapper/2.0/default/GrallocMapper.cpp
+++ b/graphics/mapper/2.0/default/GrallocMapper.cpp
@@ -17,14 +17,14 @@
 
 #include "GrallocMapper.h"
 
-#include <mutex>
-#include <vector>
-#include <unordered_map>
+#include "Gralloc0Mapper.h"
+#include "Gralloc1Mapper.h"
+#include "GrallocBufferDescriptor.h"
 
-#include <string.h>
+#include <inttypes.h>
 
-#include <hardware/gralloc1.h>
 #include <log/log.h>
+#include <sync/sync.h>
 
 namespace android {
 namespace hardware {
@@ -33,374 +33,251 @@
 namespace V2_0 {
 namespace implementation {
 
-namespace {
-
-using android::hardware::graphics::allocator::V2_0::Error;
+using android::hardware::graphics::common::V1_0::BufferUsage;
 using android::hardware::graphics::common::V1_0::PixelFormat;
 
-class GrallocMapperHal : public IMapper {
-public:
-    GrallocMapperHal(const hw_module_t* module);
-    ~GrallocMapperHal();
+std::mutex GrallocMapper::mMutex;
+std::unordered_set<buffer_handle_t> GrallocMapper::mRegisteredHandles;
 
-    // IMapper interface
-    Return<Error> retain(const hidl_handle& bufferHandle) override;
-    Return<Error> release(const hidl_handle& bufferHandle) override;
-    Return<void> getDimensions(const hidl_handle& bufferHandle,
-            getDimensions_cb hidl_cb) override;
-    Return<void> getFormat(const hidl_handle& bufferHandle,
-            getFormat_cb hidl_cb) override;
-    Return<void> getLayerCount(const hidl_handle& bufferHandle,
-            getLayerCount_cb hidl_cb) override;
-    Return<void> getProducerUsageMask(const hidl_handle& bufferHandle,
-            getProducerUsageMask_cb hidl_cb) override;
-    Return<void> getConsumerUsageMask(const hidl_handle& bufferHandle,
-            getConsumerUsageMask_cb hidl_cb) override;
-    Return<void> getBackingStore(const hidl_handle& bufferHandle,
-            getBackingStore_cb hidl_cb) override;
-    Return<void> getStride(const hidl_handle& bufferHandle,
-            getStride_cb hidl_cb) override;
-    Return<void> lock(const hidl_handle& bufferHandle,
-            uint64_t producerUsageMask, uint64_t consumerUsageMask,
-            const IMapper::Rect& accessRegion, const hidl_handle& acquireFence,
-            lock_cb hidl_cb) override;
-    Return<void> lockFlex(const hidl_handle& bufferHandle,
-            uint64_t producerUsageMask, uint64_t consumerUsageMask,
-            const IMapper::Rect& accessRegion, const hidl_handle& acquireFence,
-            lockFlex_cb hidl_cb) override;
-    Return<void> unlock(const hidl_handle& bufferHandle,
-            unlock_cb hidl_cb) override;
+bool GrallocMapper::validateDescriptorInfo(
+    const BufferDescriptorInfo& descriptorInfo) const {
+    const uint64_t validUsageBits =
+        BufferUsage::CPU_READ_MASK | BufferUsage::CPU_WRITE_MASK |
+        BufferUsage::GPU_TEXTURE | BufferUsage::GPU_RENDER_TARGET |
+        BufferUsage::COMPOSER_OVERLAY | BufferUsage::COMPOSER_CLIENT_TARGET |
+        BufferUsage::PROTECTED | BufferUsage::COMPOSER_CURSOR |
+        BufferUsage::VIDEO_ENCODER | BufferUsage::CAMERA_OUTPUT |
+        BufferUsage::CAMERA_INPUT | BufferUsage::RENDERSCRIPT |
+        BufferUsage::VIDEO_DECODER | BufferUsage::SENSOR_DIRECT_DATA |
+        BufferUsage::GPU_DATA_BUFFER | BufferUsage::VENDOR_MASK |
+        (mCapabilities.highUsageBits ? BufferUsage::VENDOR_MASK_HI
+                                     : static_cast<BufferUsage>(0));
 
-private:
-    void initCapabilities();
-
-    template<typename T>
-    void initDispatch(gralloc1_function_descriptor_t desc, T* outPfn);
-    void initDispatch();
-
-    static gralloc1_rect_t asGralloc1Rect(const IMapper::Rect& rect);
-    static bool dupFence(const hidl_handle& fenceHandle, int* outFd);
-
-    gralloc1_device_t* mDevice;
-
-    struct {
-        bool layeredBuffers;
-    } mCapabilities;
-
-    struct {
-        GRALLOC1_PFN_RETAIN retain;
-        GRALLOC1_PFN_RELEASE release;
-        GRALLOC1_PFN_GET_DIMENSIONS getDimensions;
-        GRALLOC1_PFN_GET_FORMAT getFormat;
-        GRALLOC1_PFN_GET_LAYER_COUNT getLayerCount;
-        GRALLOC1_PFN_GET_PRODUCER_USAGE getProducerUsage;
-        GRALLOC1_PFN_GET_CONSUMER_USAGE getConsumerUsage;
-        GRALLOC1_PFN_GET_BACKING_STORE getBackingStore;
-        GRALLOC1_PFN_GET_STRIDE getStride;
-        GRALLOC1_PFN_GET_NUM_FLEX_PLANES getNumFlexPlanes;
-        GRALLOC1_PFN_LOCK lock;
-        GRALLOC1_PFN_LOCK_FLEX lockFlex;
-        GRALLOC1_PFN_UNLOCK unlock;
-    } mDispatch;
-
-    std::mutex mMutex;
-    std::unordered_map<buffer_handle_t, size_t> mBufferReferenceCounts;
-};
-
-GrallocMapperHal::GrallocMapperHal(const hw_module_t* module)
-    : mDevice(nullptr), mCapabilities(), mDispatch()
-{
-    int status = gralloc1_open(module, &mDevice);
-    if (status) {
-        LOG_ALWAYS_FATAL("failed to open gralloc1 device: %s",
-                strerror(-status));
-    }
-
-    initCapabilities();
-    initDispatch();
-}
-
-GrallocMapperHal::~GrallocMapperHal()
-{
-    gralloc1_close(mDevice);
-}
-
-void GrallocMapperHal::initCapabilities()
-{
-    uint32_t count = 0;
-    mDevice->getCapabilities(mDevice, &count, nullptr);
-
-    std::vector<int32_t> caps(count);
-    mDevice->getCapabilities(mDevice, &count, caps.data());
-    caps.resize(count);
-
-    for (auto cap : caps) {
-        switch (cap) {
-        case GRALLOC1_CAPABILITY_LAYERED_BUFFERS:
-            mCapabilities.layeredBuffers = true;
-            break;
-        default:
-            break;
-        }
-    }
-}
-
-template<typename T>
-void GrallocMapperHal::initDispatch(gralloc1_function_descriptor_t desc,
-        T* outPfn)
-{
-    auto pfn = mDevice->getFunction(mDevice, desc);
-    if (!pfn) {
-        LOG_ALWAYS_FATAL("failed to get gralloc1 function %d", desc);
-    }
-
-    *outPfn = reinterpret_cast<T>(pfn);
-}
-
-void GrallocMapperHal::initDispatch()
-{
-    initDispatch(GRALLOC1_FUNCTION_RETAIN, &mDispatch.retain);
-    initDispatch(GRALLOC1_FUNCTION_RELEASE, &mDispatch.release);
-    initDispatch(GRALLOC1_FUNCTION_GET_DIMENSIONS, &mDispatch.getDimensions);
-    initDispatch(GRALLOC1_FUNCTION_GET_FORMAT, &mDispatch.getFormat);
-    if (mCapabilities.layeredBuffers) {
-        initDispatch(GRALLOC1_FUNCTION_GET_LAYER_COUNT,
-                &mDispatch.getLayerCount);
-    }
-    initDispatch(GRALLOC1_FUNCTION_GET_PRODUCER_USAGE,
-            &mDispatch.getProducerUsage);
-    initDispatch(GRALLOC1_FUNCTION_GET_CONSUMER_USAGE,
-            &mDispatch.getConsumerUsage);
-    initDispatch(GRALLOC1_FUNCTION_GET_BACKING_STORE,
-            &mDispatch.getBackingStore);
-    initDispatch(GRALLOC1_FUNCTION_GET_STRIDE, &mDispatch.getStride);
-    initDispatch(GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES,
-            &mDispatch.getNumFlexPlanes);
-    initDispatch(GRALLOC1_FUNCTION_LOCK, &mDispatch.lock);
-    initDispatch(GRALLOC1_FUNCTION_LOCK_FLEX, &mDispatch.lockFlex);
-    initDispatch(GRALLOC1_FUNCTION_UNLOCK, &mDispatch.unlock);
-}
-
-gralloc1_rect_t GrallocMapperHal::asGralloc1Rect(const IMapper::Rect& rect)
-{
-    return gralloc1_rect_t{rect.left, rect.top, rect.width, rect.height};
-}
-
-bool GrallocMapperHal::dupFence(const hidl_handle& fenceHandle, int* outFd)
-{
-    auto handle = fenceHandle.getNativeHandle();
-    if (!handle || handle->numFds == 0) {
-        *outFd = -1;
-        return true;
-    }
-
-    if (handle->numFds > 1) {
-        ALOGE("invalid fence handle with %d fds", handle->numFds);
+    if (!descriptorInfo.width || !descriptorInfo.height ||
+        !descriptorInfo.layerCount) {
         return false;
     }
 
-    *outFd = dup(handle->data[0]);
-    return (*outFd >= 0);
-}
-
-Return<Error> GrallocMapperHal::retain(const hidl_handle& bufferHandle)
-{
-    int32_t err = mDispatch.retain(mDevice, bufferHandle);
-    if (err == GRALLOC1_ERROR_NONE) {
-        auto nativeHandle = bufferHandle.getNativeHandle();
-        std::lock_guard<std::mutex> lock(mMutex);
-
-        ++mBufferReferenceCounts[nativeHandle];
-    }
-    return static_cast<Error>(err);
-}
-
-Return<Error> GrallocMapperHal::release(const hidl_handle& bufferHandle)
-{
-    int32_t err = mDispatch.release(mDevice, bufferHandle);
-    if (err == GRALLOC1_ERROR_NONE) {
-        auto nativeHandle = bufferHandle.getNativeHandle();
-        std::lock_guard<std::mutex> lock(mMutex);
-
-        auto iter = mBufferReferenceCounts.find(bufferHandle);
-        if (iter == mBufferReferenceCounts.end()) {
-            // this should never happen
-            err = GRALLOC1_ERROR_BAD_HANDLE;
-        } else if (--iter->second == 0) {
-            native_handle_close(nativeHandle);
-            native_handle_delete(const_cast<native_handle_t*>(nativeHandle));
-
-            mBufferReferenceCounts.erase(iter);
-        }
+    if (!mCapabilities.layeredBuffers && descriptorInfo.layerCount > 1) {
+        return false;
     }
 
-    return static_cast<Error>(err);
-}
-
-Return<void> GrallocMapperHal::getDimensions(const hidl_handle& bufferHandle,
-        getDimensions_cb hidl_cb)
-{
-    uint32_t width = 0;
-    uint32_t height = 0;
-    int32_t err = mDispatch.getDimensions(mDevice, bufferHandle,
-            &width, &height);
-
-    hidl_cb(static_cast<Error>(err), width, height);
-    return Void();
-}
-
-Return<void> GrallocMapperHal::getFormat(const hidl_handle& bufferHandle,
-        getFormat_cb hidl_cb)
-{
-    int32_t format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
-    int32_t err = mDispatch.getFormat(mDevice, bufferHandle, &format);
-
-    hidl_cb(static_cast<Error>(err), static_cast<PixelFormat>(format));
-    return Void();
-}
-
-Return<void> GrallocMapperHal::getLayerCount(const hidl_handle& bufferHandle,
-        getLayerCount_cb hidl_cb)
-{
-    int32_t err = GRALLOC1_ERROR_NONE;
-    uint32_t count = 1;
-    if (mCapabilities.layeredBuffers) {
-        err = mDispatch.getLayerCount(mDevice, bufferHandle, &count);
+    if (descriptorInfo.format == static_cast<PixelFormat>(0)) {
+        return false;
     }
 
-    hidl_cb(static_cast<Error>(err), count);
+    if (descriptorInfo.usage & ~validUsageBits) {
+        // could not fail as gralloc may use the reserved bits...
+        ALOGW("buffer descriptor with invalid usage bits 0x%" PRIx64,
+              descriptorInfo.usage & ~validUsageBits);
+    }
+
+    return true;
+}
+
+Return<void> GrallocMapper::createDescriptor(
+    const BufferDescriptorInfo& descriptorInfo, createDescriptor_cb hidl_cb) {
+    if (validateDescriptorInfo(descriptorInfo)) {
+        hidl_cb(Error::NONE, grallocEncodeBufferDescriptor(descriptorInfo));
+    } else {
+        hidl_cb(Error::BAD_VALUE, BufferDescriptor());
+    }
+
     return Void();
 }
 
-Return<void> GrallocMapperHal::getProducerUsageMask(
-        const hidl_handle& bufferHandle, getProducerUsageMask_cb hidl_cb)
-{
-    uint64_t mask = 0x0;
-    int32_t err = mDispatch.getProducerUsage(mDevice, bufferHandle, &mask);
-
-    hidl_cb(static_cast<Error>(err), mask);
-    return Void();
+bool GrallocMapper::addRegisteredHandle(buffer_handle_t bufferHandle) {
+    std::lock_guard<std::mutex> lock(mMutex);
+    return mRegisteredHandles.insert(bufferHandle).second;
 }
 
-Return<void> GrallocMapperHal::getConsumerUsageMask(
-        const hidl_handle& bufferHandle, getConsumerUsageMask_cb hidl_cb)
-{
-    uint64_t mask = 0x0;
-    int32_t err = mDispatch.getConsumerUsage(mDevice, bufferHandle, &mask);
+native_handle_t* GrallocMapper::popRegisteredHandle(void* buffer) {
+    auto bufferHandle = static_cast<native_handle_t*>(buffer);
 
-    hidl_cb(static_cast<Error>(err), mask);
-    return Void();
+    std::lock_guard<std::mutex> lock(mMutex);
+    return mRegisteredHandles.erase(bufferHandle) == 1 ? bufferHandle : nullptr;
 }
 
-Return<void> GrallocMapperHal::getBackingStore(
-        const hidl_handle& bufferHandle, getBackingStore_cb hidl_cb)
-{
-    uint64_t store = 0;
-    int32_t err = mDispatch.getBackingStore(mDevice, bufferHandle, &store);
+buffer_handle_t GrallocMapper::getRegisteredHandle(const void* buffer) {
+    auto bufferHandle = static_cast<buffer_handle_t>(buffer);
 
-    hidl_cb(static_cast<Error>(err), store);
-    return Void();
+    std::lock_guard<std::mutex> lock(mMutex);
+    return mRegisteredHandles.count(bufferHandle) == 1 ? bufferHandle : nullptr;
 }
 
-Return<void> GrallocMapperHal::getStride(const hidl_handle& bufferHandle,
-        getStride_cb hidl_cb)
-{
-    uint32_t stride = 0;
-    int32_t err = mDispatch.getStride(mDevice, bufferHandle, &stride);
+Return<void> GrallocMapper::importBuffer(const hidl_handle& rawHandle,
+                                         importBuffer_cb hidl_cb) {
+    // importing an already imported handle rather than a raw handle
+    if (getRegisteredHandle(rawHandle.getNativeHandle())) {
+        hidl_cb(Error::BAD_BUFFER, nullptr);
+        return Void();
+    }
 
-    hidl_cb(static_cast<Error>(err), stride);
-    return Void();
-}
+    if (!rawHandle.getNativeHandle()) {
+        hidl_cb(Error::BAD_BUFFER, nullptr);
+        return Void();
+    }
 
-Return<void> GrallocMapperHal::lock(const hidl_handle& bufferHandle,
-        uint64_t producerUsageMask, uint64_t consumerUsageMask,
-        const IMapper::Rect& accessRegion, const hidl_handle& acquireFence,
-        lock_cb hidl_cb)
-{
-    gralloc1_rect_t rect = asGralloc1Rect(accessRegion);
-
-    int fence = -1;
-    if (!dupFence(acquireFence, &fence)) {
+    native_handle_t* bufferHandle =
+        native_handle_clone(rawHandle.getNativeHandle());
+    if (!bufferHandle) {
         hidl_cb(Error::NO_RESOURCES, nullptr);
         return Void();
     }
 
+    Error error = registerBuffer(bufferHandle);
+    if (error != Error::NONE) {
+        native_handle_close(bufferHandle);
+        native_handle_delete(bufferHandle);
+
+        hidl_cb(error, nullptr);
+        return Void();
+    }
+
+    // The newly cloned handle is already registered?  This can only happen
+    // when a handle previously registered was native_handle_delete'd instead
+    // of freeBuffer'd.
+    if (!addRegisteredHandle(bufferHandle)) {
+        ALOGE("handle %p has already been imported; potential fd leaking",
+              bufferHandle);
+        unregisterBuffer(bufferHandle);
+        if (!mCapabilities.unregisterImplyDelete) {
+            native_handle_close(bufferHandle);
+            native_handle_delete(bufferHandle);
+        }
+
+        hidl_cb(Error::NO_RESOURCES, nullptr);
+        return Void();
+    }
+
+    hidl_cb(Error::NONE, bufferHandle);
+    return Void();
+}
+
+Return<Error> GrallocMapper::freeBuffer(void* buffer) {
+    native_handle_t* bufferHandle = popRegisteredHandle(buffer);
+    if (!bufferHandle) {
+        return Error::BAD_BUFFER;
+    }
+
+    unregisterBuffer(bufferHandle);
+    if (!mCapabilities.unregisterImplyDelete) {
+        native_handle_close(bufferHandle);
+        native_handle_delete(bufferHandle);
+    }
+
+    return Error::NONE;
+}
+
+void GrallocMapper::waitFenceFd(int fenceFd, const char* logname) {
+    if (fenceFd < 0) {
+        return;
+    }
+
+    const int warningTimeout = 3500;
+    const int error = sync_wait(fenceFd, warningTimeout);
+    if (error < 0 && errno == ETIME) {
+        ALOGE("%s: fence %d didn't signal in %u ms", logname, fenceFd,
+              warningTimeout);
+        sync_wait(fenceFd, -1);
+    }
+}
+
+bool GrallocMapper::getFenceFd(const hidl_handle& fenceHandle,
+                               int* outFenceFd) {
+    auto handle = fenceHandle.getNativeHandle();
+    if (handle && handle->numFds > 1) {
+        ALOGE("invalid fence handle with %d fds", handle->numFds);
+        return false;
+    }
+
+    *outFenceFd = (handle && handle->numFds == 1) ? handle->data[0] : -1;
+    return true;
+}
+
+hidl_handle GrallocMapper::getFenceHandle(int fenceFd, char* handleStorage) {
+    native_handle_t* handle = nullptr;
+    if (fenceFd >= 0) {
+        handle = native_handle_init(handleStorage, 1, 0);
+        handle->data[0] = fenceFd;
+    }
+
+    return hidl_handle(handle);
+}
+
+Return<void> GrallocMapper::lock(void* buffer, uint64_t cpuUsage,
+                                 const IMapper::Rect& accessRegion,
+                                 const hidl_handle& acquireFence,
+                                 lock_cb hidl_cb) {
+    buffer_handle_t bufferHandle = getRegisteredHandle(buffer);
+    if (!bufferHandle) {
+        hidl_cb(Error::BAD_BUFFER, nullptr);
+        return Void();
+    }
+
+    int fenceFd;
+    if (!getFenceFd(acquireFence, &fenceFd)) {
+        hidl_cb(Error::BAD_VALUE, nullptr);
+        return Void();
+    }
+
     void* data = nullptr;
-    int32_t err = mDispatch.lock(mDevice, bufferHandle, producerUsageMask,
-            consumerUsageMask, &rect, &data, fence);
-    if (err != GRALLOC1_ERROR_NONE) {
-        close(fence);
-    }
+    Error error =
+        lockBuffer(bufferHandle, cpuUsage, accessRegion, fenceFd, &data);
 
-    hidl_cb(static_cast<Error>(err), data);
+    hidl_cb(error, data);
     return Void();
 }
 
-Return<void> GrallocMapperHal::lockFlex(const hidl_handle& bufferHandle,
-        uint64_t producerUsageMask, uint64_t consumerUsageMask,
-        const IMapper::Rect& accessRegion, const hidl_handle& acquireFence,
-        lockFlex_cb hidl_cb)
-{
-    FlexLayout layout_reply{};
+Return<void> GrallocMapper::lockYCbCr(void* buffer, uint64_t cpuUsage,
+                                      const IMapper::Rect& accessRegion,
+                                      const hidl_handle& acquireFence,
+                                      lockYCbCr_cb hidl_cb) {
+    YCbCrLayout layout = {};
 
-    uint32_t planeCount = 0;
-    int32_t err = mDispatch.getNumFlexPlanes(mDevice, bufferHandle,
-            &planeCount);
-    if (err != GRALLOC1_ERROR_NONE) {
-        hidl_cb(static_cast<Error>(err), layout_reply);
+    buffer_handle_t bufferHandle = getRegisteredHandle(buffer);
+    if (!bufferHandle) {
+        hidl_cb(Error::BAD_BUFFER, layout);
         return Void();
     }
 
-    gralloc1_rect_t rect = asGralloc1Rect(accessRegion);
-
-    int fence = -1;
-    if (!dupFence(acquireFence, &fence)) {
-        hidl_cb(Error::NO_RESOURCES, layout_reply);
+    int fenceFd;
+    if (!getFenceFd(acquireFence, &fenceFd)) {
+        hidl_cb(Error::BAD_VALUE, layout);
         return Void();
     }
 
-    std::vector<android_flex_plane_t> planes(planeCount);
-    android_flex_layout_t layout{};
-    layout.num_planes = planes.size();
-    layout.planes = planes.data();
+    Error error =
+        lockBuffer(bufferHandle, cpuUsage, accessRegion, fenceFd, &layout);
 
-    err = mDispatch.lockFlex(mDevice, bufferHandle, producerUsageMask,
-            consumerUsageMask, &rect, &layout, fence);
-    if (err == GRALLOC1_ERROR_NONE) {
-        layout_reply.format = static_cast<FlexFormat>(layout.format);
+    hidl_cb(error, layout);
+    return Void();
+}
 
-        planes.resize(layout.num_planes);
-        layout_reply.planes.setToExternal(
-                reinterpret_cast<FlexPlane*>(planes.data()), planes.size());
+Return<void> GrallocMapper::unlock(void* buffer, unlock_cb hidl_cb) {
+    buffer_handle_t bufferHandle = getRegisteredHandle(buffer);
+    if (!bufferHandle) {
+        hidl_cb(Error::BAD_BUFFER, nullptr);
+        return Void();
+    }
+
+    int fenceFd;
+    Error error = unlockBuffer(bufferHandle, &fenceFd);
+    if (error == Error::NONE) {
+        NATIVE_HANDLE_DECLARE_STORAGE(fenceStorage, 1, 0);
+
+        hidl_cb(error, getFenceHandle(fenceFd, fenceStorage));
+
+        if (fenceFd >= 0) {
+            close(fenceFd);
+        }
     } else {
-        close(fence);
+        hidl_cb(error, nullptr);
     }
 
-    hidl_cb(static_cast<Error>(err), layout_reply);
     return Void();
 }
 
-Return<void> GrallocMapperHal::unlock(const hidl_handle& bufferHandle,
-        unlock_cb hidl_cb)
-{
-    int32_t fence = -1;
-    int32_t err = mDispatch.unlock(mDevice, bufferHandle, &fence);
-
-    NATIVE_HANDLE_DECLARE_STORAGE(fenceStorage, 1, 0);
-    hidl_handle fenceHandle;
-    if (err == GRALLOC1_ERROR_NONE && fence >= 0) {
-        auto nativeHandle = native_handle_init(fenceStorage, 1, 0);
-        nativeHandle->data[0] = fence;
-
-        fenceHandle = nativeHandle;
-    }
-
-    hidl_cb(static_cast<Error>(err), fenceHandle);
-    return Void();
-}
-
-} // anonymous namespace
-
 IMapper* HIDL_FETCH_IMapper(const char* /* name */) {
     const hw_module_t* module = nullptr;
     int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
@@ -410,12 +287,15 @@
     }
 
     uint8_t major = (module->module_api_version >> 8) & 0xff;
-    if (major != 1) {
-        ALOGE("unknown gralloc module major version %d", major);
-        return nullptr;
+    switch (major) {
+        case 1:
+            return new Gralloc1Mapper(module);
+        case 0:
+            return new Gralloc0Mapper(module);
+        default:
+            ALOGE("unknown gralloc module major version %d", major);
+            return nullptr;
     }
-
-    return new GrallocMapperHal(module);
 }
 
 } // namespace implementation
diff --git a/graphics/mapper/2.0/default/GrallocMapper.h b/graphics/mapper/2.0/default/GrallocMapper.h
index a2f89d1..c9c6d8a 100644
--- a/graphics/mapper/2.0/default/GrallocMapper.h
+++ b/graphics/mapper/2.0/default/GrallocMapper.h
@@ -18,6 +18,10 @@
 #define ANDROID_HARDWARE_GRAPHICS_MAPPER_V2_0_GRALLOC_MAPPER_H
 
 #include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <system/window.h>
+
+#include <mutex>
+#include <unordered_set>
 
 namespace android {
 namespace hardware {
@@ -26,6 +30,68 @@
 namespace V2_0 {
 namespace implementation {
 
+class GrallocMapper : public IMapper {
+   public:
+    // IMapper interface
+    Return<void> createDescriptor(const BufferDescriptorInfo& descriptorInfo,
+                                  createDescriptor_cb hidl_cb) override;
+    Return<void> importBuffer(const hidl_handle& rawHandle,
+                              importBuffer_cb hidl_cb) override;
+    Return<Error> freeBuffer(void* buffer) override;
+    Return<void> lock(void* buffer, uint64_t cpuUsage,
+                      const IMapper::Rect& accessRegion,
+                      const hidl_handle& acquireFence,
+                      lock_cb hidl_cb) override;
+    Return<void> lockYCbCr(void* buffer, uint64_t cpuUsage,
+                           const IMapper::Rect& accessRegion,
+                           const hidl_handle& acquireFence,
+                           lockYCbCr_cb hidl_cb) override;
+    Return<void> unlock(void* buffer, unlock_cb hidl_cb) override;
+
+   protected:
+    static void waitFenceFd(int fenceFd, const char* logname);
+
+    struct {
+        bool highUsageBits;
+        bool layeredBuffers;
+        bool unregisterImplyDelete;
+    } mCapabilities = {};
+
+   private:
+    virtual bool validateDescriptorInfo(
+        const BufferDescriptorInfo& descriptorInfo) const;
+
+    // Register a buffer.  The handle is already cloned by the caller.
+    virtual Error registerBuffer(buffer_handle_t bufferHandle) = 0;
+
+    // Unregister a buffer.  The handle is closed and deleted by the
+    // callee if and only if mCapabilities.unregisterImplyDelete is set.
+    virtual void unregisterBuffer(buffer_handle_t bufferHandle) = 0;
+
+    // Lock a buffer.  The fence is owned by the caller.
+    virtual Error lockBuffer(buffer_handle_t bufferHandle, uint64_t cpuUsage,
+                             const IMapper::Rect& accessRegion, int fenceFd,
+                             void** outData) = 0;
+    virtual Error lockBuffer(buffer_handle_t bufferHandle, uint64_t cpuUsage,
+                             const IMapper::Rect& accessRegion, int fenceFd,
+                             YCbCrLayout* outLayout) = 0;
+
+    // Unlock a buffer.  The returned fence is owned by the caller.
+    virtual Error unlockBuffer(buffer_handle_t bufferHandle,
+                               int* outFenceFd) = 0;
+
+    static bool addRegisteredHandle(buffer_handle_t bufferHandle);
+    static buffer_handle_t getRegisteredHandle(const void* buffer);
+    static native_handle_t* popRegisteredHandle(void* buffer);
+
+    static bool getFenceFd(const hidl_handle& fenceHandle, int* outFenceFd);
+    static hidl_handle getFenceHandle(int fenceFd, char* handleStorage);
+
+    // these are static and shared by all mappers
+    static std::mutex mMutex;
+    static std::unordered_set<buffer_handle_t> mRegisteredHandles;
+};
+
 extern "C" IMapper* HIDL_FETCH_IMapper(const char* name);
 
 } // namespace implementation
diff --git a/graphics/mapper/2.0/types.hal b/graphics/mapper/2.0/types.hal
index 2946e85..e9b2f3a 100644
--- a/graphics/mapper/2.0/types.hal
+++ b/graphics/mapper/2.0/types.hal
@@ -16,101 +16,50 @@
 
 package android.hardware.graphics.mapper@2.0;
 
+enum Error : int32_t {
+    NONE            = 0, /** no error */
+    BAD_DESCRIPTOR  = 1, /** invalid BufferDescriptor */
+    BAD_BUFFER      = 2, /** invalid buffer handle */
+    BAD_VALUE       = 3, /** invalid width, height, etc. */
+    /* 4 is reserved */
+    NO_RESOURCES    = 5, /** temporary failure due to resource contention */
+    /* 6 is reserved */
+    UNSUPPORTED     = 7, /** permanent failure */
+};
+
 /**
- * Structures for describing flexible YUVA/RGBA formats for consumption by
- * applications. Such flexible formats contain a plane for each component (e.g.
- * red, green, blue), where each plane is laid out in a grid-like pattern
- * occupying unique byte addresses and with consistent byte offsets between
- * neighboring pixels.
- *
- * The FlexLayout structure is used with any pixel format that can be
- * represented by it, such as:
- *  - PixelFormat::YCBCR_*_888
- *  - PixelFormat::FLEX_RGB*_888
- *  - PixelFormat::RGB[AX]_888[8],BGRA_8888,RGB_888
- *  - PixelFormat::YV12,Y8,Y16,YCBCR_422_SP/I,YCRCB_420_SP
- *  - even implementation defined formats that can be represented by
- *    the structures
- *
- * Vertical increment (aka. row increment or stride) describes the distance in
- * bytes from the first pixel of one row to the first pixel of the next row
- * (below) for the component plane. This can be negative.
- *
- * Horizontal increment (aka. column or pixel increment) describes the distance
- * in bytes from one pixel to the next pixel (to the right) on the same row for
- * the component plane. This can be negative.
- *
- * Each plane can be subsampled either vertically or horizontally by
- * a power-of-two factor.
- *
- * The bit-depth of each component can be arbitrary, as long as the pixels are
- * laid out on whole bytes, in native byte-order, using the most significant
- * bits of each unit.
+ * A buffer descriptor is an implementation-defined opaque data returned by
+ * createDescriptor. It describes the properties of a buffer and is consumed
+ * by the allocator.
  */
+typedef vec<uint32_t> BufferDescriptor;
 
-enum FlexComponent : int32_t {
-    Y  = 1 << 0, /** luma */
-    CB = 1 << 1, /** chroma blue */
-    CR = 1 << 2, /** chroma red */
-
-    R  = 1 << 10, /** red */
-    G  = 1 << 11, /** green */
-    B  = 1 << 12, /** blue */
-
-    A  = 1 << 30, /** alpha */
+/**
+ * Structure for describing YCbCr formats for consumption by applications.
+ * This is used with PixelFormat::YCBCR_*_888.
+ *
+ * Buffer chroma subsampling is defined in the format.
+ * e.g. PixelFormat::YCBCR_420_888 has subsampling 4:2:0.
+ *
+ * Buffers must have a 8 bit depth.
+ *
+ * y, cb, and cr point to the first byte of their respective planes.
+ *
+ * Stride describes the distance in bytes from the first value of one row of
+ * the image to the first value of the next row. It includes the width of the
+ * image plus padding.
+ * yStride is the stride of the luma plane.
+ * cStride is the stride of the chroma planes.
+ *
+ * chromaStep is the distance in bytes from one chroma pixel value to the
+ * next. This is 2 bytes for semiplanar (because chroma values are interleaved
+ * and each chroma value is one byte) and 1 for planar.
+ */
+struct YCbCrLayout {
+    pointer y;
+    pointer cb;
+    pointer cr;
+    uint32_t yStride;
+    uint32_t cStride;
+    uint32_t chromaStep;
 };
-
-enum FlexFormat : int32_t {
-    /** not a flexible format */
-    INVALID = 0x0,
-
-    Y       = FlexComponent:Y,
-    YCBCR   = Y | FlexComponent:CB | FlexComponent:CR,
-    YCBCRA  = YCBCR | FlexComponent:A,
-
-    RGB     = FlexComponent:R | FlexComponent:G | FlexComponent:B,
-    RGBA    = RGB | FlexComponent:A,
-};
-
-struct FlexPlane {
-    /** Pointer to the first byte of the top-left pixel of the plane. */
-    pointer topLeft;
-
-    FlexComponent component;
-
-    /**
-     * Bits allocated for the component in each pixel. Must be a positive
-     * multiple of 8.
-     */
-    int32_t bitsPerComponent;
-
-    /**
-     * Number of the most significant bits used in the format for this
-     * component. Must be between 1 and bitsPerComponent, inclusive.
-     */
-    int32_t bitsUsed;
-
-    /** Horizontal increment. */
-    int32_t hIncrement;
-    /** Vertical increment. */
-    int32_t vIncrement;
-    /** Horizontal subsampling. Must be a positive power of 2. */
-    int32_t hSubsampling;
-    /** Vertical subsampling. Must be a positive power of 2. */
-    int32_t vSubsampling;
-};
-
-struct FlexLayout {
-    /** The kind of flexible format. */
-    FlexFormat format;
-
-    /**
-     * A plane for each component; ordered in increasing component value
-     * order. E.g. FlexFormat::RGBA maps 0 -> R, 1 -> G, etc.  Can have size 0
-     * for FlexFormat::INVALID.
-     */
-    vec<FlexPlane> planes;
-};
-
-/** Backing store ID of a buffer. See IMapper::getBackingStore. */
-typedef uint64_t BackingStore;
diff --git a/graphics/mapper/2.0/vts/functional/Android.bp b/graphics/mapper/2.0/vts/functional/Android.bp
index e26f087..1c0e4c5 100644
--- a/graphics/mapper/2.0/vts/functional/Android.bp
+++ b/graphics/mapper/2.0/vts/functional/Android.bp
@@ -24,7 +24,6 @@
     ],
     static_libs: [
         "VtsHalHidlTargetTestBase",
-        "libVtsHalGraphicsAllocatorTestUtils",
     ],
     cflags: [
         "-Wall",
@@ -54,7 +53,6 @@
         "android.hardware.graphics.common@1.0",
     ],
     static_libs: [
-        "libVtsHalGraphicsAllocatorTestUtils",
         "libVtsHalGraphicsMapperTestUtils",
         "VtsHalHidlTargetTestBase",
     ],
diff --git a/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperTestUtils.cpp b/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperTestUtils.cpp
index f6a26ac..c534889 100644
--- a/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperTestUtils.cpp
+++ b/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperTestUtils.cpp
@@ -25,228 +25,233 @@
 namespace V2_0 {
 namespace tests {
 
-using android::hardware::graphics::allocator::V2_0::Buffer;
-using android::hardware::graphics::allocator::V2_0::BufferDescriptor;
-using android::hardware::graphics::allocator::V2_0::Error;
-
-Mapper::Mapper() { init(); }
-
-void Mapper::init() {
-  mMapper = ::testing::VtsHalHidlTargetTestBase::getService<IMapper>();
-  ASSERT_NE(nullptr, mMapper.get()) << "failed to get mapper service";
-  ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
+Gralloc::Gralloc() {
+    init();
 }
 
-Mapper::~Mapper() {
-  for (auto it : mHandles) {
-    while (it.second) {
-      EXPECT_EQ(Error::NONE, mMapper->release(it.first))
-          << "failed to release handle " << it.first;
-      it.second--;
+void Gralloc::init() {
+    mAllocator = ::testing::VtsHalHidlTargetTestBase::getService<IAllocator>();
+    ASSERT_NE(nullptr, mAllocator.get()) << "failed to get allocator service";
+
+    mMapper = ::testing::VtsHalHidlTargetTestBase::getService<IMapper>();
+    ASSERT_NE(nullptr, mMapper.get()) << "failed to get mapper service";
+    ASSERT_FALSE(mMapper->isRemote()) << "mapper is not in passthrough mode";
+}
+
+Gralloc::~Gralloc() {
+    for (auto bufferHandle : mClonedBuffers) {
+        auto buffer = const_cast<native_handle_t*>(bufferHandle);
+        native_handle_close(buffer);
+        native_handle_delete(buffer);
     }
-  }
-  mHandles.clear();
+    mClonedBuffers.clear();
+
+    for (auto bufferHandle : mImportedBuffers) {
+        auto buffer = const_cast<native_handle_t*>(bufferHandle);
+        EXPECT_EQ(Error::NONE, mMapper->freeBuffer(buffer))
+            << "failed to free buffer " << buffer;
+    }
+    mImportedBuffers.clear();
 }
 
-sp<IMapper> Mapper::getRaw() const { return mMapper; }
-
-void Mapper::retain(const native_handle_t* handle) {
-  Error error = mMapper->retain(handle);
-  ASSERT_EQ(Error::NONE, error) << "failed to retain handle " << handle;
-
-  mHandles[handle]++;
+sp<IAllocator> Gralloc::getAllocator() const {
+    return mAllocator;
 }
 
-void Mapper::release(const native_handle_t* handle) {
-  Error error = mMapper->release(handle);
-  ASSERT_EQ(Error::NONE, error) << "failed to release handle " << handle;
+std::string Gralloc::dumpDebugInfo() {
+    std::string debugInfo;
+    mAllocator->dumpDebugInfo(
+        [&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); });
 
-  if (--mHandles[handle] == 0) {
-    mHandles.erase(handle);
-  }
+    return debugInfo;
 }
 
-Mapper::Dimensions Mapper::getDimensions(const native_handle_t* handle) {
-  Dimensions dimensions = {};
-  mMapper->getDimensions(handle, [&](const auto& tmpError, const auto& tmpWidth,
-                                     const auto& tmpHeight) {
-    ASSERT_EQ(Error::NONE, tmpError)
-        << "failed to get dimensions for handle " << handle;
-    dimensions.width = tmpWidth;
-    dimensions.height = tmpHeight;
-  });
+const native_handle_t* Gralloc::cloneBuffer(const hidl_handle& rawHandle) {
+    const native_handle_t* bufferHandle =
+        native_handle_clone(rawHandle.getNativeHandle());
+    EXPECT_NE(nullptr, bufferHandle);
 
-  return dimensions;
+    if (bufferHandle) {
+        mClonedBuffers.insert(bufferHandle);
+    }
+
+    return bufferHandle;
 }
 
-PixelFormat Mapper::getFormat(const native_handle_t* handle) {
-  PixelFormat format = static_cast<PixelFormat>(0);
-  mMapper->getFormat(handle, [&](const auto& tmpError, const auto& tmpFormat) {
-    ASSERT_EQ(Error::NONE, tmpError)
-        << "failed to get format for handle " << handle;
-    format = tmpFormat;
-  });
+std::vector<const native_handle_t*> Gralloc::allocate(
+    const BufferDescriptor& descriptor, uint32_t count, bool import,
+    uint32_t* outStride) {
+    std::vector<const native_handle_t*> bufferHandles;
+    bufferHandles.reserve(count);
+    mAllocator->allocate(
+        descriptor, count, [&](const auto& tmpError, const auto& tmpStride,
+                               const auto& tmpBuffers) {
+            ASSERT_EQ(Error::NONE, tmpError) << "failed to allocate buffers";
+            ASSERT_EQ(count, tmpBuffers.size()) << "invalid buffer array";
 
-  return format;
+            for (uint32_t i = 0; i < count; i++) {
+                if (import) {
+                    ASSERT_NO_FATAL_FAILURE(
+                        bufferHandles.push_back(importBuffer(tmpBuffers[i])));
+                } else {
+                    ASSERT_NO_FATAL_FAILURE(
+                        bufferHandles.push_back(cloneBuffer(tmpBuffers[i])));
+                }
+            }
+
+            if (outStride) {
+                *outStride = tmpStride;
+            }
+        });
+
+    if (::testing::Test::HasFatalFailure()) {
+        bufferHandles.clear();
+    }
+
+    return bufferHandles;
 }
 
-uint32_t Mapper::getLayerCount(const native_handle_t* handle) {
-  uint32_t count = 0;
-  mMapper->getLayerCount(
-      handle, [&](const auto& tmpError, const auto& tmpCount) {
-        ASSERT_EQ(Error::NONE, tmpError)
-            << "failed to get layer count for handle " << handle;
-        count = tmpCount;
-      });
+const native_handle_t* Gralloc::allocate(
+    const IMapper::BufferDescriptorInfo& descriptorInfo, bool import,
+    uint32_t* outStride) {
+    BufferDescriptor descriptor = createDescriptor(descriptorInfo);
+    if (::testing::Test::HasFatalFailure()) {
+        return nullptr;
+    }
 
-  return count;
+    auto buffers = allocate(descriptor, 1, import, outStride);
+    if (::testing::Test::HasFatalFailure()) {
+        return nullptr;
+    }
+
+    return buffers[0];
 }
 
-uint64_t Mapper::getProducerUsageMask(const native_handle_t* handle) {
-  uint64_t usageMask = 0;
-  mMapper->getProducerUsageMask(
-      handle, [&](const auto& tmpError, const auto& tmpUsageMask) {
-        ASSERT_EQ(Error::NONE, tmpError)
-            << "failed to get producer usage mask for handle " << handle;
-        usageMask = tmpUsageMask;
-      });
-
-  return usageMask;
+sp<IMapper> Gralloc::getMapper() const {
+    return mMapper;
 }
 
-uint64_t Mapper::getConsumerUsageMask(const native_handle_t* handle) {
-  uint64_t usageMask = 0;
-  mMapper->getConsumerUsageMask(
-      handle, [&](const auto& tmpError, const auto& tmpUsageMask) {
-        ASSERT_EQ(Error::NONE, tmpError)
-            << "failed to get consumer usage mask for handle " << handle;
-        usageMask = tmpUsageMask;
-      });
+BufferDescriptor Gralloc::createDescriptor(
+    const IMapper::BufferDescriptorInfo& descriptorInfo) {
+    BufferDescriptor descriptor;
+    mMapper->createDescriptor(
+        descriptorInfo, [&](const auto& tmpError, const auto& tmpDescriptor) {
+            ASSERT_EQ(Error::NONE, tmpError) << "failed to create descriptor";
+            descriptor = tmpDescriptor;
+        });
 
-  return usageMask;
+    return descriptor;
 }
 
-BackingStore Mapper::getBackingStore(const native_handle_t* handle) {
-  BackingStore backingStore = 0;
-  mMapper->getBackingStore(
-      handle, [&](const auto& tmpError, const auto& tmpBackingStore) {
-        ASSERT_EQ(Error::NONE, tmpError)
-            << "failed to get backing store for handle " << handle;
-        backingStore = tmpBackingStore;
-      });
+const native_handle_t* Gralloc::importBuffer(const hidl_handle& rawHandle) {
+    const native_handle_t* bufferHandle = nullptr;
+    mMapper->importBuffer(
+        rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
+            ASSERT_EQ(Error::NONE, tmpError) << "failed to import buffer %p"
+                                             << rawHandle.getNativeHandle();
+            bufferHandle = static_cast<const native_handle_t*>(tmpBuffer);
+        });
 
-  return backingStore;
+    if (bufferHandle) {
+        mImportedBuffers.insert(bufferHandle);
+    }
+
+    return bufferHandle;
 }
 
-uint32_t Mapper::getStride(const native_handle_t* handle) {
-  uint32_t stride = 0;
-  mMapper->getStride(handle, [&](const auto& tmpError, const auto& tmpStride) {
-    ASSERT_EQ(Error::NONE, tmpError)
-        << "failed to get stride for handle " << handle;
-    stride = tmpStride;
-  });
+void Gralloc::freeBuffer(const native_handle_t* bufferHandle) {
+    auto buffer = const_cast<native_handle_t*>(bufferHandle);
 
-  return stride;
+    if (mImportedBuffers.erase(bufferHandle)) {
+        Error error = mMapper->freeBuffer(buffer);
+        ASSERT_EQ(Error::NONE, error) << "failed to free buffer " << buffer;
+    } else {
+        mClonedBuffers.erase(bufferHandle);
+        native_handle_close(buffer);
+        native_handle_delete(buffer);
+    }
 }
 
-void* Mapper::lock(const native_handle_t* handle, uint64_t producerUsageMask,
-                   uint64_t consumerUsageMask,
-                   const IMapper::Rect& accessRegion, int acquireFence) {
-  NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 0, 1);
-  native_handle_t* acquireFenceHandle = nullptr;
-  if (acquireFence >= 0) {
-    acquireFenceHandle = native_handle_init(acquireFenceStorage, 0, 1);
-    acquireFenceHandle->data[0] = acquireFence;
-  }
+void* Gralloc::lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
+                    const IMapper::Rect& accessRegion, int acquireFence) {
+    auto buffer = const_cast<native_handle_t*>(bufferHandle);
 
-  void* data = nullptr;
-  mMapper->lock(
-      handle, producerUsageMask, consumerUsageMask, accessRegion,
-      acquireFenceHandle, [&](const auto& tmpError, const auto& tmpData) {
-        ASSERT_EQ(Error::NONE, tmpError) << "failed to lock handle " << handle;
-        data = tmpData;
-      });
+    NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
+    hidl_handle acquireFenceHandle;
+    if (acquireFence >= 0) {
+        auto h = native_handle_init(acquireFenceStorage, 1, 0);
+        h->data[0] = acquireFence;
+        acquireFenceHandle = h;
+    }
 
-  if (acquireFence >= 0) {
-    close(acquireFence);
-  }
-
-  return data;
-}
-
-FlexLayout Mapper::lockFlex(const native_handle_t* handle,
-                            uint64_t producerUsageMask,
-                            uint64_t consumerUsageMask,
-                            const IMapper::Rect& accessRegion,
-                            int acquireFence) {
-  NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 0, 1);
-  native_handle_t* acquireFenceHandle = nullptr;
-  if (acquireFence >= 0) {
-    acquireFenceHandle = native_handle_init(acquireFenceStorage, 0, 1);
-    acquireFenceHandle->data[0] = acquireFence;
-  }
-
-  FlexLayout layout = {};
-  mMapper->lockFlex(handle, producerUsageMask, consumerUsageMask, accessRegion,
-                    acquireFenceHandle,
-                    [&](const auto& tmpError, const auto& tmpLayout) {
+    void* data = nullptr;
+    mMapper->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
+                  [&](const auto& tmpError, const auto& tmpData) {
                       ASSERT_EQ(Error::NONE, tmpError)
-                          << "failed to lockFlex handle " << handle;
-                      layout = tmpLayout;
-                    });
+                          << "failed to lock buffer " << buffer;
+                      data = tmpData;
+                  });
 
-  if (acquireFence >= 0) {
-    close(acquireFence);
-  }
-
-  return layout;
-}
-
-int Mapper::unlock(const native_handle_t* handle) {
-  int releaseFence = -1;
-  mMapper->unlock(handle, [&](const auto& tmpError,
-                              const auto& tmpReleaseFence) {
-    ASSERT_EQ(Error::NONE, tmpError) << "failed to unlock handle " << handle;
-
-    auto handle = tmpReleaseFence.getNativeHandle();
-    if (handle) {
-      ASSERT_EQ(0, handle->numInts) << "invalid fence handle " << handle;
-      if (handle->numFds == 1) {
-        releaseFence = dup(handle->data[0]);
-        ASSERT_LT(0, releaseFence) << "failed to dup fence fd";
-      } else {
-        ASSERT_EQ(0, handle->numFds) << " invalid fence handle " << handle;
-      }
+    if (acquireFence >= 0) {
+        close(acquireFence);
     }
-  });
 
-  return releaseFence;
+    return data;
 }
 
-const native_handle_t* Mapper::allocate(
-    std::unique_ptr<AllocatorClient>& allocatorClient,
-    const IAllocatorClient::BufferDescriptorInfo& info) {
-  BufferDescriptor descriptor = allocatorClient->createDescriptor(info);
-  if (::testing::Test::HasFatalFailure()) {
-    return nullptr;
-  }
+YCbCrLayout Gralloc::lockYCbCr(const native_handle_t* bufferHandle,
+                               uint64_t cpuUsage,
+                               const IMapper::Rect& accessRegion,
+                               int acquireFence) {
+    auto buffer = const_cast<native_handle_t*>(bufferHandle);
 
-  Buffer buffer = allocatorClient->allocate(descriptor);
-  if (::testing::Test::HasFatalFailure()) {
-    allocatorClient->destroyDescriptor(descriptor);
-    return nullptr;
-  }
+    NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
+    hidl_handle acquireFenceHandle;
+    if (acquireFence >= 0) {
+        auto h = native_handle_init(acquireFenceStorage, 1, 0);
+        h->data[0] = acquireFence;
+        acquireFenceHandle = h;
+    }
 
-  const native_handle_t* handle =
-      allocatorClient->exportHandle(descriptor, buffer);
-  if (handle) {
-    retain(handle);
-  }
+    YCbCrLayout layout = {};
+    mMapper->lockYCbCr(buffer, cpuUsage, accessRegion, acquireFenceHandle,
+                       [&](const auto& tmpError, const auto& tmpLayout) {
+                           ASSERT_EQ(Error::NONE, tmpError)
+                               << "failed to lockYCbCr buffer " << buffer;
+                           layout = tmpLayout;
+                       });
 
-  allocatorClient->free(buffer);
-  allocatorClient->destroyDescriptor(descriptor);
+    if (acquireFence >= 0) {
+        close(acquireFence);
+    }
 
-  return handle;
+    return layout;
+}
+
+int Gralloc::unlock(const native_handle_t* bufferHandle) {
+    auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+    int releaseFence = -1;
+    mMapper->unlock(
+        buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
+            ASSERT_EQ(Error::NONE, tmpError) << "failed to unlock buffer "
+                                             << buffer;
+
+            auto fenceHandle = tmpReleaseFence.getNativeHandle();
+            if (fenceHandle) {
+                ASSERT_EQ(0, fenceHandle->numInts) << "invalid fence handle "
+                                                   << fenceHandle;
+                if (fenceHandle->numFds == 1) {
+                    releaseFence = dup(fenceHandle->data[0]);
+                    ASSERT_LT(0, releaseFence) << "failed to dup fence fd";
+                } else {
+                    ASSERT_EQ(0, fenceHandle->numFds)
+                        << " invalid fence handle " << fenceHandle;
+                }
+            }
+        });
+
+    return releaseFence;
 }
 
 }  // namespace tests
diff --git a/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperTestUtils.h b/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperTestUtils.h
index c186b00..757f20b 100644
--- a/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperTestUtils.h
+++ b/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperTestUtils.h
@@ -17,14 +17,12 @@
 #ifndef VTS_HAL_GRAPHICS_MAPPER_UTILS
 #define VTS_HAL_GRAPHICS_MAPPER_UTILS
 
-#include <memory>
-#include <unordered_map>
+#include <unordered_set>
 
+#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
 #include <android/hardware/graphics/mapper/2.0/IMapper.h>
 #include <utils/StrongPointer.h>
 
-#include "VtsHalGraphicsAllocatorTestUtils.h"
-
 namespace android {
 namespace hardware {
 namespace graphics {
@@ -32,59 +30,62 @@
 namespace V2_0 {
 namespace tests {
 
-using android::hardware::graphics::common::V1_0::PixelFormat;
-using android::hardware::graphics::allocator::V2_0::IAllocatorClient;
-using android::hardware::graphics::allocator::V2_0::tests::AllocatorClient;
+using android::hardware::graphics::allocator::V2_0::IAllocator;
 
-// A wrapper to IMapper.
-class Mapper {
- public:
-  Mapper();
-  ~Mapper();
+// A wrapper to IAllocator and IMapper.
+class Gralloc {
+   public:
+    Gralloc();
+    ~Gralloc();
 
-  sp<IMapper> getRaw() const;
+    // IAllocator methods
 
-  void retain(const native_handle_t* handle);
-  void release(const native_handle_t* handle);
+    sp<IAllocator> getAllocator() const;
 
-  struct Dimensions {
-    uint32_t width;
-    uint32_t height;
-  };
-  Dimensions getDimensions(const native_handle_t* handle);
+    std::string dumpDebugInfo();
 
-  PixelFormat getFormat(const native_handle_t* handle);
-  uint32_t getLayerCount(const native_handle_t* handle);
-  uint64_t getProducerUsageMask(const native_handle_t* handle);
-  uint64_t getConsumerUsageMask(const native_handle_t* handle);
-  BackingStore getBackingStore(const native_handle_t* handle);
-  uint32_t getStride(const native_handle_t* handle);
+    // When import is false, this simply calls IAllocator::allocate. When import
+    // is true, the returned buffers are also imported into the mapper.
+    //
+    // Either case, the returned buffers must be freed with freeBuffer.
+    std::vector<const native_handle_t*> allocate(
+        const BufferDescriptor& descriptor, uint32_t count, bool import = true,
+        uint32_t* outStride = nullptr);
+    const native_handle_t* allocate(
+        const IMapper::BufferDescriptorInfo& descriptorInfo, bool import = true,
+        uint32_t* outStride = nullptr);
 
-  // We use fd instead of hidl_handle in these functions to pass fences
-  // in and out of the mapper.  The ownership of the fd is always transferred
-  // with each of these functions.
-  void* lock(const native_handle_t* handle, uint64_t producerUsageMask,
-             uint64_t consumerUsageMask, const IMapper::Rect& accessRegion,
-             int acquireFence);
-  FlexLayout lockFlex(const native_handle_t* handle, uint64_t producerUsageMask,
-                      uint64_t consumerUsageMask,
-                      const IMapper::Rect& accessRegion, int acquireFence);
-  int unlock(const native_handle_t* handle);
+    // IMapper methods
 
-  // Requests AllocatorClient to allocate a buffer, export the handle, and
-  // register the handle with mapper.
-  const native_handle_t* allocate(
-      std::unique_ptr<AllocatorClient>& allocatorClient,
-      const IAllocatorClient::BufferDescriptorInfo& info);
+    sp<IMapper> getMapper() const;
 
- private:
-  void init();
+    BufferDescriptor createDescriptor(
+        const IMapper::BufferDescriptorInfo& descriptorInfo);
 
-  sp<IMapper> mMapper;
+    const native_handle_t* importBuffer(const hidl_handle& rawHandle);
+    void freeBuffer(const native_handle_t* bufferHandle);
 
-  // Keep track of all registered (retained) handles.  When a test fails with
-  // ASSERT_*, the destructor will release the handles for the test.
-  std::unordered_map<const native_handle_t*, uint64_t> mHandles;
+    // We use fd instead of hidl_handle in these functions to pass fences
+    // in and out of the mapper.  The ownership of the fd is always transferred
+    // with each of these functions.
+    void* lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
+               const IMapper::Rect& accessRegion, int acquireFence);
+    YCbCrLayout lockYCbCr(const native_handle_t* bufferHandle,
+                          uint64_t cpuUsage, const IMapper::Rect& accessRegion,
+                          int acquireFence);
+    int unlock(const native_handle_t* bufferHandle);
+
+   private:
+    void init();
+    const native_handle_t* cloneBuffer(const hidl_handle& rawHandle);
+
+    sp<IAllocator> mAllocator;
+    sp<IMapper> mMapper;
+
+    // Keep track of all cloned and imported handles.  When a test fails with
+    // ASSERT_*, the destructor will free the handles for the test.
+    std::unordered_set<const native_handle_t*> mClonedBuffers;
+    std::unordered_set<const native_handle_t*> mImportedBuffers;
 };
 
 }  // namespace tests
diff --git a/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperV2_0TargetTest.cpp b/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperV2_0TargetTest.cpp
index 92d74d5..f066a1e 100644
--- a/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperV2_0TargetTest.cpp
+++ b/graphics/mapper/2.0/vts/functional/VtsHalGraphicsMapperV2_0TargetTest.cpp
@@ -14,10 +14,10 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "graphics_mapper_hidl_hal_test"
+#define LOG_TAG "VtsHalGraphicsMapperV2_0TargetTest"
 
-#include <android-base/logging.h>
 #include <VtsHalHidlTargetTestBase.h>
+#include <android-base/logging.h>
 #include <sync/sync.h>
 #include "VtsHalGraphicsMapperTestUtils.h"
 
@@ -29,202 +29,384 @@
 namespace tests {
 namespace {
 
-using namespace android::hardware::graphics::allocator::V2_0;
-using namespace android::hardware::graphics::allocator::V2_0::tests;
+using android::hardware::graphics::common::V1_0::BufferUsage;
+using android::hardware::graphics::common::V1_0::PixelFormat;
 
 class GraphicsMapperHidlTest : public ::testing::VtsHalHidlTargetTestBase {
  protected:
   void SetUp() override {
-    ASSERT_NO_FATAL_FAILURE(mAllocator = std::make_unique<Allocator>());
-    ASSERT_NO_FATAL_FAILURE(mAllocatorClient = mAllocator->createClient());
-    ASSERT_NO_FATAL_FAILURE(mMapper = std::make_unique<Mapper>());
+      ASSERT_NO_FATAL_FAILURE(mGralloc = std::make_unique<Gralloc>());
 
-    mDummyDescriptorInfo.width = 64;
-    mDummyDescriptorInfo.height = 64;
-    mDummyDescriptorInfo.layerCount = 1;
-    mDummyDescriptorInfo.format = PixelFormat::RGBA_8888;
-    mDummyDescriptorInfo.producerUsageMask =
-        static_cast<uint64_t>(ProducerUsage::CPU_WRITE);
-    mDummyDescriptorInfo.consumerUsageMask =
-        static_cast<uint64_t>(ConsumerUsage::CPU_READ);
+      mDummyDescriptorInfo.width = 64;
+      mDummyDescriptorInfo.height = 64;
+      mDummyDescriptorInfo.layerCount = 1;
+      mDummyDescriptorInfo.format = PixelFormat::RGBA_8888;
+      mDummyDescriptorInfo.usage = static_cast<uint64_t>(
+          BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN);
   }
 
   void TearDown() override {}
 
-  std::unique_ptr<Allocator> mAllocator;
-  std::unique_ptr<AllocatorClient> mAllocatorClient;
-  std::unique_ptr<Mapper> mMapper;
-  IAllocatorClient::BufferDescriptorInfo mDummyDescriptorInfo{};
+  std::unique_ptr<Gralloc> mGralloc;
+  IMapper::BufferDescriptorInfo mDummyDescriptorInfo{};
 };
 
 /**
- * Test IMapper::retain and IMapper::release.
+ * Test IAllocator::dumpDebugInfo by calling it.
  */
-TEST_F(GraphicsMapperHidlTest, RetainRelease) {
-  const native_handle_t* buffer;
-  ASSERT_NO_FATAL_FAILURE(
-      buffer = mMapper->allocate(mAllocatorClient, mDummyDescriptorInfo));
-
-  const int maxRefs = 10;
-  for (int i = 0; i < maxRefs; i++) {
-    ASSERT_NO_FATAL_FAILURE(mMapper->retain(buffer));
-  }
-  for (int i = 0; i < maxRefs; i++) {
-    ASSERT_NO_FATAL_FAILURE(mMapper->release(buffer));
-  }
-
-  ASSERT_NO_FATAL_FAILURE(mMapper->release(buffer));
+TEST_F(GraphicsMapperHidlTest, AllocatorDumpDebugInfo) {
+    mGralloc->dumpDebugInfo();
 }
 
 /**
- * Test IMapper::get* getters.
+ * Test IAllocator::allocate with valid buffer descriptors.
  */
-TEST_F(GraphicsMapperHidlTest, Getters) {
-  const native_handle_t* buffer;
-  ASSERT_NO_FATAL_FAILURE(
-      buffer = mMapper->allocate(mAllocatorClient, mDummyDescriptorInfo));
+TEST_F(GraphicsMapperHidlTest, AllocatorAllocate) {
+    BufferDescriptor descriptor;
+    ASSERT_NO_FATAL_FAILURE(
+        descriptor = mGralloc->createDescriptor(mDummyDescriptorInfo));
 
-  IAllocatorClient::BufferDescriptorInfo info = {};
+    for (uint32_t count = 0; count < 5; count++) {
+        std::vector<const native_handle_t*> bufferHandles;
+        uint32_t stride;
+        ASSERT_NO_FATAL_FAILURE(bufferHandles = mGralloc->allocate(
+                                    descriptor, count, false, &stride));
 
-  Mapper::Dimensions dimensions;
-  ASSERT_NO_FATAL_FAILURE(dimensions = mMapper->getDimensions(buffer));
-  info.width = dimensions.width;
-  info.height = dimensions.height;
+        if (count >= 1) {
+            EXPECT_LE(mDummyDescriptorInfo.width, stride)
+                << "invalid buffer stride";
+        }
 
-  ASSERT_NO_FATAL_FAILURE(info.format = mMapper->getFormat(buffer));
-  ASSERT_NO_FATAL_FAILURE(info.producerUsageMask =
-                              mMapper->getProducerUsageMask(buffer));
-  ASSERT_NO_FATAL_FAILURE(info.consumerUsageMask =
-                              mMapper->getConsumerUsageMask(buffer));
+        for (auto bufferHandle : bufferHandles) {
+            mGralloc->freeBuffer(bufferHandle);
+        }
+    }
+}
 
-  EXPECT_EQ(mDummyDescriptorInfo.width, info.width);
-  EXPECT_EQ(mDummyDescriptorInfo.height, info.height);
-  EXPECT_EQ(mDummyDescriptorInfo.format, info.format);
-  EXPECT_EQ(mDummyDescriptorInfo.producerUsageMask, info.producerUsageMask);
-  EXPECT_EQ(mDummyDescriptorInfo.consumerUsageMask, info.consumerUsageMask);
+/**
+ * Test IAllocator::allocate with invalid buffer descriptors.
+ */
+TEST_F(GraphicsMapperHidlTest, AllocatorAllocateNegative) {
+    // this assumes any valid descriptor is non-empty
+    BufferDescriptor descriptor;
+    mGralloc->getAllocator()->allocate(
+        descriptor, 1, [&](const auto& tmpError, const auto&, const auto&) {
+            EXPECT_EQ(Error::BAD_DESCRIPTOR, tmpError);
+        });
+}
 
-  ASSERT_NO_FATAL_FAILURE(mMapper->getBackingStore(buffer));
+/**
+ * Test IAllocator::allocate does not leak.
+ */
+TEST_F(GraphicsMapperHidlTest, AllocatorAllocateNoLeak) {
+    auto info = mDummyDescriptorInfo;
+    info.width = 1024;
+    info.height = 1024;
 
-  uint32_t stride;
-  ASSERT_NO_FATAL_FAILURE(stride = mMapper->getStride(buffer));
-  EXPECT_LE(info.width, stride);
+    for (int i = 0; i < 2048; i++) {
+        auto bufferHandle = mGralloc->allocate(info, false);
+        mGralloc->freeBuffer(bufferHandle);
+    }
+}
+
+/**
+ * Test IMapper::createDescriptor with valid descriptor info.
+ */
+TEST_F(GraphicsMapperHidlTest, CreateDescriptorBasic) {
+    ASSERT_NO_FATAL_FAILURE(mGralloc->createDescriptor(mDummyDescriptorInfo));
+}
+
+/**
+ * Test IMapper::createDescriptor with invalid descriptor info.
+ */
+TEST_F(GraphicsMapperHidlTest, CreateDescriptorNegative) {
+    auto info = mDummyDescriptorInfo;
+    info.width = 0;
+    mGralloc->getMapper()->createDescriptor(
+        info, [&](const auto& tmpError, const auto&) {
+            EXPECT_EQ(Error::BAD_VALUE, tmpError)
+                << "createDescriptor did not fail with BAD_VALUE";
+        });
+}
+
+/**
+ * Test IMapper::importBuffer and IMapper::freeBuffer with allocated buffers.
+ */
+TEST_F(GraphicsMapperHidlTest, ImportFreeBufferBasic) {
+    const native_handle_t* bufferHandle;
+    ASSERT_NO_FATAL_FAILURE(bufferHandle =
+                                mGralloc->allocate(mDummyDescriptorInfo, true));
+    ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(bufferHandle));
+}
+
+/**
+ * Test IMapper::importBuffer and IMapper::freeBuffer with cloned buffers.
+ */
+TEST_F(GraphicsMapperHidlTest, ImportFreeBufferClone) {
+    const native_handle_t* clonedBufferHandle;
+    ASSERT_NO_FATAL_FAILURE(
+        clonedBufferHandle = mGralloc->allocate(mDummyDescriptorInfo, false));
+
+    // A cloned handle is a raw handle. Check that we can import it multiple
+    // times.
+    const native_handle_t* importedBufferHandles[2];
+    ASSERT_NO_FATAL_FAILURE(importedBufferHandles[0] =
+                                mGralloc->importBuffer(clonedBufferHandle));
+    ASSERT_NO_FATAL_FAILURE(importedBufferHandles[1] =
+                                mGralloc->importBuffer(clonedBufferHandle));
+    ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(importedBufferHandles[0]));
+    ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(importedBufferHandles[1]));
+
+    ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(clonedBufferHandle));
+}
+
+/**
+ * Test IMapper::importBuffer and IMapper::freeBuffer cross mapper instances.
+ */
+TEST_F(GraphicsMapperHidlTest, ImportFreeBufferSingleton) {
+    const native_handle_t* rawHandle;
+    ASSERT_NO_FATAL_FAILURE(
+        rawHandle = mGralloc->allocate(mDummyDescriptorInfo, false));
+
+    native_handle_t* importedHandle = nullptr;
+    mGralloc->getMapper()->importBuffer(
+        rawHandle, [&](const auto& tmpError, const auto& buffer) {
+            ASSERT_EQ(Error::NONE, tmpError);
+            importedHandle = static_cast<native_handle_t*>(buffer);
+        });
+
+    // free the imported handle with another mapper
+    std::unique_ptr<Gralloc> anotherGralloc;
+    ASSERT_NO_FATAL_FAILURE(anotherGralloc = std::make_unique<Gralloc>());
+    Error error = mGralloc->getMapper()->freeBuffer(importedHandle);
+    ASSERT_EQ(Error::NONE, error);
+
+    ASSERT_NO_FATAL_FAILURE(mGralloc->freeBuffer(rawHandle));
+}
+
+/**
+ * Test IMapper::importBuffer and IMapper::freeBuffer do not leak.
+ */
+TEST_F(GraphicsMapperHidlTest, ImportFreeBufferNoLeak) {
+    auto info = mDummyDescriptorInfo;
+    info.width = 1024;
+    info.height = 1024;
+
+    for (int i = 0; i < 2048; i++) {
+        auto bufferHandle = mGralloc->allocate(info, true);
+        mGralloc->freeBuffer(bufferHandle);
+    }
+}
+
+/**
+ * Test IMapper::importBuffer with invalid buffers.
+ */
+TEST_F(GraphicsMapperHidlTest, ImportBufferNegative) {
+    native_handle_t* invalidHandle = nullptr;
+    mGralloc->getMapper()->importBuffer(
+        invalidHandle, [&](const auto& tmpError, const auto&) {
+            EXPECT_EQ(Error::BAD_BUFFER, tmpError)
+                << "importBuffer with nullptr did not fail with BAD_BUFFER";
+        });
+
+    invalidHandle = native_handle_create(0, 0);
+    mGralloc->getMapper()->importBuffer(invalidHandle, [&](const auto& tmpError,
+                                                           const auto&) {
+        EXPECT_EQ(Error::BAD_BUFFER, tmpError)
+            << "importBuffer with invalid handle did not fail with BAD_BUFFER";
+    });
+    native_handle_delete(invalidHandle);
+
+    const native_handle_t* importedHandle;
+    ASSERT_NO_FATAL_FAILURE(importedHandle =
+                                mGralloc->allocate(mDummyDescriptorInfo, true));
+    mGralloc->getMapper()->importBuffer(
+        importedHandle, [&](const auto& tmpError, const auto&) {
+            EXPECT_EQ(Error::BAD_BUFFER, tmpError)
+                << "importBuffer with an "
+                   "already imported handle did "
+                   "not fail with BAD_BUFFER";
+        });
+    mGralloc->freeBuffer(importedHandle);
+}
+
+/**
+ * Test IMapper::freeBuffer with invalid buffers.
+ */
+TEST_F(GraphicsMapperHidlTest, FreeBufferNegative) {
+    native_handle_t* invalidHandle = nullptr;
+    Error error = mGralloc->getMapper()->freeBuffer(invalidHandle);
+    EXPECT_EQ(Error::BAD_BUFFER, error)
+        << "freeBuffer with nullptr did not fail with BAD_BUFFER";
+
+    invalidHandle = native_handle_create(0, 0);
+    error = mGralloc->getMapper()->freeBuffer(invalidHandle);
+    EXPECT_EQ(Error::BAD_BUFFER, error)
+        << "freeBuffer with invalid handle did not fail with BAD_BUFFER";
+    native_handle_delete(invalidHandle);
+
+    const native_handle_t* clonedBufferHandle;
+    ASSERT_NO_FATAL_FAILURE(
+        clonedBufferHandle = mGralloc->allocate(mDummyDescriptorInfo, false));
+    error = mGralloc->getMapper()->freeBuffer(invalidHandle);
+    EXPECT_EQ(Error::BAD_BUFFER, error)
+        << "freeBuffer with un-imported handle did not fail with BAD_BUFFER";
+
+    mGralloc->freeBuffer(clonedBufferHandle);
 }
 
 /**
  * Test IMapper::lock and IMapper::unlock.
  */
-TEST_F(GraphicsMapperHidlTest, LockBasic) {
-  const auto& info = mDummyDescriptorInfo;
+TEST_F(GraphicsMapperHidlTest, LockUnlockBasic) {
+    const auto& info = mDummyDescriptorInfo;
 
-  const native_handle_t* buffer;
-  ASSERT_NO_FATAL_FAILURE(
-      buffer = mMapper->allocate(mAllocatorClient, mDummyDescriptorInfo));
+    const native_handle_t* bufferHandle;
+    uint32_t stride;
+    ASSERT_NO_FATAL_FAILURE(bufferHandle =
+                                mGralloc->allocate(info, true, &stride));
 
-  uint32_t stride;
-  ASSERT_NO_FATAL_FAILURE(stride = mMapper->getStride(buffer));
+    // lock buffer for writing
+    const IMapper::Rect region{0, 0, static_cast<int32_t>(info.width),
+                               static_cast<int32_t>(info.height)};
+    int fence = -1;
+    uint8_t* data;
+    ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(mGralloc->lock(
+                                bufferHandle, info.usage, region, fence)));
 
-  // lock buffer for writing
-  const IMapper::Rect region{0, 0, static_cast<int32_t>(info.width),
-                             static_cast<int32_t>(info.height)};
-  int fence = -1;
-  uint32_t* data;
-  ASSERT_NO_FATAL_FAILURE(
-      data = static_cast<uint32_t*>(
-          mMapper->lock(buffer, info.producerUsageMask, 0, region, fence)));
+    // RGBA_8888
+    size_t strideInBytes = stride * 4;
+    size_t writeInBytes = info.width * 4;
 
-  for (uint32_t y = 0; y < info.height; y++) {
-    for (uint32_t x = 0; x < info.width; x++) {
-      data[stride * y + x] = info.height * y + x;
+    for (uint32_t y = 0; y < info.height; y++) {
+        memset(data, y, writeInBytes);
+        data += strideInBytes;
     }
-  }
 
-  ASSERT_NO_FATAL_FAILURE(fence = mMapper->unlock(buffer));
+    ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
 
-  // lock buffer for reading
-  ASSERT_NO_FATAL_FAILURE(
-      data = static_cast<uint32_t*>(
-          mMapper->lock(buffer, 0, info.consumerUsageMask, region, fence)));
-  for (uint32_t y = 0; y < info.height; y++) {
-    for (uint32_t x = 0; x < info.width; x++) {
-      EXPECT_EQ(info.height * y + x, data[stride * y + x]);
+    // lock again for reading
+    ASSERT_NO_FATAL_FAILURE(data = static_cast<uint8_t*>(mGralloc->lock(
+                                bufferHandle, info.usage, region, fence)));
+    for (uint32_t y = 0; y < info.height; y++) {
+        for (size_t i = 0; i < writeInBytes; i++) {
+            EXPECT_EQ(static_cast<uint8_t>(y), data[i]);
+        }
+        data += strideInBytes;
     }
-  }
 
-  ASSERT_NO_FATAL_FAILURE(fence = mMapper->unlock(buffer));
-  if (fence >= 0) {
-    close(fence);
-  }
+    ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
+    if (fence >= 0) {
+        close(fence);
+    }
 }
 
 /**
- * Test IMapper::lockFlex.  This locks a YV12 buffer, and makes sure we can
+ * Test IMapper::lockYCbCr.  This locks a YV12 buffer, and makes sure we can
  * write to and read from it.
  */
-TEST_F(GraphicsMapperHidlTest, LockFlexBasic) {
-  auto info = mDummyDescriptorInfo;
-  info.format = PixelFormat::YV12;
+TEST_F(GraphicsMapperHidlTest, LockYCbCrBasic) {
+    auto info = mDummyDescriptorInfo;
+    info.format = PixelFormat::YV12;
 
-  const native_handle_t* buffer;
-  ASSERT_NO_FATAL_FAILURE(buffer = mMapper->allocate(mAllocatorClient, info));
+    const native_handle_t* bufferHandle;
+    uint32_t stride;
+    ASSERT_NO_FATAL_FAILURE(bufferHandle =
+                                mGralloc->allocate(info, true, &stride));
 
-  // lock buffer for writing
-  const IMapper::Rect region{0, 0, static_cast<int32_t>(info.width),
-                             static_cast<int32_t>(info.height)};
-  int fence = -1;
-  FlexLayout layout;
-  ASSERT_NO_FATAL_FAILURE(
-      layout =
-          mMapper->lockFlex(buffer, info.producerUsageMask, 0, region, fence));
-  ASSERT_EQ(FlexFormat::YCBCR, layout.format);
-  ASSERT_EQ(3u, layout.planes.size());
+    // lock buffer for writing
+    const IMapper::Rect region{0, 0, static_cast<int32_t>(info.width),
+                               static_cast<int32_t>(info.height)};
+    int fence = -1;
+    YCbCrLayout layout;
+    ASSERT_NO_FATAL_FAILURE(
+        layout = mGralloc->lockYCbCr(bufferHandle, info.usage, region, fence));
 
-  const auto y_stride = layout.planes[0].vIncrement;
-  const auto c_stride = layout.planes[1].vIncrement;
-  auto y_data = static_cast<uint8_t*>(layout.planes[0].topLeft);
-  auto cb_data = static_cast<uint8_t*>(layout.planes[1].topLeft);
-  auto cr_data = static_cast<uint8_t*>(layout.planes[2].topLeft);
+    auto yData = static_cast<uint8_t*>(layout.y);
+    auto cbData = static_cast<uint8_t*>(layout.cb);
+    auto crData = static_cast<uint8_t*>(layout.cr);
+    for (uint32_t y = 0; y < info.height; y++) {
+        for (uint32_t x = 0; x < info.width; x++) {
+            auto val = static_cast<uint8_t>(info.height * y + x);
 
-  for (uint32_t y = 0; y < info.height; y++) {
-    for (uint32_t x = 0; x < info.width; x++) {
-      auto val = static_cast<uint8_t>(info.height * y + x);
-
-      y_data[y_stride * y + x] = val;
-      if (y % 2 == 0 && x % 2 == 0) {
-        cb_data[c_stride * y / 2 + x / 2] = val;
-        cr_data[c_stride * y / 2 + x / 2] = val;
-      }
+            yData[layout.yStride * y + x] = val;
+            if (y % 2 == 0 && x % 2 == 0) {
+                cbData[layout.cStride * y / 2 + x / 2] = val;
+                crData[layout.cStride * y / 2 + x / 2] = val;
+            }
+        }
     }
-  }
 
-  ASSERT_NO_FATAL_FAILURE(fence = mMapper->unlock(buffer));
+    ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
 
-  // lock buffer for reading
-  ASSERT_NO_FATAL_FAILURE(
-      layout =
-          mMapper->lockFlex(buffer, 0, info.consumerUsageMask, region, fence));
+    // lock again for reading
+    ASSERT_NO_FATAL_FAILURE(
+        layout = mGralloc->lockYCbCr(bufferHandle, info.usage, region, fence));
 
-  y_data = static_cast<uint8_t*>(layout.planes[0].topLeft);
-  cb_data = static_cast<uint8_t*>(layout.planes[1].topLeft);
-  cr_data = static_cast<uint8_t*>(layout.planes[2].topLeft);
-  for (uint32_t y = 0; y < info.height; y++) {
-    for (uint32_t x = 0; x < info.width; x++) {
-      auto val = static_cast<uint8_t>(info.height * y + x);
+    yData = static_cast<uint8_t*>(layout.y);
+    cbData = static_cast<uint8_t*>(layout.cb);
+    crData = static_cast<uint8_t*>(layout.cr);
+    for (uint32_t y = 0; y < info.height; y++) {
+        for (uint32_t x = 0; x < info.width; x++) {
+            auto val = static_cast<uint8_t>(info.height * y + x);
 
-      EXPECT_EQ(val, y_data[y_stride * y + x]);
-      if (y % 2 == 0 && x % 2 == 0) {
-        EXPECT_EQ(val, cb_data[c_stride * y / 2 + x / 2]);
-        EXPECT_EQ(val, cr_data[c_stride * y / 2 + x / 2]);
-      }
+            EXPECT_EQ(val, yData[layout.yStride * y + x]);
+            if (y % 2 == 0 && x % 2 == 0) {
+                EXPECT_EQ(val, cbData[layout.cStride * y / 2 + x / 2]);
+                EXPECT_EQ(val, crData[layout.cStride * y / 2 + x / 2]);
+            }
+        }
     }
-  }
 
-  ASSERT_NO_FATAL_FAILURE(fence = mMapper->unlock(buffer));
-  if (fence >= 0) {
-    close(fence);
-  }
+    ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
+    if (fence >= 0) {
+        close(fence);
+    }
 }
 
-}  // namespace anonymous
+/**
+ * Test IMapper::unlock with invalid buffers.
+ */
+TEST_F(GraphicsMapperHidlTest, UnlockNegative) {
+    native_handle_t* invalidHandle = nullptr;
+    mGralloc->getMapper()->unlock(
+        invalidHandle, [&](const auto& tmpError, const auto&) {
+            EXPECT_EQ(Error::BAD_BUFFER, tmpError)
+                << "unlock with nullptr did not fail with BAD_BUFFER";
+        });
+
+    invalidHandle = native_handle_create(0, 0);
+    mGralloc->getMapper()->unlock(
+        invalidHandle, [&](const auto& tmpError, const auto&) {
+            EXPECT_EQ(Error::BAD_BUFFER, tmpError)
+                << "unlock with invalid handle did not fail with BAD_BUFFER";
+        });
+    native_handle_delete(invalidHandle);
+
+    ASSERT_NO_FATAL_FAILURE(invalidHandle =
+                                const_cast<native_handle_t*>(mGralloc->allocate(
+                                    mDummyDescriptorInfo, false)));
+    mGralloc->getMapper()->unlock(invalidHandle, [&](const auto& tmpError,
+                                                     const auto&) {
+        EXPECT_EQ(Error::BAD_BUFFER, tmpError)
+            << "unlock with un-imported handle did not fail with BAD_BUFFER";
+    });
+    mGralloc->freeBuffer(invalidHandle);
+
+// disabled as it fails on many existing drivers
+#if 0
+  ASSERT_NO_FATAL_FAILURE(invalidHandle = const_cast<native_handle_t*>(
+                              mGralloc->allocate(mDummyDescriptorInfo, true)));
+  mGralloc->getMapper()->unlock(
+      invalidHandle, [&](const auto& tmpError, const auto&) {
+        EXPECT_EQ(Error::BAD_BUFFER, tmpError)
+            << "unlock with unlocked handle did not fail with BAD_BUFFER";
+      });
+  mGralloc->freeBuffer(invalidHandle);
+#endif
+}
+
+}  // namespace
 }  // namespace tests
 }  // namespace V2_0
 }  // namespace mapper