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