gralloc: add allocator and mapper 3.0 support to SF

Add support for IAllocator and IMapper 3.0 support
to SurfaceFlinger.

Bug: 120493579
Test: manual
Change-Id: I8b7311cfa6b58502b334460d65eb66715ef429e8
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index 84414e2..ef05af1 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -62,6 +62,7 @@
         "FrameStats.cpp",
         "Gralloc.cpp",
         "Gralloc2.cpp",
+        "Gralloc3.cpp",
         "GraphicBuffer.cpp",
         "GraphicBufferAllocator.cpp",
         "GraphicBufferMapper.cpp",
@@ -79,9 +80,11 @@
 
     shared_libs: [
         "android.hardware.graphics.allocator@2.0",
+        "android.hardware.graphics.allocator@3.0",
         "android.hardware.graphics.common@1.2",
         "android.hardware.graphics.mapper@2.0",
         "android.hardware.graphics.mapper@2.1",
+        "android.hardware.graphics.mapper@3.0",
         "android.hardware.configstore@1.0",
         "android.hardware.configstore-utils",
         "libbase",
diff --git a/libs/ui/Gralloc2.cpp b/libs/ui/Gralloc2.cpp
index c2f0732..ea7321e 100644
--- a/libs/ui/Gralloc2.cpp
+++ b/libs/ui/Gralloc2.cpp
@@ -27,11 +27,13 @@
 #include <sync/sync.h>
 #pragma clang diagnostic pop
 
+using android::hardware::graphics::allocator::V2_0::IAllocator;
 using android::hardware::graphics::common::V1_1::BufferUsage;
 using android::hardware::graphics::common::V1_1::PixelFormat;
 using android::hardware::graphics::mapper::V2_0::BufferDescriptor;
 using android::hardware::graphics::mapper::V2_0::Error;
 using android::hardware::graphics::mapper::V2_0::YCbCrLayout;
+using android::hardware::graphics::mapper::V2_1::IMapper;
 
 namespace android {
 
@@ -81,7 +83,8 @@
 Gralloc2Mapper::Gralloc2Mapper() {
     mMapper = hardware::graphics::mapper::V2_0::IMapper::getService();
     if (mMapper == nullptr) {
-        LOG_ALWAYS_FATAL("gralloc-mapper is missing");
+        ALOGW("mapper 2.x is not supported");
+        return;
     }
     if (mMapper->isRemote()) {
         LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
@@ -91,6 +94,10 @@
     mMapperV2_1 = IMapper::castFrom(mMapper);
 }
 
+bool Gralloc2Mapper::isSupported() const {
+    return mMapper != nullptr;
+}
+
 status_t Gralloc2Mapper::validateBufferDescriptorInfo(
         IMapper::BufferDescriptorInfo* descriptorInfo) const {
     uint64_t validUsageBits = getValid10UsageBits();
@@ -340,10 +347,15 @@
 Gralloc2Allocator::Gralloc2Allocator(const Gralloc2Mapper& mapper) : mMapper(mapper) {
     mAllocator = IAllocator::getService();
     if (mAllocator == nullptr) {
-        LOG_ALWAYS_FATAL("gralloc-alloc is missing");
+        ALOGW("allocator 2.x is not supported");
+        return;
     }
 }
 
+bool Gralloc2Allocator::isSupported() const {
+    return mAllocator != nullptr;
+}
+
 std::string Gralloc2Allocator::dumpDebugInfo() const {
     std::string debugInfo;
 
diff --git a/libs/ui/Gralloc3.cpp b/libs/ui/Gralloc3.cpp
new file mode 100644
index 0000000..128200e
--- /dev/null
+++ b/libs/ui/Gralloc3.cpp
@@ -0,0 +1,371 @@
+/*
+ * 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 "Gralloc3"
+
+#include <hidl/ServiceManagement.h>
+#include <hwbinder/IPCThreadState.h>
+#include <ui/Gralloc3.h>
+
+#include <inttypes.h>
+#include <log/log.h>
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wzero-length-array"
+#include <sync/sync.h>
+#pragma clang diagnostic pop
+
+using android::hardware::graphics::allocator::V3_0::IAllocator;
+using android::hardware::graphics::common::V1_1::BufferUsage;
+using android::hardware::graphics::mapper::V3_0::BufferDescriptor;
+using android::hardware::graphics::mapper::V3_0::Error;
+using android::hardware::graphics::mapper::V3_0::IMapper;
+using android::hardware::graphics::mapper::V3_0::YCbCrLayout;
+
+namespace android {
+
+namespace {
+
+static constexpr Error kTransactionError = Error::NO_RESOURCES;
+
+uint64_t getValidUsageBits() {
+    static const uint64_t validUsageBits = []() -> uint64_t {
+        uint64_t bits = 0;
+        for (const auto bit :
+             hardware::hidl_enum_range<hardware::graphics::common::V1_0::BufferUsage>()) {
+            bits = bits | bit;
+        }
+        for (const auto bit :
+             hardware::hidl_enum_range<hardware::graphics::common::V1_1::BufferUsage>()) {
+            bits = bits | bit;
+        }
+        return bits;
+    }();
+    return validUsageBits;
+}
+
+static inline IMapper::Rect sGralloc3Rect(const Rect& rect) {
+    IMapper::Rect outRect{};
+    outRect.left = rect.left;
+    outRect.top = rect.top;
+    outRect.width = rect.width();
+    outRect.height = rect.height();
+    return outRect;
+}
+static inline void sBufferDescriptorInfo(uint32_t width, uint32_t height,
+                                         android::PixelFormat format, uint32_t layerCount,
+                                         uint64_t usage,
+                                         IMapper::BufferDescriptorInfo* outDescriptorInfo) {
+    outDescriptorInfo->width = width;
+    outDescriptorInfo->height = height;
+    outDescriptorInfo->layerCount = layerCount;
+    outDescriptorInfo->format = static_cast<hardware::graphics::common::V1_1::PixelFormat>(format);
+    outDescriptorInfo->usage = usage;
+}
+
+} // anonymous namespace
+
+void Gralloc3Mapper::preload() {
+    android::hardware::preloadPassthroughService<IMapper>();
+}
+
+Gralloc3Mapper::Gralloc3Mapper() {
+    mMapper = IMapper::getService();
+    if (mMapper == nullptr) {
+        ALOGW("mapper 3.x is not supported");
+        return;
+    }
+    if (mMapper->isRemote()) {
+        LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
+    }
+}
+
+bool Gralloc3Mapper::isSupported() const {
+    return mMapper != nullptr;
+}
+
+status_t Gralloc3Mapper::validateBufferDescriptorInfo(
+        IMapper::BufferDescriptorInfo* descriptorInfo) const {
+    uint64_t validUsageBits = getValidUsageBits();
+
+    if (descriptorInfo->usage & ~validUsageBits) {
+        ALOGE("buffer descriptor contains invalid usage bits 0x%" PRIx64,
+              descriptorInfo->usage & ~validUsageBits);
+        return BAD_VALUE;
+    }
+    return NO_ERROR;
+}
+
+status_t Gralloc3Mapper::createDescriptor(void* bufferDescriptorInfo,
+                                          void* outBufferDescriptor) const {
+    IMapper::BufferDescriptorInfo* descriptorInfo =
+            static_cast<IMapper::BufferDescriptorInfo*>(bufferDescriptorInfo);
+    BufferDescriptor* outDescriptor = static_cast<BufferDescriptor*>(outBufferDescriptor);
+
+    status_t status = validateBufferDescriptorInfo(descriptorInfo);
+    if (status != NO_ERROR) {
+        return status;
+    }
+
+    Error error;
+    auto hidl_cb = [&](const auto& tmpError, const auto& tmpDescriptor) {
+        error = tmpError;
+        if (error != Error::NONE) {
+            return;
+        }
+        *outDescriptor = tmpDescriptor;
+    };
+
+    hardware::Return<void> ret = mMapper->createDescriptor(*descriptorInfo, hidl_cb);
+
+    return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
+}
+
+status_t Gralloc3Mapper::importBuffer(const hardware::hidl_handle& rawHandle,
+                                      buffer_handle_t* outBufferHandle) const {
+    Error error;
+    auto ret = mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
+        error = tmpError;
+        if (error != Error::NONE) {
+            return;
+        }
+        *outBufferHandle = static_cast<buffer_handle_t>(tmpBuffer);
+    });
+
+    return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
+}
+
+void Gralloc3Mapper::freeBuffer(buffer_handle_t bufferHandle) const {
+    auto buffer = const_cast<native_handle_t*>(bufferHandle);
+    auto ret = mMapper->freeBuffer(buffer);
+
+    auto error = (ret.isOk()) ? static_cast<Error>(ret) : kTransactionError;
+    ALOGE_IF(error != Error::NONE, "freeBuffer(%p) failed with %d", buffer, error);
+}
+
+status_t Gralloc3Mapper::validateBufferSize(buffer_handle_t bufferHandle, uint32_t width,
+                                            uint32_t height, android::PixelFormat format,
+                                            uint32_t layerCount, uint64_t usage,
+                                            uint32_t stride) const {
+    IMapper::BufferDescriptorInfo descriptorInfo;
+    sBufferDescriptorInfo(width, height, format, layerCount, usage, &descriptorInfo);
+
+    auto buffer = const_cast<native_handle_t*>(bufferHandle);
+    auto ret = mMapper->validateBufferSize(buffer, descriptorInfo, stride);
+
+    return static_cast<status_t>((ret.isOk()) ? static_cast<Error>(ret) : kTransactionError);
+}
+
+void Gralloc3Mapper::getTransportSize(buffer_handle_t bufferHandle, uint32_t* outNumFds,
+                                      uint32_t* outNumInts) const {
+    *outNumFds = uint32_t(bufferHandle->numFds);
+    *outNumInts = uint32_t(bufferHandle->numInts);
+
+    Error error;
+    auto buffer = const_cast<native_handle_t*>(bufferHandle);
+    auto ret = mMapper->getTransportSize(buffer,
+                                         [&](const auto& tmpError, const auto& tmpNumFds,
+                                             const auto& tmpNumInts) {
+                                             error = tmpError;
+                                             if (error != Error::NONE) {
+                                                 return;
+                                             }
+                                             *outNumFds = tmpNumFds;
+                                             *outNumInts = tmpNumInts;
+                                         });
+
+    error = (ret.isOk()) ? error : kTransactionError;
+
+    ALOGE_IF(error != Error::NONE, "getTransportSize(%p) failed with %d", buffer, error);
+}
+
+status_t Gralloc3Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
+                              int acquireFence, void** outData) const {
+    auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+    IMapper::Rect accessRegion = sGralloc3Rect(bounds);
+
+    // put acquireFence in a hidl_handle
+    hardware::hidl_handle acquireFenceHandle;
+    NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
+    if (acquireFence >= 0) {
+        auto h = native_handle_init(acquireFenceStorage, 1, 0);
+        h->data[0] = acquireFence;
+        acquireFenceHandle = h;
+    }
+
+    Error error;
+    auto ret = mMapper->lock(buffer, usage, accessRegion, acquireFenceHandle,
+                             [&](const auto& tmpError, const auto& tmpData) {
+                                 error = tmpError;
+                                 if (error != Error::NONE) {
+                                     return;
+                                 }
+                                 *outData = tmpData;
+                             });
+
+    // we own acquireFence even on errors
+    if (acquireFence >= 0) {
+        close(acquireFence);
+    }
+
+    error = (ret.isOk()) ? error : kTransactionError;
+
+    ALOGW_IF(error != Error::NONE, "lock(%p, ...) failed: %d", bufferHandle, error);
+
+    return static_cast<status_t>(error);
+}
+
+status_t Gralloc3Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
+                              int acquireFence, android_ycbcr* ycbcr) const {
+    auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+    IMapper::Rect accessRegion = sGralloc3Rect(bounds);
+
+    // put acquireFence in a hidl_handle
+    hardware::hidl_handle acquireFenceHandle;
+    NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
+    if (acquireFence >= 0) {
+        auto h = native_handle_init(acquireFenceStorage, 1, 0);
+        h->data[0] = acquireFence;
+        acquireFenceHandle = h;
+    }
+
+    YCbCrLayout layout;
+    Error error;
+    auto ret = mMapper->lockYCbCr(buffer, usage, accessRegion, acquireFenceHandle,
+                                  [&](const auto& tmpError, const auto& tmpLayout) {
+                                      error = tmpError;
+                                      if (error != Error::NONE) {
+                                          return;
+                                      }
+
+                                      layout = tmpLayout;
+                                  });
+
+    if (error == Error::NONE) {
+        ycbcr->y = layout.y;
+        ycbcr->cb = layout.cb;
+        ycbcr->cr = layout.cr;
+        ycbcr->ystride = static_cast<size_t>(layout.yStride);
+        ycbcr->cstride = static_cast<size_t>(layout.cStride);
+        ycbcr->chroma_step = static_cast<size_t>(layout.chromaStep);
+    }
+
+    // we own acquireFence even on errors
+    if (acquireFence >= 0) {
+        close(acquireFence);
+    }
+
+    return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
+}
+
+int Gralloc3Mapper::unlock(buffer_handle_t bufferHandle) const {
+    auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+    int releaseFence = -1;
+    Error error;
+    auto ret = mMapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
+        error = tmpError;
+        if (error != Error::NONE) {
+            return;
+        }
+
+        auto fenceHandle = tmpReleaseFence.getNativeHandle();
+        if (fenceHandle && fenceHandle->numFds == 1) {
+            int fd = dup(fenceHandle->data[0]);
+            if (fd >= 0) {
+                releaseFence = fd;
+            } else {
+                ALOGD("failed to dup unlock release fence");
+                sync_wait(fenceHandle->data[0], -1);
+            }
+        }
+    });
+
+    if (!ret.isOk()) {
+        error = kTransactionError;
+    }
+
+    if (error != Error::NONE) {
+        ALOGE("unlock(%p) failed with %d", buffer, error);
+    }
+
+    return releaseFence;
+}
+
+Gralloc3Allocator::Gralloc3Allocator(const Gralloc3Mapper& mapper) : mMapper(mapper) {
+    mAllocator = IAllocator::getService();
+    if (mAllocator == nullptr) {
+        ALOGW("allocator 3.x is not supported");
+        return;
+    }
+}
+
+bool Gralloc3Allocator::isSupported() const {
+    return mAllocator != nullptr;
+}
+
+std::string Gralloc3Allocator::dumpDebugInfo() const {
+    std::string debugInfo;
+
+    mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) { debugInfo = tmpDebugInfo.c_str(); });
+
+    return debugInfo;
+}
+
+status_t Gralloc3Allocator::allocate(uint32_t width, uint32_t height, android::PixelFormat format,
+                                     uint32_t layerCount, uint64_t usage, uint32_t bufferCount,
+                                     uint32_t* outStride, buffer_handle_t* outBufferHandles) const {
+    IMapper::BufferDescriptorInfo descriptorInfo;
+    sBufferDescriptorInfo(width, height, format, layerCount, usage, &descriptorInfo);
+
+    BufferDescriptor descriptor;
+    status_t error = mMapper.createDescriptor(static_cast<void*>(&descriptorInfo),
+                                              static_cast<void*>(&descriptor));
+    if (error != NO_ERROR) {
+        return error;
+    }
+
+    auto ret = mAllocator->allocate(descriptor, bufferCount,
+                                    [&](const auto& tmpError, const auto& tmpStride,
+                                        const auto& tmpBuffers) {
+                                        error = static_cast<status_t>(tmpError);
+                                        if (tmpError != Error::NONE) {
+                                            return;
+                                        }
+
+                                        // import buffers
+                                        for (uint32_t i = 0; i < bufferCount; i++) {
+                                            error = mMapper.importBuffer(tmpBuffers[i],
+                                                                         &outBufferHandles[i]);
+                                            if (error != NO_ERROR) {
+                                                for (uint32_t j = 0; j < i; j++) {
+                                                    mMapper.freeBuffer(outBufferHandles[j]);
+                                                    outBufferHandles[j] = nullptr;
+                                                }
+                                                return;
+                                            }
+                                        }
+                                        *outStride = tmpStride;
+                                    });
+
+    // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
+    hardware::IPCThreadState::self()->flushCommands();
+
+    return (ret.isOk()) ? error : static_cast<status_t>(kTransactionError);
+}
+
+} // namespace android
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index 3fd4e2a..efb5798 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -31,6 +31,7 @@
 
 #include <ui/Gralloc.h>
 #include <ui/Gralloc2.h>
+#include <ui/Gralloc3.h>
 #include <ui/GraphicBufferMapper.h>
 
 namespace android {
@@ -44,10 +45,18 @@
 KeyedVector<buffer_handle_t,
     GraphicBufferAllocator::alloc_rec_t> GraphicBufferAllocator::sAllocList;
 
-GraphicBufferAllocator::GraphicBufferAllocator()
-      : mMapper(GraphicBufferMapper::getInstance()),
-        mAllocator(std::make_unique<Gralloc2Allocator>(
-                reinterpret_cast<const Gralloc2Mapper&>(mMapper.getGrallocMapper()))) {}
+GraphicBufferAllocator::GraphicBufferAllocator() : mMapper(GraphicBufferMapper::getInstance()) {
+    mAllocator = std::make_unique<const Gralloc3Allocator>(
+            reinterpret_cast<const Gralloc3Mapper&>(mMapper.getGrallocMapper()));
+    if (!mAllocator->isSupported()) {
+        mAllocator = std::make_unique<const Gralloc2Allocator>(
+                reinterpret_cast<const Gralloc2Mapper&>(mMapper.getGrallocMapper()));
+    }
+
+    if (!mAllocator->isSupported()) {
+        LOG_ALWAYS_FATAL("gralloc-allocator is missing");
+    }
+}
 
 GraphicBufferAllocator::~GraphicBufferAllocator() {}
 
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
index d7bf4d5..b049329 100644
--- a/libs/ui/GraphicBufferMapper.cpp
+++ b/libs/ui/GraphicBufferMapper.cpp
@@ -34,6 +34,7 @@
 
 #include <ui/Gralloc.h>
 #include <ui/Gralloc2.h>
+#include <ui/Gralloc3.h>
 #include <ui/GraphicBuffer.h>
 
 #include <system/graphics.h>
@@ -45,9 +46,19 @@
 
 void GraphicBufferMapper::preloadHal() {
     Gralloc2Mapper::preload();
+    Gralloc3Mapper::preload();
 }
 
-GraphicBufferMapper::GraphicBufferMapper() : mMapper(std::make_unique<const Gralloc2Mapper>()) {}
+GraphicBufferMapper::GraphicBufferMapper() {
+    mMapper = std::make_unique<const Gralloc3Mapper>();
+    if (!mMapper->isSupported()) {
+        mMapper = std::make_unique<const Gralloc2Mapper>();
+    }
+
+    if (!mMapper->isSupported()) {
+        LOG_ALWAYS_FATAL("gralloc-mapper is missing");
+    }
+}
 
 status_t GraphicBufferMapper::importBuffer(buffer_handle_t rawHandle,
         uint32_t width, uint32_t height, uint32_t layerCount,
diff --git a/libs/ui/include/ui/Gralloc.h b/libs/ui/include/ui/Gralloc.h
index db5543f..92bf043 100644
--- a/libs/ui/include/ui/Gralloc.h
+++ b/libs/ui/include/ui/Gralloc.h
@@ -31,6 +31,8 @@
 public:
     virtual ~GrallocMapper();
 
+    virtual bool isSupported() const = 0;
+
     virtual status_t createDescriptor(void* bufferDescriptorInfo,
                                       void* outBufferDescriptor) const = 0;
 
@@ -71,6 +73,8 @@
 public:
     virtual ~GrallocAllocator();
 
+    virtual bool isSupported() const = 0;
+
     virtual std::string dumpDebugInfo() const = 0;
 
     /*
diff --git a/libs/ui/include/ui/Gralloc2.h b/libs/ui/include/ui/Gralloc2.h
index bded3e4..e03cb43 100644
--- a/libs/ui/include/ui/Gralloc2.h
+++ b/libs/ui/include/ui/Gralloc2.h
@@ -30,15 +30,14 @@
 
 namespace android {
 
-using hardware::graphics::allocator::V2_0::IAllocator;
-using hardware::graphics::mapper::V2_1::IMapper;
-
 class Gralloc2Mapper : public GrallocMapper {
 public:
     static void preload();
 
     Gralloc2Mapper();
 
+    bool isSupported() const override;
+
     status_t createDescriptor(void* bufferDescriptorInfo, void* outBufferDescriptor) const override;
 
     status_t importBuffer(const hardware::hidl_handle& rawHandle,
@@ -63,10 +62,11 @@
 
 private:
     // Determines whether the passed info is compatible with the mapper.
-    status_t validateBufferDescriptorInfo(IMapper::BufferDescriptorInfo* descriptorInfo) const;
+    status_t validateBufferDescriptorInfo(
+            hardware::graphics::mapper::V2_1::IMapper::BufferDescriptorInfo* descriptorInfo) const;
 
     sp<hardware::graphics::mapper::V2_0::IMapper> mMapper;
-    sp<IMapper> mMapperV2_1;
+    sp<hardware::graphics::mapper::V2_1::IMapper> mMapperV2_1;
 };
 
 class Gralloc2Allocator : public GrallocAllocator {
@@ -75,6 +75,8 @@
     // time.
     Gralloc2Allocator(const Gralloc2Mapper& mapper);
 
+    bool isSupported() const override;
+
     std::string dumpDebugInfo() const override;
 
     status_t allocate(uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount,
@@ -83,7 +85,7 @@
 
 private:
     const Gralloc2Mapper& mMapper;
-    sp<IAllocator> mAllocator;
+    sp<hardware::graphics::allocator::V2_0::IAllocator> mAllocator;
 };
 
 } // namespace android
diff --git a/libs/ui/include/ui/Gralloc3.h b/libs/ui/include/ui/Gralloc3.h
new file mode 100644
index 0000000..510ce4a
--- /dev/null
+++ b/libs/ui/include/ui/Gralloc3.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_UI_GRALLOC3_H
+#define ANDROID_UI_GRALLOC3_H
+
+#include <string>
+
+#include <android/hardware/graphics/allocator/3.0/IAllocator.h>
+#include <android/hardware/graphics/common/1.1/types.h>
+#include <android/hardware/graphics/mapper/3.0/IMapper.h>
+#include <ui/Gralloc.h>
+#include <ui/PixelFormat.h>
+#include <ui/Rect.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+class Gralloc3Mapper : public GrallocMapper {
+public:
+    static void preload();
+
+    Gralloc3Mapper();
+
+    bool isSupported() const override;
+
+    status_t createDescriptor(void* bufferDescriptorInfo, void* outBufferDescriptor) const override;
+
+    status_t importBuffer(const hardware::hidl_handle& rawHandle,
+                          buffer_handle_t* outBufferHandle) const override;
+
+    void freeBuffer(buffer_handle_t bufferHandle) const override;
+
+    status_t validateBufferSize(buffer_handle_t bufferHandle, uint32_t width, uint32_t height,
+                                android::PixelFormat format, uint32_t layerCount, uint64_t usage,
+                                uint32_t stride) const override;
+
+    void getTransportSize(buffer_handle_t bufferHandle, uint32_t* outNumFds,
+                          uint32_t* outNumInts) const override;
+
+    status_t lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
+                  int acquireFence, void** outData) const override;
+
+    status_t lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
+                  int acquireFence, android_ycbcr* ycbcr) const override;
+
+    int unlock(buffer_handle_t bufferHandle) const override;
+
+private:
+    // Determines whether the passed info is compatible with the mapper.
+    status_t validateBufferDescriptorInfo(
+            hardware::graphics::mapper::V3_0::IMapper::BufferDescriptorInfo* descriptorInfo) const;
+
+    sp<hardware::graphics::mapper::V3_0::IMapper> mMapper;
+};
+
+class Gralloc3Allocator : public GrallocAllocator {
+public:
+    // An allocator relies on a mapper, and that mapper must be alive at all
+    // time.
+    Gralloc3Allocator(const Gralloc3Mapper& mapper);
+
+    bool isSupported() const override;
+
+    std::string dumpDebugInfo() const override;
+
+    status_t allocate(uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount,
+                      uint64_t usage, uint32_t bufferCount, uint32_t* outStride,
+                      buffer_handle_t* outBufferHandles) const override;
+
+private:
+    const Gralloc3Mapper& mMapper;
+    sp<hardware::graphics::allocator::V3_0::IAllocator> mAllocator;
+};
+
+} // namespace android
+
+#endif // ANDROID_UI_GRALLOC3_H
diff --git a/libs/ui/include/ui/GraphicBufferAllocator.h b/libs/ui/include/ui/GraphicBufferAllocator.h
index 94dbbed..3a547b6 100644
--- a/libs/ui/include/ui/GraphicBufferAllocator.h
+++ b/libs/ui/include/ui/GraphicBufferAllocator.h
@@ -34,7 +34,7 @@
 
 namespace android {
 
-class Gralloc2Allocator;
+class GrallocAllocator;
 class GraphicBufferMapper;
 
 class GraphicBufferAllocator : public Singleton<GraphicBufferAllocator>
@@ -72,7 +72,7 @@
     ~GraphicBufferAllocator();
 
     GraphicBufferMapper& mMapper;
-    const std::unique_ptr<const Gralloc2Allocator> mAllocator;
+    std::unique_ptr<const GrallocAllocator> mAllocator;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/libs/ui/include/ui/GraphicBufferMapper.h b/libs/ui/include/ui/GraphicBufferMapper.h
index a9bc2d4..156bd7a 100644
--- a/libs/ui/include/ui/GraphicBufferMapper.h
+++ b/libs/ui/include/ui/GraphicBufferMapper.h
@@ -36,7 +36,6 @@
 // ---------------------------------------------------------------------------
 
 class GrallocMapper;
-class Gralloc2Mapper;
 class Rect;
 
 class GraphicBufferMapper : public Singleton<GraphicBufferMapper>
@@ -87,7 +86,7 @@
 
     GraphicBufferMapper();
 
-    const std::unique_ptr<const Gralloc2Mapper> mMapper;
+    std::unique_ptr<const GrallocMapper> mMapper;
 };
 
 // ---------------------------------------------------------------------------