1 #include "GrallocAllocator2.h"
2
3 #include <aidl/android/hardware/graphics/allocator/AllocationError.h>
4 #include <aidlcommonsupport/NativeHandle.h>
5 #include <android/binder_ibinder.h>
6 #include <android/binder_status.h>
7 #include <cutils/android_filesystem_config.h>
8 #include <hidl/HidlSupport.h>
9 #include "hidl_common/Allocator.h"
10
11 namespace pixel::allocator {
12
13 namespace AidlAllocator = aidl::android::hardware::graphics::allocator;
14
15 using android::hardware::hidl_handle;
16 using android::hardware::hidl_vec;
17 using HidlError = android::hardware::graphics::mapper::V4_0::Error;
18
callingPid()19 unsigned long callingPid() {
20 return static_cast<unsigned long>(AIBinder_getCallingPid());
21 }
22
callingUid()23 unsigned long callingUid() {
24 return static_cast<unsigned long>(AIBinder_getCallingUid());
25 }
26
GrallocAllocator()27 GrallocAllocator::GrallocAllocator() {}
28
~GrallocAllocator()29 GrallocAllocator::~GrallocAllocator() {}
30
allocate(const std::vector<uint8_t> & descriptor,int32_t count,AidlAllocator::AllocationResult * result)31 ndk::ScopedAStatus GrallocAllocator::allocate(const std::vector<uint8_t>& descriptor, int32_t count,
32 AidlAllocator::AllocationResult* result) {
33 MALI_GRALLOC_LOGV("Allocation request from process: %lu", callingPid());
34
35 buffer_descriptor_t bufferDescriptor;
36 if (!arm::mapper::common::grallocDecodeBufferDescriptor(hidl_vec(descriptor),
37 bufferDescriptor)) {
38 return ndk::ScopedAStatus::fromServiceSpecificError(
39 static_cast<int32_t>(AidlAllocator::AllocationError::BAD_DESCRIPTOR));
40 }
41
42 // TODO(layog@): This dependency between AIDL and HIDL backends is not good.
43 // Ideally common::allocate should return the result and it should be encoded
44 // by this interface into HIDL or AIDL.
45 HidlError error = HidlError::NONE;
46 auto hidl_cb = [&](HidlError _error, int _stride, hidl_vec<hidl_handle> _buffers) {
47 if (_error != HidlError::NONE) {
48 error = _error;
49 return;
50 }
51
52 const uint32_t size = _buffers.size();
53
54 result->stride = _stride;
55 result->buffers.resize(size);
56 for (uint32_t i = 0; i < size; i++) {
57 // Dup here is necessary. After this callback returns common::allocate
58 // will free the buffer which will destroy the older fd.
59 result->buffers[i] = android::dupToAidl(static_cast<const native_handle*>(_buffers[i]));
60 }
61 };
62
63 arm::allocator::common::allocate(bufferDescriptor, count, hidl_cb);
64
65 switch (error) {
66 case HidlError::NONE:
67 break;
68
69 case HidlError::BAD_DESCRIPTOR:
70 return ndk::ScopedAStatus::fromServiceSpecificError(
71 static_cast<int32_t>(AidlAllocator::AllocationError::BAD_DESCRIPTOR));
72
73 case HidlError::NO_RESOURCES:
74 return ndk::ScopedAStatus::fromServiceSpecificError(
75 static_cast<int32_t>(AidlAllocator::AllocationError::NO_RESOURCES));
76
77 case HidlError::UNSUPPORTED:
78 return ndk::ScopedAStatus::fromServiceSpecificError(
79 static_cast<int32_t>(AidlAllocator::AllocationError::UNSUPPORTED));
80
81 default:
82 return ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_ERROR);
83 }
84
85 return ndk::ScopedAStatus::ok();
86 }
87
toInternalDescriptor(const AidlAllocator::BufferDescriptorInfo & descriptor)88 buffer_descriptor_t toInternalDescriptor(
89 const AidlAllocator::BufferDescriptorInfo& descriptor) {
90 buffer_descriptor_t bufferDescriptor;
91 bufferDescriptor.width = descriptor.width;
92 bufferDescriptor.height = descriptor.height;
93 bufferDescriptor.layer_count = descriptor.layerCount;
94 bufferDescriptor.hal_format = static_cast<uint64_t>(descriptor.format);
95 bufferDescriptor.producer_usage = static_cast<uint64_t>(descriptor.usage);
96 bufferDescriptor.consumer_usage = bufferDescriptor.producer_usage;
97 bufferDescriptor.format_type = MALI_GRALLOC_FORMAT_TYPE_USAGE;
98 bufferDescriptor.signature = sizeof(buffer_descriptor_t);
99 bufferDescriptor.reserved_size = descriptor.reservedSize;
100 const char *str = (const char*) descriptor.name.data();
101 bufferDescriptor.name = std::string(str);
102 return bufferDescriptor;
103 }
104
allocate2(const AidlAllocator::BufferDescriptorInfo & descriptor,int32_t count,AidlAllocator::AllocationResult * result)105 ndk::ScopedAStatus GrallocAllocator::allocate2(
106 const AidlAllocator::BufferDescriptorInfo& descriptor, int32_t count,
107 AidlAllocator::AllocationResult* result) {
108 MALI_GRALLOC_LOGV("Allocation request from process: %lu", callingPid());
109
110 buffer_descriptor_t bufferDescriptor = toInternalDescriptor(descriptor);
111
112 HidlError error = HidlError::NONE;
113 auto hidl_cb = [&](HidlError _error, int _stride, hidl_vec<hidl_handle> _buffers) {
114 if (_error != HidlError::NONE) {
115 error = _error;
116 return;
117 }
118
119 const uint32_t size = _buffers.size();
120
121 result->stride = _stride;
122 result->buffers.resize(size);
123 for (uint32_t i = 0; i < size; i++) {
124 // Dup here is necessary. After this callback returns common::allocate
125 // will free the buffer which will destroy the older fd.
126 result->buffers[i] = android::dupToAidl(static_cast<const native_handle*>(_buffers[i]));
127 }
128 };
129
130 arm::allocator::common::allocate(bufferDescriptor, count, hidl_cb);
131
132 switch (error) {
133 case HidlError::NONE:
134 break;
135
136 case HidlError::BAD_DESCRIPTOR:
137 return ndk::ScopedAStatus::fromServiceSpecificError(
138 static_cast<int32_t>(AidlAllocator::AllocationError::BAD_DESCRIPTOR));
139
140 case HidlError::NO_RESOURCES:
141 return ndk::ScopedAStatus::fromServiceSpecificError(
142 static_cast<int32_t>(AidlAllocator::AllocationError::NO_RESOURCES));
143
144 case HidlError::UNSUPPORTED:
145 return ndk::ScopedAStatus::fromServiceSpecificError(
146 static_cast<int32_t>(AidlAllocator::AllocationError::UNSUPPORTED));
147
148 default:
149 return ndk::ScopedAStatus::fromStatus(STATUS_UNKNOWN_ERROR);
150 }
151
152 return ndk::ScopedAStatus::ok();
153 }
154
155 // TODO(b/315883761): isSupported should return false for unknown-to-HAL usage
isSupported(const AidlAllocator::BufferDescriptorInfo & descriptor,bool * result)156 ndk::ScopedAStatus GrallocAllocator::isSupported(
157 const AidlAllocator::BufferDescriptorInfo& descriptor, bool* result) {
158 buffer_descriptor_t bufferDescriptor = toInternalDescriptor(descriptor);
159
160 bool isBufferDescriptorSupported = arm::allocator::common::isSupported(&bufferDescriptor);
161 *result = isBufferDescriptorSupported;
162
163 if (isBufferDescriptorSupported) {
164 MALI_GRALLOC_LOGV("Allocation for the given description will not succeed");
165 }
166 return ndk::ScopedAStatus::ok();
167 }
168
getIMapperLibrarySuffix(std::string * result)169 ndk::ScopedAStatus GrallocAllocator::getIMapperLibrarySuffix(std::string* result) {
170 *result = "pixel";
171 return ndk::ScopedAStatus::ok();
172 }
173
dump(int fd,const char **,uint32_t numArgs)174 binder_status_t GrallocAllocator::dump(int fd, const char** /* args */, uint32_t numArgs) {
175 if (callingUid() != AID_ROOT) {
176 const std::string permission_denied = "Permission Denied\n";
177 write(fd, permission_denied.c_str(), permission_denied.size());
178 return STATUS_PERMISSION_DENIED;
179 }
180
181 if (numArgs != 0) {
182 const std::string argument_error = "No argument expected\n";
183 write(fd, argument_error.c_str(), argument_error.size());
184 return STATUS_BAD_VALUE;
185 }
186
187 const std::string dump_info = arm::allocator::common::dump();
188 write(fd, dump_info.c_str(), dump_info.size());
189 return STATUS_OK;
190 }
191
192 } // namespace pixel::allocator
193
194