Reland: gralloc: Adds Minigbm AIDL allocator

The switch from HIDL to AIDL does not introduce any new interface
methods.

This reverts commit 95b765d807a1e6a213d907f1c99ab931b8fabf4b.

Reland notes:

- Avoids using `minigbm_cros_gralloc_library_defaults`
for new `libminigbm_gralloc4_utils` to avoid having two libraries
compiling cros_gralloc_driver.cc.

- Makes `libminigbm_gralloc4_utils` a shared library.

Bug: b/223410512
Test: cvd start
Test: vts -m VtsHalGraphicsAllocatorAidl_TargetTest
Test: vts -m VtsHalGraphicsMapperV4_0Target
Test: cvd start --gpu_mode=gfxstream
Test: vts -m VtsHalGraphicsAllocatorAidl_TargetTest
Test: vts -m VtsHalGraphicsMapperV4_0Target
Change-Id: I69c4014a44b1bfe07ebc309b1c52e292100913c4
diff --git a/cros_gralloc/aidl/.clang-format b/cros_gralloc/aidl/.clang-format
new file mode 100644
index 0000000..e5e7076
--- /dev/null
+++ b/cros_gralloc/aidl/.clang-format
@@ -0,0 +1,19 @@
+# Copyright 2022 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+#
+# This directory is formatted to match the format of the interfaces implemented.
+
+BasedOnStyle: Google
+Standard: Cpp11
+AccessModifierOffset: -2
+AllowShortFunctionsOnASingleLine: Inline
+ColumnLimit: 100
+CommentPragmas: NOLINT:.*
+DerivePointerAlignment: false
+IncludeBlocks: Preserve
+IndentWidth: 4
+ContinuationIndentWidth: 8
+PointerAlignment: Left
+TabWidth: 4
+UseTab: Never
\ No newline at end of file
diff --git a/cros_gralloc/aidl/Allocator.cpp b/cros_gralloc/aidl/Allocator.cpp
new file mode 100644
index 0000000..0d81d5c
--- /dev/null
+++ b/cros_gralloc/aidl/Allocator.cpp
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2022 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "Allocator.h"
+
+#include <aidl/android/hardware/graphics/allocator/AllocationError.h>
+#include <aidlcommonsupport/NativeHandle.h>
+#include <android-base/logging.h>
+#include <android/binder_ibinder_platform.h>
+#include <gralloctypes/Gralloc4.h>
+#include <log/log.h>
+
+#include "cros_gralloc/gralloc4/CrosGralloc4Utils.h"
+
+using aidl::android::hardware::common::NativeHandle;
+using BufferDescriptorInfo =
+        android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo;
+
+namespace aidl::android::hardware::graphics::allocator::impl {
+namespace {
+
+inline ndk::ScopedAStatus ToBinderStatus(AllocationError error) {
+    return ndk::ScopedAStatus::fromServiceSpecificError(static_cast<int32_t>(error));
+}
+
+}  // namespace
+
+bool Allocator::init() {
+    mDriver = cros_gralloc_driver::get_instance();
+    return mDriver != nullptr;
+}
+
+// TODO(natsu): deduplicate with CrosGralloc4Allocator after the T release.
+ndk::ScopedAStatus Allocator::initializeMetadata(
+        cros_gralloc_handle_t crosHandle,
+        const struct cros_gralloc_buffer_descriptor& crosDescriptor) {
+    if (!mDriver) {
+        ALOGE("Failed to initializeMetadata. Driver is uninitialized.\n");
+        return ToBinderStatus(AllocationError::NO_RESOURCES);
+    }
+
+    if (!crosHandle) {
+        ALOGE("Failed to initializeMetadata. Invalid handle.\n");
+        return ToBinderStatus(AllocationError::NO_RESOURCES);
+    }
+
+    void* addr;
+    uint64_t size;
+    int ret = mDriver->get_reserved_region(crosHandle, &addr, &size);
+    if (ret) {
+        ALOGE("Failed to getReservedRegion.\n");
+        return ToBinderStatus(AllocationError::NO_RESOURCES);
+    }
+
+    CrosGralloc4Metadata* crosMetadata = reinterpret_cast<CrosGralloc4Metadata*>(addr);
+
+    snprintf(crosMetadata->name, CROS_GRALLOC4_METADATA_MAX_NAME_SIZE, "%s",
+             crosDescriptor.name.c_str());
+    crosMetadata->dataspace = common::Dataspace::UNKNOWN;
+    crosMetadata->blendMode = common::BlendMode::INVALID;
+
+    return ndk::ScopedAStatus::ok();
+}
+
+void Allocator::releaseBufferAndHandle(native_handle_t* handle) {
+    mDriver->release(handle);
+    native_handle_close(handle);
+    native_handle_delete(handle);
+}
+
+ndk::ScopedAStatus Allocator::allocate(const std::vector<uint8_t>& descriptor, int32_t count,
+                                       allocator::AllocationResult* outResult) {
+    if (!mDriver) {
+        ALOGE("Failed to allocate. Driver is uninitialized.\n");
+        return ToBinderStatus(AllocationError::NO_RESOURCES);
+    }
+
+    BufferDescriptorInfo description;
+
+    int ret = ::android::gralloc4::decodeBufferDescriptorInfo(descriptor, &description);
+    if (ret) {
+        ALOGE("Failed to allocate. Failed to decode buffer descriptor: %d.\n", ret);
+        return ToBinderStatus(AllocationError::BAD_DESCRIPTOR);
+    }
+
+    std::vector<native_handle_t*> handles;
+    handles.resize(count, nullptr);
+
+    for (int32_t i = 0; i < count; i++) {
+        ndk::ScopedAStatus status = allocate(description, &outResult->stride, &handles[i]);
+        if (!status.isOk()) {
+            for (int32_t j = 0; j < i; j++) {
+                releaseBufferAndHandle(handles[j]);
+            }
+            return status;
+        }
+    }
+
+    outResult->buffers.resize(count);
+    for (int32_t i = 0; i < count; i++) {
+        auto handle = handles[i];
+        outResult->buffers[i] = ::android::dupToAidl(handle);
+        releaseBufferAndHandle(handle);
+    }
+
+    return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Allocator::allocate(const BufferDescriptorInfo& descriptor, int32_t* outStride,
+                                       native_handle_t** outHandle) {
+    if (!mDriver) {
+        ALOGE("Failed to allocate. Driver is uninitialized.\n");
+        return ToBinderStatus(AllocationError::NO_RESOURCES);
+    }
+
+    struct cros_gralloc_buffer_descriptor crosDescriptor;
+    if (convertToCrosDescriptor(descriptor, &crosDescriptor)) {
+        return ToBinderStatus(AllocationError::UNSUPPORTED);
+    }
+
+    crosDescriptor.reserved_region_size += sizeof(CrosGralloc4Metadata);
+
+    if (!mDriver->is_supported(&crosDescriptor)) {
+        const std::string drmFormatString = get_drm_format_string(crosDescriptor.drm_format);
+        const std::string pixelFormatString = getPixelFormatString(descriptor.format);
+        const std::string usageString = getUsageString(descriptor.usage);
+        ALOGE("Failed to allocate. Unsupported combination: pixel format:%s, drm format:%s, "
+              "usage:%s\n",
+              pixelFormatString.c_str(), drmFormatString.c_str(), usageString.c_str());
+        return ToBinderStatus(AllocationError::UNSUPPORTED);
+    }
+
+    native_handle_t* handle;
+    int ret = mDriver->allocate(&crosDescriptor, &handle);
+    if (ret) {
+        return ToBinderStatus(AllocationError::NO_RESOURCES);
+    }
+
+    cros_gralloc_handle_t crosHandle = cros_gralloc_convert_handle(handle);
+
+    auto status = initializeMetadata(crosHandle, crosDescriptor);
+    if (!status.isOk()) {
+        ALOGE("Failed to allocate. Failed to initialize gralloc buffer metadata.");
+        releaseBufferAndHandle(handle);
+        return status;
+    }
+
+    *outStride = static_cast<int32_t>(crosHandle->pixel_stride);
+    *outHandle = handle;
+
+    return ndk::ScopedAStatus::ok();
+}
+
+::ndk::SpAIBinder Allocator::createBinder() {
+    auto binder = BnAllocator::createBinder();
+    AIBinder_setInheritRt(binder.get(), true);
+    return binder;
+}
+
+}  // namespace aidl::android::hardware::graphics::allocator::impl
\ No newline at end of file
diff --git a/cros_gralloc/aidl/Allocator.h b/cros_gralloc/aidl/Allocator.h
new file mode 100644
index 0000000..801c852
--- /dev/null
+++ b/cros_gralloc/aidl/Allocator.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2022 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef MINIGBM_CROSGRALLOC_AIDL_ALLOCATOR_H_
+#define MINIGBM_CROSGRALLOC_AIDL_ALLOCATOR_H_
+
+#include <aidl/android/hardware/graphics/allocator/AllocationResult.h>
+#include <aidl/android/hardware/graphics/allocator/BnAllocator.h>
+#include <android/hardware/graphics/mapper/4.0/IMapper.h>
+
+#include "cros_gralloc/cros_gralloc_driver.h"
+#include "cros_gralloc/cros_gralloc_helpers.h"
+#include "cros_gralloc/gralloc4/CrosGralloc4Metadata.h"
+
+namespace aidl::android::hardware::graphics::allocator::impl {
+
+class Allocator : public BnAllocator {
+  public:
+    Allocator() = default;
+
+    bool init();
+
+    ndk::ScopedAStatus allocate(const std::vector<uint8_t>& descriptor, int32_t count,
+                                allocator::AllocationResult* outResult) override;
+
+  protected:
+    ndk::SpAIBinder createBinder() override;
+
+  private:
+    ndk::ScopedAStatus allocate(
+            const ::android::hardware::graphics::mapper::V4_0::IMapper::BufferDescriptorInfo&
+                    descriptor,
+            int32_t* outStride, native_handle_t** outHandle);
+
+    ndk::ScopedAStatus initializeMetadata(
+            cros_gralloc_handle_t crosHandle,
+            const struct cros_gralloc_buffer_descriptor& crosDescriptor);
+
+    void releaseBufferAndHandle(native_handle_t* handle);
+
+    cros_gralloc_driver* mDriver = nullptr;
+};
+
+}  // namespace aidl::android::hardware::graphics::allocator::impl
+
+#endif
\ No newline at end of file
diff --git a/cros_gralloc/aidl/Android.bp b/cros_gralloc/aidl/Android.bp
new file mode 100644
index 0000000..71e2ae7
--- /dev/null
+++ b/cros_gralloc/aidl/Android.bp
@@ -0,0 +1,61 @@
+//
+// Copyright (C) 2022 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "external_minigbm_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-BSD
+    default_applicable_licenses: ["external_minigbm_license"],
+}
+
+cc_binary {
+    name: "android.hardware.graphics.allocator-V1-service.minigbm",
+    defaults: ["minigbm_cros_gralloc_defaults"],
+    relative_install_path: "hw",
+    init_rc: [":allocator_rc"],
+    vintf_fragments: [":allocator_xml"],
+    vendor: true,
+    shared_libs: [
+        "android.hardware.graphics.allocator-V1-ndk",
+        "android.hardware.graphics.mapper@4.0",
+        "libbase",
+        "libbinder_ndk",
+        "libgralloctypes",
+        "libhidlbase",
+        "liblog",
+        "libminigbm_gralloc",
+        "libminigbm_gralloc4_utils",
+    ],
+    static_libs: [
+        "libaidlcommonsupport",
+    ],
+    srcs: [
+        "Allocator.cpp",
+        "Main.cpp",
+    ],
+}
+
+filegroup {
+    name: "allocator_rc",
+    srcs: ["allocator.rc"],
+}
+
+filegroup {
+    name: "allocator_xml",
+    srcs: ["allocator.xml"],
+}
\ No newline at end of file
diff --git a/cros_gralloc/aidl/Main.cpp b/cros_gralloc/aidl/Main.cpp
new file mode 100644
index 0000000..c2c4c5c
--- /dev/null
+++ b/cros_gralloc/aidl/Main.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2022 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "Allocator.h"
+
+#include <android-base/logging.h>
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+#include <log/log.h>
+
+using aidl::android::hardware::graphics::allocator::impl::Allocator;
+
+int main(int /*argc*/, char** /*argv*/) {
+    ALOGI("Minigbm AIDL allocator starting up...");
+
+    // same as SF main thread
+    struct sched_param param = {0};
+    param.sched_priority = 2;
+    if (sched_setscheduler(0, SCHED_FIFO | SCHED_RESET_ON_FORK, &param) != 0) {
+        ALOGI("%s: failed to set priority: %s", __FUNCTION__, strerror(errno));
+    }
+
+    auto allocator = ndk::SharedRefBase::make<Allocator>();
+    CHECK(allocator != nullptr);
+
+    if (!allocator->init()) {
+        ALOGE("Failed to initialize Minigbm AIDL allocator.");
+        return EXIT_FAILURE;
+    }
+
+    const std::string instance = std::string() + Allocator::descriptor + "/default";
+    binder_status_t status =
+            AServiceManager_addService(allocator->asBinder().get(), instance.c_str());
+    CHECK_EQ(status, STATUS_OK);
+
+    ABinderProcess_setThreadPoolMaxThreadCount(4);
+    ABinderProcess_startThreadPool();
+    ABinderProcess_joinThreadPool();
+
+    return EXIT_FAILURE;
+}
\ No newline at end of file
diff --git a/cros_gralloc/aidl/allocator.rc b/cros_gralloc/aidl/allocator.rc
new file mode 100644
index 0000000..5859384
--- /dev/null
+++ b/cros_gralloc/aidl/allocator.rc
@@ -0,0 +1,7 @@
+service vendor.graphics.allocator /vendor/bin/hw/android.hardware.graphics.allocator-V1-service.minigbm
+    class hal animation
+    user system
+    group graphics drmrpc
+    capabilities SYS_NICE
+    onrestart restart surfaceflinger
+    task_profiles ServiceCapacityLow
\ No newline at end of file
diff --git a/cros_gralloc/aidl/allocator.xml b/cros_gralloc/aidl/allocator.xml
new file mode 100644
index 0000000..74fd4cd
--- /dev/null
+++ b/cros_gralloc/aidl/allocator.xml
@@ -0,0 +1,10 @@
+<manifest version="1.0" type="device">
+    <hal format="aidl">
+        <name>android.hardware.graphics.allocator</name>
+        <version>1</version>
+        <interface>
+            <name>IAllocator</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
\ No newline at end of file