/* * Copyright (C) 2021-2022 Arm Limited. All rights reserved. * * 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. */ /** * @file * Contains the implementation to get file descriptors for * reference Gralloc for the DRM Hardware Composer */ #define LOG_TAG "hwc-bufferinfo-mappermetadata-arm" #include #include #include #include #include #include #include #include #include #include using android::hardware::hidl_vec; using android::hardware::graphics::mapper::V4_0::Error; using android::hardware::graphics::mapper::V4_0::IMapper; namespace android { #define GRALLOC_ARM_METADATA_TYPE_NAME "arm.graphics.ArmMetadataType" const IMapper::MetadataType arm_plane_fds_metadata_type = { GRALLOC_ARM_METADATA_TYPE_NAME, static_cast(aidl::arm::graphics::ArmMetadataType::PLANE_FDS) }; static status_t DecodePlaneFds(const hidl_vec &input, std::vector *fds) { int64_t size = 0; auto input_size = input.size(); if (input_size < sizeof(int64_t)) { ALOGE("Bad input size %zu", input_size); return android::BAD_VALUE; } memcpy(&size, input.data(), sizeof(int64_t)); if (size < 0) { ALOGE("Bad fds size decoded %" PRId64, size); return android::BAD_VALUE; } auto fds_size = size * sizeof(int64_t); if (input_size - sizeof(int64_t) < fds_size) { ALOGE("Bad input size %d to expected %" PRId64, static_cast(input_size - sizeof(int64_t)), fds_size); return android::BAD_VALUE; } const uint8_t *fds_start = input.data() + sizeof(int64_t); fds->resize(size); memcpy(fds->data(), fds_start, fds_size); return android::OK; } int BufferInfoMapperMetadata::GetFds(buffer_handle_t buffer_handle, hwc_drm_bo_t *bo) { std::vector fds; android::status_t result = android::BAD_VALUE; const void *handle = reinterpret_cast(buffer_handle); static android::sp mapper = IMapper::getService(); mapper->get(const_cast(handle), arm_plane_fds_metadata_type, [&result, &fds](Error error, const hidl_vec &metadata) { switch (error) { case Error::NONE: break; case Error::UNSUPPORTED: ALOGE("Gralloc implementation does not support the metadata needed " "to access the plane fds"); result = android::BAD_VALUE; return; default: ALOGE("Gralloc metadata error %d", error); result = android::BAD_VALUE; return; } result = android::DecodePlaneFds(metadata, &fds); }); if (result != android::OK) { return result; } else if (fds.empty()) { return android::BAD_VALUE; } for (int i = 0; i < fds.size(); i++) { /* Check for valid fd and also that it doesn't overflow when casted */ if (fds[i] <= 0 || fds[i] > UINT_MAX) { ALOGE("Encountered invalid fd %" PRId64, fds[i]); return android::BAD_VALUE; } bo->prime_fds[i] = static_cast(fds[i]); } return result; } } /* end namespace android */