Merge changes from topic "IA/IM-3.0-feature"

* changes:
  allocator: require optimal allocations
  mapper: add isSupported
  mapper: update lock's return values
  mapper: update documentation on locking
diff --git a/graphics/allocator/3.0/IAllocator.hal b/graphics/allocator/3.0/IAllocator.hal
index 3651e91..34b08e7 100644
--- a/graphics/allocator/3.0/IAllocator.hal
+++ b/graphics/allocator/3.0/IAllocator.hal
@@ -30,6 +30,9 @@
     /**
      * Allocates buffers with the properties specified by the descriptor.
      *
+     * Allocations should be optimized for usage bits provided in the
+     * descriptor.
+     *
      * @param descriptor Properties of the buffers to allocate. This must be
      *     obtained from IMapper::createDescriptor().
      * @param count The number of buffers to allocate.
diff --git a/graphics/mapper/3.0/IMapper.hal b/graphics/mapper/3.0/IMapper.hal
index e399045..a0e4d7a 100644
--- a/graphics/mapper/3.0/IMapper.hal
+++ b/graphics/mapper/3.0/IMapper.hal
@@ -183,6 +183,9 @@
      * buffer content in an indeterminate state or returning an error are both
      * acceptable.
      *
+     * 1D buffers (width = size in bytes, height = 1, pixel_format = BLOB) must
+     * "lock in place". The buffers must be directly accessible via mapping.
+     *
      * The client must not modify the content of the buffer outside of
      * @p accessRegion, and the device need not guarantee that content outside
      * of @p accessRegion is valid for reading. The result of reading or writing
@@ -193,6 +196,12 @@
      * memory. This address will represent the top-left corner of the entire
      * buffer, even if @p accessRegion does not begin at the top-left corner.
      *
+     * On success, bytesPerPixel must contain the number of bytes per pixel in
+     * the buffer. If the bytesPerPixel is unknown or variable, a value of -1
+     * should be returned. bytesPerStride must contain the bytes per stride of
+     * the buffer. If the bytesPerStride is unknown or variable, a value of -1
+     * should be returned.
+     *
      * @param buffer Buffer to lock.
      * @param cpuUsage CPU usage flags to request. See +ndk
      *     libnativewindow#AHardwareBuffer_UsageFlags for possible values.
@@ -211,13 +220,17 @@
      *     - `NO_RESOURCES` if the buffer cannot be locked at this time. Note
      *       that locking may succeed at a later time.
      * @return data CPU-accessible pointer to the buffer data.
+     * @return bytesPerPixel the number of bytes per pixel in the buffer
+     * @return bytesPerStride the number of bytes per stride of the buffer
      */
     lock(pointer buffer,
          uint64_t cpuUsage,
          Rect accessRegion,
          handle acquireFence)
             generates (Error error,
-                       pointer data);
+                       pointer data,
+                       int32_t bytesPerPixel,
+                       int32_t bytesPerStride);
 
     /**
      * Locks a YCbCr buffer for the specified CPU usage.
@@ -272,5 +285,20 @@
      */
     unlock(pointer buffer) generates (Error error, handle releaseFence);
 
+    /**
+     * Test whether the given BufferDescriptorInfo is allocatable.
+     *
+     * If this function returns true, it means that a buffer with the given
+     * description can be allocated on this implementation, unless resource
+     * exhaustion occurs. If this function returns false, it means that the
+     * allocation of the given description will never succeed.
+     *
+     * @param description the description of the buffer
+     * @return supported whether the description is supported
+     */
+    isSupported(BufferDescriptorInfo description)
+            generates (Error error,
+                       bool supported);
+
 };
 
diff --git a/graphics/mapper/3.0/utils/vts/MapperVts.cpp b/graphics/mapper/3.0/utils/vts/MapperVts.cpp
index 8428403..f2b7594 100644
--- a/graphics/mapper/3.0/utils/vts/MapperVts.cpp
+++ b/graphics/mapper/3.0/utils/vts/MapperVts.cpp
@@ -164,7 +164,8 @@
 }
 
 void* Gralloc::lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
-                    const IMapper::Rect& accessRegion, int acquireFence) {
+                    const IMapper::Rect& accessRegion, int acquireFence, int32_t* outBytesPerPixel,
+                    int32_t* outBytesPerStride) {
     auto buffer = const_cast<native_handle_t*>(bufferHandle);
 
     NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
@@ -175,11 +176,17 @@
         acquireFenceHandle = h;
     }
 
+    *outBytesPerPixel = -1;
+    *outBytesPerStride = -1;
+
     void* data = nullptr;
     mMapper->lock(buffer, cpuUsage, accessRegion, acquireFenceHandle,
-                  [&](const auto& tmpError, const auto& tmpData) {
+                  [&](const auto& tmpError, const auto& tmpData, int32_t tmpBytesPerPixel,
+                      int32_t tmpBytesPerStride) {
                       ASSERT_EQ(Error::NONE, tmpError) << "failed to lock buffer " << buffer;
                       data = tmpData;
+                      *outBytesPerPixel = tmpBytesPerPixel;
+                      *outBytesPerStride = tmpBytesPerStride;
                   });
 
     if (acquireFence >= 0) {
@@ -264,6 +271,15 @@
         });
 }
 
+bool Gralloc::isSupported(const IMapper::BufferDescriptorInfo& descriptorInfo) {
+    bool supported = false;
+    mMapper->isSupported(descriptorInfo, [&](const auto& tmpError, const auto& tmpSupported) {
+        ASSERT_EQ(Error::NONE, tmpError) << "failed to check is supported";
+        supported = tmpSupported;
+    });
+    return supported;
+}
+
 }  // namespace vts
 }  // namespace V3_0
 }  // namespace mapper
diff --git a/graphics/mapper/3.0/utils/vts/include/mapper-vts/3.0/MapperVts.h b/graphics/mapper/3.0/utils/vts/include/mapper-vts/3.0/MapperVts.h
index c94961c..ba79ca4 100644
--- a/graphics/mapper/3.0/utils/vts/include/mapper-vts/3.0/MapperVts.h
+++ b/graphics/mapper/3.0/utils/vts/include/mapper-vts/3.0/MapperVts.h
@@ -68,7 +68,8 @@
     // 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);
+               const IMapper::Rect& accessRegion, int acquireFence, int32_t* outBytesPerPixel,
+               int32_t* outBytesPerStride);
     YCbCrLayout lockYCbCr(const native_handle_t* bufferHandle, uint64_t cpuUsage,
                           const IMapper::Rect& accessRegion, int acquireFence);
     int unlock(const native_handle_t* bufferHandle);
@@ -78,6 +79,8 @@
     void getTransportSize(const native_handle_t* bufferHandle, uint32_t* outNumFds,
                           uint32_t* outNumInts);
 
+    bool isSupported(const IMapper::BufferDescriptorInfo& descriptorInfo);
+
    private:
     void init(const std::string& allocatorServiceName, const std::string& mapperServiceName);
     const native_handle_t* cloneBuffer(const hidl_handle& rawHandle);
diff --git a/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp b/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp
index 430a526..cfae635 100644
--- a/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp
+++ b/graphics/mapper/3.0/vts/functional/VtsHalGraphicsMapperV3_0TargetTest.cpp
@@ -298,8 +298,15 @@
                                static_cast<int32_t>(info.height)};
     int fence = -1;
     uint8_t* data;
+    int32_t bytesPerPixel = -1;
+    int32_t bytesPerStride = -1;
     ASSERT_NO_FATAL_FAILURE(
-        data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage, region, fence)));
+            data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage, region, fence,
+                                                        &bytesPerPixel, &bytesPerStride)));
+
+    // Valid return values are -1 for unsupported or the number bytes for supported which is >=0
+    EXPECT_GT(bytesPerPixel, -1);
+    EXPECT_GT(bytesPerStride, -1);
 
     // RGBA_8888
     size_t strideInBytes = stride * 4;
@@ -312,9 +319,13 @@
 
     ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
 
+    bytesPerPixel = -1;
+    bytesPerStride = -1;
+
     // lock again for reading
     ASSERT_NO_FATAL_FAILURE(
-        data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage, region, fence)));
+            data = static_cast<uint8_t*>(mGralloc->lock(bufferHandle, info.usage, region, fence,
+                                                        &bytesPerPixel, &bytesPerStride)));
     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]);
@@ -322,6 +333,9 @@
         data += strideInBytes;
     }
 
+    EXPECT_GT(bytesPerPixel, -1);
+    EXPECT_GT(bytesPerStride, -1);
+
     ASSERT_NO_FATAL_FAILURE(fence = mGralloc->unlock(bufferHandle));
     if (fence >= 0) {
         close(fence);
@@ -426,6 +440,40 @@
 #endif
 }
 
+/**
+ * Test IMapper::isSupported with required format RGBA_8888
+ */
+TEST_F(GraphicsMapperHidlTest, IsSupportedRGBA8888) {
+    const auto& info = mDummyDescriptorInfo;
+    bool supported = false;
+
+    ASSERT_NO_FATAL_FAILURE(supported = mGralloc->isSupported(info));
+    ASSERT_TRUE(supported);
+}
+
+/**
+ * Test IMapper::isSupported with required format YV12
+ */
+TEST_F(GraphicsMapperHidlTest, IsSupportedYV12) {
+    auto info = mDummyDescriptorInfo;
+    info.format = PixelFormat::YV12;
+    bool supported = false;
+
+    ASSERT_NO_FATAL_FAILURE(supported = mGralloc->isSupported(info));
+    ASSERT_TRUE(supported);
+}
+
+/**
+ * Test IMapper::isSupported with optional format Y16
+ */
+TEST_F(GraphicsMapperHidlTest, IsSupportedY16) {
+    auto info = mDummyDescriptorInfo;
+    info.format = PixelFormat::Y16;
+    bool supported = false;
+
+    ASSERT_NO_FATAL_FAILURE(supported = mGralloc->isSupported(info));
+}
+
 }  // namespace
 }  // namespace vts
 }  // namespace V3_0