1 /* 2 * Copyright 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <string> 20 #include <unordered_set> 21 #include <vector> 22 23 #include <aidl/android/hardware/graphics/allocator/AllocationError.h> 24 #include <aidl/android/hardware/graphics/allocator/IAllocator.h> 25 #include <android/hardware/graphics/allocator/4.0/IAllocator.h> 26 #include <android/hardware/graphics/mapper/4.0/IMapper.h> 27 #include <gtest/gtest.h> 28 #include <utils/StrongPointer.h> 29 30 namespace android { 31 namespace hardware { 32 namespace graphics { 33 namespace mapper { 34 namespace V4_0 { 35 namespace vts { 36 37 using android::hardware::graphics::allocator::V4_0::IAllocator; 38 39 // A wrapper to IAllocator and IMapper. 40 class Gralloc { 41 public: 42 enum class Tolerance : uint32_t { 43 kToleranceStrict = 0x0U, 44 kToleranceBadDescriptor = 0x1U << std::underlying_type_t<Error>(Error::BAD_DESCRIPTOR), 45 kToleranceBadBuffer = 0x1U << std::underlying_type_t<Error>(Error::BAD_BUFFER), 46 kToleranceBadValue = 0x1U << std::underlying_type_t<Error>(Error::BAD_VALUE), 47 kToleranceNoResource = 0x1U << std::underlying_type_t<Error>(Error::NO_RESOURCES), 48 kToleranceUnSupported = 0x1U << std::underlying_type_t<Error>(Error::UNSUPPORTED), 49 kToleranceAllErrors = ~0x0U, 50 }; 51 52 Gralloc(const std::string& aidlAllocatorServiceName = 53 "android.hardware.graphics.allocator.IAllocator/default", 54 const std::string& hidlAllocatorServiceName = "default", 55 const std::string& mapperServiceName = "default", bool errOnFailure = true); 56 ~Gralloc(); 57 toHidlError(aidl::android::hardware::graphics::allocator::AllocationError error)58 static Error toHidlError(aidl::android::hardware::graphics::allocator::AllocationError error) { 59 switch (error) { 60 case aidl::android::hardware::graphics::allocator::AllocationError::BAD_DESCRIPTOR: 61 return Error::BAD_DESCRIPTOR; 62 case aidl::android::hardware::graphics::allocator::AllocationError::NO_RESOURCES: 63 return Error::NO_RESOURCES; 64 case aidl::android::hardware::graphics::allocator::AllocationError::UNSUPPORTED: 65 return Error::UNSUPPORTED; 66 } 67 } toHidlError(const ndk::ScopedAStatus & status)68 static Error toHidlError(const ndk::ScopedAStatus& status) { 69 if (status.isOk()) { 70 return Error::NONE; 71 } 72 73 if (status.getExceptionCode() != EX_SERVICE_SPECIFIC) { 74 return Error::NO_RESOURCES; 75 } 76 77 return toHidlError( 78 static_cast<aidl::android::hardware::graphics::allocator::AllocationError>( 79 status.getServiceSpecificError())); 80 } 81 82 // IAllocator methods 83 hasAllocator()84 bool hasAllocator() { return mHidlAllocator != nullptr || mAidlAllocator != nullptr; } 85 86 // When import is false, this simply calls IAllocator::allocate. When import 87 // is true, the returned buffers are also imported into the mapper. 88 // 89 // Either case, the returned buffers must be freed with freeBuffer. 90 std::vector<const native_handle_t*> allocate( 91 const BufferDescriptor& descriptor, uint32_t count, bool import = true, 92 enum Tolerance tolerance = Tolerance::kToleranceStrict, uint32_t* outStride = nullptr); 93 94 const native_handle_t* allocate(const IMapper::BufferDescriptorInfo& descriptorInfo, 95 bool import, enum Tolerance tolerance, uint32_t* outStride); 96 allocate(const IMapper::BufferDescriptorInfo & descriptorInfo,bool import)97 const native_handle_t* allocate(const IMapper::BufferDescriptorInfo& descriptorInfo, 98 bool import) { 99 return allocate(descriptorInfo, import, Tolerance::kToleranceStrict); 100 } 101 allocate(const IMapper::BufferDescriptorInfo & descriptorInfo,bool import,enum Tolerance tolerance)102 const native_handle_t* allocate(const IMapper::BufferDescriptorInfo& descriptorInfo, 103 bool import, enum Tolerance tolerance) { 104 return allocate(descriptorInfo, import, tolerance, nullptr); 105 } 106 allocate(const IMapper::BufferDescriptorInfo & descriptorInfo,bool import,uint32_t * outStride)107 const native_handle_t* allocate(const IMapper::BufferDescriptorInfo& descriptorInfo, 108 bool import, uint32_t* outStride) { 109 return allocate(descriptorInfo, import, Tolerance::kToleranceStrict, outStride); 110 } 111 112 // Dispatches directly to the allocator 113 void rawAllocate(const BufferDescriptor& descriptor, uint32_t count, 114 std::function<void(Error, uint32_t, const hidl_vec<hidl_handle>&)> callback); 115 116 // IMapper methods 117 118 sp<IMapper> getMapper() const; 119 120 BufferDescriptor createDescriptor(const IMapper::BufferDescriptorInfo& descriptorInfo); 121 122 const native_handle_t* importBuffer(const hidl_handle& rawHandle, enum Tolerance tolerance); importBuffer(const hidl_handle & rawHandle)123 const native_handle_t* importBuffer(const hidl_handle& rawHandle) { 124 return importBuffer(rawHandle, Tolerance::kToleranceStrict); 125 } 126 127 void freeBuffer(const native_handle_t* bufferHandle); 128 129 // We use fd instead of hidl_handle in these functions to pass fences 130 // in and out of the mapper. The ownership of the fd is always transferred 131 // with each of these functions. 132 void* lock(const native_handle_t* bufferHandle, uint64_t cpuUsage, 133 const IMapper::Rect& accessRegion, int acquireFence); 134 int unlock(const native_handle_t* bufferHandle); 135 136 int flushLockedBuffer(const native_handle_t* bufferHandle); 137 void rereadLockedBuffer(const native_handle_t* bufferHandle); 138 139 bool validateBufferSize(const native_handle_t* bufferHandle, 140 const IMapper::BufferDescriptorInfo& descriptorInfo, uint32_t stride); 141 void getTransportSize(const native_handle_t* bufferHandle, uint32_t* outNumFds, 142 uint32_t* outNumInts); 143 144 bool isSupported(const IMapper::BufferDescriptorInfo& descriptorInfo); 145 146 // A version of isSupported that simply treats failure as no support, so it 147 // does not fail the test. 148 bool isSupportedNoFailure(const IMapper::BufferDescriptorInfo& descriptorInfo); 149 150 Error get(const native_handle_t* bufferHandle, const IMapper::MetadataType& metadataType, 151 hidl_vec<uint8_t>* outVec); 152 153 Error set(const native_handle_t* bufferHandle, const IMapper::MetadataType& metadataType, 154 const hidl_vec<uint8_t>& vec); 155 156 Error getFromBufferDescriptorInfo(const IMapper::BufferDescriptorInfo& descriptorInfo, 157 const IMapper::MetadataType& metadataType, 158 hidl_vec<uint8_t>* outVec); 159 160 Error getReservedRegion(const native_handle_t* bufferHandle, void** outReservedRegion, 161 uint64_t* outReservedSize); 162 163 private: canTolerate(Tolerance tolerance,Error error)164 bool canTolerate(Tolerance tolerance, Error error) { 165 return (std::underlying_type_t<Tolerance>(tolerance) & 166 0x1U << std::underlying_type_t<Error>(error)) != 0; 167 } 168 169 void init(const std::string& aidlAllocatorServiceName, 170 const std::string& hidlAllocatorServiceName, const std::string& mapperServiceName); 171 172 // initialize without checking for failure to get service 173 void initNoErr(const std::string& aidlAllocatorServiceName, 174 const std::string& hidlAllocatorServiceName, 175 const std::string& mapperServiceName); 176 const native_handle_t* cloneBuffer(const hidl_handle& rawHandle, enum Tolerance tolerance); cloneBuffer(const hidl_handle & rawHandle)177 const native_handle_t* cloneBuffer(const hidl_handle& rawHandle) { 178 return cloneBuffer(rawHandle, Tolerance::kToleranceStrict); 179 } 180 181 sp<IAllocator> mHidlAllocator; 182 std::shared_ptr<aidl::android::hardware::graphics::allocator::IAllocator> mAidlAllocator; 183 sp<IMapper> mMapper; 184 185 // Keep track of all cloned and imported handles. When a test fails with 186 // ASSERT_*, the destructor will free the handles for the test. 187 std::unordered_set<const native_handle_t*> mClonedBuffers; 188 std::unordered_set<const native_handle_t*> mImportedBuffers; 189 }; 190 191 } // namespace vts 192 } // namespace V4_0 193 } // namespace mapper 194 } // namespace graphics 195 } // namespace hardware 196 } // namespace android 197