graphics: revise gralloc interfaces

Revise IAllocator and IMapper to reduce IPC and to support gralloc0
devices.

Specifically, IAllocator is trimmed down to have essentially only

    allocate(BufferDescriptor descriptor, uint32_t count)
        generates (Error error,
                   uint32_t stride,
                   vec<handle> buffers);

The ability to allocate buffers with shared backing store is
removed.  ProducerUsage and ConsumerUsage are moved to the
graphics.common package and are merged and renamed to BufferUsage.
BufferUsage's bits follow gralloc0.

IMapper gains

    typedef vec<uint32_t> BufferDescriptor;
    createDescriptor(BufferDescriptorInfo descriptorInfo)
          generates (Error error,
                     BufferDescriptor descriptor);

where BufferDescriptor is an implementation-defined blob.  lockFlex
is replaced by lockYCbCr.  All getters are removed.

Reference counting with retain/release is replaced by
importBuffer/freeBuffer.

Most if not all gralloc1 features are not used by the runtime yet.
There is also not too much test written for them.  As such, they
tend to behave differently between implementations and cannot be
used reliably.

Bug: 36481301
Test: builds and boots on Pixel
Change-Id: I1d31105120517ea2c128c7a19297acf3bfd312bb
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