libui: add support for android.hardware.graphics

Add Gralloc2::Allocator and Gralloc2::Mapper as wrappers to
android.hardware.graphics.allocator@2.0 and
android.hardware.graphics.mapper@2.0 respectively.  Prefer
Gralloc2::{Allocator,Mapper} in
GraphicBufferAllocator/GraphicBufferMapper.

The new path has these differences

 - it does not support gralloc0
 - it does not dup-and-close fence fds to and from HAL
   (not sure why we did that)
 - release implies native_handle_close and native_handle_delete
   (same as in gralloc1?)

When all interesting targets have android.hardware.graphics
implementations, the old path will be removed.  That is why the new path
is added in the least intrusive way, as in:

  if (new-path-valid) {
    new-path;
  } else {
    old-path;
  }

despite the ugliness.

Test: booted to launcher, tested with YouTube and some games
Change-Id: Idabb6c62e73c96a59736b497c6d6d1366095e7e3
diff --git a/include/ui/GrallocAllocator.h b/include/ui/GrallocAllocator.h
new file mode 100644
index 0000000..23b78ed
--- /dev/null
+++ b/include/ui/GrallocAllocator.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_UI_GRALLOC_ALLOCATOR_H
+#define ANDROID_UI_GRALLOC_ALLOCATOR_H
+
+#include <string>
+
+#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+namespace Gralloc2 {
+
+using hardware::graphics::allocator::V2_0::Error;
+using hardware::graphics::allocator::V2_0::PixelFormat;
+using hardware::graphics::allocator::V2_0::ProducerUsage;
+using hardware::graphics::allocator::V2_0::ConsumerUsage;
+using hardware::graphics::allocator::V2_0::BufferDescriptor;
+using hardware::graphics::allocator::V2_0::Buffer;
+using hardware::graphics::allocator::V2_0::IAllocator;
+
+// Allocator is a wrapper to IAllocator, a proxy to server-side allocator.
+class Allocator {
+public:
+    Allocator();
+
+    // this will be removed and Allocator will be always valid
+    bool valid() const { return (mService != nullptr); }
+
+    std::string dumpDebugInfo() const;
+
+    Error createBufferDescriptor(
+            const IAllocator::BufferDescriptorInfo& descriptorInfo,
+            BufferDescriptor& descriptor) const;
+    void destroyBufferDescriptor(BufferDescriptor descriptor) const;
+
+    Error allocate(BufferDescriptor descriptor, Buffer& buffer) const;
+    void free(Buffer buffer) const;
+
+    Error exportHandle(BufferDescriptor descriptor, Buffer buffer,
+            native_handle_t*& bufferHandle) const;
+
+private:
+    sp<IAllocator> mService;
+};
+
+} // namespace Gralloc2
+
+} // namespace android
+
+#endif // ANDROID_UI_GRALLOC_ALLOCATOR_H
diff --git a/include/ui/GrallocMapper.h b/include/ui/GrallocMapper.h
new file mode 100644
index 0000000..5517449
--- /dev/null
+++ b/include/ui/GrallocMapper.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_UI_GRALLOC_MAPPER_H
+#define ANDROID_UI_GRALLOC_MAPPER_H
+
+#include <memory>
+
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <system/window.h>
+
+namespace android {
+
+namespace Gralloc2 {
+
+using hardware::graphics::allocator::V2_0::Error;
+using hardware::graphics::allocator::V2_0::PixelFormat;
+using hardware::graphics::allocator::V2_0::ProducerUsage;
+using hardware::graphics::allocator::V2_0::ConsumerUsage;
+using hardware::graphics::mapper::V2_0::FlexLayout;
+using hardware::graphics::mapper::V2_0::BackingStore;
+using hardware::graphics::mapper::V2_0::Device;
+using hardware::graphics::mapper::V2_0::IMapper;
+
+// Mapper is a wrapper to IMapper, a client-side graphics buffer mapper.
+class Mapper {
+public:
+    Mapper();
+    ~Mapper();
+
+    // this will be removed and Mapper will be always valid
+    bool valid() const { return (mMapper != nullptr); }
+
+    Error retain(buffer_handle_t handle) const
+    {
+        return mMapper->retain(mDevice, handle);
+    }
+
+    void release(buffer_handle_t handle) const;
+
+    Error getDimensions(buffer_handle_t handle,
+            uint32_t& width, uint32_t& height) const
+    {
+        return mMapper->getDimensions(mDevice, handle, &width, &height);
+    }
+
+    Error getFormat(buffer_handle_t handle,
+            PixelFormat& format) const
+    {
+        return mMapper->getFormat(mDevice, handle, &format);
+    }
+
+    Error getProducerUsageMask(buffer_handle_t handle,
+            uint64_t& usageMask) const
+    {
+        return mMapper->getProducerUsageMask(mDevice, handle, &usageMask);
+    }
+
+    Error getConsumerUsageMask(buffer_handle_t handle,
+            uint64_t& usageMask) const
+    {
+        return mMapper->getConsumerUsageMask(mDevice, handle, &usageMask);
+    }
+
+    Error getBackingStore(buffer_handle_t handle,
+            BackingStore& store) const
+    {
+        return mMapper->getBackingStore(mDevice, handle, &store);
+    }
+
+    Error getStride(buffer_handle_t handle, uint32_t& stride) const
+    {
+        return mMapper->getStride(mDevice, handle, &stride);
+    }
+
+    Error getNumFlexPlanes(buffer_handle_t handle, uint32_t& numPlanes) const
+    {
+        return mMapper->getNumFlexPlanes(mDevice, handle, &numPlanes);
+    }
+
+    Error lock(buffer_handle_t handle,
+            uint64_t producerUsageMask,
+            uint64_t consumerUsageMask,
+            const Device::Rect& accessRegion,
+            int acquireFence, void*& data) const
+    {
+        return mMapper->lock(mDevice, handle,
+                producerUsageMask, consumerUsageMask,
+                &accessRegion, acquireFence, &data);
+    }
+
+    Error lock(buffer_handle_t handle,
+            uint64_t producerUsageMask,
+            uint64_t consumerUsageMask,
+            const Device::Rect& accessRegion,
+            int acquireFence, FlexLayout& flexLayout) const
+    {
+        return mMapper->lockFlex(mDevice, handle,
+                producerUsageMask, consumerUsageMask,
+                &accessRegion, acquireFence, &flexLayout);
+    }
+
+    int unlock(buffer_handle_t handle) const;
+
+private:
+    const IMapper* mMapper;
+    Device* mDevice;
+};
+
+} // namespace Gralloc2
+
+} // namespace android
+
+#endif // ANDROID_UI_GRALLOC_MAPPER_H
diff --git a/include/ui/GraphicBufferAllocator.h b/include/ui/GraphicBufferAllocator.h
index 28d0238..9cc5806 100644
--- a/include/ui/GraphicBufferAllocator.h
+++ b/include/ui/GraphicBufferAllocator.h
@@ -32,7 +32,12 @@
 
 namespace android {
 
+namespace Gralloc2 {
+class Allocator;
+}
+
 class Gralloc1Loader;
+class GraphicBufferMapper;
 class String8;
 
 class GraphicBufferAllocator : public Singleton<GraphicBufferAllocator>
@@ -86,6 +91,9 @@
     GraphicBufferAllocator();
     ~GraphicBufferAllocator();
 
+    const std::unique_ptr<const Gralloc2::Allocator> mAllocator;
+    GraphicBufferMapper& mMapper;
+
     std::unique_ptr<Gralloc1::Loader> mLoader;
     std::unique_ptr<Gralloc1::Device> mDevice;
 };
diff --git a/include/ui/GraphicBufferMapper.h b/include/ui/GraphicBufferMapper.h
index a25809c..b6de1b2 100644
--- a/include/ui/GraphicBufferMapper.h
+++ b/include/ui/GraphicBufferMapper.h
@@ -28,6 +28,10 @@
 
 // ---------------------------------------------------------------------------
 
+namespace Gralloc2 {
+class Mapper;
+}
+
 class Rect;
 
 class GraphicBufferMapper : public Singleton<GraphicBufferMapper>
@@ -57,11 +61,18 @@
 
     status_t unlockAsync(buffer_handle_t handle, int *fenceFd);
 
+    const Gralloc2::Mapper& getGrallocMapper() const
+    {
+        return *mMapper;
+    }
+
 private:
     friend class Singleton<GraphicBufferMapper>;
 
     GraphicBufferMapper();
 
+    const std::unique_ptr<const Gralloc2::Mapper> mMapper;
+
     std::unique_ptr<Gralloc1::Loader> mLoader;
     std::unique_ptr<Gralloc1::Device> mDevice;
 };
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index 0777468..1dc40b3 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -46,6 +46,8 @@
         "FrameStats.cpp",
         "Gralloc1.cpp",
         "Gralloc1On0Adapter.cpp",
+        "GrallocAllocator.cpp",
+        "GrallocMapper.cpp",
         "GraphicBuffer.cpp",
         "GraphicBufferAllocator.cpp",
         "GraphicBufferMapper.cpp",
@@ -56,10 +58,17 @@
         "UiConfig.cpp",
     ],
 
+    static_libs: [
+        "android.hardware.graphics.mapper@2.0",
+    ],
+
     shared_libs: [
+        "android.hardware.graphics.allocator@2.0",
         "libbinder",
         "libcutils",
         "libhardware",
+        "libhidl",
+        "libhwbinder",
         "libsync",
         "libutils",
         "liblog",
diff --git a/libs/ui/GrallocAllocator.cpp b/libs/ui/GrallocAllocator.cpp
new file mode 100644
index 0000000..2eb1988
--- /dev/null
+++ b/libs/ui/GrallocAllocator.cpp
@@ -0,0 +1,114 @@
+/*
+ * 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 "GrallocAllocator"
+
+#include <log/log.h>
+#include <ui/GrallocAllocator.h>
+
+namespace android {
+
+namespace Gralloc2 {
+
+// assume NO_RESOURCES when Status::isOk returns false
+constexpr Error kDefaultError = Error::NO_RESOURCES;
+
+Allocator::Allocator()
+{
+    mService = IAllocator::getService("gralloc");
+}
+
+std::string Allocator::dumpDebugInfo() const
+{
+    std::string info;
+
+    mService->dumpDebugInfo([&](const auto& tmpInfo) {
+        info = tmpInfo.c_str();
+    });
+
+    return info;
+}
+
+Error Allocator::createBufferDescriptor(
+        const IAllocator::BufferDescriptorInfo& descriptorInfo,
+        BufferDescriptor& descriptor) const
+{
+    Error error = kDefaultError;
+    mService->createDescriptor(descriptorInfo,
+            [&](const auto& tmpError, const auto& tmpDescriptor) {
+                error = tmpError;
+                if (error != Error::NONE) {
+                    return;
+                }
+
+                descriptor = tmpDescriptor;
+            });
+
+    return error;
+}
+
+void Allocator::destroyBufferDescriptor(BufferDescriptor descriptor) const
+{
+    mService->destroyDescriptor(descriptor);
+}
+
+Error Allocator::allocate(BufferDescriptor descriptor, Buffer& buffer) const
+{
+    hardware::hidl_vec<BufferDescriptor> descriptors;
+    descriptors.setToExternal(&descriptor, 1);
+
+    Error error = kDefaultError;
+    auto status = mService->allocate(descriptors,
+            [&](const auto& tmpError, const auto& tmpBuffers) {
+                error = tmpError;
+                if (tmpError != Error::NONE) {
+                    return;
+                }
+
+                buffer = tmpBuffers[0];
+            });
+
+    return error;
+}
+
+void Allocator::free(Buffer buffer) const
+{
+    mService->free(buffer);
+}
+
+Error Allocator::exportHandle(BufferDescriptor descriptor, Buffer buffer,
+        native_handle_t*& bufferHandle) const
+{
+    Error error = kDefaultError;
+    auto status = mService->exportHandle(descriptor, buffer,
+            [&](const auto& tmpError, const auto& tmpBufferHandle) {
+                error = tmpError;
+                if (tmpError != Error::NONE) {
+                    return;
+                }
+
+                bufferHandle = native_handle_clone(tmpBufferHandle);
+                if (!bufferHandle) {
+                    error = Error::NO_RESOURCES;
+                }
+            });
+
+    return error;
+}
+
+} // namespace Gralloc2
+
+} // namespace android
diff --git a/libs/ui/GrallocMapper.cpp b/libs/ui/GrallocMapper.cpp
new file mode 100644
index 0000000..d568b68
--- /dev/null
+++ b/libs/ui/GrallocMapper.cpp
@@ -0,0 +1,118 @@
+/*
+ * 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 "GrallocMapper"
+
+#include <array>
+#include <string>
+
+#include <log/log.h>
+#include <ui/GrallocMapper.h>
+
+namespace android {
+
+namespace Gralloc2 {
+
+typedef const void*(*FetchInterface)(const char* name);
+
+static FetchInterface loadHalLib(const char* pkg_name)
+{
+    static const std::array<const char*, 3> sSearchDirs = {{
+        HAL_LIBRARY_PATH_ODM,
+        HAL_LIBRARY_PATH_VENDOR,
+        HAL_LIBRARY_PATH_SYSTEM,
+    }};
+    static const char sSymbolName[] = "HALLIB_FETCH_Interface";
+
+    void* handle = nullptr;
+    std::string path;
+    for (auto dir : sSearchDirs) {
+        path = dir;
+        path += pkg_name;
+        path += ".hallib.so";
+        handle = dlopen(path.c_str(), RTLD_LOCAL | RTLD_NOW);
+        if (handle) {
+            break;
+        }
+    }
+    if (!handle) {
+        return nullptr;
+    }
+
+    void* symbol = dlsym(handle, sSymbolName);
+    if (!symbol) {
+        ALOGE("%s is missing from %s", sSymbolName, path.c_str());
+        dlclose(handle);
+        return nullptr;
+    }
+
+    return reinterpret_cast<FetchInterface>(symbol);
+}
+
+Mapper::Mapper()
+    : mMapper(nullptr), mDevice(nullptr)
+{
+    static const char sHalLibName[] = "android.hardware.graphics.mapper";
+    static const char sSupportedInterface[] =
+        "android.hardware.graphics.mapper@2.0::IMapper";
+
+    FetchInterface fetchInterface = loadHalLib(sHalLibName);
+    if (!fetchInterface) {
+        return;
+    }
+
+    mMapper = static_cast<const IMapper*>(
+            fetchInterface(sSupportedInterface));
+    if (!mMapper) {
+        ALOGE("%s is not supported", sSupportedInterface);
+        return;
+    }
+
+    if (mMapper->createDevice(&mDevice) != Error::NONE) {
+        ALOGE("failed to create mapper device");
+        mMapper = nullptr;
+    }
+}
+
+Mapper::~Mapper()
+{
+    if (mMapper) {
+        mMapper->destroyDevice(mDevice);
+    }
+}
+
+void Mapper::release(buffer_handle_t handle) const
+{
+    auto error = mMapper->release(mDevice, handle);
+    ALOGE_IF(error != Error::NONE,
+            "release(%p) failed with %d", handle, error);
+}
+
+int Mapper::unlock(buffer_handle_t handle) const
+{
+    int releaseFence;
+    auto error = mMapper->unlock(mDevice, handle, &releaseFence);
+    if (error != Error::NONE) {
+        ALOGE("unlock(%p) failed with %d", handle, error);
+        releaseFence = -1;
+    }
+
+    return releaseFence;
+}
+
+} // namespace Gralloc2
+
+} // namespace android
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index 97b948d..6d72900 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -23,6 +23,7 @@
 #include <utils/Errors.h>
 #include <utils/Log.h>
 
+#include <ui/GrallocMapper.h>
 #include <ui/GraphicBuffer.h>
 #include <ui/GraphicBufferAllocator.h>
 #include <ui/GraphicBufferMapper.h>
@@ -108,8 +109,10 @@
 {
     if (mOwner == ownHandle) {
         mBufferMapper.unregisterBuffer(handle);
-        native_handle_close(handle);
-        native_handle_delete(const_cast<native_handle*>(handle));
+        if (!mBufferMapper.getGrallocMapper().valid()) {
+            native_handle_close(handle);
+            native_handle_delete(const_cast<native_handle*>(handle));
+        }
     } else if (mOwner == ownData) {
         GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
         allocator.free(handle);
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index edfff4d..693c7cb 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -26,6 +26,9 @@
 
 #include <ui/GraphicBufferAllocator.h>
 #include <ui/Gralloc1On0Adapter.h>
+#include <ui/GrallocAllocator.h>
+#include <ui/GrallocMapper.h>
+#include <ui/GraphicBufferMapper.h>
 
 namespace android {
 // ---------------------------------------------------------------------------
@@ -37,8 +40,14 @@
     GraphicBufferAllocator::alloc_rec_t> GraphicBufferAllocator::sAllocList;
 
 GraphicBufferAllocator::GraphicBufferAllocator()
-  : mLoader(std::make_unique<Gralloc1::Loader>()),
-    mDevice(mLoader->getDevice()) {}
+  : mAllocator(std::make_unique<Gralloc2::Allocator>()),
+    mMapper(GraphicBufferMapper::getInstance())
+{
+    if (!mAllocator->valid()) {
+        mLoader = std::make_unique<Gralloc1::Loader>();
+        mDevice = mLoader->getDevice();
+    }
+}
 
 GraphicBufferAllocator::~GraphicBufferAllocator() {}
 
@@ -70,7 +79,14 @@
     }
     snprintf(buffer, SIZE, "Total allocated (estimate): %.2f KB\n", total/1024.0f);
     result.append(buffer);
-    std::string deviceDump = mDevice->dump();
+
+    std::string deviceDump;
+    if (mAllocator->valid()) {
+        deviceDump = mAllocator->dumpDebugInfo();
+    } else {
+        deviceDump = mDevice->dump();
+    }
+
     result.append(deviceDump.c_str(), deviceDump.size());
 }
 
@@ -81,6 +97,103 @@
     ALOGD("%s", s.string());
 }
 
+namespace {
+
+class HalBuffer {
+public:
+    HalBuffer(const Gralloc2::Allocator* allocator,
+            uint32_t width, uint32_t height,
+            PixelFormat format, uint32_t usage)
+        : mAllocator(allocator), mBufferValid(false)
+    {
+        Gralloc2::IAllocator::BufferDescriptorInfo info = {};
+        info.width = width;
+        info.height = height;
+        info.format = static_cast<Gralloc2::PixelFormat>(format);
+        info.producerUsageMask = usage;
+        info.consumerUsageMask = usage;
+
+        Gralloc2::BufferDescriptor descriptor;
+        auto error = mAllocator->createBufferDescriptor(info, descriptor);
+        if (error != Gralloc2::Error::NONE) {
+            ALOGE("Failed to create desc (%u x %u) format %d usage %u: %d",
+                    width, height, format, usage, error);
+            return;
+        }
+
+        error = mAllocator->allocate(descriptor, mBuffer);
+        if (error == Gralloc2::Error::NOT_SHARED) {
+            error = Gralloc2::Error::NONE;
+        }
+
+        if (error != Gralloc2::Error::NONE) {
+            ALOGE("Failed to allocate (%u x %u) format %d usage %u: %d",
+                    width, height, format, usage, error);
+            mAllocator->destroyBufferDescriptor(descriptor);
+            return;
+        }
+
+        error = mAllocator->exportHandle(descriptor, mBuffer, mHandle);
+        if (error != Gralloc2::Error::NONE) {
+            ALOGE("Failed to export handle");
+            mAllocator->free(mBuffer);
+            mAllocator->destroyBufferDescriptor(descriptor);
+            return;
+        }
+
+        mAllocator->destroyBufferDescriptor(descriptor);
+
+        mBufferValid = true;
+    }
+
+    ~HalBuffer()
+    {
+        if (mBufferValid) {
+            if (mHandle) {
+                native_handle_close(mHandle);
+                native_handle_delete(mHandle);
+            }
+
+            mAllocator->free(mBuffer);
+        }
+    }
+
+    bool exportHandle(GraphicBufferMapper& mapper,
+            buffer_handle_t* handle, uint32_t* stride)
+    {
+        if (!mBufferValid) {
+            return false;
+        }
+
+        if (mapper.registerBuffer(mHandle)) {
+            return false;
+        }
+
+        *handle = mHandle;
+
+        auto error = mapper.getGrallocMapper().getStride(mHandle, *stride);
+        if (error != Gralloc2::Error::NONE) {
+            ALOGW("Failed to get stride from buffer: %d", error);
+            *stride = 0;
+        }
+
+        mHandle = nullptr;
+        mAllocator->free(mBuffer);
+        mBufferValid = false;
+
+        return true;
+    }
+
+private:
+    const Gralloc2::Allocator* mAllocator;
+
+    bool mBufferValid;
+    Gralloc2::Buffer mBuffer;
+    native_handle_t* mHandle;
+};
+
+} // namespace
+
 status_t GraphicBufferAllocator::allocate(uint32_t width, uint32_t height,
         PixelFormat format, uint32_t usage, buffer_handle_t* handle,
         uint32_t* stride, uint64_t graphicBufferId, std::string requestorName)
@@ -95,40 +208,51 @@
     // Filter out any usage bits that should not be passed to the gralloc module
     usage &= GRALLOC_USAGE_ALLOC_MASK;
 
-    auto descriptor = mDevice->createDescriptor();
-    auto error = descriptor->setDimensions(width, height);
-    if (error != GRALLOC1_ERROR_NONE) {
-        ALOGE("Failed to set dimensions to (%u, %u): %d", width, height, error);
-        return BAD_VALUE;
-    }
-    error = descriptor->setFormat(static_cast<android_pixel_format_t>(format));
-    if (error != GRALLOC1_ERROR_NONE) {
-        ALOGE("Failed to set format to %d: %d", format, error);
-        return BAD_VALUE;
-    }
-    error = descriptor->setProducerUsage(
-            static_cast<gralloc1_producer_usage_t>(usage));
-    if (error != GRALLOC1_ERROR_NONE) {
-        ALOGE("Failed to set producer usage to %u: %d", usage, error);
-        return BAD_VALUE;
-    }
-    error = descriptor->setConsumerUsage(
-            static_cast<gralloc1_consumer_usage_t>(usage));
-    if (error != GRALLOC1_ERROR_NONE) {
-        ALOGE("Failed to set consumer usage to %u: %d", usage, error);
-        return BAD_VALUE;
-    }
+    gralloc1_error_t error;
+    if (mAllocator->valid()) {
+        HalBuffer buffer(mAllocator.get(), width, height, format, usage);
+        if (!buffer.exportHandle(mMapper, handle, stride)) {
+            return NO_MEMORY;
+        }
+        error = GRALLOC1_ERROR_NONE;
+    } else {
+        auto descriptor = mDevice->createDescriptor();
+        error = descriptor->setDimensions(width, height);
+        if (error != GRALLOC1_ERROR_NONE) {
+            ALOGE("Failed to set dimensions to (%u, %u): %d",
+                    width, height, error);
+            return BAD_VALUE;
+        }
+        error = descriptor->setFormat(
+                static_cast<android_pixel_format_t>(format));
+        if (error != GRALLOC1_ERROR_NONE) {
+            ALOGE("Failed to set format to %d: %d", format, error);
+            return BAD_VALUE;
+        }
+        error = descriptor->setProducerUsage(
+                static_cast<gralloc1_producer_usage_t>(usage));
+        if (error != GRALLOC1_ERROR_NONE) {
+            ALOGE("Failed to set producer usage to %u: %d", usage, error);
+            return BAD_VALUE;
+        }
+        error = descriptor->setConsumerUsage(
+                static_cast<gralloc1_consumer_usage_t>(usage));
+        if (error != GRALLOC1_ERROR_NONE) {
+            ALOGE("Failed to set consumer usage to %u: %d", usage, error);
+            return BAD_VALUE;
+        }
 
-    error = mDevice->allocate(descriptor, graphicBufferId, handle);
-    if (error != GRALLOC1_ERROR_NONE) {
-        ALOGE("Failed to allocate (%u x %u) format %d usage %u: %d",
-                width, height, format, usage, error);
-        return NO_MEMORY;
-    }
+        error = mDevice->allocate(descriptor, graphicBufferId, handle);
+        if (error != GRALLOC1_ERROR_NONE) {
+            ALOGE("Failed to allocate (%u x %u) format %d usage %u: %d",
+                    width, height, format, usage, error);
+            return NO_MEMORY;
+        }
 
-    error = mDevice->getStride(*handle, stride);
-    if (error != GRALLOC1_ERROR_NONE) {
-        ALOGW("Failed to get stride from buffer: %d", error);
+        error = mDevice->getStride(*handle, stride);
+        if (error != GRALLOC1_ERROR_NONE) {
+            ALOGW("Failed to get stride from buffer: %d", error);
+        }
     }
 
     if (error == NO_ERROR) {
@@ -153,7 +277,14 @@
 {
     ATRACE_CALL();
 
-    auto error = mDevice->release(handle);
+    gralloc1_error_t error;
+    if (mAllocator->valid()) {
+        error = static_cast<gralloc1_error_t>(
+                mMapper.unregisterBuffer(handle));
+    } else {
+        error = mDevice->release(handle);
+    }
+
     if (error != GRALLOC1_ERROR_NONE) {
         ALOGE("Failed to free buffer: %d", error);
     }
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
index 481d43c..fb55bf1 100644
--- a/libs/ui/GraphicBufferMapper.cpp
+++ b/libs/ui/GraphicBufferMapper.cpp
@@ -33,6 +33,7 @@
 #include <utils/Trace.h>
 
 #include <ui/Gralloc1On0Adapter.h>
+#include <ui/GrallocMapper.h>
 #include <ui/GraphicBufferMapper.h>
 #include <ui/Rect.h>
 
@@ -44,8 +45,13 @@
 ANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferMapper )
 
 GraphicBufferMapper::GraphicBufferMapper()
-  : mLoader(std::make_unique<Gralloc1::Loader>()),
-    mDevice(mLoader->getDevice()) {}
+  : mMapper(std::make_unique<const Gralloc2::Mapper>())
+{
+    if (!mMapper->valid()) {
+        mLoader = std::make_unique<Gralloc1::Loader>();
+        mDevice = mLoader->getDevice();
+    }
+}
 
 
 
@@ -53,7 +59,13 @@
 {
     ATRACE_CALL();
 
-    gralloc1_error_t error = mDevice->retain(handle);
+    gralloc1_error_t error;
+    if (mMapper->valid()) {
+        error = static_cast<gralloc1_error_t>(mMapper->retain(handle));
+    } else {
+        error = mDevice->retain(handle);
+    }
+
     ALOGW_IF(error != GRALLOC1_ERROR_NONE, "registerBuffer(%p) failed: %d",
             handle, error);
 
@@ -64,7 +76,14 @@
 {
     ATRACE_CALL();
 
-    gralloc1_error_t error = mDevice->retain(buffer);
+    gralloc1_error_t error;
+    if (mMapper->valid()) {
+        error = static_cast<gralloc1_error_t>(
+                mMapper->retain(buffer->getNativeBuffer()->handle));
+    } else {
+        error = mDevice->retain(buffer);
+    }
+
     ALOGW_IF(error != GRALLOC1_ERROR_NONE, "registerBuffer(%p) failed: %d",
             buffer->getNativeBuffer()->handle, error);
 
@@ -75,7 +94,14 @@
 {
     ATRACE_CALL();
 
-    gralloc1_error_t error = mDevice->release(handle);
+    gralloc1_error_t error;
+    if (mMapper->valid()) {
+        mMapper->release(handle);
+        error = GRALLOC1_ERROR_NONE;
+    } else {
+        error = mDevice->release(handle);
+    }
+
     ALOGW_IF(error != GRALLOC1_ERROR_NONE, "unregisterBuffer(%p): failed %d",
             handle, error);
 
@@ -120,11 +146,20 @@
     ATRACE_CALL();
 
     gralloc1_rect_t accessRegion = asGralloc1Rect(bounds);
-    sp<Fence> fence = new Fence(fenceFd);
-    gralloc1_error_t error = mDevice->lock(handle,
-            static_cast<gralloc1_producer_usage_t>(usage),
-            static_cast<gralloc1_consumer_usage_t>(usage),
-            &accessRegion, vaddr, fence);
+    gralloc1_error_t error;
+    if (mMapper->valid()) {
+        const Gralloc2::Device::Rect& accessRect =
+            *reinterpret_cast<Gralloc2::Device::Rect*>(&accessRegion);
+        error = static_cast<gralloc1_error_t>(mMapper->lock(
+                    handle, usage, usage, accessRect, fenceFd, *vaddr));
+    } else {
+        sp<Fence> fence = new Fence(fenceFd);
+        error = mDevice->lock(handle,
+                static_cast<gralloc1_producer_usage_t>(usage),
+                static_cast<gralloc1_consumer_usage_t>(usage),
+                &accessRegion, vaddr, fence);
+    }
+
     ALOGW_IF(error != GRALLOC1_ERROR_NONE, "lock(%p, ...) failed: %d", handle,
             error);
 
@@ -160,20 +195,29 @@
     ATRACE_CALL();
 
     gralloc1_rect_t accessRegion = asGralloc1Rect(bounds);
-    sp<Fence> fence = new Fence(fenceFd);
 
-    if (mDevice->hasCapability(GRALLOC1_CAPABILITY_ON_ADAPTER)) {
-        gralloc1_error_t error = mDevice->lockYCbCr(handle,
-                static_cast<gralloc1_producer_usage_t>(usage),
-                static_cast<gralloc1_consumer_usage_t>(usage),
-                &accessRegion, ycbcr, fence);
-        ALOGW_IF(error != GRALLOC1_ERROR_NONE, "lockYCbCr(%p, ...) failed: %d",
-                handle, error);
-        return error;
+    if (!mMapper->valid()) {
+        if (mDevice->hasCapability(GRALLOC1_CAPABILITY_ON_ADAPTER)) {
+            sp<Fence> fence = new Fence(fenceFd);
+            gralloc1_error_t error = mDevice->lockYCbCr(handle,
+                    static_cast<gralloc1_producer_usage_t>(usage),
+                    static_cast<gralloc1_consumer_usage_t>(usage),
+                    &accessRegion, ycbcr, fence);
+            ALOGW_IF(error != GRALLOC1_ERROR_NONE,
+                    "lockYCbCr(%p, ...) failed: %d", handle, error);
+            return error;
+        }
     }
 
     uint32_t numPlanes = 0;
-    gralloc1_error_t error = mDevice->getNumFlexPlanes(handle, &numPlanes);
+    gralloc1_error_t error;
+    if (mMapper->valid()) {
+        error = static_cast<gralloc1_error_t>(
+                mMapper->getNumFlexPlanes(handle, numPlanes));
+    } else {
+        error = mDevice->getNumFlexPlanes(handle, &numPlanes);
+    }
+
     if (error != GRALLOC1_ERROR_NONE) {
         ALOGV("Failed to retrieve number of flex planes: %d", error);
         return error;
@@ -188,10 +232,21 @@
     flexLayout.num_planes = numPlanes;
     flexLayout.planes = planes.data();
 
-    error = mDevice->lockFlex(handle,
-            static_cast<gralloc1_producer_usage_t>(usage),
-            static_cast<gralloc1_consumer_usage_t>(usage),
-            &accessRegion, &flexLayout, fence);
+    if (mMapper->valid()) {
+        const Gralloc2::Device::Rect& accessRect =
+            *reinterpret_cast<Gralloc2::Device::Rect*>(&accessRegion);
+        Gralloc2::FlexLayout& layout =
+            *reinterpret_cast<Gralloc2::FlexLayout*>(&flexLayout);
+        error = static_cast<gralloc1_error_t>(mMapper->lock(
+                    handle, usage, usage, accessRect, fenceFd, layout));
+    } else {
+        sp<Fence> fence = new Fence(fenceFd);
+        error = mDevice->lockFlex(handle,
+                static_cast<gralloc1_producer_usage_t>(usage),
+                static_cast<gralloc1_consumer_usage_t>(usage),
+                &accessRegion, &flexLayout, fence);
+    }
+
     if (error != GRALLOC1_ERROR_NONE) {
         ALOGW("lockFlex(%p, ...) failed: %d", handle, error);
         return error;
@@ -276,14 +331,20 @@
 {
     ATRACE_CALL();
 
-    sp<Fence> fence = Fence::NO_FENCE;
-    gralloc1_error_t error = mDevice->unlock(handle, &fence);
-    if (error != GRALLOC1_ERROR_NONE) {
-        ALOGE("unlock(%p) failed: %d", handle, error);
-        return error;
-    }
+    gralloc1_error_t error;
+    if (mMapper->valid()) {
+        *fenceFd = mMapper->unlock(handle);
+        error = GRALLOC1_ERROR_NONE;
+    } else {
+        sp<Fence> fence = Fence::NO_FENCE;
+        error = mDevice->unlock(handle, &fence);
+        if (error != GRALLOC1_ERROR_NONE) {
+            ALOGE("unlock(%p) failed: %d", handle, error);
+            return error;
+        }
 
-    *fenceFd = fence->dup();
+        *fenceFd = fence->dup();
+    }
     return error;
 }