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 <android/hardware/graphics/allocator/4.0/IAllocator.h>
24 #include <android/hardware/graphics/mapper/4.0/IMapper.h>
25 #include <gtest/gtest.h>
26 #include <utils/StrongPointer.h>
27 
28 namespace android {
29 namespace hardware {
30 namespace graphics {
31 namespace mapper {
32 namespace V4_0 {
33 namespace vts {
34 
35 using android::hardware::graphics::allocator::V4_0::IAllocator;
36 
37 // A wrapper to IAllocator and IMapper.
38 class Gralloc {
39   public:
40     enum class Tolerance : uint32_t {
41         kToleranceStrict = 0x0U,
42         kToleranceBadDescriptor = 0x1U << std::underlying_type_t<Error>(Error::BAD_DESCRIPTOR),
43         kToleranceBadBuffer = 0x1U << std::underlying_type_t<Error>(Error::BAD_BUFFER),
44         kToleranceBadValue = 0x1U << std::underlying_type_t<Error>(Error::BAD_VALUE),
45         kToleranceNoResource = 0x1U << std::underlying_type_t<Error>(Error::NO_RESOURCES),
46         kToleranceUnSupported = 0x1U << std::underlying_type_t<Error>(Error::UNSUPPORTED),
47         kToleranceAllErrors = ~0x0U,
48     };
49 
50     Gralloc(const std::string& allocatorServiceName = "default",
51             const std::string& mapperServiceName = "default", bool errOnFailure = true);
52     ~Gralloc();
53 
54     // IAllocator methods
55 
56     sp<IAllocator> getAllocator() const;
57 
58     // When import is false, this simply calls IAllocator::allocate. When import
59     // is true, the returned buffers are also imported into the mapper.
60     //
61     // Either case, the returned buffers must be freed with freeBuffer.
62     std::vector<const native_handle_t*> allocate(
63             const BufferDescriptor& descriptor, uint32_t count, bool import = true,
64             enum Tolerance tolerance = Tolerance::kToleranceStrict, uint32_t* outStride = nullptr);
65 
66     const native_handle_t* allocate(const IMapper::BufferDescriptorInfo& descriptorInfo,
67                                     bool import, enum Tolerance tolerance, uint32_t* outStride);
68 
allocate(const IMapper::BufferDescriptorInfo & descriptorInfo,bool import)69     const native_handle_t* allocate(const IMapper::BufferDescriptorInfo& descriptorInfo,
70                                     bool import) {
71         return allocate(descriptorInfo, import, Tolerance::kToleranceStrict);
72     }
73 
allocate(const IMapper::BufferDescriptorInfo & descriptorInfo,bool import,enum Tolerance tolerance)74     const native_handle_t* allocate(const IMapper::BufferDescriptorInfo& descriptorInfo,
75                                     bool import, enum Tolerance tolerance) {
76         return allocate(descriptorInfo, import, tolerance, nullptr);
77     }
78 
allocate(const IMapper::BufferDescriptorInfo & descriptorInfo,bool import,uint32_t * outStride)79     const native_handle_t* allocate(const IMapper::BufferDescriptorInfo& descriptorInfo,
80                                     bool import, uint32_t* outStride) {
81         return allocate(descriptorInfo, import, Tolerance::kToleranceStrict, outStride);
82     }
83 
84     // IMapper methods
85 
86     sp<IMapper> getMapper() const;
87 
88     BufferDescriptor createDescriptor(const IMapper::BufferDescriptorInfo& descriptorInfo);
89 
90     const native_handle_t* importBuffer(const hidl_handle& rawHandle, enum Tolerance tolerance);
importBuffer(const hidl_handle & rawHandle)91     const native_handle_t* importBuffer(const hidl_handle& rawHandle) {
92         return importBuffer(rawHandle, Tolerance::kToleranceStrict);
93     }
94 
95     void freeBuffer(const native_handle_t* bufferHandle);
96 
97     // We use fd instead of hidl_handle in these functions to pass fences
98     // in and out of the mapper.  The ownership of the fd is always transferred
99     // with each of these functions.
100     void* lock(const native_handle_t* bufferHandle, uint64_t cpuUsage,
101                const IMapper::Rect& accessRegion, int acquireFence);
102     int unlock(const native_handle_t* bufferHandle);
103 
104     int flushLockedBuffer(const native_handle_t* bufferHandle);
105     void rereadLockedBuffer(const native_handle_t* bufferHandle);
106 
107     bool validateBufferSize(const native_handle_t* bufferHandle,
108                             const IMapper::BufferDescriptorInfo& descriptorInfo, uint32_t stride);
109     void getTransportSize(const native_handle_t* bufferHandle, uint32_t* outNumFds,
110                           uint32_t* outNumInts);
111 
112     bool isSupported(const IMapper::BufferDescriptorInfo& descriptorInfo);
113 
114     Error get(const native_handle_t* bufferHandle, const IMapper::MetadataType& metadataType,
115               hidl_vec<uint8_t>* outVec);
116 
117     Error set(const native_handle_t* bufferHandle, const IMapper::MetadataType& metadataType,
118               const hidl_vec<uint8_t>& vec);
119 
120     Error getFromBufferDescriptorInfo(const IMapper::BufferDescriptorInfo& descriptorInfo,
121                                       const IMapper::MetadataType& metadataType,
122                                       hidl_vec<uint8_t>* outVec);
123 
124     Error getReservedRegion(const native_handle_t* bufferHandle, void** outReservedRegion,
125                             uint64_t* outReservedSize);
126 
127   private:
canTolerate(Tolerance tolerance,Error error)128     bool canTolerate(Tolerance tolerance, Error error) {
129         return (std::underlying_type_t<Tolerance>(tolerance) &
130                 0x1U << std::underlying_type_t<Error>(error)) != 0;
131     }
132 
133     void init(const std::string& allocatorServiceName, const std::string& mapperServiceName);
134 
135     // initialize without checking for failure to get service
136     void initNoErr(const std::string& allocatorServiceName, const std::string& mapperServiceName);
137     const native_handle_t* cloneBuffer(const hidl_handle& rawHandle, enum Tolerance tolerance);
cloneBuffer(const hidl_handle & rawHandle)138     const native_handle_t* cloneBuffer(const hidl_handle& rawHandle) {
139         return cloneBuffer(rawHandle, Tolerance::kToleranceStrict);
140     }
141 
142     sp<IAllocator> mAllocator;
143     sp<IMapper> mMapper;
144 
145     // Keep track of all cloned and imported handles.  When a test fails with
146     // ASSERT_*, the destructor will free the handles for the test.
147     std::unordered_set<const native_handle_t*> mClonedBuffers;
148     std::unordered_set<const native_handle_t*> mImportedBuffers;
149 };
150 
151 }  // namespace vts
152 }  // namespace V4_0
153 }  // namespace mapper
154 }  // namespace graphics
155 }  // namespace hardware
156 }  // namespace android
157