• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 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 #undef LOG_TAG
18 #define LOG_TAG "VtsHalGraphicsMapperStableC_TargetTest"
19 
20 #include <aidl/Vintf.h>
21 #include <aidl/android/hardware/graphics/allocator/AllocationError.h>
22 #include <aidl/android/hardware/graphics/allocator/AllocationResult.h>
23 #include <aidl/android/hardware/graphics/allocator/IAllocator.h>
24 #include <aidl/android/hardware/graphics/common/BufferUsage.h>
25 #include <aidl/android/hardware/graphics/common/PixelFormat.h>
26 #include <aidlcommonsupport/NativeHandle.h>
27 #include <android/binder_enums.h>
28 #include <android/binder_manager.h>
29 #include <android/dlext.h>
30 #include <android/hardware/graphics/mapper/IMapper.h>
31 #include <android/hardware/graphics/mapper/utils/IMapperMetadataTypes.h>
32 #include <gralloctypes/Gralloc4.h>
33 #include <hidl/GtestPrinter.h>
34 #include <system/graphics.h>
35 
36 #include <dlfcn.h>
37 #include <drm/drm_fourcc.h>
38 #include <gtest/gtest.h>
39 #include <vndksupport/linker.h>
40 #include <initializer_list>
41 #include <optional>
42 #include <string>
43 #include <tuple>
44 #include <vector>
45 
46 using namespace aidl::android::hardware::graphics::allocator;
47 using namespace aidl::android::hardware::graphics::common;
48 using namespace android;
49 using namespace android::hardware;
50 using namespace ::android::hardware::graphics::mapper;
51 
52 typedef AIMapper_Error (*AIMapper_loadIMapperFn)(AIMapper* _Nullable* _Nonnull outImplementation);
53 
operator |(BufferUsage lhs,BufferUsage rhs)54 inline constexpr BufferUsage operator|(BufferUsage lhs, BufferUsage rhs) {
55     using T = std::underlying_type_t<BufferUsage>;
56     return static_cast<BufferUsage>(static_cast<T>(lhs) | static_cast<T>(rhs));
57 }
58 
operator |=(BufferUsage & lhs,BufferUsage rhs)59 inline BufferUsage& operator|=(BufferUsage& lhs, BufferUsage rhs) {
60     lhs = lhs | rhs;
61     return lhs;
62 }
63 
64 struct YCbCr {
65     android_ycbcr yCbCr;
66     int64_t horizontalSubSampling;
67     int64_t verticalSubSampling;
68 };
69 
70 constexpr const char* STANDARD_METADATA_NAME =
71         "android.hardware.graphics.common.StandardMetadataType";
72 
isStandardMetadata(AIMapper_MetadataType metadataType)73 static bool isStandardMetadata(AIMapper_MetadataType metadataType) {
74     return strcmp(STANDARD_METADATA_NAME, metadataType.name) == 0;
75 }
76 
toString(const std::vector<StandardMetadataType> types)77 static std::string toString(const std::vector<StandardMetadataType> types) {
78     std::stringstream buf;
79     buf << "[";
80     for (auto type : types) {
81         buf << toString(type) << ", ";
82     }
83     buf.seekp(-2, buf.cur);
84     buf << "]";
85     return buf.str();
86 }
87 
88 class BufferHandle {
89     AIMapper* mIMapper;
90     buffer_handle_t mHandle = nullptr;
91 
92   public:
BufferHandle(AIMapper * mapper,native_handle_t * rawHandle)93     explicit BufferHandle(AIMapper* mapper, native_handle_t* rawHandle) : mIMapper(mapper) {
94         EXPECT_EQ(AIMAPPER_ERROR_NONE, mIMapper->v5.importBuffer(rawHandle, &mHandle));
95     }
96 
BufferHandle(BufferHandle && other)97     explicit BufferHandle(BufferHandle&& other) { *this = std::move(other); }
98 
operator =(BufferHandle && other)99     BufferHandle& operator=(BufferHandle&& other) noexcept {
100         reset();
101         mIMapper = other.mIMapper;
102         mHandle = other.mHandle;
103         other.mHandle = nullptr;
104         return *this;
105     }
106 
~BufferHandle()107     ~BufferHandle() { reset(); }
108 
operator bool() const109     constexpr explicit operator bool() const noexcept { return mHandle != nullptr; }
110 
operator *() const111     buffer_handle_t operator*() const noexcept { return mHandle; }
112 
reset()113     void reset() {
114         if (mHandle != nullptr) {
115             EXPECT_EQ(AIMAPPER_ERROR_NONE, mIMapper->v5.freeBuffer(mHandle));
116             mHandle = nullptr;
117         }
118     }
119 };
120 
121 class BufferAllocation {
122     AIMapper* mIMapper;
123     native_handle_t* mRawHandle;
124     uint32_t mStride;
125     const BufferDescriptorInfo mInfo;
126 
127   public:
128     BufferAllocation(const BufferAllocation&) = delete;
129     void operator=(const BufferAllocation&) = delete;
130 
BufferAllocation(AIMapper * mapper,native_handle_t * handle,uint32_t stride,const BufferDescriptorInfo & info)131     BufferAllocation(AIMapper* mapper, native_handle_t* handle, uint32_t stride,
132                      const BufferDescriptorInfo& info)
133         : mIMapper(mapper), mRawHandle(handle), mStride(stride), mInfo(info) {}
134 
~BufferAllocation()135     ~BufferAllocation() {
136         if (mRawHandle == nullptr) return;
137 
138         native_handle_close(mRawHandle);
139         native_handle_delete(mRawHandle);
140     }
141 
stride() const142     uint32_t stride() const { return mStride; }
info() const143     const BufferDescriptorInfo& info() const { return mInfo; }
144 
import()145     BufferHandle import() { return BufferHandle{mIMapper, mRawHandle}; }
146 
rawHandle() const147     const native_handle_t* rawHandle() const { return mRawHandle; }
148 };
149 
150 class GraphicsTestsBase {
151   private:
152     friend class BufferAllocation;
153     int32_t mIAllocatorVersion = 1;
154     std::shared_ptr<IAllocator> mAllocator;
155     AIMapper* mIMapper = nullptr;
156     AIMapper_loadIMapperFn mIMapperLoader;
157     int32_t* mIMapperHALVersion = nullptr;
158 
159   protected:
Initialize(std::shared_ptr<IAllocator> allocator)160     void Initialize(std::shared_ptr<IAllocator> allocator) {
161         mAllocator = allocator;
162         ASSERT_NE(nullptr, mAllocator.get()) << "failed to get allocator service";
163         ASSERT_TRUE(mAllocator->getInterfaceVersion(&mIAllocatorVersion).isOk());
164         ASSERT_GE(mIAllocatorVersion, 2);
165         std::string mapperSuffix;
166         auto status = mAllocator->getIMapperLibrarySuffix(&mapperSuffix);
167         ASSERT_TRUE(status.isOk()) << "Failed to get IMapper library suffix";
168         std::string lib_name = "mapper." + mapperSuffix + ".so";
169         void* so = AServiceManager_openDeclaredPassthroughHal("mapper", mapperSuffix.c_str(),
170                                                               RTLD_LOCAL | RTLD_NOW);
171         ASSERT_NE(nullptr, so) << "Failed to load " << lib_name;
172         mIMapperLoader = (AIMapper_loadIMapperFn)dlsym(so, "AIMapper_loadIMapper");
173         ASSERT_NE(nullptr, mIMapperLoader) << "AIMapper_locaIMapper missing from " << lib_name;
174         ASSERT_EQ(AIMAPPER_ERROR_NONE, mIMapperLoader(&mIMapper));
175         ASSERT_NE(mIMapper, nullptr);
176         mIMapperHALVersion = (int32_t*)dlsym(so, "ANDROID_HAL_MAPPER_VERSION");
177     }
178 
179   public:
getIMapperLoader() const180     AIMapper_loadIMapperFn getIMapperLoader() const { return mIMapperLoader; }
getHalVersion() const181     int32_t* getHalVersion() const { return mIMapperHALVersion; }
182 
allocate(const BufferDescriptorInfo & descriptorInfo)183     std::unique_ptr<BufferAllocation> allocate(const BufferDescriptorInfo& descriptorInfo) {
184         AllocationResult result;
185         ::ndk::ScopedAStatus status = mAllocator->allocate2(descriptorInfo, 1, &result);
186         if (!status.isOk()) {
187             status_t error = status.getExceptionCode();
188             if (error == EX_SERVICE_SPECIFIC) {
189                 error = status.getServiceSpecificError();
190                 EXPECT_NE(OK, error) << "Failed to set error properly";
191             } else {
192                 EXPECT_EQ(OK, error) << "Allocation transport failure";
193             }
194             return nullptr;
195         } else {
196             return std::make_unique<BufferAllocation>(mIMapper, dupFromAidl(result.buffers[0]),
197                                                       result.stride, descriptorInfo);
198         }
199     }
200 
allocateGeneric()201     std::unique_ptr<BufferAllocation> allocateGeneric() {
202         return allocate({
203                 .name = {"VTS_TEMP"},
204                 .width = 64,
205                 .height = 64,
206                 .layerCount = 1,
207                 .format = PixelFormat::RGBA_8888,
208                 .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
209                 .reservedSize = 0,
210         });
211     }
212 
isSupported(const BufferDescriptorInfo & descriptorInfo)213     bool isSupported(const BufferDescriptorInfo& descriptorInfo) {
214         bool ret = false;
215         EXPECT_TRUE(mAllocator->isSupported(descriptorInfo, &ret).isOk());
216         return ret;
217     }
218 
mapper() const219     AIMapper* mapper() const { return mIMapper; }
220 
221     template <StandardMetadataType T>
getStandardMetadata(buffer_handle_t bufferHandle)222     auto getStandardMetadata(buffer_handle_t bufferHandle)
223             -> decltype(StandardMetadata<T>::value::decode(nullptr, 0)) {
224         using Value = typename StandardMetadata<T>::value;
225         std::vector<uint8_t> buffer;
226         // Initial guess
227         buffer.resize(512);
228         int32_t sizeRequired = mapper()->v5.getStandardMetadata(
229                 bufferHandle, static_cast<int64_t>(T), buffer.data(), buffer.size());
230         if (sizeRequired < 0) {
231             EXPECT_EQ(-AIMAPPER_ERROR_UNSUPPORTED, sizeRequired)
232                     << "Received something other than UNSUPPORTED from valid getStandardMetadata "
233                        "call";
234             return std::nullopt;
235         }
236         if (sizeRequired > buffer.size()) {
237             buffer.resize(sizeRequired);
238             sizeRequired = mapper()->v5.getStandardMetadata(bufferHandle, static_cast<int64_t>(T),
239                                                             buffer.data(), buffer.size());
240         }
241         if (sizeRequired < 0 || sizeRequired > buffer.size()) {
242             ADD_FAILURE() << "getStandardMetadata failed, received " << sizeRequired
243                           << " with buffer size " << buffer.size();
244             // Generate a fail type
245             return std::nullopt;
246         }
247         return Value::decode(buffer.data(), sizeRequired);
248     }
249 
250     template <StandardMetadataType T>
setStandardMetadata(buffer_handle_t bufferHandle,const typename StandardMetadata<T>::value_type & value)251     AIMapper_Error setStandardMetadata(buffer_handle_t bufferHandle,
252                                        const typename StandardMetadata<T>::value_type& value) {
253         using Value = typename StandardMetadata<T>::value;
254         int32_t sizeRequired = Value::encode(value, nullptr, 0);
255         if (sizeRequired < 0) {
256             EXPECT_GE(sizeRequired, 0) << "Failed to calculate required size";
257             return static_cast<AIMapper_Error>(-sizeRequired);
258         }
259         std::vector<uint8_t> buffer;
260         buffer.resize(sizeRequired);
261         sizeRequired = Value::encode(value, buffer.data(), buffer.size());
262         if (sizeRequired < 0 || sizeRequired > buffer.size()) {
263             ADD_FAILURE() << "Failed to encode with calculated size " << sizeRequired
264                           << "; buffer size" << buffer.size();
265             return static_cast<AIMapper_Error>(-sizeRequired);
266         }
267         return mapper()->v5.setStandardMetadata(bufferHandle, static_cast<int64_t>(T),
268                                                 buffer.data(), sizeRequired);
269     }
270 
verifyRGBA8888PlaneLayouts(const std::vector<PlaneLayout> & planeLayouts)271     void verifyRGBA8888PlaneLayouts(const std::vector<PlaneLayout>& planeLayouts) {
272         ASSERT_EQ(1, planeLayouts.size());
273 
274         const auto& planeLayout = planeLayouts.front();
275 
276         ASSERT_EQ(4, planeLayout.components.size());
277 
278         int64_t offsetInBitsR = -1;
279         int64_t offsetInBitsG = -1;
280         int64_t offsetInBitsB = -1;
281         int64_t offsetInBitsA = -1;
282 
283         for (const auto& component : planeLayout.components) {
284             if (!gralloc4::isStandardPlaneLayoutComponentType(component.type)) {
285                 continue;
286             }
287             EXPECT_EQ(8, component.sizeInBits);
288             if (component.type.value == gralloc4::PlaneLayoutComponentType_R.value) {
289                 offsetInBitsR = component.offsetInBits;
290             }
291             if (component.type.value == gralloc4::PlaneLayoutComponentType_G.value) {
292                 offsetInBitsG = component.offsetInBits;
293             }
294             if (component.type.value == gralloc4::PlaneLayoutComponentType_B.value) {
295                 offsetInBitsB = component.offsetInBits;
296             }
297             if (component.type.value == gralloc4::PlaneLayoutComponentType_A.value) {
298                 offsetInBitsA = component.offsetInBits;
299             }
300         }
301 
302         EXPECT_EQ(0, offsetInBitsR);
303         EXPECT_EQ(8, offsetInBitsG);
304         EXPECT_EQ(16, offsetInBitsB);
305         EXPECT_EQ(24, offsetInBitsA);
306 
307         EXPECT_EQ(0, planeLayout.offsetInBytes);
308         EXPECT_EQ(32, planeLayout.sampleIncrementInBits);
309         // Skip testing stride because any stride is valid
310         EXPECT_LE(planeLayout.widthInSamples * planeLayout.heightInSamples * 4,
311                   planeLayout.totalSizeInBytes);
312         EXPECT_EQ(1, planeLayout.horizontalSubsampling);
313         EXPECT_EQ(1, planeLayout.verticalSubsampling);
314     }
315 
fillRGBA8888(uint8_t * data,uint32_t height,size_t strideInBytes,size_t widthInBytes)316     void fillRGBA8888(uint8_t* data, uint32_t height, size_t strideInBytes, size_t widthInBytes) {
317         for (uint32_t y = 0; y < height; y++) {
318             memset(data, y, widthInBytes);
319             data += strideInBytes;
320         }
321     }
322 
verifyRGBA8888(const buffer_handle_t bufferHandle,const uint8_t * data,uint32_t height,size_t strideInBytes,size_t widthInBytes)323     void verifyRGBA8888(const buffer_handle_t bufferHandle, const uint8_t* data, uint32_t height,
324                         size_t strideInBytes, size_t widthInBytes) {
325         auto decodeResult = getStandardMetadata<StandardMetadataType::PLANE_LAYOUTS>(bufferHandle);
326         ASSERT_TRUE(decodeResult.has_value());
327         const auto& planeLayouts = *decodeResult;
328         ASSERT_TRUE(planeLayouts.size() > 0);
329 
330         verifyRGBA8888PlaneLayouts(planeLayouts);
331 
332         for (uint32_t y = 0; y < height; y++) {
333             for (size_t i = 0; i < widthInBytes; i++) {
334                 EXPECT_EQ(static_cast<uint8_t>(y), data[i]);
335             }
336             data += strideInBytes;
337         }
338     }
339 
traverseYCbCrData(const android_ycbcr & yCbCr,int32_t width,int32_t height,int64_t hSubsampling,int64_t vSubsampling,std::function<void (uint8_t *,uint8_t)> traverseFuncion)340     void traverseYCbCrData(const android_ycbcr& yCbCr, int32_t width, int32_t height,
341                            int64_t hSubsampling, int64_t vSubsampling,
342                            std::function<void(uint8_t*, uint8_t)> traverseFuncion) {
343         auto yData = static_cast<uint8_t*>(yCbCr.y);
344         auto cbData = static_cast<uint8_t*>(yCbCr.cb);
345         auto crData = static_cast<uint8_t*>(yCbCr.cr);
346         auto yStride = yCbCr.ystride;
347         auto cStride = yCbCr.cstride;
348         auto chromaStep = yCbCr.chroma_step;
349 
350         for (uint32_t y = 0; y < height; y++) {
351             for (uint32_t x = 0; x < width; x++) {
352                 auto val = static_cast<uint8_t>(height * y + x);
353 
354                 traverseFuncion(yData + yStride * y + x, val);
355 
356                 if (y % vSubsampling == 0 && x % hSubsampling == 0) {
357                     uint32_t subSampleX = x / hSubsampling;
358                     uint32_t subSampleY = y / vSubsampling;
359                     const auto subSampleOffset = cStride * subSampleY + chromaStep * subSampleX;
360                     const auto subSampleVal =
361                             static_cast<uint8_t>(height * subSampleY + subSampleX);
362 
363                     traverseFuncion(cbData + subSampleOffset, subSampleVal);
364                     traverseFuncion(crData + subSampleOffset, subSampleVal + 1);
365                 }
366             }
367         }
368     }
369 
fillYCbCrData(const android_ycbcr & yCbCr,int32_t width,int32_t height,int64_t hSubsampling,int64_t vSubsampling)370     void fillYCbCrData(const android_ycbcr& yCbCr, int32_t width, int32_t height,
371                        int64_t hSubsampling, int64_t vSubsampling) {
372         traverseYCbCrData(yCbCr, width, height, hSubsampling, vSubsampling,
373                           [](auto address, auto fillingData) { *address = fillingData; });
374     }
375 
verifyYCbCrData(const android_ycbcr & yCbCr,int32_t width,int32_t height,int64_t hSubsampling,int64_t vSubsampling)376     void verifyYCbCrData(const android_ycbcr& yCbCr, int32_t width, int32_t height,
377                          int64_t hSubsampling, int64_t vSubsampling) {
378         traverseYCbCrData(
379                 yCbCr, width, height, hSubsampling, vSubsampling,
380                 [](auto address, auto expectedData) { EXPECT_EQ(*address, expectedData); });
381     }
382 
bitsToBytes(int64_t bits)383     constexpr uint64_t bitsToBytes(int64_t bits) { return bits / 8; }
bytesToBits(int64_t bytes)384     constexpr uint64_t bytesToBits(int64_t bytes) { return bytes * 8; }
385 
getAndroidYCbCr(buffer_handle_t bufferHandle,uint8_t * data,android_ycbcr * outYCbCr,int64_t * hSubsampling,int64_t * vSubsampling)386     void getAndroidYCbCr(buffer_handle_t bufferHandle, uint8_t* data, android_ycbcr* outYCbCr,
387                          int64_t* hSubsampling, int64_t* vSubsampling) {
388         auto decodeResult = getStandardMetadata<StandardMetadataType::PLANE_LAYOUTS>(bufferHandle);
389         ASSERT_TRUE(decodeResult.has_value());
390         const auto& planeLayouts = *decodeResult;
391         ASSERT_TRUE(planeLayouts.size() > 0);
392 
393         outYCbCr->y = nullptr;
394         outYCbCr->cb = nullptr;
395         outYCbCr->cr = nullptr;
396         outYCbCr->ystride = 0;
397         outYCbCr->cstride = 0;
398         outYCbCr->chroma_step = 0;
399 
400         for (const auto& planeLayout : planeLayouts) {
401             for (const auto& planeLayoutComponent : planeLayout.components) {
402                 if (!gralloc4::isStandardPlaneLayoutComponentType(planeLayoutComponent.type)) {
403                     continue;
404                 }
405                 ASSERT_EQ(0, planeLayoutComponent.offsetInBits % 8);
406 
407                 uint8_t* tmpData = data + planeLayout.offsetInBytes +
408                                    bitsToBytes(planeLayoutComponent.offsetInBits);
409                 uint64_t sampleIncrementInBytes;
410 
411                 auto type = static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value);
412                 switch (type) {
413                     case PlaneLayoutComponentType::Y:
414                         ASSERT_EQ(nullptr, outYCbCr->y);
415                         ASSERT_EQ(8, planeLayoutComponent.sizeInBits);
416                         ASSERT_EQ(8, planeLayout.sampleIncrementInBits);
417                         outYCbCr->y = tmpData;
418                         outYCbCr->ystride = planeLayout.strideInBytes;
419                         break;
420 
421                     case PlaneLayoutComponentType::CB:
422                     case PlaneLayoutComponentType::CR:
423                         ASSERT_EQ(0, planeLayout.sampleIncrementInBits % 8);
424 
425                         sampleIncrementInBytes = planeLayout.sampleIncrementInBits / 8;
426                         ASSERT_TRUE(sampleIncrementInBytes == 1 || sampleIncrementInBytes == 2);
427 
428                         if (outYCbCr->cstride == 0 && outYCbCr->chroma_step == 0) {
429                             outYCbCr->cstride = planeLayout.strideInBytes;
430                             outYCbCr->chroma_step = sampleIncrementInBytes;
431                         } else {
432                             ASSERT_EQ(outYCbCr->cstride, planeLayout.strideInBytes);
433                             ASSERT_EQ(outYCbCr->chroma_step, sampleIncrementInBytes);
434                         }
435 
436                         if (*hSubsampling == 0 && *vSubsampling == 0) {
437                             *hSubsampling = planeLayout.horizontalSubsampling;
438                             *vSubsampling = planeLayout.verticalSubsampling;
439                         } else {
440                             ASSERT_EQ(*hSubsampling, planeLayout.horizontalSubsampling);
441                             ASSERT_EQ(*vSubsampling, planeLayout.verticalSubsampling);
442                         }
443 
444                         if (type == PlaneLayoutComponentType::CB) {
445                             ASSERT_EQ(nullptr, outYCbCr->cb);
446                             outYCbCr->cb = tmpData;
447                         } else {
448                             ASSERT_EQ(nullptr, outYCbCr->cr);
449                             outYCbCr->cr = tmpData;
450                         }
451                         break;
452                     default:
453                         break;
454                 };
455             }
456         }
457 
458         ASSERT_NE(nullptr, outYCbCr->y);
459         ASSERT_NE(nullptr, outYCbCr->cb);
460         ASSERT_NE(nullptr, outYCbCr->cr);
461     }
462 
getAndroidYCbCr_10bit(const native_handle_t * bufferHandle,uint8_t * data)463     YCbCr getAndroidYCbCr_10bit(const native_handle_t* bufferHandle, uint8_t* data) {
464         YCbCr yCbCr_10bit;
465         auto decodeResult = getStandardMetadata<StandardMetadataType::PLANE_LAYOUTS>(bufferHandle);
466         if (!decodeResult.has_value()) {
467             ADD_FAILURE() << "failed to get plane layout";
468             return YCbCr{};
469         }
470         const auto& planeLayouts = *decodeResult;
471         EXPECT_EQ(2, planeLayouts.size());
472         EXPECT_EQ(1, planeLayouts[0].components.size());
473         EXPECT_EQ(2, planeLayouts[1].components.size());
474 
475         yCbCr_10bit.yCbCr.y = nullptr;
476         yCbCr_10bit.yCbCr.cb = nullptr;
477         yCbCr_10bit.yCbCr.cr = nullptr;
478         yCbCr_10bit.yCbCr.ystride = 0;
479         yCbCr_10bit.yCbCr.cstride = 0;
480         yCbCr_10bit.yCbCr.chroma_step = 0;
481         int64_t cb_offset = 0;
482         int64_t cr_offset = 0;
483 
484         for (const auto& planeLayout : planeLayouts) {
485             for (const auto& planeLayoutComponent : planeLayout.components) {
486                 if (!gralloc4::isStandardPlaneLayoutComponentType(planeLayoutComponent.type)) {
487                     continue;
488                 }
489 
490                 uint8_t* tmpData = data + planeLayout.offsetInBytes +
491                                    bitsToBytes(planeLayoutComponent.offsetInBits);
492                 uint64_t sampleIncrementInBytes = 0;
493                 auto type = static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value);
494                 switch (type) {
495                     case PlaneLayoutComponentType::Y:
496                         // For specs refer to:
497                         // https://docs.microsoft.com/en-us/windows/win32/medfound/10-bit-and-16-bit-yuv-video-formats
498                         EXPECT_EQ(6, planeLayoutComponent.offsetInBits);
499                         EXPECT_EQ(nullptr, yCbCr_10bit.yCbCr.y);
500                         EXPECT_EQ(10, planeLayoutComponent.sizeInBits);
501                         EXPECT_EQ(16, planeLayout.sampleIncrementInBits);
502 
503                         yCbCr_10bit.yCbCr.y = tmpData;
504                         yCbCr_10bit.yCbCr.ystride = planeLayout.strideInBytes;
505                         break;
506 
507                     case PlaneLayoutComponentType::CB:
508                     case PlaneLayoutComponentType::CR:
509                         sampleIncrementInBytes = bitsToBytes(planeLayout.sampleIncrementInBits);
510                         EXPECT_EQ(4, sampleIncrementInBytes);
511 
512                         if (yCbCr_10bit.yCbCr.cstride == 0 && yCbCr_10bit.yCbCr.chroma_step == 0) {
513                             yCbCr_10bit.yCbCr.cstride = planeLayout.strideInBytes;
514                             yCbCr_10bit.yCbCr.chroma_step = sampleIncrementInBytes;
515                         } else {
516                             EXPECT_EQ(yCbCr_10bit.yCbCr.cstride, planeLayout.strideInBytes);
517                             EXPECT_EQ(yCbCr_10bit.yCbCr.chroma_step, sampleIncrementInBytes);
518                         }
519 
520                         if (yCbCr_10bit.horizontalSubSampling == 0 &&
521                             yCbCr_10bit.verticalSubSampling == 0) {
522                             yCbCr_10bit.horizontalSubSampling = planeLayout.horizontalSubsampling;
523                             yCbCr_10bit.verticalSubSampling = planeLayout.verticalSubsampling;
524                         } else {
525                             EXPECT_EQ(yCbCr_10bit.horizontalSubSampling,
526                                       planeLayout.horizontalSubsampling);
527                             EXPECT_EQ(yCbCr_10bit.verticalSubSampling,
528                                       planeLayout.verticalSubsampling);
529                         }
530 
531                         if (type == PlaneLayoutComponentType::CB) {
532                             EXPECT_EQ(nullptr, yCbCr_10bit.yCbCr.cb);
533                             yCbCr_10bit.yCbCr.cb = tmpData;
534                             cb_offset = planeLayoutComponent.offsetInBits;
535                         } else {
536                             EXPECT_EQ(nullptr, yCbCr_10bit.yCbCr.cr);
537                             yCbCr_10bit.yCbCr.cr = tmpData;
538                             cr_offset = planeLayoutComponent.offsetInBits;
539                         }
540                         break;
541                     default:
542                         break;
543                 }
544             }
545         }
546 
547         EXPECT_EQ(cb_offset + bytesToBits(2), cr_offset);
548         EXPECT_NE(nullptr, yCbCr_10bit.yCbCr.y);
549         EXPECT_NE(nullptr, yCbCr_10bit.yCbCr.cb);
550         EXPECT_NE(nullptr, yCbCr_10bit.yCbCr.cr);
551         return yCbCr_10bit;
552     }
553 };
554 
555 class GraphicsMapperStableCTests
556     : public GraphicsTestsBase,
557       public ::testing::TestWithParam<std::tuple<std::string, std::shared_ptr<IAllocator>>> {
558   public:
SetUp()559     void SetUp() override { Initialize(std::get<1>(GetParam())); }
560 
TearDown()561     void TearDown() override {}
562 };
563 
TEST_P(GraphicsMapperStableCTests,VersionChecks)564 TEST_P(GraphicsMapperStableCTests, VersionChecks) {
565     ASSERT_NE(nullptr, getHalVersion()) << "Resolving ANDROID_HAL_MAPPER_VERSION symbol failed";
566     int32_t halVersion = *getHalVersion();
567     EXPECT_EQ(halVersion, AIMAPPER_VERSION_5) << "Unrecognized ANDROID_HAL_MAPPER_VERSION";
568     EXPECT_EQ(mapper()->version, AIMAPPER_VERSION_5) << "Unrecognized AIMapper::version";
569     EXPECT_EQ(halVersion, mapper()->version)
570             << "AIMapper version & ANDROID_HAL_MAPPER_VERSION don't agree";
571 }
572 
TEST_P(GraphicsMapperStableCTests,AllV5CallbacksDefined)573 TEST_P(GraphicsMapperStableCTests, AllV5CallbacksDefined) {
574     ASSERT_GE(mapper()->version, AIMAPPER_VERSION_5);
575 
576     EXPECT_TRUE(mapper()->v5.importBuffer);
577     EXPECT_TRUE(mapper()->v5.freeBuffer);
578     EXPECT_TRUE(mapper()->v5.getTransportSize);
579     EXPECT_TRUE(mapper()->v5.lock);
580     EXPECT_TRUE(mapper()->v5.unlock);
581     EXPECT_TRUE(mapper()->v5.flushLockedBuffer);
582     EXPECT_TRUE(mapper()->v5.rereadLockedBuffer);
583     EXPECT_TRUE(mapper()->v5.getMetadata);
584     EXPECT_TRUE(mapper()->v5.getStandardMetadata);
585     EXPECT_TRUE(mapper()->v5.setMetadata);
586     EXPECT_TRUE(mapper()->v5.setStandardMetadata);
587     EXPECT_TRUE(mapper()->v5.listSupportedMetadataTypes);
588     EXPECT_TRUE(mapper()->v5.dumpBuffer);
589     EXPECT_TRUE(mapper()->v5.getReservedRegion);
590 }
591 
TEST_P(GraphicsMapperStableCTests,DualLoadIsIdentical)592 TEST_P(GraphicsMapperStableCTests, DualLoadIsIdentical) {
593     ASSERT_GE(mapper()->version, AIMAPPER_VERSION_5);
594     AIMapper* secondMapper;
595     ASSERT_EQ(AIMAPPER_ERROR_NONE, getIMapperLoader()(&secondMapper));
596 
597     EXPECT_EQ(secondMapper->v5.importBuffer, mapper()->v5.importBuffer);
598     EXPECT_EQ(secondMapper->v5.freeBuffer, mapper()->v5.freeBuffer);
599     EXPECT_EQ(secondMapper->v5.getTransportSize, mapper()->v5.getTransportSize);
600     EXPECT_EQ(secondMapper->v5.lock, mapper()->v5.lock);
601     EXPECT_EQ(secondMapper->v5.unlock, mapper()->v5.unlock);
602     EXPECT_EQ(secondMapper->v5.flushLockedBuffer, mapper()->v5.flushLockedBuffer);
603     EXPECT_EQ(secondMapper->v5.rereadLockedBuffer, mapper()->v5.rereadLockedBuffer);
604     EXPECT_EQ(secondMapper->v5.getMetadata, mapper()->v5.getMetadata);
605     EXPECT_EQ(secondMapper->v5.getStandardMetadata, mapper()->v5.getStandardMetadata);
606     EXPECT_EQ(secondMapper->v5.setMetadata, mapper()->v5.setMetadata);
607     EXPECT_EQ(secondMapper->v5.setStandardMetadata, mapper()->v5.setStandardMetadata);
608     EXPECT_EQ(secondMapper->v5.listSupportedMetadataTypes, mapper()->v5.listSupportedMetadataTypes);
609     EXPECT_EQ(secondMapper->v5.dumpBuffer, mapper()->v5.dumpBuffer);
610     EXPECT_EQ(secondMapper->v5.getReservedRegion, mapper()->v5.getReservedRegion);
611 }
612 
TEST_P(GraphicsMapperStableCTests,CanAllocate)613 TEST_P(GraphicsMapperStableCTests, CanAllocate) {
614     auto buffer = allocate({
615             .name = {"VTS_TEMP"},
616             .width = 64,
617             .height = 64,
618             .layerCount = 1,
619             .format = PixelFormat::RGBA_8888,
620             .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
621             .reservedSize = 0,
622     });
623     ASSERT_NE(nullptr, buffer.get());
624     EXPECT_GE(buffer->stride(), 64);
625 }
626 
TEST_P(GraphicsMapperStableCTests,ImportFreeBuffer)627 TEST_P(GraphicsMapperStableCTests, ImportFreeBuffer) {
628     auto buffer = allocate({
629             .name = {"VTS_TEMP"},
630             .width = 64,
631             .height = 64,
632             .layerCount = 1,
633             .format = PixelFormat::RGBA_8888,
634             .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
635             .reservedSize = 0,
636     });
637     ASSERT_NE(nullptr, buffer.get());
638     EXPECT_GE(buffer->stride(), 64);
639 
640     {
641         auto import1 = buffer->import();
642         auto import2 = buffer->import();
643         EXPECT_TRUE(import1);
644         EXPECT_TRUE(import2);
645         EXPECT_NE(*import1, *import2);
646     }
647 }
648 
649 /**
650  * Test IMapper::importBuffer and IMapper::freeBuffer cross mapper instances.
651  */
TEST_P(GraphicsMapperStableCTests,ImportFreeBufferSingleton)652 TEST_P(GraphicsMapperStableCTests, ImportFreeBufferSingleton) {
653     auto buffer = allocate({
654             .name = {"VTS_TEMP"},
655             .width = 64,
656             .height = 64,
657             .layerCount = 1,
658             .format = PixelFormat::RGBA_8888,
659             .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
660             .reservedSize = 0,
661     });
662     ASSERT_NE(nullptr, buffer.get());
663     EXPECT_GE(buffer->stride(), 64);
664 
665     buffer_handle_t bufferHandle = nullptr;
666     ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.importBuffer(buffer->rawHandle(), &bufferHandle));
667     ASSERT_NE(nullptr, bufferHandle);
668 
669     AIMapper* secondMapper;
670     ASSERT_EQ(AIMAPPER_ERROR_NONE, getIMapperLoader()(&secondMapper));
671     ASSERT_EQ(AIMAPPER_ERROR_NONE, secondMapper->v5.freeBuffer(bufferHandle));
672 }
673 
674 /**
675  * Test IMapper::importBuffer with invalid buffers.
676  */
TEST_P(GraphicsMapperStableCTests,ImportBufferNegative)677 TEST_P(GraphicsMapperStableCTests, ImportBufferNegative) {
678     native_handle_t* invalidHandle = nullptr;
679     buffer_handle_t bufferHandle = nullptr;
680     EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.importBuffer(invalidHandle, &bufferHandle))
681             << "importBuffer with nullptr did not fail with BAD_BUFFER";
682 
683     invalidHandle = native_handle_create(0, 0);
684     EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.importBuffer(invalidHandle, &bufferHandle))
685             << "importBuffer with invalid handle did not fail with BAD_BUFFER";
686     native_handle_delete(invalidHandle);
687 }
688 
689 /**
690  * Test IMapper::freeBuffer with invalid buffers.
691  */
TEST_P(GraphicsMapperStableCTests,FreeBufferNegative)692 TEST_P(GraphicsMapperStableCTests, FreeBufferNegative) {
693     native_handle_t* bufferHandle = nullptr;
694     EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.freeBuffer(bufferHandle))
695             << "freeBuffer with nullptr did not fail with BAD_BUFFER";
696 
697     bufferHandle = native_handle_create(0, 0);
698     EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.freeBuffer(bufferHandle))
699             << "freeBuffer with invalid handle did not fail with BAD_BUFFER";
700     native_handle_delete(bufferHandle);
701 
702     auto buffer = allocateGeneric();
703     EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.freeBuffer(buffer->rawHandle()))
704             << "freeBuffer with un-imported handle did not fail with BAD_BUFFER";
705 }
706 
707 /**
708  * Test IMapper::lock and IMapper::unlock.
709  */
TEST_P(GraphicsMapperStableCTests,LockUnlockBasic)710 TEST_P(GraphicsMapperStableCTests, LockUnlockBasic) {
711     constexpr auto usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN;
712     auto buffer = allocate({
713             .name = {"VTS_TEMP"},
714             .width = 64,
715             .height = 64,
716             .layerCount = 1,
717             .format = PixelFormat::RGBA_8888,
718             .usage = usage,
719             .reservedSize = 0,
720     });
721     ASSERT_NE(nullptr, buffer.get());
722 
723     // lock buffer for writing
724     const auto& info = buffer->info();
725     const auto stride = buffer->stride();
726     const ARect region{0, 0, info.width, info.height};
727     auto handle = buffer->import();
728     uint8_t* data = nullptr;
729     ASSERT_EQ(AIMAPPER_ERROR_NONE,
730               mapper()->v5.lock(*handle, static_cast<int64_t>(usage), region, -1, (void**)&data));
731 
732     // RGBA_8888
733     fillRGBA8888(data, info.height, stride * 4, info.width * 4);
734 
735     int releaseFence = -1;
736     ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
737 
738     // lock again for reading
739     ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(usage), region,
740                                                      releaseFence, (void**)&data));
741     releaseFence = -1;
742 
743     ASSERT_NO_FATAL_FAILURE(verifyRGBA8888(*handle, data, info.height, stride * 4, info.width * 4));
744 
745     releaseFence = -1;
746     ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
747     if (releaseFence != -1) {
748         close(releaseFence);
749     }
750 }
751 
752 /**
753  * Test IMapper::lock and IMapper::unlock with no CPU usage requested.
754  */
TEST_P(GraphicsMapperStableCTests,LockUnlockNoCPUUsage)755 TEST_P(GraphicsMapperStableCTests, LockUnlockNoCPUUsage) {
756     constexpr auto usage = BufferUsage::CPU_READ_RARELY | BufferUsage::CPU_WRITE_NEVER;
757     auto buffer = allocate({
758             .name = {"VTS_TEMP"},
759             .width = 64,
760             .height = 64,
761             .layerCount = 1,
762             .format = PixelFormat::RGBA_8888,
763             .usage = usage,
764             .reservedSize = 0,
765     });
766     ASSERT_NE(nullptr, buffer.get());
767 
768     // lock buffer for writing
769     const auto& info = buffer->info();
770     const ARect region{0, 0, info.width, info.height};
771     auto handle = buffer->import();
772     uint8_t* data = nullptr;
773 
774     EXPECT_EQ(AIMAPPER_ERROR_BAD_VALUE, mapper()->v5.lock(*handle, 0, region, -1, (void**)&data))
775             << "Locking with 0 access succeeded";
776 
777     int releaseFence = -1;
778     EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.unlock(*handle, &releaseFence))
779             << "Unlocking not locked buffer succeeded";
780     if (releaseFence != -1) {
781         close(releaseFence);
782     }
783 }
784 
785 /**
786  *  Test multiple operations associated with different color formats
787  */
TEST_P(GraphicsMapperStableCTests,Lock_YCRCB_420_SP)788 TEST_P(GraphicsMapperStableCTests, Lock_YCRCB_420_SP) {
789     BufferDescriptorInfo info{
790             .name = {"VTS_TEMP"},
791             .width = 64,
792             .height = 64,
793             .layerCount = 1,
794             .format = PixelFormat::YCRCB_420_SP,
795             .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
796             .reservedSize = 0,
797     };
798     auto buffer = allocate(info);
799     if (!buffer) {
800         ASSERT_FALSE(isSupported(info));
801         GTEST_SUCCEED() << "YCRCB_420_SP format is unsupported";
802         return;
803     }
804 
805     // lock buffer for writing
806     const ARect region{0, 0, info.width, info.height};
807     auto handle = buffer->import();
808     uint8_t* data = nullptr;
809     ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
810                                                      region, -1, (void**)&data));
811 
812     android_ycbcr yCbCr;
813     int64_t hSubsampling = 0;
814     int64_t vSubsampling = 0;
815     ASSERT_NO_FATAL_FAILURE(getAndroidYCbCr(*handle, data, &yCbCr, &hSubsampling, &vSubsampling));
816 
817     constexpr uint32_t kCbCrSubSampleFactor = 2;
818     ASSERT_EQ(kCbCrSubSampleFactor, hSubsampling);
819     ASSERT_EQ(kCbCrSubSampleFactor, vSubsampling);
820 
821     auto cbData = static_cast<uint8_t*>(yCbCr.cb);
822     auto crData = static_cast<uint8_t*>(yCbCr.cr);
823     ASSERT_EQ(crData + 1, cbData);
824     ASSERT_EQ(2, yCbCr.chroma_step);
825 
826     fillYCbCrData(yCbCr, info.width, info.height, hSubsampling, vSubsampling);
827 
828     int releaseFence = -1;
829     ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
830 
831     // lock again for reading
832     ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
833                                                      region, releaseFence, (void**)&data));
834     releaseFence = -1;
835 
836     ASSERT_NO_FATAL_FAILURE(getAndroidYCbCr(*handle, data, &yCbCr, &hSubsampling, &vSubsampling));
837 
838     verifyYCbCrData(yCbCr, info.width, info.height, hSubsampling, vSubsampling);
839 
840     releaseFence = -1;
841     ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
842     if (releaseFence != -1) {
843         close(releaseFence);
844     }
845 }
846 
TEST_P(GraphicsMapperStableCTests,YV12SubsampleMetadata)847 TEST_P(GraphicsMapperStableCTests, YV12SubsampleMetadata) {
848     BufferDescriptorInfo info{
849             .name = {"VTS_TEMP"},
850             .width = 64,
851             .height = 64,
852             .layerCount = 1,
853             .format = PixelFormat::YV12,
854             .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
855             .reservedSize = 0,
856     };
857     auto buffer = allocate(info);
858     ASSERT_NE(nullptr, buffer.get());
859 
860     // lock buffer for writing
861     const ARect region{0, 0, info.width, info.height};
862     auto handle = buffer->import();
863     uint8_t* data = nullptr;
864     ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
865                                                      region, -1, (void**)&data));
866 
867     auto decodeResult = getStandardMetadata<StandardMetadataType::PLANE_LAYOUTS>(*handle);
868     ASSERT_TRUE(decodeResult.has_value());
869     const auto& planeLayouts = *decodeResult;
870 
871     ASSERT_EQ(3, planeLayouts.size());
872 
873     auto yPlane = planeLayouts[0];
874     auto crPlane = planeLayouts[1];
875     auto cbPlane = planeLayouts[2];
876 
877     constexpr uint32_t kCbCrSubSampleFactor = 2;
878     EXPECT_EQ(kCbCrSubSampleFactor, crPlane.horizontalSubsampling);
879     EXPECT_EQ(kCbCrSubSampleFactor, crPlane.verticalSubsampling);
880 
881     EXPECT_EQ(kCbCrSubSampleFactor, cbPlane.horizontalSubsampling);
882     EXPECT_EQ(kCbCrSubSampleFactor, cbPlane.verticalSubsampling);
883 
884     const long chromaSampleWidth = info.width / kCbCrSubSampleFactor;
885     const long chromaSampleHeight = info.height / kCbCrSubSampleFactor;
886 
887     EXPECT_EQ(info.width, yPlane.widthInSamples);
888     EXPECT_EQ(info.height, yPlane.heightInSamples);
889 
890     EXPECT_EQ(chromaSampleWidth, crPlane.widthInSamples);
891     EXPECT_EQ(chromaSampleHeight, crPlane.heightInSamples);
892 
893     EXPECT_EQ(chromaSampleWidth, cbPlane.widthInSamples);
894     EXPECT_EQ(chromaSampleHeight, cbPlane.heightInSamples);
895 
896     EXPECT_LE(crPlane.widthInSamples, crPlane.strideInBytes);
897     EXPECT_LE(cbPlane.widthInSamples, cbPlane.strideInBytes);
898 
899     int releaseFence = -1;
900     ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
901     if (releaseFence != -1) {
902         close(releaseFence);
903     }
904 }
905 
TEST_P(GraphicsMapperStableCTests,Lock_YV12)906 TEST_P(GraphicsMapperStableCTests, Lock_YV12) {
907     BufferDescriptorInfo info{
908             .name = {"VTS_TEMP"},
909             .width = 64,
910             .height = 64,
911             .layerCount = 1,
912             .format = PixelFormat::YV12,
913             .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
914             .reservedSize = 0,
915     };
916     auto buffer = allocate(info);
917     ASSERT_NE(nullptr, buffer.get());
918 
919     // lock buffer for writing
920     const ARect region{0, 0, info.width, info.height};
921     auto handle = buffer->import();
922     uint8_t* data = nullptr;
923     ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
924                                                      region, -1, (void**)&data));
925 
926     android_ycbcr yCbCr;
927     int64_t hSubsampling = 0;
928     int64_t vSubsampling = 0;
929     ASSERT_NO_FATAL_FAILURE(getAndroidYCbCr(*handle, data, &yCbCr, &hSubsampling, &vSubsampling));
930 
931     constexpr uint32_t kCbCrSubSampleFactor = 2;
932     ASSERT_EQ(kCbCrSubSampleFactor, hSubsampling);
933     ASSERT_EQ(kCbCrSubSampleFactor, vSubsampling);
934 
935     auto cbData = static_cast<uint8_t*>(yCbCr.cb);
936     auto crData = static_cast<uint8_t*>(yCbCr.cr);
937     ASSERT_EQ(crData + yCbCr.cstride * info.height / vSubsampling, cbData);
938     ASSERT_EQ(1, yCbCr.chroma_step);
939 
940     fillYCbCrData(yCbCr, info.width, info.height, hSubsampling, vSubsampling);
941 
942     int releaseFence = -1;
943     ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
944 
945     // lock again for reading
946     ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
947                                                      region, releaseFence, (void**)&data));
948     releaseFence = -1;
949 
950     ASSERT_NO_FATAL_FAILURE(getAndroidYCbCr(*handle, data, &yCbCr, &hSubsampling, &vSubsampling));
951 
952     verifyYCbCrData(yCbCr, info.width, info.height, hSubsampling, vSubsampling);
953 
954     ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
955     if (releaseFence != -1) {
956         close(releaseFence);
957     }
958 }
959 
TEST_P(GraphicsMapperStableCTests,Lock_YCBCR_420_888)960 TEST_P(GraphicsMapperStableCTests, Lock_YCBCR_420_888) {
961     BufferDescriptorInfo info{
962             .name = {"VTS_TEMP"},
963             .width = 64,
964             .height = 64,
965             .layerCount = 1,
966             .format = PixelFormat::YCBCR_420_888,
967             .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
968             .reservedSize = 0,
969     };
970     auto buffer = allocate(info);
971     ASSERT_NE(nullptr, buffer.get());
972 
973     // lock buffer for writing
974     const ARect region{0, 0, info.width, info.height};
975     auto handle = buffer->import();
976     uint8_t* data = nullptr;
977     ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
978                                                      region, -1, (void**)&data));
979 
980     android_ycbcr yCbCr;
981     int64_t hSubsampling = 0;
982     int64_t vSubsampling = 0;
983     ASSERT_NO_FATAL_FAILURE(getAndroidYCbCr(*handle, data, &yCbCr, &hSubsampling, &vSubsampling));
984 
985     constexpr uint32_t kCbCrSubSampleFactor = 2;
986     ASSERT_EQ(kCbCrSubSampleFactor, hSubsampling);
987     ASSERT_EQ(kCbCrSubSampleFactor, vSubsampling);
988 
989     fillYCbCrData(yCbCr, info.width, info.height, hSubsampling, vSubsampling);
990 
991     int releaseFence = -1;
992     ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
993 
994     // lock again for reading
995     ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
996                                                      region, releaseFence, (void**)&data));
997     releaseFence = -1;
998 
999     ASSERT_NO_FATAL_FAILURE(getAndroidYCbCr(*handle, data, &yCbCr, &hSubsampling, &vSubsampling));
1000 
1001     verifyYCbCrData(yCbCr, info.width, info.height, hSubsampling, vSubsampling);
1002 
1003     ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
1004     if (releaseFence != -1) {
1005         close(releaseFence);
1006     }
1007 }
1008 
TEST_P(GraphicsMapperStableCTests,Lock_RAW10)1009 TEST_P(GraphicsMapperStableCTests, Lock_RAW10) {
1010     BufferDescriptorInfo info{
1011             .name = {"VTS_TEMP"},
1012             .width = 64,
1013             .height = 64,
1014             .layerCount = 1,
1015             .format = PixelFormat::RAW10,
1016             .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
1017             .reservedSize = 0,
1018     };
1019     auto buffer = allocate(info);
1020     if (!buffer) {
1021         ASSERT_FALSE(isSupported(info));
1022         GTEST_SUCCEED() << "RAW10 format is unsupported";
1023         return;
1024     }
1025 
1026     // lock buffer for writing
1027     const ARect region{0, 0, info.width, info.height};
1028     auto handle = buffer->import();
1029     uint8_t* data = nullptr;
1030     ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
1031                                                      region, -1, (void**)&data));
1032 
1033     auto decodeResult = getStandardMetadata<StandardMetadataType::PLANE_LAYOUTS>(*handle);
1034     ASSERT_TRUE(decodeResult.has_value());
1035     const auto& planeLayouts = *decodeResult;
1036 
1037     ASSERT_EQ(1, planeLayouts.size());
1038     auto planeLayout = planeLayouts[0];
1039 
1040     EXPECT_EQ(0, planeLayout.sampleIncrementInBits);
1041     EXPECT_EQ(1, planeLayout.horizontalSubsampling);
1042     EXPECT_EQ(1, planeLayout.verticalSubsampling);
1043 
1044     ASSERT_EQ(1, planeLayout.components.size());
1045     auto planeLayoutComponent = planeLayout.components[0];
1046 
1047     EXPECT_EQ(PlaneLayoutComponentType::RAW,
1048               static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value));
1049     EXPECT_EQ(0, planeLayoutComponent.offsetInBits % 8);
1050     EXPECT_EQ(-1, planeLayoutComponent.sizeInBits);
1051 
1052     int releaseFence = -1;
1053     ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
1054     if (releaseFence != -1) {
1055         close(releaseFence);
1056     }
1057 }
1058 
TEST_P(GraphicsMapperStableCTests,Lock_RAW12)1059 TEST_P(GraphicsMapperStableCTests, Lock_RAW12) {
1060     BufferDescriptorInfo info{
1061             .name = {"VTS_TEMP"},
1062             .width = 64,
1063             .height = 64,
1064             .layerCount = 1,
1065             .format = PixelFormat::RAW12,
1066             .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
1067             .reservedSize = 0,
1068     };
1069     auto buffer = allocate(info);
1070     if (!buffer) {
1071         ASSERT_FALSE(isSupported(info));
1072         GTEST_SUCCEED() << "RAW12 format is unsupported";
1073         return;
1074     }
1075 
1076     // lock buffer for writing
1077     const ARect region{0, 0, info.width, info.height};
1078     auto handle = buffer->import();
1079     uint8_t* data = nullptr;
1080     ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
1081                                                      region, -1, (void**)&data));
1082 
1083     auto decodeResult = getStandardMetadata<StandardMetadataType::PLANE_LAYOUTS>(*handle);
1084     ASSERT_TRUE(decodeResult.has_value());
1085     const auto& planeLayouts = *decodeResult;
1086 
1087     ASSERT_EQ(1, planeLayouts.size());
1088     auto planeLayout = planeLayouts[0];
1089 
1090     EXPECT_EQ(0, planeLayout.sampleIncrementInBits);
1091     EXPECT_EQ(1, planeLayout.horizontalSubsampling);
1092     EXPECT_EQ(1, planeLayout.verticalSubsampling);
1093 
1094     ASSERT_EQ(1, planeLayout.components.size());
1095     auto planeLayoutComponent = planeLayout.components[0];
1096 
1097     EXPECT_EQ(PlaneLayoutComponentType::RAW,
1098               static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value));
1099     EXPECT_EQ(0, planeLayoutComponent.offsetInBits % 8);
1100     EXPECT_EQ(-1, planeLayoutComponent.sizeInBits);
1101 
1102     int releaseFence = -1;
1103     ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
1104     if (releaseFence != -1) {
1105         close(releaseFence);
1106     }
1107 }
1108 
TEST_P(GraphicsMapperStableCTests,Lock_YCBCR_P010)1109 TEST_P(GraphicsMapperStableCTests, Lock_YCBCR_P010) {
1110     BufferDescriptorInfo info{
1111             .name = {"VTS_TEMP"},
1112             .width = 64,
1113             .height = 64,
1114             .layerCount = 1,
1115             .format = PixelFormat::YCBCR_P010,
1116             .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
1117             .reservedSize = 0,
1118     };
1119     auto buffer = allocate(info);
1120     if (!buffer) {
1121         ASSERT_FALSE(isSupported(info));
1122         GTEST_SUCCEED() << "YCBCR_P010 format is unsupported";
1123         return;
1124     }
1125 
1126     // lock buffer for writing
1127     const ARect region{0, 0, info.width, info.height};
1128     auto handle = buffer->import();
1129     uint8_t* data = nullptr;
1130     ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
1131                                                      region, -1, (void**)&data));
1132 
1133     YCbCr yCbCr;
1134     ASSERT_NO_FATAL_FAILURE(yCbCr = getAndroidYCbCr_10bit(*handle, data));
1135 
1136     constexpr uint32_t kCbCrSubSampleFactor = 2;
1137     ASSERT_EQ(kCbCrSubSampleFactor, yCbCr.horizontalSubSampling);
1138     ASSERT_EQ(kCbCrSubSampleFactor, yCbCr.verticalSubSampling);
1139 
1140     ASSERT_EQ(0, info.height % 2);
1141 
1142     // fill the data
1143     fillYCbCrData(yCbCr.yCbCr, info.width, info.height, yCbCr.horizontalSubSampling,
1144                   yCbCr.verticalSubSampling);
1145     // verify the YCbCr data
1146     verifyYCbCrData(yCbCr.yCbCr, info.width, info.height, yCbCr.horizontalSubSampling,
1147                     yCbCr.verticalSubSampling);
1148 
1149     int releaseFence = -1;
1150     ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
1151     if (releaseFence != -1) {
1152         close(releaseFence);
1153     }
1154 }
1155 
TEST_P(GraphicsMapperStableCTests,Lock_YCBCR_P210)1156 TEST_P(GraphicsMapperStableCTests, Lock_YCBCR_P210) {
1157     BufferDescriptorInfo info{
1158         .name = {"VTS_TEMP"},
1159         .width = 64,
1160         .height = 64,
1161         .layerCount = 1,
1162         .format = PixelFormat::YCBCR_P210,
1163         .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
1164         .reservedSize = 0,
1165     };
1166     auto buffer = allocate(info);
1167     if (!buffer) {
1168         ASSERT_FALSE(isSupported(info));
1169         GTEST_SUCCEED() << "YCBCR_P210 format is unsupported";
1170         return;
1171     }
1172 
1173     // lock buffer for writing
1174     const ARect region{0, 0, info.width, info.height};
1175     auto handle = buffer->import();
1176     uint8_t *data = nullptr;
1177     ASSERT_EQ(AIMAPPER_ERROR_NONE,
1178               mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage), region,
1179                                 -1, (void **)&data));
1180 
1181     YCbCr yCbCr;
1182     ASSERT_NO_FATAL_FAILURE(yCbCr = getAndroidYCbCr_10bit(*handle, data));
1183 
1184     constexpr uint32_t kCbCrSubSampleFactor = 2;
1185     ASSERT_EQ(kCbCrSubSampleFactor, yCbCr.horizontalSubSampling);
1186     ASSERT_EQ(1, yCbCr.verticalSubSampling);
1187 
1188     ASSERT_EQ(0, info.height % 2);
1189 
1190     // fill the data
1191     fillYCbCrData(yCbCr.yCbCr, info.width, info.height,
1192                   yCbCr.horizontalSubSampling, yCbCr.verticalSubSampling);
1193     // verify the YCbCr data
1194     verifyYCbCrData(yCbCr.yCbCr, info.width, info.height,
1195                     yCbCr.horizontalSubSampling, yCbCr.verticalSubSampling);
1196 
1197     int releaseFence = -1;
1198     ASSERT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
1199     if (releaseFence != -1) {
1200         close(releaseFence);
1201     }
1202 }
1203 
TEST_P(GraphicsMapperStableCTests,LockBadAccessRegion)1204 TEST_P(GraphicsMapperStableCTests, LockBadAccessRegion) {
1205     auto buffer = allocateGeneric();
1206     ASSERT_NE(nullptr, buffer);
1207     const auto& info = buffer->info();
1208 
1209     // lock buffer for writing
1210     const ARect region{0, 0, info.width * 2, info.height * 2};
1211     auto handle = buffer->import();
1212     uint8_t* data = nullptr;
1213     EXPECT_EQ(AIMAPPER_ERROR_BAD_VALUE, mapper()->v5.lock(*handle, static_cast<int64_t>(info.usage),
1214                                                           region, -1, (void**)&data));
1215 }
1216 
TEST_P(GraphicsMapperStableCTests,UnlockNegative)1217 TEST_P(GraphicsMapperStableCTests, UnlockNegative) {
1218     native_handle_t* invalidHandle = nullptr;
1219     int releaseFence = -1;
1220     EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.unlock(invalidHandle, &releaseFence))
1221             << "unlock with nullptr did not fail with BAD_BUFFER";
1222 
1223     invalidHandle = native_handle_create(0, 0);
1224     EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.unlock(invalidHandle, &releaseFence))
1225             << "unlock with invalid handle did not fail with BAD_BUFFER";
1226     native_handle_delete(invalidHandle);
1227 
1228     auto buffer = allocateGeneric();
1229     EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.unlock(buffer->rawHandle(), &releaseFence))
1230             << "unlock with un-imported handle did not fail with BAD_BUFFER";
1231 }
1232 
TEST_P(GraphicsMapperStableCTests,UnlockNotImported)1233 TEST_P(GraphicsMapperStableCTests, UnlockNotImported) {
1234     int releaseFence = -1;
1235     auto buffer = allocateGeneric();
1236     ASSERT_TRUE(buffer);
1237     EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.unlock(buffer->rawHandle(), &releaseFence))
1238             << "unlock with un-imported handle did not fail with BAD_BUFFER";
1239 }
1240 
TEST_P(GraphicsMapperStableCTests,UnlockNotLocked)1241 TEST_P(GraphicsMapperStableCTests, UnlockNotLocked) {
1242     int releaseFence = -1;
1243     auto buffer = allocateGeneric();
1244     ASSERT_TRUE(buffer);
1245     auto bufferHandle = buffer->import();
1246     ASSERT_TRUE(bufferHandle);
1247     EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.unlock(*bufferHandle, &releaseFence))
1248             << "unlock with unlocked handle did not fail with BAD_BUFFER";
1249 }
1250 
TEST_P(GraphicsMapperStableCTests,LockUnlockNested)1251 TEST_P(GraphicsMapperStableCTests, LockUnlockNested) {
1252     auto buffer = allocateGeneric();
1253     ASSERT_TRUE(buffer);
1254     auto bufferHandle = buffer->import();
1255     ASSERT_TRUE(bufferHandle);
1256     const ARect region{0, 0, buffer->info().width, buffer->info().height};
1257     auto usage = static_cast<int64_t>(buffer->info().usage);
1258     auto handle = buffer->import();
1259     uint8_t* data = nullptr;
1260     EXPECT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, usage, region, -1, (void**)&data));
1261     EXPECT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.lock(*handle, usage, region, -1, (void**)&data))
1262             << "Second lock failed";
1263     int releaseFence = -1;
1264     EXPECT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence));
1265     if (releaseFence != -1) {
1266         close(releaseFence);
1267         releaseFence = -1;
1268     }
1269     EXPECT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*handle, &releaseFence))
1270             << "Second unlock failed";
1271     if (releaseFence != -1) {
1272         close(releaseFence);
1273         releaseFence = -1;
1274     }
1275     EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.unlock(*handle, &releaseFence))
1276             << "Third, unmatched, unlock should have failed with BAD_BUFFER";
1277 }
1278 
TEST_P(GraphicsMapperStableCTests,FlushRereadBasic)1279 TEST_P(GraphicsMapperStableCTests, FlushRereadBasic) {
1280     auto buffer = allocateGeneric();
1281     ASSERT_TRUE(buffer);
1282     auto bufferHandle = buffer->import();
1283     ASSERT_TRUE(bufferHandle);
1284     const auto& info = buffer->info();
1285     const auto stride = buffer->stride();
1286     const ARect region{0, 0, buffer->info().width, buffer->info().height};
1287 
1288     auto writeHandle = buffer->import();
1289     auto readHandle = buffer->import();
1290     ASSERT_TRUE(writeHandle && readHandle);
1291 
1292     // lock buffer for writing
1293 
1294     uint8_t* writeData;
1295     EXPECT_EQ(AIMAPPER_ERROR_NONE,
1296               mapper()->v5.lock(*writeHandle, static_cast<uint64_t>(BufferUsage::CPU_WRITE_OFTEN),
1297                                 region, -1, (void**)&writeData));
1298 
1299     uint8_t* readData;
1300     EXPECT_EQ(AIMAPPER_ERROR_NONE,
1301               mapper()->v5.lock(*readHandle, static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN),
1302                                 region, -1, (void**)&readData));
1303 
1304     fillRGBA8888(writeData, info.height, stride * 4, info.width * 4);
1305 
1306     EXPECT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.flushLockedBuffer(*writeHandle));
1307     EXPECT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.rereadLockedBuffer(*readHandle));
1308 
1309     ASSERT_NO_FATAL_FAILURE(
1310             verifyRGBA8888(*readHandle, readData, info.height, stride * 4, info.width * 4));
1311 
1312     int releaseFence = -1;
1313 
1314     EXPECT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*readHandle, &releaseFence));
1315     if (releaseFence != -1) {
1316         close(releaseFence);
1317         releaseFence = -1;
1318     }
1319 
1320     EXPECT_EQ(AIMAPPER_ERROR_NONE, mapper()->v5.unlock(*writeHandle, &releaseFence));
1321     if (releaseFence != -1) {
1322         close(releaseFence);
1323         releaseFence = -1;
1324     }
1325 }
1326 
TEST_P(GraphicsMapperStableCTests,FlushLockedBufferBadBuffer)1327 TEST_P(GraphicsMapperStableCTests, FlushLockedBufferBadBuffer) {
1328     // Amazingly this is enough to make the compiler happy even though flushLockedBuffer
1329     // is _Nonnull :shrug:
1330     buffer_handle_t badBuffer = nullptr;
1331     EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.flushLockedBuffer(badBuffer));
1332 }
1333 
TEST_P(GraphicsMapperStableCTests,RereadLockedBufferBadBuffer)1334 TEST_P(GraphicsMapperStableCTests, RereadLockedBufferBadBuffer) {
1335     buffer_handle_t badBuffer = nullptr;
1336     EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, mapper()->v5.rereadLockedBuffer(badBuffer));
1337 }
1338 
TEST_P(GraphicsMapperStableCTests,GetBufferId)1339 TEST_P(GraphicsMapperStableCTests, GetBufferId) {
1340     auto buffer = allocateGeneric();
1341     auto bufferHandle = buffer->import();
1342     auto bufferId = getStandardMetadata<StandardMetadataType::BUFFER_ID>(*bufferHandle);
1343     ASSERT_TRUE(bufferId.has_value());
1344 
1345     auto buffer2 = allocateGeneric();
1346     auto bufferHandle2 = buffer2->import();
1347     auto bufferId2 = getStandardMetadata<StandardMetadataType::BUFFER_ID>(*bufferHandle2);
1348     ASSERT_TRUE(bufferId2.has_value());
1349 
1350     EXPECT_NE(*bufferId, *bufferId2);
1351 }
1352 
TEST_P(GraphicsMapperStableCTests,GetName)1353 TEST_P(GraphicsMapperStableCTests, GetName) {
1354     auto buffer = allocate({
1355             .name = {"Hello, World!"},
1356             .width = 64,
1357             .height = 64,
1358             .layerCount = 1,
1359             .format = PixelFormat::RGBA_8888,
1360             .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
1361             .reservedSize = 0,
1362     });
1363     auto bufferHandle = buffer->import();
1364     auto name = getStandardMetadata<StandardMetadataType::NAME>(*bufferHandle);
1365     ASSERT_TRUE(name.has_value());
1366     EXPECT_EQ(*name, "Hello, World!");
1367 }
1368 
TEST_P(GraphicsMapperStableCTests,GetWidthHeight)1369 TEST_P(GraphicsMapperStableCTests, GetWidthHeight) {
1370     auto buffer = allocate({
1371             .name = {"Hello, World!"},
1372             .width = 64,
1373             .height = 128,
1374             .layerCount = 1,
1375             .format = PixelFormat::RGBA_8888,
1376             .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
1377             .reservedSize = 0,
1378     });
1379     auto bufferHandle = buffer->import();
1380     auto value = getStandardMetadata<StandardMetadataType::WIDTH>(*bufferHandle);
1381     ASSERT_TRUE(value.has_value());
1382     EXPECT_EQ(*value, 64);
1383     value = getStandardMetadata<StandardMetadataType::HEIGHT>(*bufferHandle);
1384     ASSERT_TRUE(value.has_value());
1385     EXPECT_EQ(*value, 128);
1386 }
1387 
TEST_P(GraphicsMapperStableCTests,GetLayerCount)1388 TEST_P(GraphicsMapperStableCTests, GetLayerCount) {
1389     auto buffer = allocateGeneric();
1390     auto bufferHandle = buffer->import();
1391     auto value = getStandardMetadata<StandardMetadataType::LAYER_COUNT>(*bufferHandle);
1392     ASSERT_TRUE(value.has_value());
1393     EXPECT_EQ(*value, buffer->info().layerCount);
1394 }
1395 
TEST_P(GraphicsMapperStableCTests,GetPixelFormatRequested)1396 TEST_P(GraphicsMapperStableCTests, GetPixelFormatRequested) {
1397     auto buffer = allocateGeneric();
1398     auto bufferHandle = buffer->import();
1399     auto value = getStandardMetadata<StandardMetadataType::PIXEL_FORMAT_REQUESTED>(*bufferHandle);
1400     ASSERT_TRUE(value.has_value());
1401     EXPECT_EQ(*value, buffer->info().format);
1402 }
1403 
TEST_P(GraphicsMapperStableCTests,GetPixelFormatFourCC)1404 TEST_P(GraphicsMapperStableCTests, GetPixelFormatFourCC) {
1405     auto buffer = allocate({
1406             .name = {"Hello, World!"},
1407             .width = 64,
1408             .height = 128,
1409             .layerCount = 1,
1410             .format = PixelFormat::RGBA_8888,
1411             .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
1412             .reservedSize = 0,
1413     });
1414     {
1415         auto bufferHandle = buffer->import();
1416         auto value = getStandardMetadata<StandardMetadataType::PIXEL_FORMAT_FOURCC>(*bufferHandle);
1417         ASSERT_TRUE(value.has_value());
1418         EXPECT_EQ(*value, DRM_FORMAT_ABGR8888);
1419     }
1420 
1421     buffer = allocate({
1422             .name = {"yv12"},
1423             .width = 64,
1424             .height = 128,
1425             .layerCount = 1,
1426             .format = PixelFormat::YV12,
1427             .usage = BufferUsage::CPU_WRITE_OFTEN | BufferUsage::CPU_READ_OFTEN,
1428             .reservedSize = 0,
1429     });
1430     {
1431         auto bufferHandle = buffer->import();
1432         auto value = getStandardMetadata<StandardMetadataType::PIXEL_FORMAT_FOURCC>(*bufferHandle);
1433         ASSERT_TRUE(value.has_value());
1434         EXPECT_EQ(*value, DRM_FORMAT_YVU420);
1435     }
1436 }
1437 
TEST_P(GraphicsMapperStableCTests,GetPixelFormatModifier)1438 TEST_P(GraphicsMapperStableCTests, GetPixelFormatModifier) {
1439     auto buffer = allocateGeneric();
1440     auto bufferHandle = buffer->import();
1441     auto value = getStandardMetadata<StandardMetadataType::PIXEL_FORMAT_MODIFIER>(*bufferHandle);
1442     ASSERT_TRUE(value.has_value());
1443     // Only the upper 8-bits are defined and is just the vendor ID, the lower 56 bits are
1444     // then vendor specific. So there's not anything useful to assert here beyond just that
1445     // we successfully queried a value
1446 }
1447 
TEST_P(GraphicsMapperStableCTests,GetUsage)1448 TEST_P(GraphicsMapperStableCTests, GetUsage) {
1449     auto buffer = allocateGeneric();
1450     auto bufferHandle = buffer->import();
1451     auto value = getStandardMetadata<StandardMetadataType::USAGE>(*bufferHandle);
1452     ASSERT_TRUE(value.has_value());
1453     EXPECT_EQ(buffer->info().usage, *value);
1454 }
1455 
TEST_P(GraphicsMapperStableCTests,GetUsage64)1456 TEST_P(GraphicsMapperStableCTests, GetUsage64) {
1457     BufferDescriptorInfo info{
1458             .name = {"VTS_TEMP"},
1459             .width = 64,
1460             .height = 64,
1461             .layerCount = 1,
1462             .format = PixelFormat::RGBA_8888,
1463             .usage = BufferUsage::FRONT_BUFFER | BufferUsage::GPU_RENDER_TARGET |
1464                      BufferUsage::COMPOSER_OVERLAY | BufferUsage::GPU_TEXTURE,
1465             .reservedSize = 0,
1466     };
1467     if (!isSupported(info)) {
1468         GTEST_SKIP();
1469     }
1470     auto buffer = allocate(info);
1471     auto bufferHandle = buffer->import();
1472     auto value = getStandardMetadata<StandardMetadataType::USAGE>(*bufferHandle);
1473     ASSERT_TRUE(value.has_value());
1474     using T = std::underlying_type_t<BufferUsage>;
1475     EXPECT_EQ(static_cast<T>(buffer->info().usage), static_cast<T>(*value));
1476 }
1477 
TEST_P(GraphicsMapperStableCTests,GetAllocationSize)1478 TEST_P(GraphicsMapperStableCTests, GetAllocationSize) {
1479     auto buffer = allocateGeneric();
1480     auto bufferHandle = buffer->import();
1481     auto value = getStandardMetadata<StandardMetadataType::ALLOCATION_SIZE>(*bufferHandle);
1482     ASSERT_TRUE(value.has_value());
1483     const auto estimatedSize = buffer->stride() * buffer->info().height * 4;
1484     // This buffer has CPU usage, so we expect at least stride * height * 4 since it should be
1485     // generally linear uncompressed.
1486     EXPECT_GE(*value, estimatedSize)
1487             << "Expected allocation size to be at least stride * height * 4bpp";
1488     // Might need refining, but hopefully this a generous-enough upper-bound?
1489     EXPECT_LT(*value, estimatedSize * 2)
1490             << "Expected allocation size to less than double stride * height * 4bpp";
1491 }
1492 
TEST_P(GraphicsMapperStableCTests,GetProtectedContent)1493 TEST_P(GraphicsMapperStableCTests, GetProtectedContent) {
1494     const BufferDescriptorInfo info{
1495             .name = {"prot8888"},
1496             .width = 64,
1497             .height = 64,
1498             .layerCount = 1,
1499             .format = PixelFormat::RGBA_8888,
1500             .usage = BufferUsage::PROTECTED | BufferUsage::COMPOSER_OVERLAY,
1501             .reservedSize = 0,
1502     };
1503     auto buffer = allocate(info);
1504     if (!buffer) {
1505         ASSERT_FALSE(isSupported(info))
1506                 << "Allocation of trivial sized buffer failed, so isSupported() must be false";
1507         GTEST_SUCCEED() << "PROTECTED RGBA_8888 is unsupported";
1508         return;
1509     }
1510     auto bufferHandle = buffer->import();
1511     auto value = getStandardMetadata<StandardMetadataType::PROTECTED_CONTENT>(*bufferHandle);
1512     ASSERT_TRUE(value.has_value());
1513     EXPECT_EQ(*value, 1);
1514 }
1515 
TEST_P(GraphicsMapperStableCTests,GetCompression)1516 TEST_P(GraphicsMapperStableCTests, GetCompression) {
1517     auto buffer = allocateGeneric();
1518     ASSERT_TRUE(buffer);
1519     auto bufferHandle = buffer->import();
1520     ASSERT_TRUE(bufferHandle);
1521     auto value = getStandardMetadata<StandardMetadataType::COMPRESSION>(*bufferHandle);
1522     ASSERT_TRUE(value.has_value());
1523     EXPECT_EQ(gralloc4::Compression_None.name, value->name);
1524     EXPECT_EQ(gralloc4::Compression_None.value, value->value);
1525 }
1526 
TEST_P(GraphicsMapperStableCTests,GetInterlaced)1527 TEST_P(GraphicsMapperStableCTests, GetInterlaced) {
1528     auto buffer = allocateGeneric();
1529     ASSERT_TRUE(buffer);
1530     auto bufferHandle = buffer->import();
1531     ASSERT_TRUE(bufferHandle);
1532     auto value = getStandardMetadata<StandardMetadataType::INTERLACED>(*bufferHandle);
1533     ASSERT_TRUE(value.has_value());
1534     EXPECT_EQ(gralloc4::Interlaced_None.name, value->name);
1535     EXPECT_EQ(gralloc4::Interlaced_None.value, value->value);
1536 }
1537 
TEST_P(GraphicsMapperStableCTests,GetChromaSiting)1538 TEST_P(GraphicsMapperStableCTests, GetChromaSiting) {
1539     auto buffer = allocateGeneric();
1540     ASSERT_TRUE(buffer);
1541     auto bufferHandle = buffer->import();
1542     ASSERT_TRUE(bufferHandle);
1543     auto value = getStandardMetadata<StandardMetadataType::CHROMA_SITING>(*bufferHandle);
1544     ASSERT_TRUE(value.has_value());
1545     EXPECT_EQ(gralloc4::ChromaSiting_None.name, value->name);
1546     EXPECT_EQ(gralloc4::ChromaSiting_None.value, value->value);
1547 }
1548 
TEST_P(GraphicsMapperStableCTests,GetPlaneLayouts)1549 TEST_P(GraphicsMapperStableCTests, GetPlaneLayouts) {
1550     auto buffer = allocateGeneric();
1551     ASSERT_TRUE(buffer);
1552     auto bufferHandle = buffer->import();
1553     ASSERT_TRUE(bufferHandle);
1554     auto value = getStandardMetadata<StandardMetadataType::PLANE_LAYOUTS>(*bufferHandle);
1555     ASSERT_TRUE(value.has_value());
1556     ASSERT_NO_FATAL_FAILURE(verifyRGBA8888PlaneLayouts(*value));
1557 }
1558 
TEST_P(GraphicsMapperStableCTests,GetCrop)1559 TEST_P(GraphicsMapperStableCTests, GetCrop) {
1560     auto buffer = allocateGeneric();
1561     ASSERT_TRUE(buffer);
1562     auto bufferHandle = buffer->import();
1563     ASSERT_TRUE(bufferHandle);
1564     auto value = getStandardMetadata<StandardMetadataType::CROP>(*bufferHandle);
1565     ASSERT_TRUE(value.has_value());
1566     EXPECT_EQ(1, value->size());
1567     const Rect expected{0, 0, buffer->info().width, buffer->info().height};
1568     EXPECT_EQ(expected, value->at(0));
1569 }
1570 
TEST_P(GraphicsMapperStableCTests,GetSetDataspace)1571 TEST_P(GraphicsMapperStableCTests, GetSetDataspace) {
1572     auto buffer = allocateGeneric();
1573     ASSERT_TRUE(buffer);
1574     auto bufferHandle = buffer->import();
1575     ASSERT_TRUE(bufferHandle);
1576     auto value = getStandardMetadata<StandardMetadataType::DATASPACE>(*bufferHandle);
1577     ASSERT_TRUE(value.has_value());
1578     EXPECT_EQ(Dataspace::UNKNOWN, *value);
1579     EXPECT_EQ(AIMAPPER_ERROR_NONE, setStandardMetadata<StandardMetadataType::DATASPACE>(
1580                                            *bufferHandle, Dataspace::DISPLAY_P3));
1581     value = getStandardMetadata<StandardMetadataType::DATASPACE>(*bufferHandle);
1582     ASSERT_TRUE(value.has_value());
1583     EXPECT_EQ(Dataspace::DISPLAY_P3, *value);
1584 }
1585 
TEST_P(GraphicsMapperStableCTests,GetSetBlendMode)1586 TEST_P(GraphicsMapperStableCTests, GetSetBlendMode) {
1587     auto buffer = allocateGeneric();
1588     ASSERT_TRUE(buffer);
1589     auto bufferHandle = buffer->import();
1590     ASSERT_TRUE(bufferHandle);
1591     auto value = getStandardMetadata<StandardMetadataType::BLEND_MODE>(*bufferHandle);
1592     ASSERT_TRUE(value.has_value());
1593     EXPECT_EQ(BlendMode::INVALID, *value);
1594     EXPECT_EQ(AIMAPPER_ERROR_NONE, setStandardMetadata<StandardMetadataType::BLEND_MODE>(
1595                                            *bufferHandle, BlendMode::COVERAGE));
1596     value = getStandardMetadata<StandardMetadataType::BLEND_MODE>(*bufferHandle);
1597     ASSERT_TRUE(value.has_value());
1598     EXPECT_EQ(BlendMode::COVERAGE, *value);
1599 }
1600 
TEST_P(GraphicsMapperStableCTests,GetSetSmpte2086)1601 TEST_P(GraphicsMapperStableCTests, GetSetSmpte2086) {
1602     auto buffer = allocateGeneric();
1603     ASSERT_TRUE(buffer);
1604     auto bufferHandle = buffer->import();
1605     ASSERT_TRUE(bufferHandle);
1606     auto value = getStandardMetadata<StandardMetadataType::SMPTE2086>(*bufferHandle);
1607     ASSERT_TRUE(value.has_value());
1608     EXPECT_FALSE(value->has_value());
1609 
1610     // TODO: Maybe use something resembling real values, but validation isn't supposed to happen
1611     // here anyway so :shrug:
1612     const Smpte2086 awesomeHdr{
1613             XyColor{1.f, 1.f},      XyColor{2.f, 2.f}, XyColor{3.f, 3.f},
1614             XyColor{400.f, 1000.f}, 100000.0f,         0.0001f,
1615     };
1616     EXPECT_EQ(AIMAPPER_ERROR_NONE,
1617               setStandardMetadata<StandardMetadataType::SMPTE2086>(*bufferHandle, awesomeHdr));
1618     value = getStandardMetadata<StandardMetadataType::SMPTE2086>(*bufferHandle);
1619     ASSERT_TRUE(value.has_value());
1620     ASSERT_TRUE(value->has_value());
1621     EXPECT_EQ(awesomeHdr, *value);
1622 
1623     EXPECT_EQ(AIMAPPER_ERROR_NONE,
1624               setStandardMetadata<StandardMetadataType::SMPTE2086>(*bufferHandle, std::nullopt));
1625     value = getStandardMetadata<StandardMetadataType::SMPTE2086>(*bufferHandle);
1626     ASSERT_TRUE(value.has_value());
1627     EXPECT_FALSE(value->has_value());
1628 }
1629 
TEST_P(GraphicsMapperStableCTests,GetCta861_3)1630 TEST_P(GraphicsMapperStableCTests, GetCta861_3) {
1631     auto buffer = allocateGeneric();
1632     ASSERT_TRUE(buffer);
1633     auto bufferHandle = buffer->import();
1634     ASSERT_TRUE(bufferHandle);
1635     auto value = getStandardMetadata<StandardMetadataType::CTA861_3>(*bufferHandle);
1636     ASSERT_TRUE(value.has_value());
1637     EXPECT_FALSE(value->has_value());
1638 
1639     const Cta861_3 genericHlgish{1000.f, 140.f};
1640     EXPECT_EQ(AIMAPPER_ERROR_NONE,
1641               setStandardMetadata<StandardMetadataType::CTA861_3>(*bufferHandle, genericHlgish));
1642     value = getStandardMetadata<StandardMetadataType::CTA861_3>(*bufferHandle);
1643     ASSERT_TRUE(value.has_value());
1644     ASSERT_TRUE(value->has_value());
1645     EXPECT_EQ(genericHlgish, *value);
1646 
1647     EXPECT_EQ(AIMAPPER_ERROR_NONE,
1648               setStandardMetadata<StandardMetadataType::CTA861_3>(*bufferHandle, std::nullopt));
1649     value = getStandardMetadata<StandardMetadataType::CTA861_3>(*bufferHandle);
1650     ASSERT_TRUE(value.has_value());
1651     EXPECT_FALSE(value->has_value());
1652 }
1653 
TEST_P(GraphicsMapperStableCTests,GetSmpte2094_10)1654 TEST_P(GraphicsMapperStableCTests, GetSmpte2094_10) {
1655     auto buffer = allocateGeneric();
1656     ASSERT_TRUE(buffer);
1657     auto bufferHandle = buffer->import();
1658     ASSERT_TRUE(bufferHandle);
1659     auto value = getStandardMetadata<StandardMetadataType::SMPTE2094_10>(*bufferHandle);
1660     if (value.has_value()) {
1661         EXPECT_FALSE(value->has_value());
1662     }
1663 }
1664 
TEST_P(GraphicsMapperStableCTests,GetSmpte2094_40)1665 TEST_P(GraphicsMapperStableCTests, GetSmpte2094_40) {
1666     auto buffer = allocateGeneric();
1667     ASSERT_TRUE(buffer);
1668     auto bufferHandle = buffer->import();
1669     ASSERT_TRUE(bufferHandle);
1670     auto value = getStandardMetadata<StandardMetadataType::SMPTE2094_40>(*bufferHandle);
1671     if (value.has_value()) {
1672         EXPECT_FALSE(value->has_value());
1673     }
1674 }
1675 
TEST_P(GraphicsMapperStableCTests,GetStride)1676 TEST_P(GraphicsMapperStableCTests, GetStride) {
1677     auto buffer = allocateGeneric();
1678     ASSERT_TRUE(buffer);
1679     auto bufferHandle = buffer->import();
1680     ASSERT_TRUE(bufferHandle);
1681     auto value = getStandardMetadata<StandardMetadataType::STRIDE>(*bufferHandle);
1682     ASSERT_TRUE(value.has_value());
1683     EXPECT_EQ(buffer->stride(), *value);
1684 }
1685 
TEST_P(GraphicsMapperStableCTests,SupportsRequiredGettersSetters)1686 TEST_P(GraphicsMapperStableCTests, SupportsRequiredGettersSetters) {
1687     auto buffer = allocateGeneric();
1688     ASSERT_TRUE(buffer);
1689     auto bufferHandle = buffer->import();
1690     ASSERT_TRUE(bufferHandle);
1691     const AIMapper_MetadataTypeDescription* descriptions = nullptr;
1692     size_t descriptionCount = 0;
1693     ASSERT_EQ(AIMAPPER_ERROR_NONE,
1694               mapper()->v5.listSupportedMetadataTypes(&descriptions, &descriptionCount));
1695     std::vector<StandardMetadataType> requiredGetters = {
1696             StandardMetadataType::BUFFER_ID,
1697             StandardMetadataType::NAME,
1698             StandardMetadataType::WIDTH,
1699             StandardMetadataType::HEIGHT,
1700             StandardMetadataType::LAYER_COUNT,
1701             StandardMetadataType::PIXEL_FORMAT_REQUESTED,
1702             StandardMetadataType::PIXEL_FORMAT_FOURCC,
1703             StandardMetadataType::PIXEL_FORMAT_MODIFIER,
1704             StandardMetadataType::USAGE,
1705             StandardMetadataType::ALLOCATION_SIZE,
1706             StandardMetadataType::PROTECTED_CONTENT,
1707             StandardMetadataType::COMPRESSION,
1708             StandardMetadataType::INTERLACED,
1709             StandardMetadataType::CHROMA_SITING,
1710             StandardMetadataType::PLANE_LAYOUTS,
1711             StandardMetadataType::CROP,
1712             StandardMetadataType::DATASPACE,
1713             StandardMetadataType::BLEND_MODE,
1714             StandardMetadataType::SMPTE2086,
1715             StandardMetadataType::CTA861_3,
1716             StandardMetadataType::STRIDE,
1717     };
1718 
1719     std::vector<StandardMetadataType> requiredSetters = {
1720             StandardMetadataType::DATASPACE,
1721             StandardMetadataType::BLEND_MODE,
1722             StandardMetadataType::SMPTE2086,
1723             StandardMetadataType::CTA861_3,
1724     };
1725 
1726     for (int i = 0; i < descriptionCount; i++) {
1727         const auto& it = descriptions[i];
1728         if (isStandardMetadata(it.metadataType)) {
1729             EXPECT_GT(it.metadataType.value, static_cast<int64_t>(StandardMetadataType::INVALID));
1730             EXPECT_LT(it.metadataType.value,
1731                       ndk::internal::enum_values<StandardMetadataType>.size());
1732 
1733             if (it.isGettable) {
1734                 std::erase(requiredGetters,
1735                            static_cast<StandardMetadataType>(it.metadataType.value));
1736             }
1737             if (it.isSettable) {
1738                 std::erase(requiredSetters,
1739                            static_cast<StandardMetadataType>(it.metadataType.value));
1740             }
1741         } else {
1742             EXPECT_NE(nullptr, it.description) << "Non-standard metadata must have a description";
1743             int len = strlen(it.description);
1744             EXPECT_GE(len, 0) << "Non-standard metadata must have a description";
1745         }
1746     }
1747 
1748     EXPECT_EQ(0, requiredGetters.size()) << "Missing required getters" << toString(requiredGetters);
1749     EXPECT_EQ(0, requiredSetters.size()) << "Missing required setters" << toString(requiredSetters);
1750 }
1751 
1752 /*
1753  * Test that verifies that if the optional StandardMetadataTypes have getters, they have
1754  * the required setters as well
1755  */
TEST_P(GraphicsMapperStableCTests,CheckRequiredSettersIfHasGetters)1756 TEST_P(GraphicsMapperStableCTests, CheckRequiredSettersIfHasGetters) {
1757     auto buffer = allocateGeneric();
1758     ASSERT_TRUE(buffer);
1759     auto bufferHandle = buffer->import();
1760     ASSERT_TRUE(bufferHandle);
1761     const AIMapper_MetadataTypeDescription* descriptions = nullptr;
1762     size_t descriptionCount = 0;
1763     ASSERT_EQ(AIMAPPER_ERROR_NONE,
1764               mapper()->v5.listSupportedMetadataTypes(&descriptions, &descriptionCount));
1765 
1766     for (int i = 0; i < descriptionCount; i++) {
1767         const auto& it = descriptions[i];
1768         if (isStandardMetadata(it.metadataType)) {
1769             const auto type = static_cast<StandardMetadataType>(it.metadataType.value);
1770             switch (type) {
1771                 case StandardMetadataType::SMPTE2094_10:
1772                 case StandardMetadataType::SMPTE2094_40:
1773                     if (it.isGettable) {
1774                         EXPECT_TRUE(it.isSettable)
1775                                 << "Type " << toString(type) << " must be settable if gettable";
1776                     }
1777                     break;
1778                 default:
1779                     break;
1780             }
1781         }
1782     }
1783 }
1784 
TEST_P(GraphicsMapperStableCTests,ListSupportedWorks)1785 TEST_P(GraphicsMapperStableCTests, ListSupportedWorks) {
1786     auto buffer = allocateGeneric();
1787     ASSERT_TRUE(buffer);
1788     auto bufferHandle = buffer->import();
1789     ASSERT_TRUE(bufferHandle);
1790     const AIMapper_MetadataTypeDescription* descriptions = nullptr;
1791     size_t descriptionCount = 0;
1792     ASSERT_EQ(AIMAPPER_ERROR_NONE,
1793               mapper()->v5.listSupportedMetadataTypes(&descriptions, &descriptionCount));
1794 
1795     std::vector<uint8_t> metadataBuffer;
1796     auto get = [&](AIMapper_MetadataType metadataType) -> int32_t {
1797         int32_t size = mapper()->v5.getMetadata(*bufferHandle, metadataType, nullptr, 0);
1798         if (size >= 0) {
1799             metadataBuffer.resize(size);
1800             size = mapper()->v5.getMetadata(*bufferHandle, metadataType, metadataBuffer.data(),
1801                                             metadataBuffer.size());
1802             EXPECT_EQ(size, metadataBuffer.size());
1803         }
1804         return size;
1805     };
1806 
1807     for (int i = 0; i < descriptionCount; i++) {
1808         const auto& it = descriptions[i];
1809         if (!isStandardMetadata(it.metadataType)) {
1810             continue;
1811         }
1812         if (!it.isGettable) {
1813             EXPECT_FALSE(it.isSettable)
1814                     << "StandardMetadata that isn't gettable must not be settable";
1815             continue;
1816         }
1817         EXPECT_GE(get(it.metadataType), 0)
1818                 << "Get failed for claimed supported getter of "
1819                 << toString(static_cast<StandardMetadataType>(it.metadataType.value));
1820         if (it.isSettable) {
1821             EXPECT_EQ(AIMAPPER_ERROR_NONE,
1822                       mapper()->v5.setMetadata(*bufferHandle, it.metadataType,
1823                                                metadataBuffer.data(), metadataBuffer.size()))
1824                     << "Failed to set metadata for "
1825                     << toString(static_cast<StandardMetadataType>(it.metadataType.value));
1826         }
1827     }
1828 }
1829 
TEST_P(GraphicsMapperStableCTests,GetMetadataBadValue)1830 TEST_P(GraphicsMapperStableCTests, GetMetadataBadValue) {
1831     auto get = [this](StandardMetadataType type) -> AIMapper_Error {
1832         // This is a _Nonnull parameter, but this is enough obfuscation to fool the linter
1833         buffer_handle_t buffer = nullptr;
1834         int32_t ret =
1835                 mapper()->v5.getStandardMetadata(buffer, static_cast<int64_t>(type), nullptr, 0);
1836         return (ret < 0) ? (AIMapper_Error)-ret : AIMAPPER_ERROR_NONE;
1837     };
1838 
1839     for (auto type : ndk::enum_range<StandardMetadataType>()) {
1840         if (type == StandardMetadataType::INVALID) {
1841             continue;
1842         }
1843         EXPECT_EQ(AIMAPPER_ERROR_BAD_BUFFER, get(type)) << "Wrong error for " << toString(type);
1844     }
1845 }
1846 
TEST_P(GraphicsMapperStableCTests,GetUnsupportedMetadata)1847 TEST_P(GraphicsMapperStableCTests, GetUnsupportedMetadata) {
1848     auto buffer = allocateGeneric();
1849     ASSERT_TRUE(buffer);
1850     auto bufferHandle = buffer->import();
1851     ASSERT_TRUE(bufferHandle);
1852 
1853     int result = mapper()->v5.getMetadata(*bufferHandle, {"Fake", 1}, nullptr, 0);
1854     EXPECT_EQ(AIMAPPER_ERROR_UNSUPPORTED, -result);
1855 
1856     result = mapper()->v5.getStandardMetadata(
1857             *bufferHandle, static_cast<int64_t>(StandardMetadataType::INVALID), nullptr, 0);
1858     EXPECT_EQ(AIMAPPER_ERROR_UNSUPPORTED, -result);
1859 
1860     constexpr int64_t unknownStandardType = ndk::internal::enum_values<StandardMetadataType>.size();
1861     result = mapper()->v5.getStandardMetadata(*bufferHandle, unknownStandardType, nullptr, 0);
1862     EXPECT_EQ(AIMAPPER_ERROR_UNSUPPORTED, -result);
1863 }
1864 
getIAllocatorsAtLeastVersion(int32_t minVersion)1865 std::vector<std::tuple<std::string, std::shared_ptr<IAllocator>>> getIAllocatorsAtLeastVersion(
1866         int32_t minVersion) {
1867     auto instanceNames = getAidlHalInstanceNames(IAllocator::descriptor);
1868     std::vector<std::tuple<std::string, std::shared_ptr<IAllocator>>> filteredInstances;
1869     filteredInstances.reserve(instanceNames.size());
1870     for (const auto& name : instanceNames) {
1871         auto allocator =
1872                 IAllocator::fromBinder(ndk::SpAIBinder(AServiceManager_checkService(name.c_str())));
1873         int32_t version = 0;
1874         if (allocator->getInterfaceVersion(&version).isOk()) {
1875             if (version >= minVersion) {
1876                 filteredInstances.emplace_back(name, std::move(allocator));
1877             }
1878         }
1879     }
1880     return filteredInstances;
1881 }
1882 
1883 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsMapperStableCTests);
1884 INSTANTIATE_TEST_CASE_P(PerInstance, GraphicsMapperStableCTests,
1885                         testing::ValuesIn(getIAllocatorsAtLeastVersion(2)),
__anonf29e99dc0502(auto info) 1886                         [](auto info) -> std::string {
1887                             std::string name =
1888                                     std::to_string(info.index) + "/" + std::get<0>(info.param);
1889                             return Sanitize(name);
1890                         });